SmartObjectForm::getTextArea()   F
last analyzed

Complexity

Conditions 20
Paths 1632

Size

Total Lines 160

Duplication

Lines 5
Ratio 3.13 %

Importance

Changes 0
Metric Value
cc 20
nc 1632
nop 1
dl 5
loc 160
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 namespace XoopsModules\Smartobject\Form;
2
3
/**
4
 * Contains the class responsible for providing forms related to a SmartObject
5
 *
6
 * @license    GNU
7
 * @author     marcan <[email protected]>
8
 * @link       http://smartfactory.ca The SmartFactory
9
 * @package    SmartObject
10
 * @subpackage SmartObjectForm
11
 */
12
13
use XoopsModules\Smartobject;
14
/** @var Smartobject\Helper $helper */
15
$helper = Smartobject\Helper::getInstance();
16
17
// defined('XOOPS_ROOT_PATH') || die('Restricted access');
18
19
/**
20
 * Including the XoopsFormLoader classes
21
 */
22
use XoopsFormDhtmlTextArea;
23
use XoopsFormEditor;
24
use XoopsFormElement;
25
use XoopsFormTextArea;
26
use XoopsModules\Smartobject\Form\Elements\SmartFormCheckElement;
27
use XoopsModules\Smartobject\Form\Elements\SmartFormRichFileElement;
28
use XoopsModules\Smartobject\Form\Elements\SmartFormSection;
29
use XoopsModules\Smartobject\Form\Elements\SmartFormSectionClose;
30
use XoopsModules\Smartobject\Form\Elements\SmartFormUrlLinkElement;
31
32
require_once XOOPS_ROOT_PATH . '/class/xoopsformloader.php';
33
//require_once SMARTOBJECT_ROOT_PATH . 'class/form/elements/smartformsection.php';
34
//require_once SMARTOBJECT_ROOT_PATH . 'class/form/elements/smartformsectionclose.php';
35
36
/**
37
 * SmartForm base class
38
 *
39
 * Base class representing a single form for a specific SmartObject
40
 *
41
 * @package SmartObject
42
 * @author  marcan <[email protected]>
43
 * @link    http://smartfactory.ca The SmartFactory
44
 */
