Completed
Push — master ( b409f5...0471ad )
by Marc
02:37
created

buildRenderChildrenClosure()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 11
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 16
rs 9.4285
1
<?php
2
namespace TYPO3Fluid\Fluid\Core\ViewHelper\Traits;
3
4
use TYPO3Fluid\Fluid\Core\Compiler\TemplateCompiler;
5
use TYPO3Fluid\Fluid\Core\Compiler\ViewHelperCompiler;
6
use TYPO3Fluid\Fluid\Core\Exception;
7
use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\ViewHelperNode;
8
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
9
10
/**
11
 * Class CompilableWithContentArgumentAndRenderStatic
12
 *
13
 * Provides default methods for rendering and compiling
14
 * any ViewHelper that conforms to the `renderStatic`
15
 * method pattern but has the added common use case that
16
 * an argument value must be checked and used instead of
17
 * the normal render children closure, if that named
18
 * argument is specified and not empty.
19
 */
20
trait CompileWithContentArgumentAndRenderStatic
21
{
22
    /**
23
     * Name of variable that contains the value to use
24
     * instead of render children closure, if specified.
25
     * If no name is provided here, the first variable
26
     * registered in `initializeArguments` of the ViewHelper
27
     * will be used.
28
     *
29
     * Note: it is significantly better practice to define
30
     * this property in your ViewHelper class and so fix it
31
     * to one particular argument instead of resolving,
32
     * especially when your ViewHelper is called multiple
33
     * times within an uncompiled template!
34
     *
35
     * @var string
36
     */
37
    protected $contentArgumentName;
38
39
    /**
40
     * Default render method to render ViewHelper with
41
     * first defined optional argument as content.
42
     *
43
     * @return string Rendered string
44
     * @api
45
     */
46
    public function render()
47
    {
48
        return self::renderStatic(
0 ignored issues
show
Bug introduced by
The method renderStatic() does not exist on TYPO3Fluid\Fluid\Core\Vi...ArgumentAndRenderStatic. Did you maybe mean render()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
49
            $this->arguments,
0 ignored issues
show
Bug introduced by
The property arguments does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
50
            $this->buildRenderChildrenClosure(),
51
            $this->renderingContext
0 ignored issues
show
Bug introduced by
The property renderingContext does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
52
        );
53
    }
54
55
    /**
56
     * @param string $argumentsName
57
     * @param string $closureName
58
     * @param string $initializationPhpCode
59
     * @param ViewHelperNode $node
60
     * @param TemplateCompiler $compiler
61
     * @return string
62
     */
63 View Code Duplication
    public function compile(
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...
64
        $argumentsName,
65
        $closureName,
66
        &$initializationPhpCode,
67
        ViewHelperNode $node,
0 ignored issues
show
Unused Code introduced by
The parameter $node 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...
68
        TemplateCompiler $compiler
0 ignored issues
show
Unused Code introduced by
The parameter $compiler 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...
69
    ) {
70
        list ($initialization, $execution) = ViewHelperCompiler::getInstance()->compileWithCallToStaticMethod(
71
            $this,
72
            $argumentsName,
73
            $closureName,
74
            ViewHelperCompiler::RENDER_STATIC,
75
            static::class
76
        );
77
        $initializationPhpCode .= $initialization;
78
        return $execution;
79
    }
80
81
    /**
82
     * Helper which is mostly needed when calling renderStatic() from within
83
     * render().
84
     *
85
     * No public API yet.
86
     *
87
     * @return \Closure
88
     */
89
    protected function buildRenderChildrenClosure()
90
    {
91
        $argumentName = $this->resolveContentArgumentName();
92
        $arguments = $this->arguments;
93
        if (!empty($argumentName) && isset($arguments[$argumentName])) {
94
            $renderChildrenClosure = function () use ($arguments, $argumentName) {
95
                return $arguments[$argumentName];
96
            };
97
        } else {
98
            $self = clone $this;
99
            $renderChildrenClosure = function () use ($self) {
100
                return $self->renderChildren();
0 ignored issues
show
Bug introduced by
The method renderChildren() does not exist on TYPO3Fluid\Fluid\Core\Vi...ArgumentAndRenderStatic. Did you maybe mean render()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
101
            };
102
        }
103
        return $renderChildrenClosure;
104
    }
105
106
    /**
107
     * @return string
108
     */
109
    protected function resolveContentArgumentName()
110
    {
111
        if (empty($this->contentArgumentName)) {
112
            $registeredArguments = call_user_func_array([$this, 'prepareArguments'], []);
113
            foreach ($registeredArguments as $registeredArgument) {
114
                if (!$registeredArgument->isRequired()) {
115
                    $this->contentArgumentName = $registeredArgument->getName();
116
                    return $this->contentArgumentName;
117
                }
118
            }
119
            throw new Exception(
120
                'Attempting to compile %s failed. Chosen compile method requires that ViewHelper has ' .
121
                'at least one registered and optional argument'
122
            );
123
        }
124
        return $this->contentArgumentName;
125
    }
126
}
127