ProfileFieldHandler::insertFields()   F
last analyzed

Complexity

Conditions 35
Paths 13056

Size

Total Lines 120
Code Lines 84

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 35
eloc 84
nc 13056
nop 2
dl 0
loc 120
rs 0
c 0
b 0
f 0

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
 You may not change or alter any portion of this comment or credits
4
 of supporting developers from this source code or any supporting source code
5
 which is considered copyrighted (c) material of the original comment or credit authors.
6
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
*/
11
12
use Xoops\Core\Database\Connection;
13
use Xoops\Core\Kernel\Dtype;
14
use Xoops\Core\Kernel\Handlers\XoopsUser;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, XoopsUser. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
15
use Xoops\Core\Kernel\XoopsObject;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, XoopsObject. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
16
use Xoops\Core\Kernel\XoopsPersistableObjectHandler;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, XoopsPersistableObjectHandler. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
17
18
/**
19
 * Extended User Profile
20
 *
21
 * @package         Profile
22
 * @author          Jan Pedersen
23
 * @author          Taiwen Jiang <[email protected]>
24
 * @copyright       2000-2016 XOOPS Project (www.xoops.org)
25
 * @license         GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
26
 * @since           2.3.0
27
 */
28
class ProfileField extends XoopsObject
29
{
30
    /**
31
     * Constructor
32
     */
33
    public function __construct()
34
    {
35
        $this->initVar('field_id', Dtype::TYPE_INTEGER, null);
36
        $this->initVar('cat_id', Dtype::TYPE_INTEGER, null, true);
37
        $this->initVar('field_type', Dtype::TYPE_TEXT_BOX);
38
        $this->initVar('field_valuetype', Dtype::TYPE_INTEGER, null, true);
39
        $this->initVar('field_name', Dtype::TYPE_TEXT_BOX, null, true);
40
        $this->initVar('field_title', Dtype::TYPE_TEXT_BOX);
41
        $this->initVar('field_description', Dtype::TYPE_TEXT_AREA);
42
        $this->initVar('field_required', Dtype::TYPE_INTEGER, 0); //0 = no, 1 = yes
43
        $this->initVar('field_maxlength', Dtype::TYPE_INTEGER, 0);
44
        $this->initVar('field_weight', Dtype::TYPE_INTEGER, 0);
45
        $this->initVar('field_default', Dtype::TYPE_TEXT_AREA, "");
46
        $this->initVar('field_notnull', Dtype::TYPE_INTEGER, 1);
47
        $this->initVar('field_edit', Dtype::TYPE_INTEGER, 0);
48
        $this->initVar('field_show', Dtype::TYPE_INTEGER, 0);
49
        $this->initVar('field_config', Dtype::TYPE_INTEGER, 0);
50
        $this->initVar('field_options', Dtype::TYPE_ARRAY, array());
51
        $this->initVar('step_id', Dtype::TYPE_INTEGER, 0);
52
    }
53
54
    /**
55
     * Extra treatment dealing with non latin encoding
56
     * Tricky solution
57
     *
58
     * @param string $key
59
     * @param mixed  $value
60
     *
61
     * @return void
62
     *
63
     * @todo evaluate removing this. New considerations: full UTF-8 system, new Dtype::TYPE_JSON
64
     */
65
    public function setVar($key, $value)
66
    {
67
        if ($key === 'field_options' && is_array($value)) {
68
            foreach (array_keys($value) as $idx) {
69
                $value[$idx] = base64_encode($value[$idx]);
70
            }
71
        }
72
        parent::setVar($key, $value);
73
    }
74
75
    /**
76
     * @param string $key
77
     * @param string $format
78
     * @return array|mixed
79
     */
80
    public function getVar($key, $format = 's')
81
    {
82
        $value = parent::getVar($key, $format);
83
        if ($key === 'field_options' && !empty($value)) {
84
            foreach (array_keys($value) as $idx) {
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type 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

84
            foreach (array_keys(/** @scrutinizer ignore-type */ $value) as $idx) {
Loading history...
85
                $value[$idx] = base64_decode($value[$idx]);
86
            }
87
        }
88
        return $value;
89
    }
90
91
    /**
92
     * Returns a {@link Xoops\Form\Element} for editing the value of this field
93
     *
94
     * @param XoopsUser $user {@link XoopsUser} object to edit the value of
95
     * @param ProfileProfile $profile {@link ProfileProfile} object to edit the value of
96
     *
97
     * @return Xoops\Form\Element
98
     **/
99
    public function getEditElement(XoopsUser $user, ProfileProfile $profile)
100
    {
101
        $xoops = Xoops::getInstance();
102
        $value = in_array($this->getVar('field_name'), $this->getUserVars())
103
                ? $user->getVar($this->getVar('field_name'), 'e') : $profile->getVar($this->getVar('field_name'), 'e');
0 ignored issues
show
Bug introduced by
It seems like $this->getVar('field_name') can also be of type array; however, parameter $key of Xoops\Core\Kernel\XoopsObject::getVar() 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

103
                ? $user->getVar(/** @scrutinizer ignore-type */ $this->getVar('field_name'), 'e') : $profile->getVar($this->getVar('field_name'), 'e');
Loading history...
104
105
        $caption = $this->getVar('field_title');
106
        $caption = defined($caption) ? constant($caption) : $caption;
0 ignored issues
show
Bug introduced by
It seems like $caption can also be of type array; however, parameter $name of constant() 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

106
        $caption = defined($caption) ? constant(/** @scrutinizer ignore-type */ $caption) : $caption;
Loading history...
Bug introduced by
It seems like $caption can also be of type array; however, parameter $constant_name of defined() 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

106
        $caption = defined(/** @scrutinizer ignore-type */ $caption) ? constant($caption) : $caption;
Loading history...
107
        $name = $this->getVar('field_name', 'e');
108
        $options = $this->getVar('field_options');
109
        if (is_array($options)) {
110
            //asort($options);
111
112
            foreach (array_keys($options) as $key) {
113
                $optval = defined($options[$key]) ? constant($options[$key]) : $options[$key];
114
                $optkey = defined($key) ? constant($key) : $key;
115
                unset($options[$key]);
116
                $options[$optkey] = $optval;
117
            }
118
        }
119
        switch ($this->getVar('field_type')) {
120
            default:
121
            case "autotext":
122
                //autotext is not for editing
123
                $element = new Xoops\Form\Label($caption, $this->getOutputValue($user, $profile));
124
                break;
125
126
            case "textbox":
127
                $element = new Xoops\Form\Text($caption, $name, 35, $this->getVar('field_maxlength'), $value);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type string[]; however, parameter $value of Xoops\Form\Text::__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

127
                $element = new Xoops\Form\Text($caption, $name, 35, $this->getVar('field_maxlength'), /** @scrutinizer ignore-type */ $value);
Loading history...
Bug introduced by
It seems like $this->getVar('field_maxlength') can also be of type array; however, parameter $maxlength of Xoops\Form\Text::__construct() does only seem to accept integer, 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

127
                $element = new Xoops\Form\Text($caption, $name, 35, /** @scrutinizer ignore-type */ $this->getVar('field_maxlength'), $value);
Loading history...
Bug introduced by
It seems like $name can also be of type array; however, parameter $name of Xoops\Form\Text::__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

127
                $element = new Xoops\Form\Text($caption, /** @scrutinizer ignore-type */ $name, 35, $this->getVar('field_maxlength'), $value);
Loading history...
128
                break;
129
130
            case "textarea":
131
                $element = new Xoops\Form\TextArea($caption, $name, $value, 4, 30);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type string[]; however, parameter $value of Xoops\Form\TextArea::__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

131
                $element = new Xoops\Form\TextArea($caption, $name, /** @scrutinizer ignore-type */ $value, 4, 30);
Loading history...
Bug introduced by
It seems like $name can also be of type array; however, parameter $name of Xoops\Form\TextArea::__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

131
                $element = new Xoops\Form\TextArea($caption, /** @scrutinizer ignore-type */ $name, $value, 4, 30);
Loading history...
132
                break;
133
134
            case "dhtml":
135
                $element = new Xoops\Form\DhtmlTextArea($caption, $name, $value, 10, 30);
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type array; however, parameter $name of Xoops\Form\DhtmlTextArea::__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

135
                $element = new Xoops\Form\DhtmlTextArea($caption, /** @scrutinizer ignore-type */ $name, $value, 10, 30);
Loading history...
Bug introduced by
It seems like $value can also be of type string[]; however, parameter $value of Xoops\Form\DhtmlTextArea::__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

135
                $element = new Xoops\Form\DhtmlTextArea($caption, $name, /** @scrutinizer ignore-type */ $value, 10, 30);
Loading history...
Bug introduced by
It seems like $caption can also be of type array; however, parameter $caption of Xoops\Form\DhtmlTextArea::__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

135
                $element = new Xoops\Form\DhtmlTextArea(/** @scrutinizer ignore-type */ $caption, $name, $value, 10, 30);
Loading history...
136
                break;
137
138
            case "select":
139
                $element = new Xoops\Form\Select($caption, $name, $value);
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type array; however, parameter $name of Xoops\Form\Select::__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 Xoops\Form\Select($caption, /** @scrutinizer ignore-type */ $name, $value);
Loading history...
140
                // If options do not include an empty element, then add a blank option to prevent any default selection
141
                if (!in_array('', array_keys($options))) {
142
                    $element->addOption('', XoopsLocale::NONE);
143
144
                    $eltmsg = empty($caption) ? sprintf(XoopsLocale::F_ENTER, $name) : sprintf(XoopsLocale::F_ENTER, $caption);
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type array; however, parameter $values of sprintf() does only seem to accept double|integer|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

144
                    $eltmsg = empty($caption) ? sprintf(XoopsLocale::F_ENTER, /** @scrutinizer ignore-type */ $name) : sprintf(XoopsLocale::F_ENTER, $caption);
Loading history...
145
                    $eltmsg = str_replace('"', '\"', stripslashes($eltmsg));
146
                    $element->addCustomValidationCode("\nvar hasSelected = false; var selectBox = myform.{$name};" . "for (i = 0; i < selectBox.options.length; i++  ) { if ( selectBox.options[i].selected == true && selectBox.options[i].value != '' ) { hasSelected = true; break; } }" . "if ( !hasSelected ) { window.alert(\"{$eltmsg}\"); selectBox.focus(); return false; }");
147
                }
148
                $element->addOptionArray($options);
149
                break;
150
151
            case "select_multi":
152
                $element = new Xoops\Form\Select($caption, $name, $value, 5, true);
153
                $element->addOptionArray($options);
154
                break;
155
156
            case "radio":
157
                $element = new Xoops\Form\Radio($caption, $name, $value);
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type array; however, parameter $name of Xoops\Form\Radio::__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

157
                $element = new Xoops\Form\Radio($caption, /** @scrutinizer ignore-type */ $name, $value);
Loading history...
Bug introduced by
It seems like $value can also be of type string[]; however, parameter $value of Xoops\Form\Radio::__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

157
                $element = new Xoops\Form\Radio($caption, $name, /** @scrutinizer ignore-type */ $value);
Loading history...
158
                $element->addOptionArray($options);
159
                break;
160
161
            case "checkbox":
162
                $element = new Xoops\Form\Checkbox($caption, $name, $value);
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type array; however, parameter $name of Xoops\Form\Checkbox::__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

162
                $element = new Xoops\Form\Checkbox($caption, /** @scrutinizer ignore-type */ $name, $value);
Loading history...
163
                $element->addOptionArray($options);
164
                break;
165
166
            case "yesno":
167
                $element = new Xoops\Form\RadioYesNo($caption, $name, $value);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type string[]; however, parameter $value of Xoops\Form\RadioYesNo::__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

167
                $element = new Xoops\Form\RadioYesNo($caption, $name, /** @scrutinizer ignore-type */ $value);
Loading history...
Bug introduced by
It seems like $name can also be of type array; however, parameter $name of Xoops\Form\RadioYesNo::__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

167
                $element = new Xoops\Form\RadioYesNo($caption, /** @scrutinizer ignore-type */ $name, $value);
Loading history...
168
                break;
169
170
            case "group":
171
                $element = new Xoops\Form\SelectGroup($caption, $name, true, $value);
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type array; however, parameter $name of Xoops\Form\SelectGroup::__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

171
                $element = new Xoops\Form\SelectGroup($caption, /** @scrutinizer ignore-type */ $name, true, $value);
Loading history...
172
                break;
173
174
            case "group_multi":
175
                $element = new Xoops\Form\SelectGroup($caption, $name, true, $value, 5, true);
176
                break;
177
178
            case "language":
179
                $element = new Xoops\Form\SelectLanguage($caption, $name, $value);
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type array; however, parameter $name of Xoops\Form\SelectLanguage::__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

179
                $element = new Xoops\Form\SelectLanguage($caption, /** @scrutinizer ignore-type */ $name, $value);
Loading history...
180
                break;
181
182
            case "date":
183
                $element = new Xoops\Form\DateSelect($caption, $name, $value);
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type array; however, parameter $name of Xoops\Form\DateSelect::__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

183
                $element = new Xoops\Form\DateSelect($caption, /** @scrutinizer ignore-type */ $name, $value);
Loading history...
Bug introduced by
It seems like $value can also be of type string[]; however, parameter $value of Xoops\Form\DateSelect::__construct() does only seem to accept DateTime|integer, 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

183
                $element = new Xoops\Form\DateSelect($caption, $name, /** @scrutinizer ignore-type */ $value);
Loading history...
184
                break;
185
186
            case "longdate":
187
                $element = new Xoops\Form\DateSelect($caption, $name, str_replace("-", "/", $value));
188
                break;
189
190
            case "datetime":
191
                $element = new Xoops\Form\DateTimeSelect($caption, $name, $value);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type string[]; however, parameter $value of Xoops\Form\DateTimeSelect::__construct() does only seem to accept DateTime|integer, 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

191
                $element = new Xoops\Form\DateTimeSelect($caption, $name, /** @scrutinizer ignore-type */ $value);
Loading history...
Bug introduced by
It seems like $name can also be of type array; however, parameter $name of Xoops\Form\DateTimeSelect::__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

191
                $element = new Xoops\Form\DateTimeSelect($caption, /** @scrutinizer ignore-type */ $name, $value);
Loading history...
192
                break;
193
194
            case "timezone":
195
                $element = new Xoops\Form\SelectTimeZone($caption, $name, $value);
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type array; however, parameter $name of Xoops\Form\SelectTimeZone::__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

195
                $element = new Xoops\Form\SelectTimeZone($caption, /** @scrutinizer ignore-type */ $name, $value);
Loading history...
196
                break;
197
198
            case "rank":
199
                $ranklist = $xoops->service('userrank')->getAssignableUserRankList()->getValue();
200
                if ($ranklist !== null) {
201
                    $element = new Xoops\Form\Select($caption, $name, $value);
202
                    $element->addOption(0, "--------------");
203
                    $element->addOptionArray($ranklist);
204
                } else {
205
                    $element = new Xoops\Form\Hidden($name, $value);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type string[]; however, parameter $value of Xoops\Form\Hidden::__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

205
                    $element = new Xoops\Form\Hidden($name, /** @scrutinizer ignore-type */ $value);
Loading history...
206
                }
207
                break;
208
209
            case 'theme':
210
                $element = new Xoops\Form\Select($caption, $name, $value);
211
                $element->addOption("0", _PROFILE_MA_SITEDEFAULT);
212
                $handle = opendir(\XoopsBaseConfig::get('themes-path') . '/');
213
                $dirlist = array();
214
                while (false !== ($file = readdir($handle))) {
215
                    if (is_dir(\XoopsBaseConfig::get('themes-path') . '/' . $file) && !preg_match("/^[.]{1,2}$/", $file) && strtolower($file) !== 'cvs') {
216
                        if (XoopsLoad::fileExists(\XoopsBaseConfig::get('themes-path') . "/" . $file . "/theme.tpl") && in_array($file, $xoops->getConfig('theme_set_allowed'))) {
217
                            $dirlist[$file] = $file;
218
                        }
219
                    }
220
                }
221
                closedir($handle);
222
                if (!empty($dirlist)) {
223
                    asort($dirlist);
224
                    $element->addOptionArray($dirlist);
225
                }
226
                break;
227
        }
228
        if ($this->getVar('field_description') != "") {
229
            $element->setDescription($this->getVar('field_description'));
0 ignored issues
show
Bug introduced by
It seems like $this->getVar('field_description') can also be of type array; however, parameter $description of Xoops\Form\Element::setDescription() 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

229
            $element->setDescription(/** @scrutinizer ignore-type */ $this->getVar('field_description'));
Loading history...
230
        }
231
        return $element;
232
    }
233
234
    /**
235
     * Returns a value for output of this field
236
     *
237
     * @param XoopsUser $user {@link XoopsUser} object to get the value of
238
     * @param profileProfile $profile object to get the value of
239
     *
240
     * @return string
241
     **/
242
    public function getOutputValue(XoopsUser $user, ProfileProfile $profile)
243
    {
244
        $xoops = Xoops::getInstance();
245
        $xoops->loadLanguage('modinfo', 'profile');
246
247
        $value = in_array($this->getVar('field_name'), $this->getUserVars())
248
                ? $user->getVar($this->getVar('field_name')) : $profile->getVar($this->getVar('field_name'));
0 ignored issues
show
Bug introduced by
It seems like $this->getVar('field_name') can also be of type array; however, parameter $key of Xoops\Core\Kernel\XoopsObject::getVar() 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

248
                ? $user->getVar(/** @scrutinizer ignore-type */ $this->getVar('field_name')) : $profile->getVar($this->getVar('field_name'));
Loading history...
249
250
        switch ($this->getVar('field_type')) {
251
            default:
252
            case "textbox":
253
                if ($this->getVar('field_name') === 'url' && $value != '') {
254
                    return '<a href="' . $xoops->formatURL($value) . '" rel="external">' . $value . '</a>';
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type string[]; however, parameter $url of Xoops::formatURL() 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

254
                    return '<a href="' . $xoops->formatURL(/** @scrutinizer ignore-type */ $value) . '" rel="external">' . $value . '</a>';
Loading history...
255
                } else {
256
                    return $value;
257
                }
258
                break;
259
            case "textarea":
260
            case "dhtml":
261
            case 'theme':
262
            case "language":
263
            case "list":
264
                return $value;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $value also could return the type string[] which is incompatible with the documented return type string.
Loading history...
265
                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...
266
267
            case "select":
268
            case "radio":
269
                $options = $this->getVar('field_options');
270
                if (isset($options[$value])) {
271
                    $value = htmlspecialchars(
272
                        defined($options[$value]) ? constant($options[$value]) : $options[$value]
273
                    );
274
                } else {
275
                    $value = "";
276
                }
277
                return $value;
278
                break;
279
280
            case "select_multi":
281
            case "checkbox":
282
                $options = $this->getVar('field_options');
283
                $ret = array();
284
                if (count($options) > 0) {
285
                    foreach (array_keys($options) as $key) {
286
                        if (in_array($key, $value)) {
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type 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

286
                        if (in_array($key, /** @scrutinizer ignore-type */ $value)) {
Loading history...
287
                            $ret[$key] = htmlspecialchars(
288
                                defined($options[$key]) ? constant($options[$key]) : $options[$key]
289
                            );
290
                        }
291
                    }
292
                }
293
                return $ret;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $ret returns the type array which is incompatible with the documented return type string.
Loading history...
294
                break;
295
296
            case "group":
297
                $member_handler = $xoops->getHandlerMember();
298
                $options = $member_handler->getGroupList();
299
                $ret = isset($options[$value]) ? $options[$value] : '';
300
                return $ret;
301
                break;
302
303
            case "group_multi":
304
                $member_handler = $xoops->getHandlerMember();
305
                $options = $member_handler->getGroupList();
306
                $ret = array();
307
                foreach (array_keys($options) as $key) {
308
                    if (in_array($key, $value)) {
309
                        $ret[$key] = htmlspecialchars($options[$key]);
310
                    }
311
                }
312
                return $ret;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $ret returns the type array which is incompatible with the documented return type string.
Loading history...
313
                break;
314
315
            case "longdate":
316
                //return YYYY/MM/DD format - not optimal as it is not using local date format, but how do we do that
317
                //when we cannot convert it to a UNIX timestamp?
318
                return str_replace("-", "/", $value);
319
320
            case "date":
321
                return XoopsLocale::formatTimestamp($value, 's');
322
                break;
323
324
            case "datetime":
325
                if (!empty($value)) {
326
                    return XoopsLocale::formatTimestamp($value, 'm');
327
                } else {
328
                    return _PROFILE_MI_NEVER_LOGGED_IN;
329
                }
330
                break;
331
332
            case "autotext":
333
                $value = $user->getVar($this->getVar('field_name'), 'n'); //autotext can have HTML in it
334
                $value = str_replace("{X_UID}", $user->getVar("uid"), $value);
335
                $value = str_replace("{X_URL}", \XoopsBaseConfig::get('url'), $value);
336
                $value = str_replace("{X_UNAME}", $user->getVar("uname"), $value);
337
                return $value;
338
                break;
339
340
            case "rank":
341
                $userrank = $user->rank();
342
                $user_rankimage = "";
343
                if (isset($userrank['image']) && $userrank['image'] != "") {
344
                    $user_rankimage = '<img src="' . $userrank['image'] . '" alt="' . $userrank['title'] . '" /><br />';
345
                }
346
                return $user_rankimage . $userrank['title'];
347
                break;
348
349
            case "yesno":
350
                return $value ? XoopsLocale::YES : XoopsLocale::NO;
351
                break;
352
353
            case "timezone":
354
                return $value->getName();
0 ignored issues
show
Bug introduced by
The method getName() does not exist on null. ( Ignorable by Annotation )

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

354
                return $value->/** @scrutinizer ignore-call */ getName();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
355
                break;
356
        }
357
    }
358
359
    /**
360
     * Returns a value ready to be saved in the database
361
     *
362
     * @param mixed $value Value to format
363
     *
364
     * @return mixed
365
     */
366
    public function getValueForSave($value)
367
    {
368
        switch ($this->getVar('field_type')) {
369
            default:
370
            case "textbox":
371
            case "textarea":
372
            case "dhtml":
373
            case "yesno":
374
            case 'theme':
375
            case "language":
376
            case "list":
377
            case "select":
378
            case "radio":
379
            case "select_multi":
380
            case "group":
381
            case "group_multi":
382
            case "longdate":
383
                return $value;
384
385
            case "timezone":
386
                return $value;
387
388
            case "checkbox":
389
                return (array)$value;
390
391
            case "date":
392
                if ($value != "") {
393
                    return strtotime($value);
394
                }
395
                return $value;
396
                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...
397
398
            case "datetime":
399
                if (!empty($value)) {
400
                    return strtotime($value['date']) + (int)($value['time']);
401
                }
402
                return $value;
403
                break;
404
        }
405
    }
406
407
    /**
408
     * Get names of user variables
409
     *
410
     * @return array
411
     */
412
    public function getUserVars()
413
    {
414
        /* @var $profile_handler ProfileProfileHandler */
415
        $profile_handler = \Xoops::getModuleHelper('profile')->getHandler('profile');
416
        return $profile_handler->getUserVars();
417
    }
418
}
419
420
class ProfileFieldHandler extends XoopsPersistableObjectHandler
421
{
422
    /**
423
     * @param null|Connection $db database
424
     */
425
    public function __construct(Connection $db = null)
426
    {
427
        parent::__construct($db, 'profile_field', 'ProfileField', 'field_id', 'field_title');
428
    }
429
430
    /**
431
     * Read field information from cached storage
432
     *
433
     * @param bool   $force_update   read fields from database and not cached storage
434
     *
435
     * @return array
436
     */
437
    public function loadFields($force_update = false)
438
    {
439
        static $fields = array();
440
        if (!empty($force_update) || count($fields) == 0) {
441
            $this->table_link = $this->db2->prefix('profile_category');
442
            $criteria = new Criteria('o.field_id', 0, "!=");
443
            $criteria->setSort('l.cat_weight ASC, o.field_weight');
444
            $field_objs = $this->getByLink($criteria, array('o.*'), true, 'cat_id', 'cat_id');
445
            /* @var ProfileField $field */
446
            foreach ($field_objs as $field) {
447
                $fields[$field->getVar('field_name')] = $field;
448
            }
449
        }
450
        return $fields;
451
    }
452
453
    /**
454
     * save a profile field in the database
455
     *
456
     * @param XoopsObject|ProfileField $obj reference to the object
457
     * @param bool $force whether to force the query execution despite security settings
458
     * @return bool FALSE if failed, TRUE if already present and unchanged or successful
459
     */
460
    public function insertFields(XoopsObject $obj, $force = false)
461
    {
462
        $profile_handler = \Xoops::getModuleHelper('profile')->getHandler('profile');
463
        $obj->setVar('field_name', str_replace(' ', '_', $obj->getVar('field_name')));
464
        $obj->cleanVars(); //Don't quote
465
        switch ($obj->getVar('field_type')) {
466
            case "datetime":
467
            case "date":
468
                $obj->setVar('field_valuetype', Dtype::TYPE_INTEGER);
469
                $obj->setVar('field_maxlength', 10);
470
                break;
471
472
            case "longdate":
473
                $obj->setVar('field_valuetype', Dtype::TYPE_MEDIUM_TIME);
474
                break;
475
476
            case "yesno":
477
                $obj->setVar('field_valuetype', Dtype::TYPE_INTEGER);
478
                $obj->setVar('field_maxlength', 1);
479
                break;
480
481
            case "textbox":
482
                if ($obj->getVar('field_valuetype') != Dtype::TYPE_INTEGER) {
483
                    $obj->setVar('field_valuetype', Dtype::TYPE_TEXT_BOX);
484
                }
485
                break;
486
487
            case "autotext":
488
                if ($obj->getVar('field_valuetype') != Dtype::TYPE_INTEGER) {
489
                    $obj->setVar('field_valuetype', Dtype::TYPE_TEXT_AREA);
490
                }
491
                break;
492
493
            case "group_multi":
494
            case "select_multi":
495
            case "checkbox":
496
                $obj->setVar('field_valuetype', Dtype::TYPE_ARRAY);
497
                break;
498
499
            case "language":
500
            case "timezone":
501
            case "theme":
502
                $obj->setVar('field_valuetype', Dtype::TYPE_TEXT_BOX);
503
                break;
504
505
            case "dhtml":
506
            case "textarea":
507
                $obj->setVar('field_valuetype', Dtype::TYPE_TEXT_AREA);
508
                break;
509
        }
510
511
        if ($obj->getVar('field_valuetype') == "") {
512
            $obj->setVar('field_valuetype', Dtype::TYPE_TEXT_BOX);
513
        }
514
515
        if (!in_array($obj->getVar('field_name'), $this->getUserVars())) {
516
            if ($obj->isNew()) {
517
                //add column to table
518
                $changetype = "ADD";
519
            } else {
520
                //update column information
521
                $changetype = "CHANGE `" . $obj->getVar('field_name', 'n') . "`";
522
            }
523
            $maxlengthstring = $obj->getVar('field_maxlength') > 0 ? "(" . $obj->getVar('field_maxlength') . ")" : "";
524
525
            //set type
526
            switch ($obj->getVar('field_valuetype')) {
527
                default:
528
                case Dtype::TYPE_ARRAY:
529
                case Dtype::TYPE_EMAIL:
530
                case Dtype::TYPE_TEXT_BOX:
531
                case Dtype::TYPE_URL:
532
                    $type = "varchar";
533
                    // varchars must have a maxlength
534
                    if (!$maxlengthstring) {
535
                        //so set it to max if maxlength is not set - or should it fail?
536
                        $maxlengthstring = "(255)";
537
                        $obj->setVar('field_maxlength', 255);
538
                    }
539
                    break;
540
541
                case Dtype::TYPE_INTEGER:
542
                    $type = "int";
543
                    break;
544
545
                case Dtype::TYPE_DECIMAL:
546
                    $type = "decimal(14,6)";
547
                    break;
548
549
                case Dtype::TYPE_FLOAT:
550
                    $type = "float(15,9)";
551
                    break;
552
553
                case Dtype::TYPE_OTHER:
554
                case Dtype::TYPE_TEXT_AREA:
555
                    $type = "text";
556
                    $maxlengthstring = "";
557
                    break;
558
559
                case Dtype::TYPE_MEDIUM_TIME:
560
                    $type = "date";
561
                    $maxlengthstring = "";
562
                    break;
563
            }
564
565
            $sql = "ALTER TABLE `" . $profile_handler->table . "` " . $changetype . " `" . $obj->cleanVars['field_name'] . "` " . $type . $maxlengthstring . ' NULL';
0 ignored issues
show
Bug introduced by
The property table does not seem to exist on XoopsObjectHandler.
Loading history...
566
            if ($force) {
567
                $this->db2->setForce(true);
568
            }
569
            if (!$this->db2->query($sql)) {
570
                return false;
571
            }
572
        }
573
574
        //change this to also update the cached field information storage
575
        $obj->setDirty();
576
        if (!parent::insert($obj, $force)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression parent::insert($obj, $force) of type false|integer is loosely compared to false; this is ambiguous if the integer can be 0. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
577
            return false;
578
        }
579
        return $obj->getVar('field_id');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $obj->getVar('field_id') also could return the type string|string[] which is incompatible with the documented return type boolean.
Loading history...
580
581
    }
582
583
    /**
584
     * delete a profile field from the database
585
     *
586
     * @param XoopsObject|ProfileField $obj reference to the object to delete
587
     * @param bool $force
588
     * @return bool FALSE if failed.
589
     **/
590
    public function deleteFields(XoopsObject $obj, $force = false)
591
    {
592
        $xoops = Xoops::getInstance();
593
        $profile_handler = \Xoops::getModuleHelper('profile')->getHandler('profile');
594
        // remove column from table
595
        $sql = "ALTER TABLE " . $profile_handler->table . " DROP `" . $obj->getVar('field_name', 'n') . "`";
0 ignored issues
show
Bug introduced by
The property table does not seem to exist on XoopsObjectHandler.
Loading history...
596
        if ($this->db2->query($sql)) {
597
            //change this to update the cached field information storage
598
            if (!parent::delete($obj, $force)) {
599
                return false;
600
            }
601
602
            if ($obj->getVar('field_show') || $obj->getVar('field_edit')) {
603
                $profile_module = $xoops->getModuleByDirname('profile');
604
                if (is_object($profile_module)) {
605
                    // Remove group permissions
606
                    $groupperm_handler = $xoops->getHandlerGroupPermission();
607
                    $criteria = new CriteriaCompo(new Criteria('gperm_modid', $profile_module->getVar('mid')));
0 ignored issues
show
Bug introduced by
It seems like $profile_module->getVar('mid') can also be of type string[]; however, parameter $value of Criteria::__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

607
                    $criteria = new CriteriaCompo(new Criteria('gperm_modid', /** @scrutinizer ignore-type */ $profile_module->getVar('mid')));
Loading history...
608
                    $criteria->add(new Criteria('gperm_itemid', $obj->getVar('field_id')));
609
                    return $groupperm_handler->deleteAll($criteria);
610
                }
611
            }
612
        }
613
        return false;
614
    }
615
616
    /**
617
     * Get array of standard variable names (user table)
618
     *
619
     * @return string[]
620
     */
621
    public function getUserVars()
622
    {
623
        return array(
624
            'uid', 'uname', 'name', 'email', 'url', 'user_avatar', 'user_regdate', 'user_icq', 'user_from', 'user_sig',
625
            'user_viewemail', 'actkey', 'user_aim', 'user_yim', 'user_msnm', 'pass', 'posts', 'attachsig', 'rank',
626
            'level', 'theme', 'timezone', 'last_login', 'umode', 'uorder', 'notify_method', 'notify_mode',
627
            'user_occ', 'bio', 'user_intrest', 'user_mailok'
628
        );
629
    }
630
}
631