45
class SmartObjectForm extends \XoopsThemeForm
46
{
47
    public $targetObject           = null;
48
    public $form_fields            = null;
49
    public $_cancel_js_action      = false;
50
    public $_custom_button         = false;
51
    public $_captcha               = false;
52
    public $_form_name             = false;
53
    public $_form_caption          = false;
54
    public $_submit_button_caption = false;
55
56
    /**
57
     * SmartobjectForm constructor.
58
     * @param string $target
59
     * @param string $form_name
60
     * @param string $form_caption
61
     * @param string $form_action
62
     * @param null   $form_fields
63
     * @param bool   $submit_button_caption
64
     * @param bool   $cancel_js_action
65
     * @param bool   $captcha
66
     */
67
    public function __construct(
68
        &$target,
69
        $form_name,
70
        $form_caption,
71
        $form_action,
72
        $form_fields = null,
73
        $submit_button_caption = false,
74
        $cancel_js_action = false,
75
        $captcha = false
76
    ) {
77
        $this->targetObject           =& $target;
78
        $this->form_fields            = $form_fields;
79
        $this->_cancel_js_action      = $cancel_js_action;
80
        $this->_captcha               = $captcha;
81
        $this->_form_name             = $form_name;
0 ignored issues
show
Documentation Bug introduced by
The property $_form_name was declared of type boolean, but $form_name is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
82
        $this->_form_caption          = $form_caption;
0 ignored issues
show
Documentation Bug introduced by
The property $_form_caption was declared of type boolean, but $form_caption is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
83
        $this->_submit_button_caption = $submit_button_caption;
84
85
        if (!isset($form_action)) {
86
            $form_action = xoops_getenv('PHP_SELF');
87
        }
88
89
        parent::__construct($form_caption, $form_name, $form_action, 'post', true);
90
        $this->setExtra('enctype="multipart/form-data"');
91
92
        $this->createElements();
93
94
        if ($captcha) {
95
            $this->addCaptcha();
96
        }
97
98
        $this->createPermissionControls();
99
100
        $this->createButtons($form_name, $form_caption, $submit_button_caption);
101
    }
102
103
    public function addCaptcha()
104
    {
105
        require_once SMARTOBJECT_ROOT_PATH . 'include/captcha/formcaptcha.php';
106
        $this->addElement(new \XoopsFormCaptcha(), true);
107
    }
108
109
    /**
110
     * @param      $name
111
     * @param      $caption
112
     * @param bool $onclick
113
     */
114
    public function addCustomButton($name, $caption, $onclick = false)
115
    {
116
        $custom_button_array    = [
117
            'name'    => $name,
118
            'caption' => $caption,
119
            'onclick' => $onclick
120
        ];
121
        $this->_custom_button[] = $custom_button_array;
122
    }
123
124
    /**
125
     * Add an element to the form
126
     *
127
     * @param string|XoopsFormElement &$formElement reference to a {@link XoopsFormElement}
128
     * @param bool                    $key
129
     * @param bool                    $var
130
     * @param bool|string             $required     is this a "required" element?
131
     */
132
    public function addElement($formElement, $key = false, $var = false, $required = 'notset')
133
    {
134
        if ($key) {
135
            if ($this->targetObject->vars[$key]['readonly']) {
136
                $formElement->setExtra('disabled="disabled"');
137
                $formElement->setName($key . '-readonly');
138
                // Since this element is disable, we still want to pass it's value in the form
139
                $hidden = new \XoopsFormHidden($key, $this->targetObject->vars[$key]['value']);
140
                $this->addElement($hidden);
141
            }
142
            $formElement->setDescription($var['form_dsc']);
143
            if (isset($this->targetObject->controls[$key]['onSelect'])) {
144
                $hidden = new \XoopsFormHidden('changedField', false);
145
                $this->addElement($hidden);
146
                $otherExtra      = isset($var['form_extra']) ? $var['form_extra'] : '';
147
                $onchangedString = "this.form.elements.changedField.value='$key'; this.form.elements.op.value='changedField'; submit()";
148
                $formElement->setExtra('onchange="' . $onchangedString . '"' . ' ' . $otherExtra);
149
            } else {
150
                if (isset($var['form_extra'])) {
151
                    $formElement->setExtra($var['form_extra']);
152
                }
153
            }
154
            $controls = $this->targetObject->controls;
155
            if (isset($controls[$key]['js'])) {
156
                $formElement->customValidationCode[] = $controls[$key]['js'];
157
            }
158
            parent::addElement($formElement, 'notset' === $required ? $var['required'] : $required);
159
        } else {
160
            parent::addElement($formElement, 'notset' === $required ? false : true);
161
        }
162
        unset($formElement);
163
    }
164
165
    public function createElements()
166
    {
167
        $controls = $this->targetObject->controls;
168
        $vars     = $this->targetObject->vars;
169
        foreach ($vars as $key => $var) {
170
171
            // If $displayOnForm is false OR this is the primary key, it doesn't
172
            // need to be displayed, then we only create an hidden field
173
            if ($key == $this->targetObject->handler->keyName || !$var['displayOnForm']) {
174
                $elementToAdd = new \XoopsFormHidden($key, $var['value']);
175
                $this->addElement($elementToAdd, $key, $var, false);
176
                unset($elementToAdd);
177
            // If not, the we need to create the proper form control for this fields
178
            } else {
179
                // If this field has a specific control, we will use it
180
181
                if ('parentid' === $key) {
182
                    /**
183
                     * Why this ?
184
                     */
185
                }
186
                if (isset($controls[$key])) {
187
                    /* If the control has name, it's because it's an object already present in the script
188
                     * for example, "user"
189
                     * If the field does not have a name, than we will use a "select" (ie XoopsFormSelect)
190
                     */
191
                    if (!isset($controls[$key]['name']) || !$controls[$key]['name']) {
192
                        $controls[$key]['name'] = 'select';
193
                    }
194
195
                    $form_select = $this->getControl($controls[$key]['name'], $key);
196
197
                    // Adding on the form, the control for this field
198
                    $this->addElement($form_select, $key, $var);
199
                    unset($form_select);
200
201
                // If this field don't have a specific control, we will use the standard one, depending on its data type
202
                } else {
203
                    switch ($var['data_type']) {
204
205
                        case XOBJ_DTYPE_TXTBOX:
206
207
                            $form_text = $this->getControl('text', $key);
208
                            $this->addElement($form_text, $key, $var);
209
                            unset($form_text);
210
                            break;
211
212 View Code Duplication
                        case XOBJ_DTYPE_INT:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
213
                            $this->targetObject->setControl($key, [
0 ignored issues
show
Bug introduced by
The method setControl cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
214
                                'name' => 'text',
215
                                'size' => '5'
216
                            ]);
217
                            $form_text = $this->getControl('text', $key);
218
                            $this->addElement($form_text, $key, $var);
219
                            unset($form_text);
220
                            break;
221
222 View Code Duplication
                        case XOBJ_DTYPE_FLOAT:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
223
                            $this->targetObject->setControl($key, [
0 ignored issues
show
Bug introduced by
The method setControl cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
224
                                'name' => 'text',
225
                                'size' => '5'
226
                            ]);
227
                            $form_text = $this->getControl('text', $key);
228
                            $this->addElement($form_text, $key, $var);
229
                            unset($form_text);
230
                            break;
231
232
                        case XOBJ_DTYPE_LTIME:
233
                            $form_date_time = $this->getControl('date_time', $key);
234
                            $this->addElement($form_date_time, $key, $var);
235
                            unset($form_date_time);
236
                            break;
237
238
                        case XOBJ_DTYPE_STIME:
239
                            $form_date_time = $this->getControl('date', $key);
240
                            $this->addElement($form_date_time, $key, $var);
241
                            unset($form_date_time);
242
                            break;
243
244
                        case XOBJ_DTYPE_TIME_ONLY:
245
                            $form_time = $this->getControl('time', $key);
246
                            $this->addElement($form_time, $key, $var);
247
                            unset($form_time);
248
                            break;
249
250 View Code Duplication
                        case XOBJ_DTYPE_CURRENCY:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
251
                            $this->targetObject->setControl($key, [
0 ignored issues
show
Bug introduced by
The method setControl cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
252
                                'name' => 'text',
253
                                'size' => '15'
254
                            ]);
255
                            $form_currency = $this->getControl('text', $key);
256
                            $this->addElement($form_currency, $key, $var);
257
                            unset($form_currency);
258
                            break;
259
260
                        case XOBJ_DTYPE_URLLINK:
261
                            $form_urllink = $this->getControl('urllink', $key);
262
                            $this->addElement($form_urllink, $key, $var);
263
                            unset($form_urllink);
264
                            break;
265
266
                        case XOBJ_DTYPE_FILE:
267
                            $form_file = $this->getControl('richfile', $key);
268
                            $this->addElement($form_file, $key, $var);
269
                            unset($form_file);
270
                            break;
271
272
                        case XOBJ_DTYPE_TXTAREA:
273
274
                            $form_text_area = $this->getTextArea($key, $var);
275
                            $this->addElement($form_text_area, $key, $var);
276
                            unset($form_text_area);
277
                            break;
278
279
                        case XOBJ_DTYPE_ARRAY:
280
                            // TODO: To come...
281
                            break;
282
                        case XOBJ_DTYPE_SOURCE:
283
                            // TODO: To come...
284
                            break;
285
                        case XOBJ_DTYPE_FORM_SECTION:
286
                            $section_control = new SmartFormSection($key, $var['value']);
287
                            $this->addElement($section_control, $key, $var);
288
                            unset($section_control);
289
                            break;
290
                        case XOBJ_DTYPE_FORM_SECTION_CLOSE:
291
                            $section_control = new SmartFormSectionClose($key, $var['value']);
292
                            $this->addElement($section_control, $key, $var);
293
                            unset($section_control);
294
                            break;
295
                    }
296
                }
297
            }
298
        }
299
        // Add an hidden field to store the URL of the page before this form
300
        $this->addElement(new \XoopsFormHidden('smart_page_before_form', Smartobject\Utility::getPageBeforeForm()));
301
    }
302
303
    public function createPermissionControls()
304
    {
305
        $smartModuleConfig = $this->targetObject->handler->getModuleConfig();
306
307
        $permissions = $this->targetObject->handler->getPermissions();
308
309
        if ($permissions) {
310
            $memberHandler = xoops_getHandler('member');
311
            $group_list    = $memberHandler->getGroupList();
312
            asort($group_list);
313
            foreach ($permissions as $permission) {
314
                if ($this->targetObject->isNew()) {
0 ignored issues
show
Bug introduced by
The method isNew cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
315
                    if (isset($smartModuleConfig['def_perm_' . $permission['perm_name']])) {
316
                        $groups_value = $smartModuleConfig['def_perm_' . $permission['perm_name']];
317
                    }
318
                } else {
319
                    $groups_value = $this->targetObject->getGroupPerm($permission['perm_name']);
0 ignored issues
show
Bug introduced by
The method getGroupPerm cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
320
                }
321
                $groups_select = new \XoopsFormSelect($permission['caption'], $permission['perm_name'], $groups_value, 4, true);
0 ignored issues
show
Bug introduced by
The variable $groups_value does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
322
                $groups_select->setDescription($permission['description']);
323
                $groups_select->addOptionArray($group_list);
324
                $this->addElement($groups_select);
325
                unset($groups_select);
326
            }
327
        }
328
    }
329
330
    /**
331
     * @param      $form_name
332
     * @param      $form_caption
333
     * @param bool $submit_button_caption
334
     */
335
    public function createButtons($form_name, $form_caption, $submit_button_caption = false)
336
    {
337
        $button_tray = new \XoopsFormElementTray('', '');
338
        $button_tray->addElement(new \XoopsFormHidden('op', $form_name));
339
        if (!$submit_button_caption) {
340
            if ($this->targetObject->isNew()) {
0 ignored issues
show
Bug introduced by
The method isNew cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
341
                $butt_create = new \XoopsFormButton('', 'create_button', _CO_SOBJECT_CREATE, 'submit');
342
            } else {
343
                $butt_create = new \XoopsFormButton('', 'modify_button', _CO_SOBJECT_MODIFY, 'submit');
344
            }
345
        } else {
346
            $butt_create = new \XoopsFormButton('', 'modify_button', $submit_button_caption, 'submit');
347
        }
348
        $butt_create->setExtra('onclick="this.form.elements.op.value=\'' . $form_name . '\'"');
349
        $button_tray->addElement($butt_create);
350
351
        //creating custom buttons
352
        if ($this->_custom_button) {
353
            foreach ($this->_custom_button as $custom_button) {
0 ignored issues
show
Bug introduced by
The expression $this->_custom_button of type boolean is not traversable.
Loading history...
354
                $butt_custom = new \XoopsFormButton('', $custom_button['name'], $custom_button['caption'], 'submit');
355
                if ($custom_button['onclick']) {
356
                    $butt_custom->setExtra('onclick="' . $custom_button['onclick'] . '"');
357
                }
358
                $button_tray->addElement($butt_custom);
359
                unset($butt_custom);
360
            }
361
        }
362
363
        // creating the "cancel" button
364
        $butt_cancel = new \XoopsFormButton('', 'cancel_button', _CO_SOBJECT_CANCEL, 'button');
365
        if ($this->_cancel_js_action) {
366
            $butt_cancel->setExtra('onclick="' . $this->_cancel_js_action . '"');
367
        } else {
368
            $butt_cancel->setExtra('onclick="history.go(-1)"');
369
        }
370
        $button_tray->addElement($butt_cancel);
371
372
        $this->addElement($button_tray);
373
    }
374
375
    /**
376
     * @param $controlName
377
     * @param $key
378
     * @return \XoopsFormLabel
379
     */
380
    public function getControl($controlName, $key)
381
    {
382
        switch ($controlName) {
383 View Code Duplication
            case 'check':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
384
//                require_once SMARTOBJECT_ROOT_PATH . 'class/form/elements/smartformcheckelement.php';
385
                $control    = $this->targetObject->getControl($key);
0 ignored issues
show
Bug introduced by
The method getControl cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
386
                $controlObj = new SmartFormCheckElement($this->targetObject->vars[$key]['form_caption'], $key, $this->targetObject->getVar($key));
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
387
                $controlObj->addOptionArray($control['options']);
388
389
                return $controlObj;
390
                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...
391
392
            case 'color':
393
                $control    = $this->targetObject->getControl($key);
0 ignored issues
show
Bug introduced by
The method getControl cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Unused Code introduced by
$control is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
394
                $controlObj = new \XoopsFormColorPicker($this->targetObject->vars[$key]['form_caption'], $key, $this->targetObject->getVar($key));
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
395
396
                return $controlObj;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $controlObj; (XoopsFormColorPicker) is incompatible with the return type documented by XoopsModules\Smartobject...tObjectForm::getControl of type XoopsFormLabel|null.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
397
                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...
398
399 View Code Duplication
            case 'radio':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
400
                $control = $this->targetObject->getControl($key);
0 ignored issues
show
Bug introduced by
The method getControl cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
401
402
                $controlObj = new \XoopsFormRadio($this->targetObject->vars[$key]['form_caption'], $key, $this->targetObject->getVar($key));
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
403
                $controlObj->addOptionArray($control['options']);
404
405
                return $controlObj;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $controlObj; (XoopsFormRadio) is incompatible with the return type documented by XoopsModules\Smartobject...tObjectForm::getControl of type XoopsFormLabel|null.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
406
                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...
407
408
            case 'label':
409
                return new \XoopsFormLabel($this->targetObject->vars[$key]['form_caption'], $this->targetObject->getVar($key));
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
410
                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...
411
412
            case 'textarea':
413
                return $this->getTextArea($key);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getTextArea($key); (XoopsFormTinymce|XoopsFo...extArea|XoopsFormEditor) is incompatible with the return type documented by XoopsModules\Smartobject...tObjectForm::getControl of type XoopsFormLabel|null.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
414
415
            case 'theme':
416
                return $this->getThemeSelect($key, $this->targetObject->vars[$key]);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getThemeSe...getObject->vars[$key]); (XoopsFormSelect) is incompatible with the return type documented by XoopsModules\Smartobject...tObjectForm::getControl of type XoopsFormLabel|null.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
417
418
            case 'theme_multi':
419
                return $this->getThemeSelect($key, $this->targetObject->vars[$key], true);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getThemeSe...ect->vars[$key], true); (XoopsFormSelect) is incompatible with the return type documented by XoopsModules\Smartobject...tObjectForm::getControl of type XoopsFormLabel|null.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
420
                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...
421
422
            case 'timezone':
423
                return new \XoopsFormSelectTimezone($this->targetObject->vars[$key]['form_caption'], $key, $this->targetObject->getVar($key));
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Bug Best Practice introduced by
The return type of return new \XoopsFormSel...tObject->getVar($key)); (XoopsFormSelectTimezone) is incompatible with the return type documented by XoopsModules\Smartobject...tObjectForm::getControl of type XoopsFormLabel|null.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
424
                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...
