Field::getEditElement()   F
last analyzed

Complexity

Conditions 28
Paths 336

Size

Total Lines 98
Code Lines 87

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 87
dl 0
loc 98
rs 1.6333
c 0
b 0
f 0
cc 28
nc 336
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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

87
            foreach (\array_keys(/** @scrutinizer ignore-type */ $value) as $idx) {
Loading history...
88
                $value[$idx] = \base64_decode($value[$idx]);
89
            }
90
        }
91
        return $value;
92
    }
93
94
    /**
95
     * Returns a {@link XoopsFormElement} for editing the value of this field
96
     *
97
     * @param \XoopsUser $user    {@link \XoopsUser} object to edit the value of
98
     * @param Profile    $profile {@link Profile} object to edit the value of
99
     *
100
     * @return \XoopsFormCheckBox|\XoopsFormDatetime|\XoopsFormDhtmlTextArea|\XoopsFormLabel|\XoopsFormRadio|\XoopsFormRadioYN|\XoopsFormSelect|\XoopsFormSelectGroup|\XoopsFormSelectLang|\XoopsFormSelectTheme|\XoopsFormSelectTimezone|\XoopsFormText|\XoopsFormTextArea|\XoopsFormTextDateSelect
101
     */
102
    public function getEditElement($user, $profile)
103
    {
104
        $value   = \in_array($this->getVar('field_name'), $this->getUserVars()) ? $user->getVar($this->getVar('field_name'), 'e') : $profile->getVar($this->getVar('field_name'), 'e');
105
        $caption = $this->getVar('field_title');
106
        $caption = \defined($caption) ? \constant($caption) : $caption;
107
        $name    = $this->getVar('field_name', 'e');
108
        $options = $this->getVar('field_options');
109
        if (\is_array($options)) {
110
            //asort($options);
111
            foreach (\array_keys($options) as $key) {
112
                $optval = \defined($options[$key]) ? \constant($options[$key]) : $options[$key];
113
                $optkey = \defined((string)$key) ? \constant($key) : $key;
114
                unset($options[$key]);
115
                $options[$optkey] = $optval;
116
            }
117
        }
118
        require_once $GLOBALS['xoops']->path('class/xoopsformloader.php');
119
        switch ($this->getVar('field_type')) {
120
            default:
121
            case 'autotext':
122
                //autotext is not for editing
123
                $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

123
                $element = new \XoopsFormLabel($caption, /** @scrutinizer ignore-type */ $this->getOutputValue($user, $profile));
Loading history...
124
                break;
125
            case 'textbox':
126
                $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

126
                $element = new \XoopsFormText($caption, $name, 35, $this->getVar('field_maxlength'), /** @scrutinizer ignore-type */ $value);
Loading history...
127
                break;
128
            case 'textarea':
129
                $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

129
                $element = new \XoopsFormTextArea($caption, $name, /** @scrutinizer ignore-type */ $value, 4, 30);
Loading history...
130
                break;
131
            case 'dhtml':
132
                $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

132
                $element = new \XoopsFormDhtmlTextArea($caption, $name, /** @scrutinizer ignore-type */ $value, 10, 30);
Loading history...
133
                break;
134
            case 'select':
135
                $element = new \XoopsFormSelect($caption, $name, $value);
136
                // If options do not include an empty element, then add a blank option to prevent any default selection
137
                //                if (!in_array('', array_keys($options))) {
138
                if (!\array_key_exists('', $options)) {
139
                    $element->addOption('', \_NONE);
140
                    $eltmsg                          = empty($caption) ? \sprintf(\_FORM_ENTER, $name) : \sprintf(\_FORM_ENTER, $caption);
141
                    $eltmsg                          = \str_replace('"', '\"', \stripslashes($eltmsg));
142
                    $element->customValidationCode[] = "\nvar hasSelected = false; var selectBox = myform.{$name};"
143
                                                       . "for (i = 0; i < selectBox.options.length; i++) { if (selectBox.options[i].selected === true && selectBox.options[i].value != '') { hasSelected = true; break; } }"
144
                                                       . "if (!hasSelected) { window.alert(\"{$eltmsg}\"); selectBox.focus(); return false; }";
145
                }
146
                $element->addOptionArray($options);
147
                break;
148
            case 'select_multi':
149
                $element = new \XoopsFormSelect($caption, $name, $value, 5, true);
150
                $element->addOptionArray($options);
151
                break;
152
            case 'radio':
153
                $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 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

153
                $element = new \XoopsFormRadio($caption, $name, /** @scrutinizer ignore-type */ $value);
Loading history...
154
                $element->addOptionArray($options);
155
                break;
156
            case 'checkbox':
157
                $element = new \XoopsFormCheckBox($caption, $name, $value);
158
                $element->addOptionArray($options);
159
                break;
160
            case 'yesno':
161
                $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

161
                $element = new \XoopsFormRadioYN($caption, $name, /** @scrutinizer ignore-type */ $value);
Loading history...
162
                break;
163
            case 'group':
164
                $element = new \XoopsFormSelectGroup($caption, $name, true, $value);
165
                break;
166
            case 'group_multi':
167
                $element = new \XoopsFormSelectGroup($caption, $name, true, $value, 5, true);
168
                break;
169
            case 'language':
170
                $element = new \XoopsFormSelectLang($caption, $name, $value);
171
                break;
172
            case 'date':
173
                $element = new \XoopsFormTextDateSelect($caption, $name, 15, $value);
174
                break;
175
            case 'longdate':
176
                $element = new \XoopsFormTextDateSelect($caption, $name, 15, \str_replace('-', '/', $value));
177
                break;
178
            case 'datetime':
179
                $element = new \XoopsFormDatetime($caption, $name, 15, $value);
180
                break;
181
            case 'timezone':
182
                $element = new \XoopsFormSelectTimezone($caption, $name, $value);
183
                $element->setExtra("style='width: 280px;'");
184
                break;
185
            case 'rank':
186
                $element = new \XoopsFormSelect($caption, $name, $value);
187
                require_once $GLOBALS['xoops']->path('class/xoopslists.php');
188
                $ranks = \XoopsLists::getUserRankList();
189
                $element->addOption(0, '--------------');
190
                $element->addOptionArray($ranks);
191
                break;
192
            case 'theme':
193
                $element = new \XoopsFormSelectTheme($caption, $name, $value, 1, true);
194
                break;
195
        }
196
        if ('' != $this->getVar('field_description')) {
197
            $element->setDescription($this->getVar('field_description'));
198
        }
199
        return $element;
200
    }
