Field::setVar()   A
last analyzed

Complexity

Conditions 4
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 4
nc 2
nop 3
1
<?php declare(strict_types=1);
2
3
namespace XoopsModules\Suico;
4
5
/**
6
 * Extended User Profile
7
 *
8
 * You may not change or alter any portion of this comment or credits
9
 * of supporting developers from this source code or any supporting source code
10
 * which is considered copyrighted (c) material of the original comment or credit authors.
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
 *
15
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
16
 * @license             GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
17
 * @since               2.3.0
18
 * @author              Jan Pedersen
19
 * @author              Taiwen Jiang <[email protected]>
20
 */
21
22
/**
23
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
24
 */
25
26
use XoopsModules\Suico;
27
28
/**
29
 * Class Field
30
 */
31
class Field extends \XoopsObject
32
{
33
    public $field_id;
34
    public $cat_id;
35
    public $field_type;
36
    public $field_valuetype;
37
    public $field_name;
38
    public $field_title;
39
    public $field_description;
40
    public $field_required;
41
    public $field_maxlength;
42
    public $field_weight;
43
    public $field_default;
44
    public $field_notnull;
45
    public $field_edit;
46
    public $field_show;
47
    public $field_config;
48
    public $field_options;
49
    public $step_id;
50
51
    public function __construct()
52
    {
53
        $this->initVar('field_id', \XOBJ_DTYPE_INT, null);
54
        $this->initVar('cat_id', \XOBJ_DTYPE_INT, null, true);
55
        $this->initVar('field_type', \XOBJ_DTYPE_TXTBOX);
56
        $this->initVar('field_valuetype', \XOBJ_DTYPE_INT, null, true);
57
        $this->initVar('field_name', \XOBJ_DTYPE_TXTBOX, null, true);
58
        $this->initVar('field_title', \XOBJ_DTYPE_TXTBOX);
59
        $this->initVar('field_description', \XOBJ_DTYPE_TXTAREA);
60
        $this->initVar('field_required', \XOBJ_DTYPE_INT, 0); //0 = no, 1 = yes
61
        $this->initVar('field_maxlength', \XOBJ_DTYPE_INT, 0);
62
        $this->initVar('field_weight', \XOBJ_DTYPE_INT, 0);
63
        $this->initVar('field_default', \XOBJ_DTYPE_TXTAREA, '');
64
        $this->initVar('field_notnull', \XOBJ_DTYPE_INT, 1);
65
        $this->initVar('field_edit', \XOBJ_DTYPE_INT, 0);
66
        $this->initVar('field_show', \XOBJ_DTYPE_INT, 0);
67
        $this->initVar('field_config', \XOBJ_DTYPE_INT, 0);
68
        $this->initVar('field_options', \XOBJ_DTYPE_ARRAY, []);
69
        $this->initVar('step_id', \XOBJ_DTYPE_INT, 0);
70
    }
71
72
    /**
73
     * Extra treatment dealing with non latin encoding
74
     * Tricky solution
75
     * @param string $key
76
     * @param mixed  $value
77
     * @param bool   $not_gpc
78
     */
79
    public function setVar($key, $value, $not_gpc = false): void
80
    {
81
        if ('field_options' === $key && \is_array($value)) {
82
            foreach (\array_keys($value) as $idx) {
83
                $value[$idx] = \base64_encode($value[$idx]);
84
            }
85
        }
86
        parent::setVar($key, $value, $not_gpc);
87
    }
88
89
    /**
90
     * @param string $key
91
     * @param string $format
92
     *
93
     * @return mixed
94
     */
95
    public function getVar($key, $format = 's')
96
    {
97
        $value = parent::getVar($key, $format);
98
        if ('field_options' === $key && !empty($value)) {
99
            foreach (\array_keys($value) as $idx) {
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type boolean and string; however, parameter $array of array_keys() 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

99
            foreach (\array_keys(/** @scrutinizer ignore-type */ $value) as $idx) {
Loading history...
100
                $value[$idx] = \base64_decode($value[$idx], true);
101
            }
102
        }
103
104
        return $value;
105
    }
106
107
    /**
108
     * Returns a {@link XoopsFormElement} for editing the value of this field
109
     *
110
     * @param \XoopsUser $user    {@link \XoopsUser} object to edit the value of
111
     * @param Profile    $profile {@link Profile} object to edit the value of
112
     *
113
     * @return \XoopsFormCheckBox|\XoopsFormDatetime|\XoopsFormDhtmlTextArea|\XoopsFormLabel|\XoopsFormRadio|\XoopsFormRadioYN|\XoopsFormSelect|\XoopsFormSelectGroup|\XoopsFormSelectLang|\XoopsFormSelectTheme|\XoopsFormSelectTimezone|\XoopsFormText|\XoopsFormTextArea|\XoopsFormTextDateSelect
114
     */
115
    public function getEditElement($user, $profile)
116
    {
117
        $value   = \in_array($this->getVar('field_name'), $this->getUserVars(), true) ? $user->getVar($this->getVar('field_name'), 'e') : $profile->getVar($this->getVar('field_name'), 'e');
118
        $caption = $this->getVar('field_title');
119
        $caption = \defined($caption) ? \constant($caption) : $caption;
120
        $name    = $this->getVar('field_name', 'e');
121
        $options = $this->getVar('field_options');
122
        if (\is_array($options)) {
123
            //asort($options);
124
            foreach (\array_keys($options) as $key) {
125
                $optval = \defined($options[$key]) ? \constant($options[$key]) : $options[$key];
126
                $optkey = \defined((string)$key) ? \constant($key) : $key;
127
                unset($options[$key]);
128
                $options[$optkey] = $optval;
129
            }
130
        }
131
        require_once $GLOBALS['xoops']->path('class/xoopsformloader.php');
132
        switch ($this->getVar('field_type')) {
133
            default:
134
            case 'autotext':
135
                //autotext is not for editing
136
                $element = new \XoopsFormLabel($caption, $this->getOutputValue($user, $profile));
0 ignored issues
show
Bug introduced by
It seems like $this->getOutputValue($user, $profile) can also be of type array and array and array; however, parameter $value of XoopsFormLabel::__construct() does only seem to accept string, 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

136
                $element = new \XoopsFormLabel($caption, /** @scrutinizer ignore-type */ $this->getOutputValue($user, $profile));
Loading history...
137
                break;
138
            case 'textbox':
139
                $element = new \XoopsFormText($caption, $name, 35, $this->getVar('field_maxlength'), $value);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type array and array; however, parameter $value of XoopsFormText::__construct() does only seem to accept string, 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

139
                $element = new \XoopsFormText($caption, $name, 35, $this->getVar('field_maxlength'), /** @scrutinizer ignore-type */ $value);
Loading history...
140
                break;
141
            case 'textarea':
142
                $element = new \XoopsFormTextArea($caption, $name, $value, 4, 30);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type array and array; however, parameter $value of XoopsFormTextArea::__construct() does only seem to accept string, 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

142
                $element = new \XoopsFormTextArea($caption, $name, /** @scrutinizer ignore-type */ $value, 4, 30);
Loading history...
143
                break;
144
            case 'dhtml':
145
                $element = new \XoopsFormDhtmlTextArea($caption, $name, $value, 10, 30);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type array and array; however, parameter $value of XoopsFormDhtmlTextArea::__construct() does only seem to accept string, 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

145
                $element = new \XoopsFormDhtmlTextArea($caption, $name, /** @scrutinizer ignore-type */ $value, 10, 30);
Loading history...
146
                break;
147
            case 'select':
148
                $element = new \XoopsFormSelect($caption, $name, $value);
149
                // If options do not include an empty element, then add a blank option to prevent any default selection
150
                //                if (!in_array('', array_keys($options))) {
151
                if (!\array_key_exists('', $options)) {
152
                    $element->addOption('', \_NONE);
153
                    $eltmsg                          = empty($caption) ? \sprintf(\_FORM_ENTER, $name) : \sprintf(\_FORM_ENTER, $caption);
154
                    $eltmsg                          = \str_replace('"', '\"', \stripslashes($eltmsg));
155
                    $element->customValidationCode[] = "\nvar hasSelected = false; var selectBox = myform.{$name};"
156
                                                       . "for (i = 0; i < selectBox.options.length; i++) { if (selectBox.options[i].selected === true && selectBox.options[i].value != '') { hasSelected = true; break; } }"
157
                                                       . "if (!hasSelected) { window.alert(\"{$eltmsg}\"); selectBox.focus(); return false; }";
158
                }
159
                $element->addOptionArray($options);
160
                break;
161
            case 'select_multi':
162
                $element = new \XoopsFormSelect($caption, $name, $value, 5, true);
163
                $element->addOptionArray($options);
164
                break;
165
            case 'radio':
166
                $element = new \XoopsFormRadio($caption, $name, $value);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type array and array; however, parameter $value of XoopsFormRadio::__construct() does only seem to accept null|string, 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

166
                $element = new \XoopsFormRadio($caption, $name, /** @scrutinizer ignore-type */ $value);
Loading history...
167
                $element->addOptionArray($options);
168
                break;
169
            case 'checkbox':
170
                $element = new \XoopsFormCheckBox($caption, $name, $value);
171
                $element->addOptionArray($options);
172
                break;
173
            case 'yesno':
174
                $element = new \XoopsFormRadioYN($caption, $name, $value);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type array and array; however, parameter $value of XoopsFormRadioYN::__construct() does only seem to accept string, 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

174
                $element = new \XoopsFormRadioYN($caption, $name, /** @scrutinizer ignore-type */ $value);
Loading history...
175
                break;
176
            case 'group':
177
                $element = new \XoopsFormSelectGroup($caption, $name, true, $value);
178
                break;
179
            case 'group_multi':
180
                $element = new \XoopsFormSelectGroup($caption, $name, true, $value, 5, true);
181
                break;
182
            case 'language':
183
                $element = new \XoopsFormSelectLang($caption, $name, $value);
184
                break;
185
            case 'date':
186
                $element = new \XoopsFormTextDateSelect($caption, $name, 15, $value);
187
                break;
188
            case 'longdate':
189
                $element = new \XoopsFormTextDateSelect($caption, $name, 15, \str_replace('-', '/', $value));
190
                break;
191
            case 'datetime':
192
                $element = new \XoopsFormDatetime($caption, $name, 15, $value);
193
                break;
194
            case 'timezone':
195
                $element = new \XoopsFormSelectTimezone($caption, $name, $value);
196
                $element->setExtra("style='width: 280px;'");
197
                break;
198
            case 'rank':
199
                $element = new \XoopsFormSelect($caption, $name, $value);
200
                require_once $GLOBALS['xoops']->path('class/xoopslists.php');
201
                $ranks = \XoopsLists::getUserRankList();
202
                $element->addOption(0, '--------------');
203
                $element->addOptionArray($ranks);
204
                break;
205
            case 'theme':
206
                $element = new \XoopsFormSelectTheme($caption, $name, $value, 1, true);
207
                break;
208
        }
209
        if ('' != $this->getVar('field_description')) {
210
            $element->setDescription($this->getVar('field_description'));
211
        }
212
213
        return $element;
214
    }
215
216
    /**
217
     * Returns a value for output of this field
218
     *
219
     * @param \XoopsUser $user    {@link XoopsUser} object to get the value of
220
     * @param Profile    $profile object to get the value of
221
     *
222
     * @return mixed
223
     **/
224
    public function getOutputValue($user, $profile)
225
    {
226
        \xoops_loadLanguage('modinfo', 'suico');
227
228
        $value = \in_array($this->getVar('field_name'), $this->getUserVars(), true) ? $user->getVar($this->getVar('field_name')) : $profile->getVar($this->getVar('field_name'));
229
        switch ($this->getVar('field_type')) {
230
            default:
231
            case 'textbox':
232
                $value = \is_array($value) ? $value[0] : $value;
233
                if ('url' === $this->getVar('field_name') && '' !== $value) {
234
                    return '<a href="' . \formatURL($value) . '" rel="external">' . $value . '</a>';
235
                }
236
237
                return $value;
238
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
239
            case 'textarea':
240
            case 'dhtml':
241
            case 'theme':
242
            case 'language':
243
                return $value;
244
                break;
245
            case 'select':
246
            case 'radio':
247
                $value   = \is_array($value) ? $value[0] : $value;
248
                $options = $this->getVar('field_options');
249
                if (isset($options[$value])) {
250
                    $value = \htmlspecialchars(\defined($options[$value]) ? \constant($options[$value]) : $options[$value], \ENT_QUOTES | \ENT_HTML5);
251
                } else {
252
                    $value = '';
253
                }
254
255
                return $value;
256
                break;
257
            case 'select_multi':
258
            case 'checkbox':
259
                $options = $this->getVar('field_options');
260
                $ret     = [];
261
                if (\count($options) > 0) {
262
                    foreach (\array_keys($options) as $key) {
263
                        if (\in_array($key, $value, true)) {
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type boolean and null and string; however, parameter $haystack of in_array() 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

263
                        if (\in_array($key, /** @scrutinizer ignore-type */ $value, true)) {
Loading history...
264
                            $ret[$key] = \htmlspecialchars(\defined($options[$key]) ? \constant($options[$key]) : $options[$key], \ENT_QUOTES | \ENT_HTML5);
265
                        }
266
                    }
267
                }
268
269
                return $ret;
270
                break;
271
            case 'group':
272
                /** @var \XoopsMemberHandler $memberHandler */ $memberHandler = \xoops_getHandler('member');
273
                $options                                                      = $memberHandler->getGroupList();
274
                $ret                                                          = $options[$value] ?? '';
275
276
                return $ret;
277
                break;
278
            case 'group_multi':
279
                /** @var \XoopsMemberHandler $memberHandler */ $memberHandler = \xoops_getHandler('member');
280
                $options                                                      = $memberHandler->getGroupList();
281
                $ret                                                          = [];
282
                foreach (\array_keys($options) as $key) {
283
                    if (\in_array($key, $value, true)) {
284
                        $ret[$key] = \htmlspecialchars($options[$key], \ENT_QUOTES | \ENT_HTML5);
285
                    }
286
                }
287
288
                return $ret;
289
                break;
290
            case 'longdate':
291
                //return YYYY/MM/DD format - not optimal as it is not using local date format, but how do we do that
292
                //when we cannot convert it to a UNIX timestamp?
293
                return \str_replace('-', '/', $value);
294
            case 'date':
295
                return \formatTimestamp($value, 's');
296
                break;
297
            case 'datetime':
298
                if (!empty($value)) {
299
                    return \formatTimestamp($value, 'm');
300
                }
301
302
                return $value = \_MI_SUICO_NEVER_LOGGED_IN;
0 ignored issues
show
Unused Code introduced by
The assignment to $value is dead and can be removed.
Loading history...
303
                break;
304
            case 'autotext':
305
                $value = $user->getVar($this->getVar('field_name'), 'n'); //autotext can have HTML in it
306
                $value = \str_replace('{X_UID}', $user->getVar('uid'), $value);
307
                $value = \str_replace('{X_URL}', XOOPS_URL, $value);
308
                $value = \str_replace('{X_UNAME}', $user->getVar('uname'), $value);
309
310
                return $value;
311
                break;
312
            case 'rank':
313
                $userrank       = $user->rank();
314
                $user_rankimage = '';
315
                if (isset($userrank['image']) && '' !== $userrank['image']) {
316
                    $user_rankimage = '<img src="' . \XOOPS_UPLOAD_URL . '/' . $userrank['image'] . '" alt="' . $userrank['title'] . '"> ';
317
                }
318
319
                return $user_rankimage . $userrank['title'];
320
                break;
321
            case 'yesno':
322
                return $value ? \_YES : \_NO;
323
                break;
324
            case 'timezone':
325
                require_once $GLOBALS['xoops']->path('class/xoopslists.php');
326
                $timezones = \XoopsLists::getTimeZoneList();
327
                $value     = empty($value) ? '0' : (string)$value;
328
329
                return $timezones[\str_replace('.0', '', $value)];
330
                break;
331
        }
332
    }
333
334
    /**
335
     * Returns a value ready to be saved in the database
336
     *
337
     * @param mixed $value Value to format
338
     *
339
     * @return mixed
340
     */
341
    public function getValueForSave($value)
342
    {
343
        switch ($this->getVar('field_type')) {
344
            default:
345
            case 'textbox':
346
            case 'textarea':
347
            case 'dhtml':
348
            case 'yesno':
349
            case 'timezone':
350
            case 'theme':
351
            case 'language':
352
            case 'select':
353
            case 'radio':
354
            case 'select_multi':
355
            case 'group':
356
            case 'group_multi':
357
            case 'longdate':
358
                return $value;
359
            case 'checkbox':
360
                return (array)$value;
361
            case 'date':
362
                if ('' !== $value) {
363
                    return \strtotime($value);
364
                }
365
366
                return $value;
367
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
368
            case 'datetime':
369
                if (!empty($value)) {
370
                    return \strtotime($value['date']) + (int)$value['time'];
371
                }
372
373
                return $value;
374
                break;
375
        }
376
    }
377
378
    /**
379
     * Get names of user variables
380
     *
381
     * @return array
382
     */
383
    public function getUserVars()
384
    {
385
        /** @var Suico\ProfileHandler $profileHandler */
386
        $helper         = Helper::getInstance();
387
        $profileHandler = $helper->getHandler('Profile');
388
389
        return $profileHandler->getUserVars();
390
    }
391
}
392