425
426 View Code Duplication
            case 'group':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
427
                return new \XoopsFormSelectGroup($this->targetObject->vars[$key]['form_caption'], $key, false, $this->targetObject->getVar($key, 'e'), 1, false);
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Bug Best Practice introduced by
The return type of return new \XoopsFormSel...($key, 'e'), 1, false); (XoopsFormSelectGroup) is incompatible with the return type documented by XoopsModules\Smartobject...tObjectForm::getControl of type XoopsFormLabel|null.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
428
                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...
429
430 View Code Duplication
            case 'group_multi':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
431
                return new \XoopsFormSelectGroup($this->targetObject->vars[$key]['form_caption'], $key, false, $this->targetObject->getVar($key, 'e'), 5, true);
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Bug Best Practice introduced by
The return type of return new \XoopsFormSel...r($key, 'e'), 5, true); (XoopsFormSelectGroup) is incompatible with the return type documented by XoopsModules\Smartobject...tObjectForm::getControl of type XoopsFormLabel|null.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
432
                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...
433
434
            /*case 'user':
435
             return new \XoopsFormSelectUser($this->targetObject->vars[$key]['form_caption'], $key, false, $this->targetObject->getVar($key, 'e'), 1, false);
436
             break;*/
437
438 View Code Duplication
            case 'user_multi':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
