FormCollection   A
last analyzed

Complexity

Total Complexity 30

Size/Duplication

Total Lines 190
Duplicated Lines 0 %

Test Coverage

Coverage 67.01%

Importance

Changes 0
Metric Value
wmc 30
eloc 110
dl 0
loc 190
ccs 65
cts 97
cp 0.6701
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A setLayout() 0 4 1
A __invoke() 0 13 3
F render() 0 158 26
1
<?php
2
3
namespace Core\Form\View\Helper;
4
5
use Laminas\Form\View\Helper\FormCollection as LaminasFormCollection;
6
use Laminas\Form\ElementInterface;
7
use Laminas\Form\Element\Collection as CollectionElement;
8
use Laminas\Form\FieldsetInterface;
9
use Core\Form\ViewPartialProviderInterface;
10
use Core\Form\Element\ViewHelperProviderInterface;
11
12
class FormCollection extends LaminasFormCollection
13
{
14
    protected $layout;
15
    protected $isWithinCollection = false;
16
    protected $defaultElementHelper = 'formRow';
17
    
18 4
    public function __invoke(ElementInterface $element = null, $wrap = true, $layout = null)
19
    {
20 4
        if (!$element) {
21
            return $this;
22
        }
23
        
24 4
        if ($layout) {
25 3
            $this->setLayout($layout);
26
        }
27
28 4
        $this->setShouldWrap($wrap);
29
30 4
        return $this->render($element);
31
    }
32
    
33 3
    public function setLayout($layout)
34
    {
35 3
        $this->layout = $layout;
36 3
        return $this;
37
    }
38
39
    /**
40
     * @param ElementInterface $element
41
     * @param bool $useViewPartial
42
     * @return string
43
     */
44 4
    public function render(ElementInterface $element, $useViewPartial = false)
45
    {
46
        /* @var $renderer \Laminas\View\Renderer\PhpRenderer */
47 4
        $renderer = $this->getView();
48 4
        if (!method_exists($renderer, 'plugin')) {
49
            // Bail early if renderer is not pluggable
50
            return '';
51
        }
52
53
        /* @var $elementHelper \Laminas\Form\View\Helper\FormRow */
54 4
        $markup           = '';
55 4
        $templateMarkup   = '';
56 4
        $escapeHtmlHelper = $this->getEscapeHtmlHelper();
57 4
        $elementHelper    = $this->getElementHelper();
58 4
        $fieldsetHelper   = $this->getFieldsetHelper();
59
    
60 4
        $isCollectionElement = $element instanceof CollectionElement;
61
        /* @var $element ElementInterface|CollectionElement */
62 4
        if ($isCollectionElement && $element->shouldCreateTemplate()) {
63
            $this->isWithinCollection = true;
64
            $templateMarkup = $this->renderTemplate($element);
65
            $this->isWithinCollection = false;
66
        }
67
68 4
        $elementId = $element->getAttribute('id');
69 4
        if (!$elementId) {
70
            $elementId = preg_replace(
71
                array('~[^A-Za-z0-9_-]~', '~--+~', '~^-|-$~'),
72
                array('-'              , '-'    , ''       ),
73
                $element->getName()
74
            );
75
        }
76 4
        if ($formId = $element->getOption('__form_id__')) {
77 4
            $elementId = "$formId-$elementId";
78
        }
79
80 4
        $element->setAttribute('id', $elementId);
81
82
        /*
83
         * We had the problem, that collection templates were not rendered using the viewPartial due to the call
84
         * to this function from the parent class, which does not provide the $useViewPartial variable.
85
         * Currently this is fixed by always using the view partial if $this->isWithinCollection is true.
86
         *
87
         * We should consider using a new property $this->useViewPartial, for cover the case, where the
88
         * template should NOT be rendered using the view partial.
89
         *
90
         */
91 4
        if ($element instanceof ViewPartialProviderInterface && ($this->isWithinCollection || $useViewPartial)) {
92
            /* @var $partial \Laminas\View\Helper\Partial */
93
            $partial = $renderer->plugin('partial');
94
            return $partial(
95
                $element->getViewPartial(),
96
                array('element' => $element)
97
            );
98
        }
99
100 4
        foreach ($element->getIterator() as $elementOrFieldset) {
0 ignored issues
show
Bug introduced by
The method getIterator() does not exist on Laminas\Form\ElementInterface. It seems like you code against a sub-type of Laminas\Form\ElementInterface such as Laminas\Form\FieldsetInterface or Core\Form\Container or Laminas\Form\Fieldset. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

100
        foreach ($element->/** @scrutinizer ignore-call */ getIterator() as $elementOrFieldset) {
Loading history...
101
            /* @var $elementOrFieldset ElementInterface|ViewPartialProviderInterface|ViewHelperProviderInterface */
102 4
            if ($elementOrFieldset instanceof ViewPartialProviderInterface) {
103 1
                $elementOrFieldsetId = $elementOrFieldset->getAttribute('id');
0 ignored issues
show
Bug introduced by
The method getAttribute() does not exist on Core\Form\ViewPartialProviderInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Core\Form\ViewPartialProviderInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

103
                /** @scrutinizer ignore-call */ 
104
                $elementOrFieldsetId = $elementOrFieldset->getAttribute('id');
Loading history...
104 1
                if (!$elementOrFieldsetId) {
105 1
                    $elementOrFieldsetId = preg_replace(
106 1
                        array('~[^A-Za-z0-9_-]~', '~--+~', '~^-|-$~'),
107 1
                        array('-'              , '-'    , ''       ),
108 1
                        $elementOrFieldset->getName()
0 ignored issues
show
Bug introduced by
The method getName() does not exist on Core\Form\ViewPartialProviderInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Core\Form\ViewPartialProviderInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

108
                        $elementOrFieldset->/** @scrutinizer ignore-call */ 
109
                                            getName()
Loading history...
109
                    );
110
                }
111 1
                if ($formId) {
112 1
                    $elementOrFieldsetId = "$formId-$elementOrFieldsetId";
113
                }
114 1
                $elementOrFieldset->setAttribute('id', $elementOrFieldsetId);
0 ignored issues
show
Bug introduced by
The method setAttribute() does not exist on Core\Form\ViewPartialProviderInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Core\Form\ViewPartialProviderInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

114
                $elementOrFieldset->/** @scrutinizer ignore-call */ 
115
                                    setAttribute('id', $elementOrFieldsetId);
Loading history...
115
                /* @var $partial \Laminas\View\Helper\Partial */
116 1
                $partial = $renderer->plugin('partial');
117 1
                $markup .= $partial(
118 1
                    $elementOrFieldset->getViewPartial(),
119 1
                    array('element' => $elementOrFieldset)
120
                );
121 3
            } elseif ($elementOrFieldset instanceof FieldsetInterface) {
122
                if ($isCollectionElement) {
123
                    $this->isWithinCollection = true;
124
                }
125
                if ($elementOrFieldset instanceof ViewHelperProviderInterface) {
126
                    $helper = $elementOrFieldset->getViewHelper();
127
                    if (is_string($helper)) {
128
                        $helper = $renderer->plugin($helper);
129
                    }
130
                    $markup .= $helper($element);
131
                } else {
132
                    $markup .= $fieldsetHelper($elementOrFieldset);
133
                }
134
                $this->isWithinCollection = false;
135 3
            } elseif (false !== $elementOrFieldset->getOption('use_formrow_helper')) {
0 ignored issues
show
Bug introduced by
The method getOption() does not exist on Core\Form\Element\ViewHelperProviderInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Core\Form\Element\ViewHelperProviderInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

135
            } elseif (false !== $elementOrFieldset->/** @scrutinizer ignore-call */ getOption('use_formrow_helper')) {
Loading history...
136 3
                $markup .= $elementHelper($elementOrFieldset, null, null, $this->layout);
137
            } else {
138
                /* @var $formElement \Laminas\Form\View\Helper\FormElement */
139
                $formElement = $renderer->plugin('formelement');
140
                $formElement->render($elementOrFieldset);
141
            }
142
        }
143
    
144
        // If $templateMarkup is not empty, use it for simplify adding new element in JavaScript
145 4
        if (!empty($templateMarkup)) {
146
            $markup .= $templateMarkup;
147
        }
148
    
149
        
150
        // Every collection is wrapped by a fieldset if needed
151 4
        if ($this->shouldWrap) {
152 4
            if ($this->isWithinCollection) {
153
                $attrStr = $this->createAttributesString($element->getAttributes());
0 ignored issues
show
Bug introduced by
It seems like $element->getAttributes() can also be of type Traversable; however, parameter $attributes of Laminas\Form\View\Helper...reateAttributesString() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

153
                $attrStr = $this->createAttributesString(/** @scrutinizer ignore-type */ $element->getAttributes());
Loading history...
154
                $markup = sprintf('<fieldset %s><a class="remove-item yk-form-remove"><i class="yk-icon yk-icon-minus"></i></a>%s</fieldset>', $attrStr, $markup);
155
            } else {
156 4
                $label = $element->getLabel();
157
158 4
                if (empty($label) && $element->getOption('renderFieldset')) {
159 3
                    $attrStr = $this->createAttributesString($element->getAttributes());
160 3
                    $markup = sprintf(
161 3
                        '<fieldset %s><div class="fieldset-content">%s</div></fieldset>',
162
                        $attrStr,
163
                        $markup
164
                    );
165 1
                } elseif (!empty($label)) {
166 1
                    if (null !== ($translator = $this->getTranslator())) {
167 1
                        $label = $translator->translate(
168 1
                            $label,
169 1
                            $this->getTranslatorTextDomain()
170
                        );
171
                    }
172
    
173 1
                    $label = $escapeHtmlHelper($label);
174
                    
175 1
                    if ($isCollectionElement) {
176
                        $extraLegend = '<a href="#" class="add-item yk-form-add"><i class="yk-icon yk-icon-plus"></i></a>';
177
                        $class  = $element->getAttribute('class');
178
                        $class .= " form-collection";
179
                        $element->setAttribute('class', $class);
180
                        $divWrapperOpen = $divWrapperClose = '';
181
                    } else {
182 1
                        $extraLegend = $class = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $class is dead and can be removed.
Loading history...
183 1
                        $divWrapperOpen = '<div class="fieldset-content">';
184 1
                        $divWrapperClose = '</div>';
185
                    }
186 1
                    $attrStr = $this->createAttributesString($element->getAttributes());
187
                    
188 1
                    $markup = sprintf(
189 1
                        '<fieldset %s><legend>%s%s</legend>%s%s%s</fieldset>',
190
                        $attrStr,
191
                        $label,
192
                        $extraLegend,
193
                        $divWrapperOpen,
194
                        $markup,
195
                        $divWrapperClose
196
                    );
197
                }
198
            }
199
        }
200
    
201 4
        return $markup;
202
    }
203
}
204