Field::setVisible()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
namespace fieldwork\components;
4
5
use fieldwork\Form;
6
use fieldwork\methods\Method;
7
use fieldwork\sanitizers\FieldSanitizer;
8
use fieldwork\validators\FieldValidator;
9
10
abstract class Field extends Component
11
{
12
13
    protected
14
        $label,
15
        $visible = true,
16
        $enabled = true,
17
        $restored = false,
18
        $value,
19
        $initialValue,
20
        $latestErrorMsg = "",
21
        $forceInvalid = false,
22
        $validators = array(),
23
        $sanitizers = array(),
24
        $collectData = true,
25
        $storeValueLocally;
26
27
    /**
28
     * Creates a new form field component
29
     *
30
     * @param string          $slug              internal slug to use
31
     * @param string          $label             label to display
32
     * @param string|string[] $value             initial value
33
     * @param int             $storeValueLocally how long to store last used value in cookie (set to 0 for no cookie)
34
     */
35
    public function __construct ($slug, $label = '', $value = '', $storeValueLocally = 0)
36
    {
37
        parent::__construct($slug);
38
        $this->label             = $label;
39
        $this->initialValue      = $this->value = $value;
40
        $this->storeValueLocally = $storeValueLocally;
41
    }
42
43
    public function reset ()
44
    {
45
        $this->value = $this->initialValue;
46
        parent::reset();
47
    }
48
49
    public function setCollectData ($collectData)
50
    {
51
        $this->collectData = $collectData;
52
    }
53
54
    public function getCollectData ()
55
    {
56
        return $this->collectData;
57
    }
58
59
    /**
60
     * Treats the value that was fetched from the request variables. If the control uses a non-scalar to represent its
61
     * value, it should be instantiated here
62
     * @param string $value
63
     * @return string
64
     */
65
    public function importValue ($value)
66
    {
67
        return stripslashes($value);
68
    }
69
70
    /**
71
     * Restores the value from the provided method
72
     * @param Method $method
73
     * @param bool   $sanitize Whether to sanitize the fetched value
74
     */
75
    public function restoreValue (Method $method, $sanitize = true)
76
    {
77
        $v = $method->getValue($this->getName(), $this->getRestoreDefault());
78
        if ($this->isMultiple() && is_array($v)) {
79
            foreach ($v as &$value)
80
                $value = $this->importValue($value);
81
        } else {
82
            $v = $this->importValue($v);
83
        }
84
        if ($sanitize)
85
            foreach ($this->sanitizers as $s)
86
                /* @var $s FieldSanitizer */
87
                $v = $s->sanitize($v);
88
        $this->value    = $v;
89
        $this->restored = true;
90
    }
91
92
    /**
93
     * Condenses multiple values (e.g. from a multiple select box) into a single string
94
     *
95
     * @param string[] $values
96
     *
97
     * @return string
98
     */
99
    public function condenseMultiple ($values = [])
100
    {
101
        return implode(',', $values);
102
    }
103
104
    /**
105
     * Extracts multiple values from a single string
106
     *
107
     * @param string $value
108
     *
109
     * @return string[]
110
     */
111
    public function extractMultiple ($value)
112
    {
113
        return explode(',', $value);
114
    }
115
116
    /**
117
     * Determines whether this field allows selection of multiple values
118
     * @return bool
119
     */
120
    public function isMultiple ()
121
    {
122
        return false;
123
    }
124
125
    public function submit ()
126
    {
127
        if ($this->storeValueLocally)
128
            setcookie($this->getCookieName(), $this->value, time() + $this->storeValueLocally, '/');
129
    }
130
131
    public function preprocess ()
132
    {
133
        if ($this->storeValueLocally && isset($_COOKIE[$this->getCookieName()]))
134
            $this->value = $_COOKIE[$this->getCookieName()];
135
    }
136
137
    private function getCookieName ()
138
    {
139
        return $this->getGlobalSlug() . '-vc';
140
    }
141
142
    /**
143
     * Gets the value of the name attribute for this field
144
     *
145
     * @param bool $asMarkup Whether to retrieve the value used in the markup (if true, [] will by default be appended
146
     *                       to fields that allow multiple values)
147
     *
148
     * @return string
149
     */
150
    public function getName ($asMarkup = false)
151
    {
152
        return $this->getGlobalSlug() . (($this->isMultiple() && $asMarkup) ? '[]' : '');
153
    }
154
155
    public function getLabel ()
156
    {
157
        return $this->label;
158
    }
159
160
    /**
161
     * Whether to condense multiple values into a single string
162
     *
163
     * @param bool $condense
164
     *
165
     * @return string|string[]
166
     */
167
    public function getValue ($condense = true)
168
    {
169
        $v = $this->value;
170
        if ($condense && $this->isMultiple() && is_array($v))
171
            $v = $this->condenseMultiple($v);
172
        return $v;
173
    }
174
175
    public function setValue ($value)
176
    {
177
        $this->value = $value;
178
        return $this;
179
    }
180
181
    /**
182
     * Sets whether the component is visible
183
     *
184
     * @param boolean $visible
185
     *
186
     * @return $this
187
     */
188
    public function setVisible ($visible = true)
189
    {
190
        $this->visible = $visible;
191
        return $this;
192
    }
193
194
    /**
195
     * Checks whether the component is visible
196
     * @return boolean
197
     */
198
    public function isVisible ()
199
    {
200
        return $this->visible;
201
    }
202
203
    /**
204
     * @return array
205
     */
206
    public function getJsonData ()
207
    {
208
        $v = array();
209
        $s = array();
210
        foreach ($this->validators as $validator)
211
            /* @var $validator FieldValidator */
212
            array_push($v, $validator->getJsonData());
213
        foreach ($this->sanitizers as $sanitizer)
214
            /* @var $sanitizer FieldSanitizer */
215
            $s[] = $sanitizer->getJsonData();
216
        $valid = $this->restored ? $this->isValid() : true;
217
        return array(
218
            'valid'       => $valid,
219
            'error'       => $this->latestErrorMsg,
220
            'validators'  => $v,
221
            'sanitizers'  => $s,
222
            'id'          => $this->getID(),
223
            'name'        => $this->getName(),
224
            'collectData' => $this->collectData
225
        );
226
    }
227
228
    public function getId ()
229
    {
230
        return "field-" . $this->getGlobalSlug();
231
    }
232
233
    public function getAttributes ()
234
    {
235
        $attributes = array(
236
            "name"  => $this->getName(true),
237
            "value" => $this->getValue(),
238
            "id"    => $this->getId()
239
        );
240
        if (!$this->enabled)
241
            $attributes['disabled'] = 'disabled';
242
        return array_merge(parent::getAttributes(), $attributes);
243
    }
244
245
    public function getClasses ()
246
    {
247
        $form = $this->getRoot();
248
        /* @var $form Form */
249
        $formClass = ($form instanceof Form) && $form->isRequested() ? ($this->isValid() ? "valid" : "invalid") : "";
250
        return array_merge(parent::getClasses(), array(
251
            "fieldwork-field",
252
            $formClass
253
        ));
254
    }
255
256
    /**
257
     * Adds validator
258
     *
259
     * @param FieldValidator $v
260
     * @param boolean        $unshift Whether to add the validator to the front of the array
261
     *
262
     * @return Field
263
     */
264
    public function addValidator (FieldValidator $v, $unshift = false)
265
    {
266
        if ($unshift)
267
            array_unshift($this->validators, $v);
268
        else
269
            $this->validators[] = $v;
270
        $v->setField($this);
271
        return $this;
272
    }
273
274
    /**
275
     * Adds sanitizer
276
     *
277
     * @param FieldSanitizer $s
278
     *
279
     * @return Field
280
     */
281
    public function addSanitizer (FieldSanitizer $s)
282
    {
283
        $this->sanitizers[] = $s;
284
        return $this;
285
    }
286
287
    public function forceInvalid ()
288
    {
289
        $this->forceInvalid = true;
290
    }
291
292
    public function isValid ()
293
    {
294
        // TODO cache
295
        if ($this->forceInvalid)
296
            return false;
297
        foreach ($this->validators as $validator) {
298
            /* @var $validator FieldValidator */
299
            if (!$validator->isValid($this->value)) {
300
                $this->latestErrorMsg = $validator->getErrorMsg();
301
                return false;
302
            } else if ($validator->skipValidation($this->value)) {
303
                return true;
304
            }
305
        }
306
        return true;
307
    }
308
309
    public function sanitize ()
310
    {
311
        foreach ($this->sanitizers as $sanitizer)
312
            /* @var $sanitizer FieldSanitizer */
313
            $this->value = $sanitizer->sanitize($this->value);
314
    }
315
316
    public function getLatestErrorMsg ()
317
    {
318
        return $this->latestErrorMsg;
319
    }
320
321
    /**
322
     * Returns the default value used if the POST var is not set
323
     * @return string
324
     */
325
    protected function getRestoreDefault ()
326
    {
327
        return $this->value;
328
    }
329
330
    /**
331
     * Sets whether the control is enabled
332
     * @param boolean $enabled
333
     * @return $this
334
     */
335
    public function setEnabled ($enabled)
336
    {
337
        $this->enabled = $enabled;
338
        return $this;
339
    }
340
341
    /**
342
     * Gets the script that will instantiate ONLY this field in an anonymous form
343
     * @return string
344
     */
345
    public function getScript ()
346
    {
347
        return "jQuery(function($){ $('#" . $this->getID() . "').fieldwork(" . json_encode($this->getJsonData(), JSON_PRETTY_PRINT) . "); });";
348
    }
349
350
    /**
351
     * Gets the script tag that will instantiate ONLY this field in an anonymous form
352
     * @return string
353
     */
354
    public function getScriptHTML ()
355
    {
356
        $openingTag = "<script type='text/javascript'>";
357
        $closingTag = "</script>";
358
        return $openingTag . $this->getScript() . $closingTag;
359
    }
360
}
361