439
                return new \XoopsFormSelectUser($this->targetObject->vars[$key]['form_caption'], $key, false, $this->targetObject->getVar($key, 'e'), 5, true);
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Bug Best Practice introduced by
The return type of return new \XoopsFormSel...r($key, 'e'), 5, true); (XoopsFormSelectUser) is incompatible with the return type documented by XoopsModules\Smartobject...tObjectForm::getControl of type XoopsFormLabel|null.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
440
                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...
441
442 View Code Duplication
            case 'password':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
443
                return new \XoopsFormPassword($this->targetObject->vars[$key]['form_caption'], $key, 50, 255, $this->targetObject->getVar($key, 'e'));
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Bug Best Practice introduced by
The return type of return new \XoopsFormPas...ct->getVar($key, 'e')); (XoopsFormPassword) is incompatible with the return type documented by XoopsModules\Smartobject...tObjectForm::getControl of type XoopsFormLabel|null.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
444
                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...
445
446
            case 'country':
447
                return new \XoopsFormSelectCountry($this->targetObject->vars[$key]['form_caption'], $key, $this->targetObject->getVar($key, 'e'));
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Bug Best Practice introduced by
The return type of return new \XoopsFormSel...ct->getVar($key, 'e')); (XoopsFormSelectCountry) is incompatible with the return type documented by XoopsModules\Smartobject...tObjectForm::getControl of type XoopsFormLabel|null.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
448
                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...
