Completed
Pull Request — master (#457)
by Claus
02:40
created

ViewHelperInvoker::invoke()   C

Complexity

Conditions 9
Paths 300

Size

Total Lines 36

Duplication

Lines 9
Ratio 25 %

Importance

Changes 0
Metric Value
cc 9
nc 300
nop 4
dl 9
loc 36
rs 5.9722
c 0
b 0
f 0
1
<?php
2
namespace TYPO3Fluid\Fluid\Core\ViewHelper;
3
4
/*
5
 * This file belongs to the package "TYPO3 Fluid".
6
 * See LICENSE.txt that was shipped with this package.
7
 */
8
9
use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\NodeInterface;
10
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
11
12
/**
13
 * Class ViewHelperInvoker
14
 *
15
 * Class which is responsible for calling the render methods
16
 * on ViewHelpers, and this alone.
17
 *
18
 * Can be replaced via the ViewHelperResolver if the system
19
 * that implements Fluid requires special handling of classes.
20
 * This includes for example when you want to validate arguments
21
 * differently, wish to use another ViewHelper initialization
22
 * process, or wish to store instances of ViewHelpers to reuse
23
 * as if they were Singletons.
24
 *
25
 * To override the instantiation process and class name resolving,
26
 * see ViewHelperResolver. This particular class should only be
27
 * responsible for invoking the render method of a ViewHelper
28
 * using the properties available in the node.
29
 */
30
class ViewHelperInvoker
31
{
32
33
    /**
34
     * Invoke the ViewHelper described by the ViewHelperNode, the properties
35
     * of which will already have been filled by the ViewHelperResolver.
36
     *
37
     * @param string|ViewHelperInterface $viewHelperClassNameOrInstance
38
     * @param array $arguments
39
     * @param RenderingContextInterface $renderingContext
40
     * @param null|\Closure $renderChildrenClosure
41
     * @return string
42
     */
43
    public function invoke($viewHelperClassNameOrInstance, array $arguments, RenderingContextInterface $renderingContext, \Closure $renderChildrenClosure = null)
44
    {
45
        $viewHelperResolver = $renderingContext->getViewHelperResolver();
46
        if ($viewHelperClassNameOrInstance instanceof ViewHelperInterface) {
47
            $viewHelper = $viewHelperClassNameOrInstance;
48
        } else {
49
            $viewHelper = $viewHelperResolver->createViewHelperInstanceFromClassName($viewHelperClassNameOrInstance);
50
        }
51
        $expectedViewHelperArguments = $viewHelperResolver->getArgumentDefinitionsForViewHelper($viewHelper);
52
53
        // Rendering process
54
        $evaluatedArguments = [];
55
        $undeclaredArguments = [];
56
57
        try {
58 View Code Duplication
            foreach ($expectedViewHelperArguments as $argumentName => $argumentDefinition) {
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...
59
                $argumentValue = $arguments[$argumentName] ?? $argumentDefinition->getDefaultValue();
60
                $evaluatedArguments[$argumentName] = $argumentValue instanceof NodeInterface ? $argumentValue->evaluate($renderingContext) : $argumentValue;
61
            }
62 View Code Duplication
            foreach ($arguments as $argumentName => $argumentValue) {
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...
63
                if (!isset($evaluatedArguments[$argumentName])) {
64
                    $undeclaredArguments[$argumentName] = $argumentValue instanceof NodeInterface ? $argumentValue->evaluate($renderingContext) : $argumentValue;
65
                }
66
            }
67
68
            if ($renderChildrenClosure) {
69
                $viewHelper->setRenderChildrenClosure($renderChildrenClosure);
70
            }
71
            $viewHelper->setRenderingContext($renderingContext);
72
            $viewHelper->setArguments($evaluatedArguments);
73
            $viewHelper->handleAdditionalArguments($undeclaredArguments);
74
            return $viewHelper->initializeArgumentsAndRender();
75
        } catch (Exception $error) {
76
            return $renderingContext->getErrorHandler()->handleViewHelperError($error);
77
        }
78
    }
79
}
80