Passed
Push — fix-html ( 588533 )
by Alexander
12:56
created

FileInput::withoutHiddenInput()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Widget;
6
7
use Yiisoft\Arrays\ArrayHelper;
8
use Yiisoft\Widget\Widget;
9
use Yiisoft\Form\FormModelInterface;
10
11
final class FileInput extends Widget
12
{
13
    private FormModelInterface $data;
14
    private string $attribute;
15
    private array $options = [];
16
    private bool $withoutHiddenInput = false;
17
18
    /**
19
     * Generates a file input tag for the given form attribute.
20
     *
21
     * @return string the generated input tag.
22
     */
23
    public function run(): string
24
    {
25
        $new = clone $this;
26
27
        $hiddenOptions = ['id' => false, 'value' => ''];
28
29
        if (isset($new->options['name'])) {
30
            $hiddenOptions['name'] = $new->options['name'];
31
        }
32
33
        /** make sure disabled input is not sending any value */
34
        if (!empty($new->options['disabled'])) {
35
            $hiddenOptions['disabled'] = $new->options['disabled'];
36
        }
37
38
        $hiddenOptions = ArrayHelper::merge($hiddenOptions, ArrayHelper::remove($new->options, 'hiddenOptions', []));
39
40
        /**
41
         * Add a hidden field so that if a form only has a file field, we can still use isset($body[$formClass]) to
42
         * detect if the input is submitted.
43
         * The hidden input will be assigned its own set of html options via `$hiddenOptions`.
44
         * This provides the possibility to interact with the hidden field via client script.
45
         *
46
         * Note: For file-field-only form with `disabled` option set to `true` input submitting detection won't work.
47
         */
48
        $hiddenInput = '';
49
50
        if ($new->withoutHiddenInput === false) {
51
            $hiddenInput = HiddenInput::widget()->config($new->data, $new->attribute, $hiddenOptions)->run();
0 ignored issues
show
Bug introduced by
The method config() does not exist on Yiisoft\Widget\Widget. It seems like you code against a sub-type of said class. However, the method does not exist in Yiisoft\Widget\Tests\Stubs\TestWidget or Yiisoft\Widget\Tests\Stubs\TestWidgetA or Yiisoft\Widget\Tests\Stubs\TestInjectionWidget or Yiisoft\Form\Widget\Form or Yiisoft\Widget\Tests\Stubs\TestWidgetB. Are you sure you never get one of those? ( Ignorable by Annotation )

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

51
            $hiddenInput = HiddenInput::widget()->/** @scrutinizer ignore-call */ config($new->data, $new->attribute, $hiddenOptions)->run();
Loading history...
52
        }
53
54
        $new->options['value'] = false;
55
        return
56
            $hiddenInput .
57
            Input::widget()
58
                ->type('file')
0 ignored issues
show
Bug introduced by
The method type() does not exist on Yiisoft\Widget\Widget. It seems like you code against a sub-type of Yiisoft\Widget\Widget such as Yiisoft\Form\Widget\ListBox or Yiisoft\Form\Widget\Input or Yiisoft\Form\Widget\ListInput or Yiisoft\Form\Widget\BooleanInput. ( Ignorable by Annotation )

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

58
                ->/** @scrutinizer ignore-call */ type('file')
Loading history...
59
                ->config($new->data, $new->attribute, $new->options)
60
                ->run();
61
    }
62
63
    /**
64
     * Set form model, name and options for the widget.
65
     *
66
     * @param FormModelInterface $data Form model.
67
     * @param string $attribute Form model property this widget is rendered for.
68
     * @param array $options The HTML attributes for the widget container tag.
69
     * See {@see \Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
70
     *
71
     * @return self
72
     */
73
    public function config(FormModelInterface $data, string $attribute, array $options = []): self
74
    {
75
        $new = clone $this;
76
        $new->data = $data;
77
        $new->attribute = $attribute;
78
        $new->options = $options;
79
        return $new;
80
    }
81
82
    /**
83
     * The accept attribute value is a string that defines the file types the file input should accept. This string is
84
     * a comma-separated list of unique file type specifiers. Because a given file type may be identified in more than
85
     * one manner, it's useful to provide a thorough set of type specifiers when you need files of a given format.
86
     *
87
     * @param string $value
88
     *
89
     * @return self
90
     */
91
    public function accept(string $value): self
92
    {
93
        $new = clone $this;
94
        $new->options['accept'] = $value;
95
        return $new;
96
    }
97
98
    /**
99
     * Focus on the control (put cursor into it) when the page loads.
100
     * Only one form element could be in focus at the same time.
101
     *
102
     * @param bool $value
103
     *
104
     * @return self
105
     */
106
    public function autofocus(bool $value = true): self
107
    {
108
        $new = clone $this;
109
        $new->options['autofocus'] = $value;
110
        return $new;
111
    }
112
113
    /**
114
     * Set whether the element is disabled or not.
115
     *
116
     * If this attribute is set to `true`, the element is disabled. Disabled elements are usually drawn with grayed-out
117
     * text.
118
     * If the element is disabled, it does not respond to user actions, it cannot be focused, and the command event
119
     * will not fire. In the case of form elements, it will not be submitted. Do not set the attribute to true, as
120
     * this will suggest you can set it to false to enable the element again, which is not the case.
121
     *
122
     * @param bool $value
123
     *
124
     * @return self
125
     */
126
    public function disabled(bool $value = true): self
127
    {
128
        $new = clone $this;
129
        $new->options['disabled'] = $value;
130
        return $new;
131
    }
132
133
    /**
134
     * HiddenOptions parameter which is another set of HTML options array is defined, to be used for the hidden input.
135
     *
136
     * @param array $value
137
     *
138
     * @return self
139
     */
140
    public function hiddenOptions(array $value = []): self
141
    {
142
        $new = clone $this;
143
        $new->options['hiddenOptions'] = $value;
144
        return $new;
145
    }
146
147
    /**
148
     * When the multiple Boolean attribute is specified, the file input allows the user to select more than one file.
149
     *
150
     * @param bool $value
151
     *
152
     * @return self
153
     */
154
    public function multiple(bool $value = true): self
155
    {
156
        $new = clone $this;
157
        $new->options['multiple'] = $value;
158
        return $new;
159
    }
160
161
    /**
162
     * If it is required to fill in a value in order to submit the form.
163
     *
164
     * @param bool $value
165
     *
166
     * @return self
167
     */
168
    public function required(bool $value = true): self
169
    {
170
        $new = clone $this;
171
        $new->options['required'] = $value;
172
        return $new;
173
    }
174
175
    /**
176
     * The tabindex global attribute indicates that its element can be focused, and where it participates in sequential
177
     * keyboard navigation (usually with the Tab key, hence the name).
178
     *
179
     * It accepts an integer as a value, with different results depending on the integer's value:
180
     *
181
     * - A negative value (usually tabindex="-1") means that the element is not reachable via sequential keyboard
182
     * navigation, but could be focused with Javascript or visually. It's mostly useful to create accessible widgets
183
     * with JavaScript.
184
     * - tabindex="0" means that the element should be focusable in sequential keyboard navigation, but its order is
185
     * defined by the document's source order.
186
     * - A positive value means the element should be focusable in sequential keyboard navigation, with its order
187
     * defined by the value of the number. That is, tabindex="4" is focused before tabindex="5", but after tabindex="3".
188
     *
189
     * @param int $value
190
     *
191
     * @return self
192
     */
193
    public function tabIndex(int $value = 0): self
194
    {
195
        $new = clone $this;
196
        $new->options['tabindex'] = $value;
197
        return $new;
198
    }
199
200
    /**
201
     * Allows you to disable hidden input widget.
202
     *
203
     * @param bool $value
204
     *
205
     * @return self
206
     */
207
    public function withoutHiddenInput(bool $value): self
208
    {
209
        $new = clone $this;
210
        $new->withoutHiddenInput = $value;
211
        return $new;
212
    }
213
}
214