449
450
            case 'urllink':
451
//                require_once SMARTOBJECT_ROOT_PATH . 'class/form/elements/smartformurllinkelement.php';
452
453
                return new SmartFormUrlLinkElement($this->targetObject->vars[$key]['form_caption'], $key, $this->targetObject->getUrlLinkObj($key));
0 ignored issues
show
Bug introduced by
The method getUrlLinkObj cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
454
                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...
455
456
            case 'richfile':
457
//                require_once SMARTOBJECT_ROOT_PATH . 'class/form/elements/smartformrichfileelement.php';
458
459
                return new SmartFormRichFileElement($this->targetObject->vars[$key]['form_caption'], $key, $this->targetObject->getFileObj($key));
0 ignored issues
show
Bug introduced by
The method getFileObj cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
460
                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...
461
            case 'section':
462
//                require_once SMARTOBJECT_ROOT_PATH . 'class/form/elements/smartformsection.php';
463
464
                return new SmartFormSection($key, $this->targetObject->vars[$key]['form_caption']);
465
                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...
466
467
            default:
468
                $classname = 'SmartForm' . ucfirst($controlName) . 'Element';
469
                if (!class_exists($classname)) {
470
                    if (file_exists(SMARTOBJECT_ROOT_PATH . 'class/form/elements/' . strtolower($classname) . '.php')) {
471
//                        require_once SMARTOBJECT_ROOT_PATH . 'class/form/elements/' . strtolower($classname) . '.php';
472
                    } else {
473
                        // perhaps this is a control created by the module
474
                        $moduleName             = $this->targetObject->handler->_moduleName;
475
                        $moduleFormElementsPath = $this->targetObject->handler->_modulePath . 'class/form/elements/';
476
                        $classname              = ucfirst($moduleName) . ucfirst($controlName) . 'Element';
477
                        $classFileName          = strtolower($classname) . '.php';
478
479
                        if (file_exists($moduleFormElementsPath . $classFileName)) {
480
//                            require_once $moduleFormElementsPath . $classFileName;
481
                        } else {
482
                            trigger_error($classname . ' Not found', E_USER_WARNING);
483
484
                            return new \XoopsFormLabel(); //Empty object
485
                        }
486
                    }
487
                }
488
489
                return new $classname($this->targetObject, $key);
490
                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...
491
        }
492
    }
493
494
    /**
495
     * @param $key
496
     * @return \XoopsFormDhtmlTextArea|\XoopsFormEditor|\XoopsFormTextArea|\XoopsFormTinymce|\XoopsFormTinymce4
497
     */
498
    public function getTextArea($key)
499
    {
500
        $var = $this->targetObject->vars[$key];
501
502
        // if no control has been created, let's create a default one
503
        if (!isset($this->targetObject->controls[$key])) {
504
            $control = [
505
                'name'        => 'textarea',
506
                'itemHandler' => false,
507
                'method'      => false,
508
                'module'      => false,
509
                'form_editor' => 'default'
510
            ];
511
        } else {
512
            $control = $this->targetObject->controls[$key];
513
        }
514
        $xoops22 = Smartobject\Utility::isXoops22();
515
516
        $form_editor = isset($control['form_editor']) ? $control['form_editor'] : 'textarea';
517
        /**
518
         * If the editor is 'default', retreive the default editor of this module
519
         */
520 View Code Duplication
        if ('default' === $form_editor) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
521
               /** @var Smartobject\Helper $helper */
522
            $helper = Smartobject\Helper::getInstance();
523
            $form_editor = null !== ($helper->getConfig('default_editor')) ? $helper->getConfig('default_editor') : 'textarea';
524
        }