201
202
    /**
203
     * Returns a value for output of this field
204
     *
205
     * @param \XoopsUser $user    {@link XoopsUser} object to get the value of
206
     * @param Profile    $profile object to get the value of
207
     *
208
     * @return mixed
209
     **/
210
    public function getOutputValue($user, $profile)
211
    {
212
        if (\is_file($file = $GLOBALS['xoops']->path('modules/suico/language/' . $GLOBALS['xoopsConfig']['language'] . '/modinfo.php'))) {
213
            require_once $file;
214
        } else {
215
            require_once $GLOBALS['xoops']->path('modules/suico/language/english/modinfo.php');
216
        }
217
        $value = \in_array($this->getVar('field_name'), $this->getUserVars()) ? $user->getVar($this->getVar('field_name')) : $profile->getVar($this->getVar('field_name'));
218
        switch ($this->getVar('field_type')) {
219
            default:
220
            case 'textbox':
221
                $value = \is_array($value) ? $value[0] : $value;
222
                if ('url' === $this->getVar('field_name') && '' !== $value) {
223
                    return '<a href="' . \formatURL($value) . '" rel="external">' . $value . '</a>';
224
                }
225
                return $value;
226
                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...
227
            case 'textarea':
228
            case 'dhtml':
229
            case 'theme':
230
            case 'language':
231
                return $value;
232
                break;
233
            case 'select':
234
            case 'radio':
235
                $value   = \is_array($value) ? $value[0] : $value;
236
                $options = $this->getVar('field_options');
237
                if (isset($options[$value])) {
238
                    $value = \htmlspecialchars(\defined($options[$value]) ? \constant($options[$value]) : $options[$value], \ENT_QUOTES | \ENT_HTML5);
239
                } else {
240
                    $value = '';
241
                }
242
                return $value;
243
                break;
244
            case 'select_multi':
245
            case 'checkbox':
246
                $options = $this->getVar('field_options');
247
                $ret     = [];
248
                if (\count($options) > 0) {
249
                    foreach (\array_keys($options) as $key) {
250
                        if (\in_array($key, $value)) {
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

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