Completed
Push — develop ( 7d6075...b57d28 )
by
unknown
23:57 queued 15:50
created

TextSearchForm::add()   D

Complexity

Conditions 9
Paths 12

Size

Total Lines 30
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 30
rs 4.909
cc 9
eloc 16
nc 12
nop 2
1
<?php
2
/**
3
 * YAWIK
4
 *
5
 * @filesource
6
 * @license    MIT
7
 * @copyright  2013 - 2016 Cross Solution <http://cross-solution.de>
8
 */
9
10
/** */
11
namespace Core\Form;
12
13
use Traversable;
14
use Zend\Form\Exception;
15
use Zend\Form\Form as ZfForm;
16
use Zend\Json\Json;
17
use Zend\Stdlib\ArrayUtils;
18
19
/**
20
 * Simple Form for result list filtering.
21
 *
22
 * Should be used with the searchForm view helper.
23
 *
24
 * @author Mathias Gelhausen <[email protected]>
25
 * @since  0.25
26
 */
27
class TextSearchForm extends ZfForm
28
{
29
    protected $elementsFieldset = 'Core/TextSearch/Elements';
30
    protected $buttonsFieldset = 'Core/TextSearch/Buttons';
31
32
    public function setOptions($options)
33
    {
34
        parent::setOptions($options);
35
36
        $options = $this->options; // assure array
37
38
        if (isset($options['elements_fieldset'])) {
39
            $this->elementsFieldset = $options['elements_fieldset'];
40
        }
41
42
        if (isset($options['buttons_fieldset'])) {
43
            $this->buttonsFieldset = $options['buttons_fieldset'];
44
        }
45
46
        if (isset($options['name'])) {
47
            $this->setName($options['name']);
48
        }
49
50
        return $this;
51
    }
52
53
    public function init()
54
    {
55
        $this->setAttributes([
56
                                 'class'          => 'form-inline search-form',
57
                                 'data-handle-by' => 'script',
58
                                 'method'         => 'get',
59
                             ]
60
        );
61
62
        if (!$this->hasAttribute('name')) {
63
            $this->setName('search');
64
        }
65
66
        $elements = $this->elementsFieldset;
67
68
        if (!is_object($elements)) {
69
            $elements = ['type' => $elements, 'options' => $this->getOption('elements_options') ? : []];
70
71
        }
72
73
        $this->add($elements, ['name' => 'elements']);
74
75
        $buttons = $this->buttonsFieldset;
76
77
        if (!is_object($buttons)) {
78
            $buttons = ['type' => $buttons];
79
        }
80
81
        $this->add($buttons, ['name' => 'buttons']);
82
    }
83
84
    /**
85
     * Adds elements.
86
     *
87
     * For instances of this form, only fieldsets are allowed,  which are named
88
     * 'elements' or 'buttons' and implement
89
     * {@link TextSearchFormFieldset} or {@link TextSearchFormButtonsFieldset}
90
     *
91
     * Adding any other element will throw Exceptions.
92
     *
93
     * @param array|Traversable|\Zend\Form\ElementInterface $elementOrFieldset
94
     * @param array                                         $flags
95
     *
96
     * @return $this|ZfForm
97
     * @throws \UnexpectedValueException
98
     * @throws \InvalidArgumentException
99
     */
100
    public function add($elementOrFieldset, array $flags = [])
101
    {
102
        $name = null;
103
        if (isset($flags['name'])) {
104
            $name = $flags['name'];
105
106
        } else if (is_array($elementOrFieldset) && isset($elementOrFieldset['name'])) {
107
            $name = $elementOrFieldset['name'];
108
109
        } else if (is_object($elementOrFieldset)) {
110
            $name = $elementOrFieldset->getName();
0 ignored issues
show
Bug introduced by
The method getName does only exist in Zend\Form\ElementInterface, but not in Traversable.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
111
112
        }
113
114
        if (!$name || !in_array($name, ['elements', 'buttons'])) {
115
            throw new \InvalidArgumentException('Invalid named element. You can only add elements named "elements" or "buttons".');
116
        }
117
118
        parent::add($elementOrFieldset, $flags);
119
120
        $element = $this->get($name);
121
122
        if (!($element instanceOf TextSearchFormFieldset || $element instanceOf TextSearchFormButtonsFieldset)) {
123
            throw new \UnexpectedValueException(
124
                'Elements added to TextSearchForm must be fieldsets which extends from TextSearchForm[Buttons]Fieldset.'
125
            );
126
        }
127
128
        return $this;
129
    }
130
131
    /**
132
     * Gets the elements fieldset.
133
     *
134
     * @return TextSearchFormFieldset
135
     */
136
    public function getElements()
137
    {
138
        return $this->get('elements');
139
    }
140
141
    /**
142
     * Sets the initial search params.
143
     *
144
     * That means, the values for the element fields in the elements fieldset,
145
     * which should be set, if the form resets.
146
     *
147
     * @param array|\Traversable $params
148
     *
149
     * @return self
150
     */
151
    public function setSearchParams($params)
152
    {
153
        if ($params instanceOf \Traversable) {
154
            $params = ArrayUtils::iteratorToArray($params);
155
        }
156
157
        $params = Json::encode($params);
158
        $this->setAttribute('data-search-params', $params);
159
160
        return $this;
161
    }
162
163
    /**
164
     * Gets the buttons fieldset
165
     *
166
     * @return TextSearchFormButtonsFieldset
167
     */
168
    public function getButtons()
169
    {
170
        return $this->get('buttons');
171
    }
172
}