525
526
        $caption = $var['form_caption'];
527
        $name    = $key;
528
529
        $value = $this->targetObject->getVar($key);
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Unused Code introduced by
$value is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
530
531
        $value = $this->targetObject->getValueFor($key, true);
0 ignored issues
show
Bug introduced by
The method getValueFor cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
532
533
        $editor_configs          = [];
534
        $editor_configs['name']  = $name;
535
        $editor_configs['value'] = $value;
536
        if ('textarea' !== $form_editor) {
537
            $editor_configs['rows'] = 35;
538
            $editor_configs['cols'] = 60;
539
        }
540
541
        if (isset($control['rows'])) {
542
            $editor_configs['rows'] = $control['rows'];
543
        }
544
        if (isset($control['cols'])) {
545
            $editor_configs['cols'] = $control['cols'];
546
        }
547
548
        $editor_configs['width']  = '100%';
549
        $editor_configs['height'] = '400px';
550
551
        $dhtml            = true;
552
        $xoopseditorclass = XOOPS_ROOT_PATH . '/class/xoopsform/formeditor.php';
553
554
        if (file_exists($xoopseditorclass)) {
555
            require_once $xoopseditorclass;
556
            $editor = new \XoopsFormEditor($caption, $form_editor, $editor_configs, $nohtml = false, $onfailure = 'textarea');
557
        } else {
558
            switch ($form_editor) {
559
560
                case 'tiny':
561
                    if (!$xoops22) {
562
                        if (is_readable(XOOPS_ROOT_PATH . '/class/xoopseditor/tinyeditor/formtinytextarea.php')) {
563
                            require_once XOOPS_ROOT_PATH . '/class/xoopseditor/tinyeditor/formtinytextarea.php';
564
                            $editor = new \XoopsFormTinymce([
565
                                                                    'caption' => $caption,
566
                                                                    'name'    => $name,
567
                                                                    'value'   => $value,
568
                                                                    'width'   => '100%',
569
                                                                    'height'  => '300px'
570
                                                                ], true);
571
                        } else {
572
                            if ($dhtml) {
573
                                $editor = new \XoopsFormDhtmlTextArea($caption, $name, $value, 20, 60);
574
                            } else {
575
                                $editor = new \XoopsFormTextArea($caption, $name, $value, 7, 60);
576
                            }
577
                        }
578
                    } else {
579
                        $editor = new \XoopsFormEditor($caption, 'tinyeditor', $editor_configs);
580
                    }
581
                    break;
582
583
                case 'dhtmltextarea':
584
                case 'dhtmltext':
585
                    $editor = new \XoopsFormDhtmlTextArea($var['form_caption'], $key, $this->targetObject->getVar($key, 'e'), 20, 60);
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
586
                    if ($var['form_dsc']) {
587
                        $editor->setDescription($var['form_dsc']);
588
                    }
589
                    break;
590
591
//                case 'inbetween':
592
//                    if (!$xoops22) {
593
//                        if (is_readable(XOOPS_ROOT_PATH . '/class/xoopseditor/inbetween/forminbetweentextarea.php')) {
594
//                            require_once XOOPS_ROOT_PATH . '/class/xoopseditor/inbetween/forminbetweentextarea.php';
595
//                            $editor = new \XoopsFormInbetweenTextArea([
596
//                                                                         'caption' => $caption,
597
//                                                                         'name'    => $name,
598
//                                                                         'value'   => $value,
599
//                                                                         'width'   => '100%',
600
//                                                                         'height'  => '300px'
601
//                                                                     ], true);
602
//                        } else {
603
//                            if ($dhtml) {
604
//                                $editor = new \XoopsFormDhtmlTextArea($caption, $name, $value, 20, 60);
605
//                            } else {
606
//                                $editor = new \XoopsFormTextArea($caption, $name, $value, 7, 60);
607
//                            }
608
//                        }
609
//                    } else {
610
//                        $editor = new \XoopsFormEditor($caption, 'inbetween', $editor_configs);
611
//                    }
612
//                    break;
613
614
//                case 'koivi':
615
//                    if (!$xoops22) {
616
//                        if (is_readable(XOOPS_ROOT_PATH . '/class/wysiwyg/formwysiwygtextarea.php')) {
617
//                            require_once XOOPS_ROOT_PATH . '/class/wysiwyg/formwysiwygtextarea.php';
618
//                            $editor = new \XoopsFormWysiwygTextArea($caption, $name, $value, '100%', '400px');
619
//                        } else {
620
//                            if ($dhtml) {
621
//                                $editor = new \XoopsFormDhtmlTextArea($caption, $name, $value, 20, 60);
622
//                            } else {
623
//                                $editor = new \XoopsFormTextArea($caption, $name, $value, 7, 60);
624
//                            }
625
//                        }
626
//                    } else {
627
//                        $editor = new \XoopsFormEditor($caption, 'koivi', $editor_configs);
628
//                    }
629
//                    break;
630
631
//                case 'htmlarea':
632
//                    if (!$xoops22) {
633
//                        if (is_readable(XOOPS_ROOT_PATH . '/class/htmlarea/formhtmlarea.php')) {
634
//                            require_once XOOPS_ROOT_PATH . '/class/htmlarea/formhtmlarea.php';
635
//                            $editor = new \XoopsFormHtmlarea($caption, $name, $value);
636
//                        }
637
//                    } else {
638
//                        $editor = new \XoopsFormEditor($caption, 'htmlarea', $editor_configs);
639
//                    }
640
//                    break;
641
642
                default:
643
                case 'textarea':
0 ignored issues
show
Unused Code introduced by
case 'textarea': $fo...sc']); } break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
644
                    $form_rows = isset($control['rows']) ? $control['rows'] : 5;
645
                    $form_cols = isset($control['cols']) ? $control['cols'] : 60;
646
647
                    $editor = new \XoopsFormTextArea($var['form_caption'], $key, $this->targetObject->getVar($key, 'e'), $form_rows, $form_cols);
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
648
                    if ($var['form_dsc']) {
649
                        $editor->setDescription($var['form_dsc']);
650
                    }
651
                    break;
652
653
            }
654
        }
