Completed
Pull Request — master (#14)
by
unknown
08:12
created

Renderer::renderClass()   B

Complexity

Conditions 5
Paths 16

Size

Total Lines 30
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 30
rs 8.439
c 0
b 0
f 0
cc 5
eloc 22
nc 16
nop 1
1
<?php
2
3
namespace SimpleEntityGeneratorBundle\Lib;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use SimpleEntityGeneratorBundle\Lib\Exceptions\RendererException;
7
use SimpleEntityGeneratorBundle\Lib\Exceptions\UnrecognizedItemToRenderException;
8
use SimpleEntityGeneratorBundle\Lib\Interfaces\RenderableInterface;
9
use SimpleEntityGeneratorBundle\Lib\Interfaces\SetterMethodInterface;
10
use SimpleEntityGeneratorBundle\Lib\Items\ClassConstructorManager;
11
use SimpleEntityGeneratorBundle\Lib\Items\ClassManager;
12
use SimpleEntityGeneratorBundle\Lib\Items\InitPropertyManager;
13
use SimpleEntityGeneratorBundle\Lib\Items\InterfaceManager;
14
use SimpleEntityGeneratorBundle\Lib\Items\MethodDerivedFromInterfaceManager;
15
use SimpleEntityGeneratorBundle\Lib\Items\MethodForPropertyManager;
16
use SimpleEntityGeneratorBundle\Lib\Items\MethodGetterBooleanInterfaceManager;
17
use SimpleEntityGeneratorBundle\Lib\Items\MethodGetterBooleanManager;
18
use SimpleEntityGeneratorBundle\Lib\Items\MethodGetterInterfaceManager;
19
use SimpleEntityGeneratorBundle\Lib\Items\MethodGetterManager;
20
use SimpleEntityGeneratorBundle\Lib\Items\PropertyManager;
21
use SimpleEntityGeneratorBundle\Lib\Items\TestClassManager;
22
use SimpleEntityGeneratorBundle\Lib\Items\TestMethodManager;
23
24
/**
25
 * Factory for rendering items
26
 *
27
 * @author Sławomir Kania <[email protected]>
28
 */
29
class Renderer
30
{
31
32
    /**
33
     * No indention
34
     *
35
     * @var integer
36
     */
37
    const INDENT_NO_INDENT = 0;
38
39
    /**
40
     * One indention
41
     *
42
     * @var integer
43
     */
44
    const INDENT_4_SPACES = 4;
45
46
    /**
47
     * Two indentations
48
     *
49
     * @var integer
50
     */
51
    const INDENT_8_SPACES = 8;
52
53
    /**
54
     * @var string
55
     */
56
    const JMS_ANNOTATION_NAMESPACE = "@\\JMS\\Serializer\\Annotation";
57
58
    /**
59
     * @var TemplateManager
60
     */
61
    private $templateManager;
62
63
    /**
64
     * CONSTR
65
     */
66
    public function __construct(TemplateManager $templateManager)
67
    {
68
        $this->templateManager = $templateManager;
69
    }
70
71
    /**
72
     * @return TemplateManager
73
     */
74
    public function getTemplateManager()
75
    {
76
        return $this->templateManager;
77
    }
78
79
    /**
80
     * Render renderable item
81
     *
82
     * @param RenderableInterface $item
83
     * @return string
84
     * @throws RendererException
85
     * @throws UnrecognizedItemToRenderException
86
     */
87
    public function render(RenderableInterface $item)
88
    {
89
        $this->getTemplateManager()->loadAndSetTemplateOnItem($item);
90
        switch (true) {
91
            case $item instanceof ClassManager:
92
                return $this->renderClass($item);
93
            case $item instanceof ClassConstructorManager:
94
                return $this->renderClassConstructor($item);
95
            case $item instanceof InitPropertyManager:
96
                return $this->renderInitProperty($item);
97
            case $item instanceof InterfaceManager:
98
                return $this->renderInterface($item);
99
            case $item instanceof PropertyManager:
100
                return $this->renderProperty($item);
101
            case $item instanceof MethodForPropertyManager:
102
                return $this->renderMethodForProperty($item);
103
            case $item instanceof MethodDerivedFromInterfaceManager:
104
                return $this->renderMethodDerivedFromInterface($item);
105
            case $item instanceof TestClassManager:
106
                return $this->renderTestClass($item);
107
            case $item instanceof TestMethodManager:
108
                return $this->renderTestMethod($item);
109
            default:
110
                throw $this->getExceptionUnrecognizedItem($item);
111
        }
112
    }
113
114
    /**
115
     * @param string $content
116
     * @param ClassConstructorManager $constructor
117
     * @param int $position
118
     * @return string
119
     */
120
    public function renderAndPutConstructorBodyToContent($content, ClassConstructorManager $constructor, $position = 0)
121
    {
122
        $source = Tools::explodeTemplateStringToArray($content);
123
        foreach ($constructor->getInitProperties() as $initProperty) {
124
            $this->putElementIntoSource($source, $position, $this->addIndentation($this->render($initProperty), self::INDENT_8_SPACES));
125
        }
126
127
        return Tools::implodeArrayToTemplate($source);
128
    }
129
130
    /**
131
     * @param string $content
132
     * @param ArrayCollection $itemsToRender
133
     * @param int $position
134
     * @return string
135
     */
136
    public function renderAndPutItemsToContent($content, ArrayCollection $itemsToRender, $position = 0)
137
    {
138
        $itemsRendered = [];
139
        foreach ($itemsToRender as $itemToRender) {
140
            $itemsRendered[] = $this->render($itemToRender);
141
        }
142
143
        return $this->updateSourceWithElements($content, $position, $itemsRendered);
144
    }
145
146
    /**
147
     * @param InitPropertyManager $initProperty
148
     * @return string
149
     * @throws RendererException
150
     */
151
    protected function renderInitProperty(InitPropertyManager $initProperty)
152
    {
153
        $template = $initProperty->getTemplate();
154
        $tags = $initProperty->getTemplateTags();
155
156
        $args[RenderableInterface::TAG_PROPERTY_NAME] = $initProperty->getProperty()->getPreparedName();
0 ignored issues
show
Coding Style Comprehensibility introduced by
$args was never initialized. Although not strictly required by PHP, it is generally a good practice to add $args = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
157
        $args[RenderableInterface::TAG_PROPERTY_TYPE] = sprintf('\%s', $initProperty->getProperty()->getTypeName());
158
        return $this->replace($tags, $args, $template);
159
    }
160
161
    /**
162
     * @param ClassConstructorManager $classConstructor
163
     * @return string
164
     * @throws RendererException
165
     */
166
    protected function renderClassConstructor(ClassConstructorManager $classConstructor)
167
    {
168
        $template = $classConstructor->getTemplate();
169
        $tags = $classConstructor->getTemplateTags();
170
171
        $initProperties = [];
172
        foreach ($classConstructor->getInitProperties() as $initProperty) {
173
            $initProperties[] = $this->render($initProperty);
174
        }
175
176
        $initPropertiesRendered = empty($initProperties) ? "" : Tools::implodeArrayToTemplate($initProperties);
177
        $args[RenderableInterface::TAG_INIT_PROPERTIES] = $initPropertiesRendered;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$args was never initialized. Although not strictly required by PHP, it is generally a good practice to add $args = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
178
179
        return $this->addNewLineAfter($this->addIndentation($this->replace($tags, $args, $template), self::INDENT_4_SPACES));
180
    }
181
182
    /**
183
     * @param MethodForPropertyManager $method
184
     * @return string
185
     * @throws RendererException
186
     * @throws UnrecognizedItemToRenderException
187
     */
188
    protected function renderMethodForProperty(MethodForPropertyManager $method)
189
    {
190
        $template = $method->getTemplate();
191
        $tags = $method->getTemplateTags();
192
193
        $property = $method->getProperty();
194
        $propertyName = $property->getPreparedName();
195
        $methodName = $method->getPreparedName();
196
        $comment = sprintf('For property "%s"', $propertyName);
197
198
        $args = [];
199
        switch (true) {
200 View Code Duplication
            case $method instanceof MethodGetterManager:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
201
                $args[RenderableInterface::TAG_COMMENT] = $comment;
202
                $args[RenderableInterface::TAG_PROPERTY_TYPE] = $this->getScalarTypeOrAbsoluteObjectTypeFromProperty($property);
203
                $args[RenderableInterface::TAG_METHOD_NAME] = $methodName;
204
                $args[RenderableInterface::TAG_PROPERTY_NAME] = $propertyName;
205
                break;
206
            case $method instanceof MethodGetterInterfaceManager:
207
                $args[RenderableInterface::TAG_COMMENT] = $comment;
208
                $args[RenderableInterface::TAG_PROPERTY_TYPE] = $this->getScalarTypeOrAbsoluteObjectTypeFromProperty($property);
209
                $args[RenderableInterface::TAG_METHOD_NAME] = $methodName;
210
                break;
211 View Code Duplication
            case $method instanceof MethodGetterBooleanManager:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
212
                $args[RenderableInterface::TAG_COMMENT] = $comment;
213
                $args[RenderableInterface::TAG_PROPERTY_TYPE] = $this->getScalarTypeOrAbsoluteObjectTypeFromProperty($property);
214
                $args[RenderableInterface::TAG_METHOD_NAME] = $methodName;
215
                $args[RenderableInterface::TAG_PROPERTY_NAME] = $propertyName;
216
                break;
217
            case $method instanceof MethodGetterBooleanInterfaceManager:
218
                $args[RenderableInterface::TAG_COMMENT] = $comment;
219
                $args[RenderableInterface::TAG_PROPERTY_TYPE] = $this->getScalarTypeOrAbsoluteObjectTypeFromProperty($property);
220
                $args[RenderableInterface::TAG_METHOD_NAME] = $methodName;
221
                break;
222
            case $method instanceof SetterMethodInterface:
223
                $typeHintitngPart = '';
224
                if ($method->canAddTypeHinting()) {
225
                    $typeHintitngPart = sprintf('%s ', $property->getTypeNameAbsoluteIfIsObjectTypeOrThrowException());
226
                }
227
228
                $optionalPart = '';
229
                if ($property->isOptional()) {
230
                    $optionalPart = ' = null';
231
                }
232
233
                $args[RenderableInterface::TAG_COMMENT] = $comment;
234
                $args[RenderableInterface::TAG_PROPERTY_TYPE] = $this->getScalarTypeOrAbsoluteObjectTypeFromProperty($property);
235
                $args[RenderableInterface::TAG_TYPE_HINTING] = $typeHintitngPart;
236
                $args[RenderableInterface::TAG_METHOD_NAME] = $methodName;
237
                $args[RenderableInterface::TAG_PROPERTY_NAME] = $propertyName;
238
                $args[RenderableInterface::TAG_OPTIONAL_PART] = $optionalPart;
239
                break;
240
            default:
241
                throw $this->getExceptionUnrecognizedItem($method);
242
        }
243
244
        return $this->addNewLineAfter($this->addIndentation($this->replace($tags, $args, $template), self::INDENT_4_SPACES));
245
    }
246
247
    protected function renderMethodDerivedFromInterface(MethodDerivedFromInterfaceManager $method)
248
    {
249
        $template = $method->getTemplate();
250
        $tags = $method->getTemplateTags();
251
        $args = [
252
            RenderableInterface::TAG_METHOD_NAME => $method->getPreparedName()
253
        ];
254
        return $this->addNewLineAfter($this->addIndentation($this->replace($tags, $args, $template), self::INDENT_4_SPACES));
255
    }
256
257
    /**
258
     * @param ClassManager $class
259
     * @return string
260
     * @throws RendererException
261
     */
262
    protected function renderClass(ClassManager $class)
263
    {
264
        $template = $class->getTemplate();
265
        $tags = $class->getTemplateTags();
266
267
        $properties = [];
268
        $methods = [];
269
        $extendsPart = '';
270
        foreach ($class->getProperties() as $property) {
271
            $properties[] = $this->render($property);
272
        }
273
        foreach ($class->getMethods() as $method) {
274
            $methods[] = $this->render($method);
275
        }
276
        if ($class->hasExtends()) {
277
            $extendsPart = sprintf(" extends %s", $class->getExtends());
278
        }
279
280
        $args[RenderableInterface::TAG_NAMESPACE] = $class->getNamespaceWithoutNameAndBackslashPrefix();
0 ignored issues
show
Coding Style Comprehensibility introduced by
$args was never initialized. Although not strictly required by PHP, it is generally a good practice to add $args = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
281
        $args[RenderableInterface::TAG_COMMENT] = empty($class->getComment()) ? "" : $class->getComment();
282
        $args[RenderableInterface::TAG_NAME] = $class->getName();
283
        $args[RenderableInterface::TAG_EXTENDS] = $extendsPart;
284
        $args[RenderableInterface::TAG_INTERFACE] = $this->renderInterfacePart($class);
285
        $args[RenderableInterface::TAG_CONSTRUCTOR] = $this->addNewLineBefore($this->render($class->getConstructor()));
286
        $args[RenderableInterface::TAG_PROPERTIES] = $this->addNewLineBefore(Tools::implodeArrayToTemplate($properties));
287
        $args[RenderableInterface::TAG_METHODS] = $this->addNewLineBefore(Tools::implodeArrayToTemplate($methods));
288
        $args[RenderableInterface::TAG_MULTILINE_COMMENT] = $this->prepareMultilineCommentForCollection($class->getMultilineComment());
289
290
        return $this->addNewLineAfter($this->replace($tags, $args, $template));
291
    }
292
293
    protected function renderInterfacePart(ClassManager $class)
294
    {
295
        $namespaces = $class->getImplements()->toArray();
296
        if ($class->hasInterface()) {
297
            $namespaces[] = $class->getInterface()->getNamespace();
298
        }
299
        $namespacesStr = implode(', ', $namespaces);
300
        return $namespacesStr ? sprintf(" implements %s", $namespacesStr) : '';
301
    }
302
303
    /**
304
     * @param InterfaceManager $interface
305
     * @return string
306
     * @throws RendererException
307
     */
308
    protected function renderInterface(InterfaceManager $interface)
309
    {
310
        $template = $interface->getTemplate();
311
        $tags = $interface->getTemplateTags();
312
313
        $methods = [];
314
        foreach ($interface->getMethods() as $method) {
315
            $methods[] = $this->render($method);
316
        }
317
318
        $args[RenderableInterface::TAG_NAMESPACE] = $interface->getNamespaceWithoutNameAndBackslashPrefix();
0 ignored issues
show
Coding Style Comprehensibility introduced by
$args was never initialized. Although not strictly required by PHP, it is generally a good practice to add $args = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
319
        $args[RenderableInterface::TAG_COMMENT] = $interface->getComment();
320
        $args[RenderableInterface::TAG_NAME] = $interface->getName();
321
        $args[RenderableInterface::TAG_METHODS] = $this->addNewLineBefore(Tools::implodeArrayToTemplate($methods));
322
323
        return $this->addNewLineAfter($this->replace($tags, $args, $template));
324
    }
325
326
    /**
327
     * @param PropertyManager $property
328
     * @return string
329
     * @throws RendererException
330
     */
331
    protected function renderProperty(PropertyManager $property)
332
    {
333
        $template = $property->getTemplate();
334
        $tags = $property->getTemplateTags();
335
336
        $comment = $property->getComment();
337
        if (empty($comment)) {
338
            $comment = sprintf("'%s' property", $property->getName());
339
        }
340
341
        $jmsCollection = new ArrayCollection();
342
        $jmsCollection->add(sprintf("%s\Type(\"%s\")", self::JMS_ANNOTATION_NAMESPACE, $property->getType()));
343
        if ($property->hasSerializedName()) {
344
            $jmsCollection->add(sprintf("%s\SerializedName(\"%s\")", self::JMS_ANNOTATION_NAMESPACE, $property->getSerializedName()));
345
        } else {
346
            $jmsCollection->add(sprintf("%s\SerializedName(\"%s\")", self::JMS_ANNOTATION_NAMESPACE, $property->getName()));
347
        }
348
349
        $args[RenderableInterface::TAG_COMMENT] = $comment;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$args was never initialized. Although not strictly required by PHP, it is generally a good practice to add $args = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
350
        $args[RenderableInterface::TAG_CONSTRAINTS] = $this->prepareMultilineCommentForCollection($property->getConstraintAnnotationCollection());
351
        $args[RenderableInterface::TAG_JMS_PART] = $this->prepareMultilineCommentForCollection($jmsCollection);
352
        $args[RenderableInterface::TAG_TYPE] = $this->getScalarTypeOrAbsoluteObjectTypeFromProperty($property);
353
        $args[RenderableInterface::TAG_NAME] = $property->getPreparedName();
354
        $args[RenderableInterface::TAG_MULTILINE_COMMENT] = $this->prepareMultilineCommentForCollection($property->getMultilineComment());
355
356
        return $this->addNewLineAfter($this->addIndentation($this->replace($tags, $args, $template), self::INDENT_4_SPACES));
357
    }
358
359
    /**
360
     * @param TestClassManager $testClass
361
     * @return string
362
     * @throws RendererException
363
     */
364
    protected function renderTestClass(TestClassManager $testClass)
365
    {
366
        $template = $testClass->getTemplate();
367
        $tags = $testClass->getTemplateTags();
368
369
        $constructTestMethodBody = [];
370
        $methods = [];
371
        foreach ($testClass->getMethods() as $method) {
372
            $methods[] = $this->render($method);
373
        }
374
375
        $class = $testClass->getClassManager();
376
377
        $constructTestMethodBody[] = "\$this->assertNotNull(\$this->object);";
378
        if ($testClass->getClassManager()->hasInterface()) {
379
            $interfaceTestAssert = sprintf("\$this->assertInstanceof('%s', \$this->object);", $testClass->getClassManager()->getInterface()->getNamespace());
380
            $constructTestMethodBody[] = $this->addIndentation($interfaceTestAssert, self::INDENT_8_SPACES);
381
        }
382
383
        $classTestAssert = sprintf("\$this->assertInstanceof('%s', \$this->object);", $class->getNamespace());
384
        $constructTestMethodBody[] = $this->addIndentation($classTestAssert, self::INDENT_8_SPACES);
385
386
        if ($testClass->getClassManager()->hasExtends()) {
387
            $extendsTestAssert = sprintf("\$this->assertInstanceof('%s', \$this->object);", $testClass->getClassManager()->getExtends());
388
            $constructTestMethodBody[] = $this->addIndentation($extendsTestAssert, self::INDENT_8_SPACES);
389
        }
390
391
        $testObjectType = $class->getNamespace();
392
        if ($class->hasInterface()) {
393
            $testObjectType = $class->getInterface()->getNamespace();
394
        }
395
396
        $args[RenderableInterface::TAG_NAMESPACE] = $testClass->getNamespaceWithoutNameAndBackslashPrefix();
0 ignored issues
show
Coding Style Comprehensibility introduced by
$args was never initialized. Although not strictly required by PHP, it is generally a good practice to add $args = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
397
        $args[RenderableInterface::TAG_COMMENT] = $testClass->getComment();
398
        $args[RenderableInterface::TAG_NAME] = $testClass->getName();
399
        $args[RenderableInterface::TAG_CLASS] = $class->getNamespace();
400
        $args[RenderableInterface::TAG_METHODS] = $this->addNewLineBefore(Tools::implodeArrayToTemplate($methods));
401
        $args[RenderableInterface::TAG_TEST_OBJECT_TYPE] = $testObjectType;
402
        $args[RenderableInterface::TAG_METHOD_BODY] = Tools::implodeArrayToTemplate($constructTestMethodBody);
403
404
        return $this->addNewLineAfter($this->replace($tags, $args, $template));
405
    }
406
407
    /**
408
     * @param TestMethodManager $testMethod
409
     * @return string
410
     * @throws RendererException
411
     */
412
    protected function renderTestMethod(TestMethodManager $testMethod)
413
    {
414
        $template = $testMethod->getTemplate();
415
        $tags = $testMethod->getTemplateTags();
416
417
        $args[RenderableInterface::TAG_CLASS] = $testMethod->getMethod()->getClassManager()->getNamespace();
0 ignored issues
show
Coding Style Comprehensibility introduced by
$args was never initialized. Although not strictly required by PHP, it is generally a good practice to add $args = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
418
        $args[RenderableInterface::TAG_METHOD_NAME] = $testMethod->getMethod()->getPreparedName();
419
        $args[RenderableInterface::TAG_TEST_METHOD_NAME] = $testMethod->getPreparedName();
420
421
        return $this->addNewLineAfter($this->addIndentation($this->replace($tags, $args, $template), self::INDENT_4_SPACES));
422
    }
423
424
    /**
425
     * Replace tags in template witch arguments
426
     *
427
     * @param array $tags
428
     * @param array $args
429
     * @param string $template
430
     * @return string
431
     * @throws RendererException
432
     */
433
    protected function replace($tags, $args, $template)
434
    {
435
        if ($tags !== array_keys($args)) {
436
            throw new RendererException("Tags and keys are not identical!");
437
        }
438
439
        return str_replace($tags, array_values($args), $template);
440
    }
441
442
    /**
443
     * Add Indentation to template
444
     *
445
     * @param string $template
446
     * @param integer $spaces
447
     * @return string
448
     */
449
    protected function addIndentation($template, $spaces = self::INDENT_NO_INDENT)
450
    {
451
        $parts = Tools::explodeTemplateStringToArray($template);
452
        array_walk(
453
            $parts, function (&$value) use ($spaces) {
454
            $value = str_pad($value, strlen($value) + (int)$spaces, " ", STR_PAD_LEFT);
455
        }
456
        );
457
458
        return Tools::implodeArrayToTemplate($parts);
459
    }
460
461
    /**
462
     * @param mixed $item
463
     * @return UnrecognizedItemToRenderException
464
     */
465
    protected function getExceptionUnrecognizedItem($item)
466
    {
467
        return new UnrecognizedItemToRenderException(sprintf("Unrecognized item: %s", get_class($item)));
468
    }
469
470
    /**
471
     * Update source file with rendered elements
472
     *
473
     * @param string $content
474
     * @param integer $startPosition
475
     * @param array $renderedElements
476
     * @return string
477
     */
478
    protected function updateSourceWithElements($content, $startPosition = 0, array $renderedElements = [])
479
    {
480
        $source = Tools::explodeTemplateStringToArray($content);
481
        foreach ($renderedElements as $renderedElement) {
482
            $this->putElementIntoSource($source, $startPosition, $renderedElement);
483
        }
484
485
        return Tools::implodeArrayToTemplate($source);
486
    }
487
488
    /**
489
     * @param array $source
490
     * @param integer $offset
491
     * @param string $element
492
     */
493
    protected function putElementIntoSource(&$source, $offset, $element)
494
    {
495
        array_splice($source, $offset, 0, [$element]);
496
    }
497
498
    /**
499
     * Put new line to the end of conent
500
     *
501
     * @param string $content
502
     * @return string
503
     * @throws RendererException
504
     */
505 View Code Duplication
    protected function addNewLineAfter($content)
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...
506
    {
507
        if (false === is_string($content)) {
508
            throw new RendererException("Invalid string!");
509
        }
510
511
        return sprintf("%s\n", $content);
512
    }
513
514
    /**
515
     * Put new line before conent
516
     *
517
     * @param string $content
518
     * @return string
519
     * @throws RendererException
520
     */
521 View Code Duplication
    protected function addNewLineBefore($content)
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...
522
    {
523
        if (false === is_string($content)) {
524
            throw new RendererException("Invalid string!");
525
        }
526
527
        return sprintf("\n%s", $content);
528
    }
529
530
    /**
531
     * @param ArrayCollection $collection
532
     * @return string
533
     * @throws \Exception
534
     */
535
    protected function prepareMultilineCommentForCollection(ArrayCollection $collection)
536
    {
537
        if ($collection->isEmpty()) {
538
            return "";
539
        }
540
541
        $multilinePrepared = [];
542
        $first = true;
543
        foreach ($collection as $row) {
544
            if ($first) {
545
                $multilinePrepared[] = sprintf("%s", $row);
546
            } else {
547
                $multilinePrepared[] = sprintf(" * %s", $row);
548
            }
549
            $first = false;
550
        }
551
552
        return Tools::implodeArrayToTemplate($multilinePrepared);
553
    }
554
555
    /**
556
     * @param PropertyManager $property
557
     * @return string
558
     * @throws \Exception
559
     */
560
    protected function getScalarTypeOrAbsoluteObjectTypeFromProperty(PropertyManager $property)
561
    {
562
        if ($property->isObjectType()) {
563
            return $property->getTypeNameAbsoluteIfIsObjectTypeOrThrowException();
564
        } else {
565
            return $property->getTypeName();
566
        }
567
    }
568
}
569