655
656
        return $editor;
657
    }
658
659
    /**
660
     * @param                  $key
661
     * @param                  $var
662
     * @param  bool            $multiple
663
     * @return \XoopsFormSelect
664
     */
665
    public function getThemeSelect($key, $var, $multiple = false)
666
    {
667
        $size         = $multiple ? 5 : 1;
668
        $theme_select = new \XoopsFormSelect($var['form_caption'], $key, $this->targetObject->getVar($key), $size, $multiple);
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $this->targetObject (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
669
670
        $handle  = opendir(XOOPS_THEME_PATH . '/');
671
        $dirlist = [];
672
        while (false !== ($file = readdir($handle))) {
673
            if (is_dir(XOOPS_THEME_PATH . '/' . $file) && !preg_match('/^[.]{1,2}$/', $file)
674
                && 'cvs' !== strtolower($file)) {
675
                $dirlist[$file] = $file;
676
            }
677
        }
678
        closedir($handle);
679
        if (!empty($dirlist)) {
680
            asort($dirlist);
681
            $theme_select->addOptionArray($dirlist);
682
        }
683
684
        return $theme_select;
685
    }
686
687
    /**
688
     * @param $keyname
689
     * @return bool
690
     */
691
    public function &getElementById($keyname)
692
    {
693
        foreach ($this->_elements as $eleObj) {
694
            if ($eleObj->getName() == $keyname) {
695
                $ret =& $eleObj;
696
                break;
697
            }
698
        }
699
700
        return isset($ret) ? $ret : false;
701
    }
702
703
    /**
704
     * create HTML to output the form as a theme-enabled table with validation.
705
     *
706
     * @return string
707
     */
708
    public function render()
709
    {
710
        $required = $this->getRequired();
0 ignored issues
show
Unused Code introduced by
$required is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
711
        $ret      = "
712
            <form name='" . $this->getName() . "' id='" . $this->getName() . "' action='" . $this->getAction() . "' method='" . $this->getMethod() . "' onsubmit='return xoopsFormValidate_" . $this->getName() . "(this);'" . $this->getExtra() . ">
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
713
            <table width='100%' class='outer' cellspacing='1'>
714
            <tr><th colspan='2'>" . $this->getTitle() . '</th></tr>
715
        ';
716
        $hidden   = '';
717
        $class    = 'even';
718
        foreach ($this->getElements() as $ele) {
719
            if (!is_object($ele)) {
720
                $ret .= $ele;
721
            } elseif (!$ele->isHidden()) {
722
                //$class = ( $class == 'even' ) ? 'odd': 'even';
723
                $ret .= "<tr id='" . $ele->getName() . "' valign='top' align='left'><td class='head'>" . $ele->getCaption();
724
                if ('' !== $ele->getDescription()) {
725
                    $ret .= '<br><br><span style="font-weight: normal;">' . $ele->getDescription() . '</span>';
726
                }
727
                $ret .= "</td><td class='$class'>" . $ele->render() . "</td></tr>\n";
728
            } else {
729
                $hidden .= $ele->render();
730
            }
731
        }
732
        $ret .= "</table>\n$hidden\n</form>\n";
733
        $ret .= $this->renderValidationJS(true);
734
735
        return $ret;
736
    }
737
738
    /**
739
     * assign to smarty form template instead of displaying directly
740
     *
741
     * @param \XoopsTpl $tpl
742
     *
743
     * object
744
     * @param bool      $smartyName
745
     * @see     Smarty
746
     */
747
    public function assign(\XoopsTpl $tpl, $smartyName = false)
748
    {
749
        $i        = 0;
750
        $elements = [];
751
        foreach ($this->getElements() as $ele) {
752
            $n                             = ('' !== $ele->getName()) ? $ele->getName() : $i;
753
            $elements[$n]['name']          = $ele->getName();
754
            $elements[$n]['caption']       = $ele->getCaption();
755
            $elements[$n]['body']          = $ele->render();
756
            $elements[$n]['hidden']        = $ele->isHidden();
757
            $elements[$n]['section']       = strtolower(get_class($ele)) == strtolower('SmartFormSection');
758
            $elements[$n]['section_close'] = $ele instanceof \XoopsModules\Smartobject\Form\Elements\SmartFormSectionClose;
759
            $elements[$n]['hide']          = isset($this->targetObject->vars[$n]['hide']) ? $this->targetObject->vars[$n]['hide'] : false;
760
            if ('' !== $ele->getDescription()) {
761
                $elements[$n]['description'] = $ele->getDescription();
762
            }
763
            ++$i;
764
        }
765
        $js = $this->renderValidationJS();
766
        if (!$smartyName) {
767
            $smartyName = $this->getName();
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
768
        }
769
770
        $tpl->assign($smartyName, [
771
            'title'      => $this->getTitle(),
772
            'name'       => $this->getName(),
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
773
            'action'     => $this->getAction(),
774
            'method'     => $this->getMethod(),
775
            'extra'      => 'onsubmit="return xoopsFormValidate_' . $this->getName() . '(this);"' . $this->getExtra(),
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
776
            'javascript' => $js,
777
            'elements'   => $elements
778
        ]);
779
    }
780
781
    /**
782
     * @param  bool $withtags
783
     * @return string
784
     */
785
    public function renderValidationJS($withtags = true)
786
    {
787
        $js = '';
788
        if ($withtags) {
789
            $js .= "\n<!-- Start Form Validation JavaScript //-->\n<script type='text/javascript'>\n<!--//\n";
790
        }
791
        $myts     = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
$myts is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
792
        $formname = $this->getName();
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
793
        $js       .= "function xoopsFormValidate_{$formname}(myform) {";
794
        // First, output code to check required elements
795
        $elements = $this->getRequired();
796
        foreach ($elements as $elt) {
797
            $eltname    = $elt->getName();
798
            $eltcaption = trim($elt->getCaption());
799
            $eltmsg     = empty($eltcaption) ? sprintf(_FORM_ENTER, $eltname) : sprintf(_FORM_ENTER, $eltcaption);
800
            $eltmsg     = str_replace('"', '\"', stripslashes($eltmsg));
801
            if ('xoopsformradio' === strtolower(get_class($elt))) {
802
                $js .= 'var myOption = -1;';
803
                $js .= "for (i=myform.{$eltname}.length-1; i > -1; i--) {
804
                    if (myform.{$eltname}[i].checked) {
805
                        myOption = i; i = -1;
806
                    }
807
                }
808
                if (myOption == -1) {
809
                    window.alert(\"{$eltmsg}\"); myform.{$eltname}[0].focus(); return false; }\n";
810
            } elseif ('smartformselect_multielement' === strtolower(get_class($elt))) {
811
                $js .= 'var hasSelections = false;';
812
                $js .= "for (var i = 0; i < myform['{$eltname}[]'].length; i++) {
813
                    if (myform['{$eltname}[]'].options[i].selected) {
814
                        hasSelections = true;
815
                    }
816
817
                }
818
                if (hasSelections === false) {
819
                    window.alert(\"{$eltmsg}\"); myform['{$eltname}[]'].options[0].focus(); return false; }\n";
820
            } elseif ('xoopsformcheckbox' === strtolower(get_class($elt))
821
                      || 'smartformcheckelement' === strtolower(get_class($elt))) {
822
                $js .= 'var hasSelections = false;';
823
                //sometimes, there is an implicit '[]', sometimes not
824 View Code Duplication
                if (false === strpos($eltname, '[')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
825
                    $js .= "for (var i = 0; i < myform['{$eltname}[]'].length; i++) {
826
                        if (myform['{$eltname}[]'][i].checked) {
827
                            hasSelections = true;
828
                        }
829
830
                    }
831
                    if (hasSelections === false) {
832
                        window.alert(\"{$eltmsg}\"); myform['{$eltname}[]'][0].focus(); return false; }\n";
833
                } else {
834
                    $js .= "for (var i = 0; i < myform['{$eltname}'].length; i++) {
835
                        if (myform['{$eltname}'][i].checked) {
836
                            hasSelections = true;
837
                        }
838
839
                    }
840
                    if (hasSelections === false) {
841
                        window.alert(\"{$eltmsg}\"); myform['{$eltname}'][0].focus(); return false; }\n";
842
                }
843
            } else {
844
                $js .= "if ( myform.{$eltname}.value == \"\" ) " . "{ window.alert(\"{$eltmsg}\"); myform.{$eltname}.focus(); return false; }\n";
845
            }
846
        }
847
        // Now, handle custom validation code
848
        $elements =& $this->getElements(true);
849
        foreach ($elements as $elt) {
850
            if (method_exists($elt, 'renderValidationJS') && 'xoopsformcheckbox' !== strtolower(get_class($elt))) {
851
                if ($eltjs = $elt->renderValidationJS()) {
852
                    $js .= $eltjs . "\n";
853
                }
854
            }
855
        }
856
        $js .= "return true;\n}\n";
857
        if ($withtags) {
858
            $js .= "//--></script>\n<!-- 'End Form Validation JavaScript' //-->\n";
859
        }
860
861
        return $js;
862
    }
863
}
864