Completed
Push — master ( bf34f3...88111b )
by Michael
03:08
created

BaseSmartObject   D

Complexity

Total Complexity 294

Size/Duplication

Total Lines 1398
Duplicated Lines 16.17 %

Coupling/Cohesion

Components 3
Dependencies 7

Importance

Changes 0
Metric Value
dl 226
loc 1398
rs 4.4102
c 0
b 0
f 0
wmc 294
lcom 3
cbo 7

54 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A accessGranted() 0 6 1
A addFormSection() 0 5 1
A closeSection() 0 4 1
D initVar() 12 43 10
A initNonPersistableVar() 13 13 1
A quickInitVar() 11 11 2
D initCommonVar() 57 81 25
A setControl() 0 10 3
A getControl() 0 4 2
A getForm() 0 13 1
B toArray() 0 35 6
A setErrors() 0 13 4
A setFieldAsRequired() 0 10 3
A setFieldForSorting() 0 10 3
A hasError() 0 4 1
A setImageDir() 0 5 1
A getGroupPerm() 0 17 3
A getImageDir() 0 8 2
A getUploadDir() 0 8 2
A getVarInfo() 0 10 4
A id() 0 4 1
A title() 0 4 1
A summary() 0 8 2
A getAdminViewItemLink() 0 6 1
A getItemLink() 0 6 1
A getEditItemLink() 0 6 1
A getDeleteItemLink() 0 6 1
A getPrintAndMailLink() 0 6 1
B getFieldsForSorting() 0 17 5
A setType() 0 4 1
A setVarInfo() 0 4 1
F getValueFor() 4 38 11
D cleanVars() 26 114 42
F getVar() 83 261 103
A doMakeFieldreadOnly() 0 7 2
A makeFieldReadOnly() 0 10 3
A doHideFieldFromForm() 0 6 2
A doHideFieldFromSingleView() 0 6 2
A hideFieldFromForm() 0 10 3
A hideFieldFromSingleView() 0 10 3
A doShowFieldOnForm() 0 6 2
B displaySingleObject() 0 24 5
A doDisplayFieldOnSingleView() 0 6 2
A doSetFieldAsRequired() 0 4 1
A doSetFieldForSorting() 0 4 1
A showFieldOnForm() 0 10 3
A displayFieldOnSingleView() 0 10 3
A doSetAdvancedFormFields() 0 6 2
A setAdvancedFormFields() 0 10 3
A getUrlLinkObj() 10 10 3
A storeUrlLinkObj() 0 6 1
A getFileObj() 10 10 3
A storeFileObj() 0 6 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like BaseSmartObject often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use BaseSmartObject, and based on these observations, apply Extract Interface, too.

1
<?php namespace XoopsModules\Smartobject;
2
3
/**
4
 * Contains the basis classes for managing any objects derived from SmartObjects
5
 *
6
 * @license    GNU
7
 * @author     marcan <[email protected]>
8
 * @link       http://smartfactory.ca The SmartFactory
9
 * @package    SmartObject
10
 * @subpackage SmartObjectCore
11
 */
12
13
use XoopsModules\Smartobject;
14
15
16
// defined('XOOPS_ROOT_PATH') || die('Restricted access');
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
17
18
require_once XOOPS_ROOT_PATH . '/modules/smartobject/include/common.php';
19
20
if (!defined('XOBJ_DTYPE_SIMPLE_ARRAY')) {
21
    define('XOBJ_DTYPE_SIMPLE_ARRAY', 101);
22
}
23
if (!defined('XOBJ_DTYPE_CURRENCY')) {
24
    define('XOBJ_DTYPE_CURRENCY', 200);
25
}
26
if (!defined('XOBJ_DTYPE_FLOAT')) {
27
    define('XOBJ_DTYPE_FLOAT', 201);
28
}
29
if (!defined('XOBJ_DTYPE_TIME_ONLY')) {
30
    define('XOBJ_DTYPE_TIME_ONLY', 202);
31
}
32
if (!defined('XOBJ_DTYPE_URLLINK')) {
33
    define('XOBJ_DTYPE_URLLINK', 203);
34
}
35
if (!defined('XOBJ_DTYPE_FILE')) {
36
    define('XOBJ_DTYPE_FILE', 204);
37
}
38
if (!defined('XOBJ_DTYPE_IMAGE')) {
39
    define('XOBJ_DTYPE_IMAGE', 205);
40
}
41
if (!defined('XOBJ_DTYPE_FORM_SECTION')) {
42
    define('XOBJ_DTYPE_FORM_SECTION', 210);
43
}
44
if (!defined('XOBJ_DTYPE_FORM_SECTION_CLOSE')) {
45
    define('XOBJ_DTYPE_FORM_SECTION_CLOSE', 211);
46
}
47
48
/**
49
 * SmartObject base class
50
 *
51
 * Base class representing a single SmartObject
52
 *
53
 * @package SmartObject
54
 * @author  marcan <[email protected]>
55
 * @link    http://smartfactory.ca The SmartFactory
56
 */
57
class BaseSmartObject extends \XoopsObject
58
{
59
    public $_image_path;
60
    public $_image_url;
61
62
    public $seoEnabled   = false;
63
    public $titleField;
64
    public $summaryField = false;
65
66
    /**
67
     * Reference to the handler managing this object
68
     *
69
     * @var SmartPersistableObjectHandler reference to {@link SmartPersistableObjectHandler}
70
     */
71
    public $handler;
72
73
    /**
74
     * References to control objects, managing the form fields of this object
75
     */
76
    public $controls = [];
77
78
    /**
79
     * SmartObject constructor.
80
     * @param $handler
81
     */
82
    public function __construct($handler)
83
    {
84
        $this->handler = $handler;
85
    }
86
87
    /**
88
     * Checks if the user has a specific access on this object
89
     *
90
     * @param $perm_name
91
     * @return bool: TRUE if user has access, false if not
0 ignored issues
show
Documentation introduced by
The doc-type bool: could not be parsed: Unknown type name "bool:" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
92
     * @internal param string $gperm_name name of the permission to test
93
     */
94
    public function accessGranted($perm_name)
95
    {
96
        $smartPermissionsHandler = new SmartobjectPermissionHandler($this->handler);
97
98
        return $smartPermissionsHandler->accessGranted($perm_name, $this->id());
99
    }
100
101
    /**
102
     * @param      $section_name
103
     * @param bool $value
104
     * @param bool $hide
105
     */
106
    public function addFormSection($section_name, $value = false, $hide = false)
107
    {
108
        $this->initVar($section_name, XOBJ_DTYPE_FORM_SECTION, $value, false, null, '', false, '', '', false, false, true);
109
        $this->vars[$section_name]['hide'] = $hide;
110
    }
111
112
    /**
113
     * @param $section_name
114
     */
115
    public function closeSection($section_name)
116
    {
117
        $this->initVar('close_section_' . $section_name, XOBJ_DTYPE_FORM_SECTION_CLOSE, '', false, null, '', false, '', '', false, false, true);
118
    }
119
120
    /**
121
     *
122
     * @param string $key          key of this field. This needs to be the name of the field in the related database table
123
     * @param int    $data_type    set to one of XOBJ_DTYPE_XXX constants (set to XOBJ_DTYPE_OTHER if no data type ckecking nor text sanitizing is required)
124
     * @param mixed  $value        default value of this variable
125
     * @param bool   $required     set to TRUE if this variable needs to have a value set before storing the object in the table
126
     * @param int    $maxlength    maximum length of this variable, for XOBJ_DTYPE_TXTBOX type only
127
     * @param string $options      does this data have any select options?
128
     * @param bool   $multilingual is this field needs to support multilingual features (NOT YET IMPLEMENTED...)
129
     * @param string $form_caption caption of this variable in a {@link SmartobjectForm} and title of a column in a  {@link SmartObjectTable}
130
     * @param string $form_dsc     description of this variable in a {@link SmartobjectForm}
131
     * @param bool   $sortby       set to TRUE to make this field used to sort objects in SmartObjectTable
132
     * @param bool   $persistent   set to FALSE if this field is not to be saved in the database
133
     * @param bool   $displayOnForm
134
     */
135
    public function initVar(
136
        $key,
137
        $data_type,
138
        $value = null,
139
        $required = false,
140
        $maxlength = null,
141
        $options = '',
142
        $multilingual = false,
143
        $form_caption = '',
144
        $form_dsc = '',
145
        $sortby = false,
146
        $persistent = true,
147
        $displayOnForm = true
148
    ) {
149
        //url_ is reserved for files.
150
        if (0 === strpos($key, 'url_')) {
151
            trigger_error("Cannot use variable starting with 'url_'.");
152
        }
153
        parent::initVar($key, $data_type, $value, $required, $maxlength, $options);
154 View Code Duplication
        if ($this->handler && (!$form_caption || '' === $form_caption)) {
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...
155
            $dyn_form_caption = strtoupper('_CO_' . $this->handler->_moduleName . '_' . $this->handler->_itemname . '_' . $key);
156
            if (defined($dyn_form_caption)) {
157
                $form_caption = constant($dyn_form_caption);
158
            }
159
        }
160 View Code Duplication
        if ($this->handler && (!$form_dsc || '' === $form_dsc)) {
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...
161
            $dyn_form_dsc = strtoupper('_CO_' . $this->handler->_moduleName . '_' . $this->handler->_itemname . '_' . $key . '_DSC');
162
            if (defined($dyn_form_dsc)) {
163
                $form_dsc = constant($dyn_form_dsc);
164
            }
165
        }
166
167
        $this->vars[$key] = array_merge($this->vars[$key], [
168
            'multilingual'        => $multilingual,
169
            'form_caption'        => $form_caption,
170
            'form_dsc'            => $form_dsc,
171
            'sortby'              => $sortby,
172
            'persistent'          => $persistent,
173
            'displayOnForm'       => $displayOnForm,
174
            'displayOnSingleView' => true,
175
            'readonly'            => false
176
        ]);
177
    }
178
179
    /**
180
     * @param        $key
181
     * @param        $data_type
182
     * @param bool   $itemName
183
     * @param string $form_caption
184
     * @param bool   $sortby
185
     * @param string $value
186
     * @param bool   $displayOnForm
187
     * @param bool   $required
188
     */
189 View Code Duplication
    public function initNonPersistableVar(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
190
        $key,
191
        $data_type,
192
        $itemName = false,
193
        $form_caption = '',
194
        $sortby = false,
195
        $value = '',
196
        $displayOnForm = false,
197
        $required = false
198
    ) {
199
        $this->initVar($key, $data_type, $value, $required, null, '', false, $form_caption, '', $sortby, false, $displayOnForm);
200
        $this->vars[$key]['itemName'] = $itemName;
201
    }
202
203
    /**
204
     * Quickly initiate a var
205
     *
206
     * Since many vars do have the same config, let's use this method with some of these configuration as a convention ;-)
207
     *
208
     * - $maxlength = 0 unless $data_type is a TEXTBOX, then $maxlength will be 255
209
     * - all other vars are NULL or '' depending of the parameter
210
     *
211
     * @param string $key          key of this field. This needs to be the name of the field in the related database table
212
     * @param int    $data_type    set to one of XOBJ_DTYPE_XXX constants (set to XOBJ_DTYPE_OTHER if no data type ckecking nor text sanitizing is required)
213
     * @param bool   $required     set to TRUE if this variable needs to have a value set before storing the object in the table
214
     * @param string $form_caption caption of this variable in a {@link SmartobjectForm} and title of a column in a  {@link SmartObjectTable}
215
     * @param string $form_dsc     description of this variable in a {@link SmartobjectForm}
216
     * @param mixed  $value        default value of this variable
217
     */
218 View Code Duplication
    public function quickInitVar(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
219
        $key,
220
        $data_type,
221
        $required = false,
222
        $form_caption = '',
223
        $form_dsc = '',
224
        $value = null
225
    ) {
226
        $maxlength = 'XOBJ_DTYPE_TXTBOX' === $data_type ? 255 : null;
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of 'XOBJ_DTYPE_TXTBOX' (string) and $data_type (integer) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
227
        $this->initVar($key, $data_type, $value, $required, $maxlength, '', false, $form_caption, $form_dsc, false, true, true);
228
    }
229
230
    /**
231
     * @param        $varname
232
     * @param bool   $displayOnForm
233
     * @param string $default
234
     */
235
    public function initCommonVar($varname, $displayOnForm = true, $default = 'notdefined')
236
    {
237
        switch ($varname) {
238 View Code Duplication
            case 'dohtml':
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...
239
                $value = 'notdefined' !== $default ? $default : true;
240
                $this->initVar($varname, XOBJ_DTYPE_INT, $value, false, null, '', false, _CO_SOBJECT_DOHTML_FORM_CAPTION, '', false, true, $displayOnForm);
241
                $this->setControl($varname, 'yesno');
242
                break;
243
244 View Code Duplication
            case 'dobr':
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...
245
                $value = ('notdefined' === $default) ? true : $default;
246
                $this->initVar($varname, XOBJ_DTYPE_INT, $value, false, null, '', false, _CO_SOBJECT_DOBR_FORM_CAPTION, '', false, true, $displayOnForm);
247
                $this->setControl($varname, 'yesno');
248
                break;
249
250 View Code Duplication
            case 'doimage':
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
                $value = 'notdefined' !== $default ? $default : true;
252
                $this->initVar($varname, XOBJ_DTYPE_INT, $value, false, null, '', false, _CO_SOBJECT_DOIMAGE_FORM_CAPTION, '', false, true, $displayOnForm);
253
                $this->setControl($varname, 'yesno');
254
                break;
255
256 View Code Duplication
            case 'dosmiley':
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...
257
                $value = 'notdefined' !== $default ? $default : true;
258
                $this->initVar($varname, XOBJ_DTYPE_INT, $value, false, null, '', false, _CO_SOBJECT_DOSMILEY_FORM_CAPTION, '', false, true, $displayOnForm);
259
                $this->setControl($varname, 'yesno');
260
                break;
261
262 View Code Duplication
            case 'doxcode':
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...
263
                $value = 'notdefined' !== $default ? $default : true;
264
                $this->initVar($varname, XOBJ_DTYPE_INT, $value, false, null, '', false, _CO_SOBJECT_DOXCODE_FORM_CAPTION, '', false, true, $displayOnForm);
265
                $this->setControl($varname, 'yesno');
266
                break;
267
268 View Code Duplication
            case 'meta_keywords':
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...
269
                $value = 'notdefined' !== $default ? $default : '';
270
                $this->initVar($varname, XOBJ_DTYPE_TXTAREA, $value, false, null, '', false, _CO_SOBJECT_META_KEYWORDS, _CO_SOBJECT_META_KEYWORDS_DSC, false, true, $displayOnForm);
271
                $this->setControl('meta_keywords', [
272
                    'name'        => 'textarea',
273
                    'form_editor' => 'textarea'
274
                ]);
275
                break;
276
277 View Code Duplication
            case 'meta_description':
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...
278
                $value = 'notdefined' !== $default ? $default : '';
279
                $this->initVar($varname, XOBJ_DTYPE_TXTAREA, $value, false, null, '', false, _CO_SOBJECT_META_DESCRIPTION, _CO_SOBJECT_META_DESCRIPTION_DSC, false, true, $displayOnForm);
280
                $this->setControl('meta_description', [
281
                    'name'        => 'textarea',
282
                    'form_editor' => 'textarea'
283
                ]);
284
                break;
285
286
            case 'short_url':
287
                $value = 'notdefined' !== $default ? $default : '';
288
                $this->initVar($varname, XOBJ_DTYPE_TXTBOX, $value, false, null, '', false, _CO_SOBJECT_SHORT_URL, _CO_SOBJECT_SHORT_URL_DSC, false, true, $displayOnForm);
289
                break;
290
291
            case 'hierarchy_path':
292
                $value = 'notdefined' !== $default ? $default : '';
293
                $this->initVar($varname, XOBJ_DTYPE_ARRAY, $value, false, null, '', false, _CO_SOBJECT_HIERARCHY_PATH, _CO_SOBJECT_HIERARCHY_PATH_DSC, false, true, $displayOnForm);
294
                break;
295
296 View Code Duplication
            case 'counter':
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...
297
                $value = 'notdefined' !== $default ? $default : 0;
298
                $this->initVar($varname, XOBJ_DTYPE_INT, $value, false, null, '', false, _CO_SOBJECT_COUNTER_FORM_CAPTION, '', false, true, $displayOnForm);
299
                break;
300
301 View Code Duplication
            case 'weight':
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...
302
                $value = 'notdefined' !== $default ? $default : 0;
303
                $this->initVar($varname, XOBJ_DTYPE_INT, $value, false, null, '', false, _CO_SOBJECT_WEIGHT_FORM_CAPTION, '', true, true, $displayOnForm);
304
                break;
305 View Code Duplication
            case 'custom_css':
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...
306
                $value = 'notdefined' !== $default ? $default : '';
307
                $this->initVar($varname, XOBJ_DTYPE_TXTAREA, $value, false, null, '', false, _CO_SOBJECT_CUSTOM_CSS, _CO_SOBJECT_CUSTOM_CSS_DSC, false, true, $displayOnForm);
308
                $this->setControl('custom_css', [
309
                    'name'        => 'textarea',
310
                    'form_editor' => 'textarea'
311
                ]);
312
                break;
313
        }
314
        $this->hideFieldFromSingleView($varname);
315
    }
316
317
    /**
318
     * Set control information for an instance variable
319
     *
320
     * The $options parameter can be a string or an array. Using a string
321
     * is the quickest way:
322
     *
323
     * $this->setControl('date', 'date_time');
324
     *
325
     * This will create a date and time selectbox for the 'date' var on the
326
     * form to edit or create this item.
327
     *
328
     * Here are the currently supported controls:
329
     *
330
     *      - color
331
     *      - country
332
     *      - date_time
333
     *      - date
334
     *      - email
335
     *      - group
336
     *      - group_multi
337
     *      - image
338
     *      - imageupload
339
     *      - label
340
     *      - language
341
     *      - parentcategory
342
     *      - password
343
     *      - select_multi
344
     *      - select
345
     *      - text
346
     *      - textarea
347
     *      - theme
348
     *      - theme_multi
349
     *      - timezone
350
     *      - user
351
     *      - user_multi
352
     *      - yesno
353
     *
354
     * Now, using an array as $options, you can customize what information to
355
     * use in the control. For example, if one needs to display a select box for
356
     * the user to choose the status of an item. We only need to tell SmartObject
357
     * what method to execute within what handler to retreive the options of the
358
     * selectbox.
359
     *
360
     * $this->setControl('status', array('name' => false,
361
     *                                   'itemHandler' => 'item',
362
     *                                   'method' => 'getStatus',
363
     *                                   'module' => 'smartshop'));
364
     *
365
     * In this example, the array elements are the following:
366
     *      - name: false, as we don't need to set a special control here.
367
     *               we will use the default control related to the object type (defined in initVar)
368
     *      - itemHandler: name of the object for which we will use the handler
369
     *      - method: name of the method of this handler that we will execute
370
     *      - module: name of the module from wich the handler is
371
     *
372
     * So in this example, SmartObject will create a selectbox for the variable 'status' and it will
373
     * populate this selectbox with the result from SmartshopItemHandler::getStatus()
374
     *
375
     * Another example of the use of $options as an array is for TextArea:
376
     *
377
     * $this->setControl('body', array('name' => 'textarea',
378
     *                                   'form_editor' => 'default'));
379
     *
380
     * In this example, SmartObject will create a TextArea for the variable 'body'. And it will use
381
     * the 'default' editor, providing it is defined in the module
382
     * preferences: $xoopsModuleConfig['default_editor']
383
     *
384
     * Of course, you can force the use of a specific editor:
385
     *
386
     * $this->setControl('body', array('name' => 'textarea',
387
     *                                   'form_editor' => 'koivi'));
388
     *
389
     * Here is a list of supported editor:
390
     *      - tiny: TinyEditor
391
     *      - dhtmltextarea: XOOPS DHTML Area
392
     *      - fckeditor: FCKEditor
393
     *      - inbetween: InBetween
394
     *      - koivi: Koivi
395
     *      - spaw: Spaw WYSIWYG Editor
396
     *      - htmlarea: HTMLArea
397
     *      - textarea: basic textarea with no options
398
     *
399
     * @param string $var name of the variable for which we want to set a control
400
     * @param array  $options
401
     */
402
    public function setControl($var, $options = [])
403
    {
404
        if (isset($this->controls[$var])) {
405
            unset($this->controls[$var]);
406
        }
407
        if (is_string($options)) {
408
            $options = ['name' => $options];
409
        }
410
        $this->controls[$var] = $options;
411
    }
412
413
    /**
414
     * Get control information for an instance variable
415
     *
416
     * @param  string $var
417
     * @return bool|mixed
418
     */
419
    public function getControl($var)
420
    {
421
        return isset($this->controls[$var]) ? $this->controls[$var] : false;
422
    }
423
424
    /**
425
     * Create the form for this object
426
     *
427
     * @param         $form_caption
428
     * @param         $form_name
429
     * @param  bool   $form_action
430
     * @param  string $submit_button_caption
431
     * @param  bool   $cancel_js_action
432
     * @param  bool   $captcha
433
     * @return \XoopsModules\Smartobject\Form\SmartobjectForm <a href='psi_element://SmartobjectForm'>SmartobjectForm</a> object for this object
434
     *                                      object for this object
435
     * @see SmartObjectForm::SmartObjectForm()
436
     */
437
    public function getForm(
438
        $form_caption,
439
        $form_name,
440
        $form_action = false,
441
        $submit_button_caption = _CO_SOBJECT_SUBMIT,
442
        $cancel_js_action = false,
443
        $captcha = false
444
    ) {
445
//        require_once SMARTOBJECT_ROOT_PATH . 'class/form/smartobjectform.php';
446
        $form = new Smartobject\Form\SmartobjectForm($this, $form_name, $form_caption, $form_action, null, $submit_button_caption, $cancel_js_action, $captcha);
447
448
        return $form;
449
    }
450
451
    /**
452
     * @return array
453
     */
454
    public function toArray()
455
    {
456
        $ret  = [];
457
        $vars =& $this->getVars();
458
        foreach ($vars as $key => $var) {
459
            $value     = $this->getVar($key);
460
            $ret[$key] = $value;
461
        }
462
        if ('' !== $this->handler->identifierName) {
463
            $controller = new SmartObjectController($this->handler);
464
            /**
465
             * Addition of some automatic value
466
             */
467
            $ret['itemLink']         = $controller->getItemLink($this);
468
            $ret['itemUrl']          = $controller->getItemLink($this, true);
469
            $ret['editItemLink']     = $controller->getEditItemLink($this, false, true);
470
            $ret['deleteItemLink']   = $controller->getDeleteItemLink($this, false, true);
471
            $ret['printAndMailLink'] = $controller->getPrintAndMailLink($this);
472
        }
473
474
        // Hightlighting searched words
475
        require_once SMARTOBJECT_ROOT_PATH . 'class/smarthighlighter.php';
476
        $highlight = smart_getConfig('module_search_highlighter', false, true);
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
477
478
        if ($highlight && isset($_GET['keywords'])) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $highlight of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

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

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
479
            $myts     = \MyTextSanitizer::getInstance();
480
            $keywords = $myts->htmlSpecialChars(trim(urldecode($_GET['keywords'])));
481
            $h        = new SmartHighlighter($keywords, true, 'smart_highlighter');
482
            foreach ($this->handler->highlightFields as $field) {
483
                $ret[$field] = $h->highlight($ret[$field]);
484
            }
485
        }
486
487
        return $ret;
488
    }
489
490
    /**
491
     * add an error
492
     *
493
     * @param      $err_str
494
     * @param bool $prefix
495
     * @internal param string $value error to add
496
     * @access   public
497
     */
498
    public function setErrors($err_str, $prefix = false)
499
    {
500
        if (is_array($err_str)) {
501
            foreach ($err_str as $str) {
502
                $this->setErrors($str, $prefix);
503
            }
504
        } else {
505
            if ($prefix) {
506
                $err_str = '[' . $prefix . '] ' . $err_str;
507
            }
508
            parent::setErrors($err_str);
509
        }
510
    }
511
512
    /**
513
     * @param      $field
514
     * @param bool $required
515
     */
516
    public function setFieldAsRequired($field, $required = true)
517
    {
518
        if (is_array($field)) {
519
            foreach ($field as $v) {
520
                $this->doSetFieldAsRequired($v, $required);
521
            }
522
        } else {
523
            $this->doSetFieldAsRequired($field, $required);
524
        }
525
    }
526
527
    /**
528
     * @param $field
529
     */
530
    public function setFieldForSorting($field)
531
    {
532
        if (is_array($field)) {
533
            foreach ($field as $v) {
534
                $this->doSetFieldForSorting($v);
535
            }
536
        } else {
537
            $this->doSetFieldForSorting($field);
538
        }
539
    }
540
541
    /**
542
     * @return bool
543
     */
544
    public function hasError()
545
    {
546
        return count($this->_errors) > 0;
547
    }
548
549
    /**
550
     * @param $url
551
     * @param $path
552
     */
553
    public function setImageDir($url, $path)
554
    {
555
        $this->_image_url  = $url;
556
        $this->_image_path = $path;
557
    }
558
559
    /**
560
     * Retreive the group that have been granted access to a specific permission for this object
561
     *
562
     * @param $group_perm
563
     * @return string $group_perm name of the permission
564
     */
565
    public function getGroupPerm($group_perm)
566
    {
567
        if (!$this->handler->getPermissions()) {
568
            $this->setError("Trying to access a permission that does not exists for thisobject's handler");
569
570
            return false;
571
        }
572
573
        $smartPermissionsHandler = new SmartobjectPermissionHandler($this->handler);
574
        $ret                     = $smartPermissionsHandler->getGrantedGroups($group_perm, $this->id());
575
576
        if (0 == count($ret)) {
577
            return false;
578
        } else {
579
            return $ret;
580
        }
581
    }
582
583
    /**
584
     * @param  bool $path
585
     * @return mixed
586
     */
587
    public function getImageDir($path = false)
588
    {
589
        if ($path) {
590
            return $this->_image_path;
591
        } else {
592
            return $this->_image_url;
593
        }
594
    }
595
596
    /**
597
     * @param  bool $path
598
     * @return mixed
599
     */
600
    public function getUploadDir($path = false)
601
    {
602
        if ($path) {
603
            return $this->_image_path;
604
        } else {
605
            return $this->_image_url;
606
        }
607
    }
608
609
    /**
610
     * @param  string $key
611
     * @param  string $info
612
     * @return array
613
     */
614
    public function getVarInfo($key = '', $info = '')
615
    {
616
        if (isset($this->vars[$key][$info])) {
617
            return $this->vars[$key][$info];
618
        } elseif ('' === $info && isset($this->vars[$key])) {
619
            return $this->vars[$key];
620
        } else {
621
            return $this->vars;
622
        }
623
    }
624
625
    /**
626
     * Get the id of the object
627
     *
628
     * @return int id of this object
629
     */
630
    public function id()
631
    {
632
        return $this->getVar($this->handler->keyName, 'e');
633
    }
634
635
    /**
636
     * Return the value of the title field of this object
637
     *
638
     * @param  string $format
639
     * @return string
640
     */
641
    public function title($format = 's')
642
    {
643
        return $this->getVar($this->handler->identifierName, $format);
644
    }
645
646
    /**
647
     * Return the value of the title field of this object
648
     *
649
     * @return string
650
     */
651
    public function summary()
652
    {
653
        if ($this->handler->summaryName) {
654
            return $this->getVar($this->handler->summaryName);
655
        } else {
656
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by XoopsModules\Smartobject\BaseSmartObject::summary of type string.

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...
657
        }
658
    }
659
660
    /**
661
     * Retreive the object admin side link, displayijng a SingleView page
662
     *
663
     * @param  bool $onlyUrl wether or not to return a simple URL or a full <a> link
664
     * @return string user side link to the object
665
     */
666
    public function getAdminViewItemLink($onlyUrl = false)
667
    {
668
        $controller = new SmartObjectController($this->handler);
669
670
        return $controller->getAdminViewItemLink($this, $onlyUrl);
671
    }
672
673
    /**
674
     * Retreive the object user side link
675
     *
676
     * @param  bool $onlyUrl wether or not to return a simple URL or a full <a> link
677
     * @return string user side link to the object
678
     */
679
    public function getItemLink($onlyUrl = false)
680
    {
681
        $controller = new SmartObjectController($this->handler);
682
683
        return $controller->getItemLink($this, $onlyUrl);
684
    }
685
686
    /**
687
     * @param  bool $onlyUrl
688
     * @param  bool $withimage
689
     * @param  bool $userSide
690
     * @return string
691
     */
692
    public function getEditItemLink($onlyUrl = false, $withimage = true, $userSide = false)
693
    {
694
        $controller = new SmartObjectController($this->handler);
695
696
        return $controller->getEditItemLink($this, $onlyUrl, $withimage, $userSide);
697
    }
698
699
    /**
700
     * @param  bool $onlyUrl
701
     * @param  bool $withimage
702
     * @param  bool $userSide
703
     * @return string
704
     */
705
    public function getDeleteItemLink($onlyUrl = false, $withimage = false, $userSide = false)
706
    {
707
        $controller = new SmartObjectController($this->handler);
708
709
        return $controller->getDeleteItemLink($this, $onlyUrl, $withimage, $userSide);
710
    }
711
712
    /**
713
     * @return string
714
     */
715
    public function getPrintAndMailLink()
716
    {
717
        $controller = new SmartObjectController($this->handler);
718
719
        return $controller->getPrintAndMailLink($this);
720
    }
721
722
    /**
723
     * @param $sortsel
724
     * @return array|bool
725
     */
726
    public function getFieldsForSorting($sortsel)
727
    {
728
        $ret = [];
729
730
        foreach ($this->vars as $key => $field_info) {
731
            if ($field_info['sortby']) {
732
                $ret[$key]['caption']  = $field_info['form_caption'];
733
                $ret[$key]['selected'] = $key == $sortsel ? 'selected' : '';
734
            }
735
        }
736
737
        if (count($ret) > 0) {
738
            return $ret;
739
        } else {
740
            return false;
741
        }
742
    }
743
744
    /**
745
     * @param $key
746
     * @param $newType
747
     */
748
    public function setType($key, $newType)
749
    {
750
        $this->vars[$key]['data_type'] = $newType;
751
    }
752
753
    /**
754
     * @param $key
755
     * @param $info
756
     * @param $value
757
     */
758
    public function setVarInfo($key, $info, $value)
759
    {
760
        $this->vars[$key][$info] = $value;
761
    }
762
763
    /**
764
     * @param         $key
765
     * @param  bool   $editor
766
     * @return string
767
     */
768
    public function getValueFor($key, $editor = true)
769
    {
770
        global $xoopsModuleConfig;
771
772
        $ret  = $this->getVar($key, 'n');
773
        $myts = \MyTextSanitizer::getInstance();
774
775
        $control     = isset($this->controls[$key]) ? $this->controls[$key] : false;
776
        $form_editor = isset($control['form_editor']) ? $control['form_editor'] : 'textarea';
777
778
        $html     = isset($this->vars['dohtml']) ? $this->getVar('dohtml') : true;
779
        $smiley   = true;
780
        $xcode    = true;
781
        $image    = true;
782
        $br       = isset($this->vars['dobr']) ? $this->getVar('dobr') : true;
783
        $formatML = true;
784
785 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...
786
            global $xoopsModuleConfig;
787
            $form_editor = isset($xoopsModuleConfig['default_editor']) ? $xoopsModuleConfig['default_editor'] : 'textarea';
788
        }
789
790
        if ($editor) {
791
            if (defined('XOOPS_EDITOR_IS_HTML')
792
                && !in_array($form_editor, ['formtextarea', 'textarea', 'dhtmltextarea'])) {
793
                $br       = false;
794
                $formatML = !$editor;
795
            } else {
796
                return htmlspecialchars($ret, ENT_QUOTES);
797
            }
798
        }
799
800
        if (method_exists($myts, 'formatForML')) {
801
            return $myts->displayTarea($ret, $html, $smiley, $xcode, $image, $br, $formatML);
802
        } else {
803
            return $myts->displayTarea($ret, $html, $smiley, $xcode, $image, $br);
804
        }
805
    }
806
807
    /**
808
     * clean values of all variables of the object for storage.
809
     * also add slashes whereever needed
810
     *
811
     * We had to put this method in the SmartObject because the XOBJ_DTYPE_ARRAY does not work properly
812
     * at least on PHP 5.1. So we have created a new type XOBJ_DTYPE_SIMPLE_ARRAY to handle 1 level array
813
     * as a string separated by |
814
     *
815
     * @return bool true if successful
816
     * @access public
817
     */
818
    public function cleanVars()
819
    {
820
        $ts              = \MyTextSanitizer::getInstance();
821
        $existing_errors = $this->getErrors();
822
        $this->_errors   = [];
823
        foreach ($this->vars as $k => $v) {
824
            $cleanv = $v['value'];
825
            if (!$v['changed']) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
826
            } else {
827
                $cleanv = is_string($cleanv) ? trim($cleanv) : $cleanv;
828
                switch ($v['data_type']) {
829
                    case XOBJ_DTYPE_TXTBOX:
830 View Code Duplication
                        if ($v['required'] && '0' != $cleanv && '' == $cleanv) {
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...
831
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
832
                            continue 2;
833
                        }
834
                        if (isset($v['maxlength']) && strlen($cleanv) > (int)$v['maxlength']) {
835
                            $this->setErrors(sprintf(_XOBJ_ERR_SHORTERTHAN, $k, (int)$v['maxlength']));
836
                            continue 2;
837
                        }
838 View Code Duplication
                        if (!$v['not_gpc']) {
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...
839
                            $cleanv = $ts->stripSlashesGPC($ts->censorString($cleanv));
840
                        } else {
841
                            $cleanv = $ts->censorString($cleanv);
842
                        }
843
                        break;
844
                    case XOBJ_DTYPE_TXTAREA:
845 View Code Duplication
                        if ($v['required'] && '0' != $cleanv && '' == $cleanv) {
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...
846
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
847
                            continue 2;
848
                        }
849 View Code Duplication
                        if (!$v['not_gpc']) {
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...
850
                            $cleanv = $ts->stripSlashesGPC($ts->censorString($cleanv));
851
                        } else {
852
                            $cleanv = $ts->censorString($cleanv);
853
                        }
854
                        break;
855
                    case XOBJ_DTYPE_SOURCE:
856
                        if (!$v['not_gpc']) {
857
                            $cleanv = $ts->stripSlashesGPC($cleanv);
858
                        } else {
859
                            $cleanv = $cleanv;
0 ignored issues
show
Bug introduced by
Why assign $cleanv to itself?

This checks looks for cases where a variable has been assigned to itself.

This assignement can be removed without consequences.

Loading history...
860
                        }
861
                        break;
862
                    case XOBJ_DTYPE_INT:
863
                    case XOBJ_DTYPE_TIME_ONLY:
864
                        $cleanv = (int)$cleanv;
865
                        break;
866
867
                    case XOBJ_DTYPE_CURRENCY:
868
                        $cleanv = smart_currency($cleanv);
869
                        break;
870
871
                    case XOBJ_DTYPE_FLOAT:
872
                        $cleanv = smart_float($cleanv);
873
                        break;
874
875
                    case XOBJ_DTYPE_EMAIL:
876 View Code Duplication
                        if ($v['required'] && '' === $cleanv) {
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...
877
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
878
                            continue 2;
879
                        }
880
                        if ('' !== $cleanv
881
                            && !preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+([\.][a-z0-9-]+)+$/i", $cleanv)) {
882
                            $this->setErrors('Invalid Email');
883
                            continue 2;
884
                        }
885
                        if (!$v['not_gpc']) {
886
                            $cleanv = $ts->stripSlashesGPC($cleanv);
887
                        }
888
                        break;
889
                    case XOBJ_DTYPE_URL:
890 View Code Duplication
                        if ($v['required'] && '' === $cleanv) {
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...
891
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
892
                            continue 2;
893
                        }
894
                        if ('' !== $cleanv && !preg_match("/^http[s]*:\/\//i", $cleanv)) {
895
                            $cleanv = 'http://' . $cleanv;
896
                        }
897
                        if (!$v['not_gpc']) {
898
                            $cleanv =& $ts->stripSlashesGPC($cleanv);
899
                        }
900
                        break;
901
                    case XOBJ_DTYPE_SIMPLE_ARRAY:
902
                        $cleanv = implode('|', $cleanv);
903
                        break;
904
                    case XOBJ_DTYPE_ARRAY:
905
                        $cleanv = serialize($cleanv);
906
                        break;
907
                    case XOBJ_DTYPE_STIME:
908
                    case XOBJ_DTYPE_MTIME:
909
                    case XOBJ_DTYPE_LTIME:
910
                        $cleanv = !is_string($cleanv) ? (int)$cleanv : strtotime($cleanv);
911
                        if (!($cleanv > 0)) {
912
                            $cleanv = strtotime($cleanv);
913
                        }
914
                        break;
915
                    default:
916
                        break;
917
                }
918
            }
919
            $this->cleanVars[$k] =& $cleanv;
920
            unset($cleanv);
921
        }
922
        if (count($this->_errors) > 0) {
923
            $this->_errors = array_merge($existing_errors, $this->_errors);
924
925
            return false;
926
        }
927
        $this->_errors = array_merge($existing_errors, $this->_errors);
928
        $this->unsetDirty();
929
930
        return true;
931
    }
932
933
    /**
934
     * returns a specific variable for the object in a proper format
935
     *
936
     * We had to put this method in the SmartObject because the XOBJ_DTYPE_ARRAY does not work properly
937
     * at least on PHP 5.1. So we have created a new type XOBJ_DTYPE_SIMPLE_ARRAY to handle 1 level array
938
     * as a string separated by |
939
     *
940
     * @access public
941
     * @param  string $key    key of the object's variable to be returned
942
     * @param  string $format format to use for the output
943
     * @return mixed  formatted value of the variable
944
     */
945
    public function getVar($key, $format = 's')
946
    {
947
        global $myts;
948
949
        $ret = $this->vars[$key]['value'];
950
951
        switch ($this->vars[$key]['data_type']) {
952
953
            case XOBJ_DTYPE_TXTBOX:
954
                switch (strtolower($format)) {
955
                    case 's':
956
                    case 'show':
957
                        // ML Hack by marcan
958
                        $ts  = \MyTextSanitizer::getInstance();
959
                        $ret = $ts->htmlSpecialChars($ret);
960
961
                        if (method_exists($myts, 'formatForML')) {
962
                            return $ts->formatForML($ret);
963
                        } else {
964
                            return $ret;
965
                        }
966
                        break 1;
0 ignored issues
show
Unused Code introduced by
break 1; 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...
967
                    // End of ML Hack by marcan
968
969
                    case 'clean':
970
                        $ts = \MyTextSanitizer::getInstance();
971
972
                        $ret = smart_html2text($ret);
973
                        $ret = smart_purifyText($ret);
974
975
                        if (method_exists($myts, 'formatForML')) {
976
                            return $ts->formatForML($ret);
977
                        } else {
978
                            return $ret;
979
                        }
980
                        break 1;
0 ignored issues
show
Unused Code introduced by
break 1; 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...
981
                    // End of ML Hack by marcan
982
983
                    case 'e':
984
                    case 'edit':
985
                        $ts = \MyTextSanitizer::getInstance();
986
987
                        return $ts->htmlSpecialChars($ret);
988
                        break 1;
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...
989
                    case 'p':
990
                    case 'preview':
991
                    case 'f':
992
                    case 'formpreview':
993
                        $ts = \MyTextSanitizer::getInstance();
994
995
                        return $ts->htmlSpecialChars($ts->stripSlashesGPC($ret));
996
                        break 1;
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...
997
                    case 'n':
998
                    case 'none':
999
                    default:
1000
                        break 1;
1001
                }
1002
                break;
1003 View Code Duplication
            case XOBJ_DTYPE_LTIME:
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...
1004
                switch (strtolower($format)) {
1005
                    case 's':
1006
                    case 'show':
1007
                    case 'p':
1008
                    case 'preview':
1009
                    case 'f':
1010
                    case 'formpreview':
1011
                        $ret = formatTimestamp($ret, _DATESTRING);
1012
1013
                        return $ret;
1014
                        break 1;
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...
1015
                    case 'n':
1016
                    case 'none':
1017
                    case 'e':
1018
                    case 'edit':
1019
                        break 1;
1020
                    default:
1021
                        break 1;
1022
                }
1023
                break;
1024 View Code Duplication
            case XOBJ_DTYPE_STIME:
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...
1025
                switch (strtolower($format)) {
1026
                    case 's':
1027
                    case 'show':
1028
                    case 'p':
1029
                    case 'preview':
1030
                    case 'f':
1031
                    case 'formpreview':
1032
                        $ret = formatTimestamp($ret, _SHORTDATESTRING);
1033
1034
                        return $ret;
1035
                        break 1;
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...
1036
                    case 'n':
1037
                    case 'none':
1038
                    case 'e':
1039
                    case 'edit':
1040
                        break 1;
1041
                    default:
1042
                        break 1;
1043
                }
1044
                break;
1045 View Code Duplication
            case XOBJ_DTYPE_TIME_ONLY:
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...
1046
                switch (strtolower($format)) {
1047
                    case 's':
1048
                    case 'show':
1049
                    case 'p':
1050
                    case 'preview':
1051
                    case 'f':
1052
                    case 'formpreview':
1053
                        $ret = formatTimestamp($ret, 'G:i');
1054
1055
                        return $ret;
1056
                        break 1;
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...
1057
                    case 'n':
1058
                    case 'none':
1059
                    case 'e':
1060
                    case 'edit':
1061
                        break 1;
1062
                    default:
1063
                        break 1;
1064
                }
1065
                break;
1066
1067
            case XOBJ_DTYPE_CURRENCY:
1068
                $decimal_section_original = strstr($ret, '.');
1069
                $decimal_section          = $decimal_section_original;
1070 View Code Duplication
                if ($decimal_section) {
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...
1071
                    if (1 == strlen($decimal_section)) {
1072
                        $decimal_section = '.00';
1073
                    } elseif (2 == strlen($decimal_section)) {
1074
                        $decimal_section .= '0';
1075
                    }
1076
                    $ret = str_replace($decimal_section_original, $decimal_section, $ret);
1077
                } else {
1078
                    $ret .= '.00';
1079
                }
1080
                break;
1081
1082
            case XOBJ_DTYPE_TXTAREA:
1083
                switch (strtolower($format)) {
1084
                    case 's':
1085
                    case 'show':
1086
                        $ts   = \MyTextSanitizer::getInstance();
1087
                        $html = !empty($this->vars['dohtml']['value']) ? 1 : 0;
1088
1089
                        $xcode = (!isset($this->vars['doxcode']['value'])
1090
                                  || 1 == $this->vars['doxcode']['value']) ? 1 : 0;
1091
1092
                        $smiley = (!isset($this->vars['dosmiley']['value'])
1093
                                   || 1 == $this->vars['dosmiley']['value']) ? 1 : 0;
1094
                        $image  = (!isset($this->vars['doimage']['value'])
1095
                                   || 1 == $this->vars['doimage']['value']) ? 1 : 0;
1096
                        $br     = (!isset($this->vars['dobr']['value']) || 1 == $this->vars['dobr']['value']) ? 1 : 0;
1097
1098
                        /**
1099
                         * Hack by marcan <INBOX> for SCSPRO
1100
                         * Setting mastop as the main editor
1101
                         */
1102
                        if (defined('XOOPS_EDITOR_IS_HTML')) {
1103
                            $br = false;
1104
                        }
1105
1106
                        /**
1107
                         * Hack by marcan <INBOX> for SCSPRO
1108
                         * Setting mastop as the main editor
1109
                         */
1110
1111
                        return $ts->displayTarea($ret, $html, $smiley, $xcode, $image, $br);
1112
                        break 1;
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...
1113
                    case 'e':
1114
                    case 'edit':
1115
                        return htmlspecialchars($ret, ENT_QUOTES);
1116
                        break 1;
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...
1117
                    case 'p':
1118
                    case 'preview':
1119
                        $ts     = \MyTextSanitizer::getInstance();
1120
                        $html   = !empty($this->vars['dohtml']['value']) ? 1 : 0;
1121
                        $xcode  = (!isset($this->vars['doxcode']['value'])
1122
                                   || 1 == $this->vars['doxcode']['value']) ? 1 : 0;
1123
                        $smiley = (!isset($this->vars['dosmiley']['value'])
1124
                                   || 1 == $this->vars['dosmiley']['value']) ? 1 : 0;
1125
                        $image  = (!isset($this->vars['doimage']['value'])
1126
                                   || 1 == $this->vars['doimage']['value']) ? 1 : 0;
1127
                        $br     = (!isset($this->vars['dobr']['value']) || 1 == $this->vars['dobr']['value']) ? 1 : 0;
1128
1129
                        return $ts->previewTarea($ret, $html, $smiley, $xcode, $image, $br);
1130
                        break 1;
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...
1131
                    case 'f':
1132 View Code Duplication
                    case 'formpreview':
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...
1133
                        $ts = \MyTextSanitizer::getInstance();
1134
1135
                        return htmlspecialchars($ts->stripSlashesGPC($ret), ENT_QUOTES);
1136
                        break 1;
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...
1137
                    case 'n':
1138
                    case 'none':
1139
                    default:
1140
                        break 1;
1141
                }
1142
                break;
1143
            case XOBJ_DTYPE_SIMPLE_ARRAY:
1144
                $ret =& explode('|', $ret);
1145
                break;
1146
            case XOBJ_DTYPE_ARRAY:
1147
                $ret =& unserialize($ret);
1148
                break;
1149
            case XOBJ_DTYPE_SOURCE:
1150
                switch (strtolower($format)) {
1151
                    case 's':
1152
                    case 'show':
1153
                        break 1;
1154
                    case 'e':
1155
                    case 'edit':
1156
                        return htmlspecialchars($ret, ENT_QUOTES);
1157
                        break 1;
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...
1158
                    case 'p':
1159
                    case 'preview':
1160
                        $ts = \MyTextSanitizer::getInstance();
1161
1162
                        return $ts->stripSlashesGPC($ret);
1163
                        break 1;
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...
1164
                    case 'f':
1165 View Code Duplication
                    case 'formpreview':
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...
1166
                        $ts = \MyTextSanitizer::getInstance();
1167
1168
                        return htmlspecialchars($ts->stripSlashesGPC($ret), ENT_QUOTES);
1169
                        break 1;
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...
1170
                    case 'n':
1171
                    case 'none':
1172
                    default:
1173
                        break 1;
1174
                }
1175
                break;
1176
            default:
1177
                if ('' !== $this->vars[$key]['options'] && '' != $ret) {
1178
                    switch (strtolower($format)) {
1179
                        case 's':
1180
                        case 'show':
1181
                            $selected = explode('|', $ret);
1182
                            $options  = explode('|', $this->vars[$key]['options']);
1183
                            $i        = 1;
1184
                            $ret      = [];
1185
                            foreach ($options as $op) {
1186
                                if (in_array($i, $selected)) {
1187
                                    $ret[] = $op;
1188
                                }
1189
                                ++$i;
1190
                            }
1191
1192
                            return implode(', ', $ret);
1193
                        case 'e':
1194
                        case 'edit':
1195
                            $ret = explode('|', $ret);
1196
                            break 1;
1197
                        default:
1198
                            break 1;
1199
                    }
1200
                }
1201
                break;
1202
        }
1203
1204
        return $ret;
1205
    }
1206
1207
    /**
1208
     * @param $key
1209
     */
1210
    public function doMakeFieldreadOnly($key)
1211
    {
1212
        if (isset($this->vars[$key])) {
1213
            $this->vars[$key]['readonly']      = true;
1214
            $this->vars[$key]['displayOnForm'] = true;
1215
        }
1216
    }
1217
1218
    /**
1219
     * @param $key
1220
     */
1221
    public function makeFieldReadOnly($key)
1222
    {
1223
        if (is_array($key)) {
1224
            foreach ($key as $v) {
1225
                $this->doMakeFieldreadOnly($v);
1226
            }
1227
        } else {
1228
            $this->doMakeFieldreadOnly($key);
1229
        }
1230
    }
1231
1232
    /**
1233
     * @param $key
1234
     */
1235
    public function doHideFieldFromForm($key)
1236
    {
1237
        if (isset($this->vars[$key])) {
1238
            $this->vars[$key]['displayOnForm'] = false;
1239
        }
1240
    }
1241
1242
    /**
1243
     * @param $key
1244
     */
1245
    public function doHideFieldFromSingleView($key)
1246
    {
1247
        if (isset($this->vars[$key])) {
1248
            $this->vars[$key]['displayOnSingleView'] = false;
1249
        }
1250
    }
1251
1252
    /**
1253
     * @param $key
1254
     */
1255
    public function hideFieldFromForm($key)
1256
    {
1257
        if (is_array($key)) {
1258
            foreach ($key as $v) {
1259
                $this->doHideFieldFromForm($v);
1260
            }
1261
        } else {
1262
            $this->doHideFieldFromForm($key);
1263
        }
1264
    }
1265
1266
    /**
1267
     * @param $key
1268
     */
1269
    public function hideFieldFromSingleView($key)
1270
    {
1271
        if (is_array($key)) {
1272
            foreach ($key as $v) {
1273
                $this->doHideFieldFromSingleView($v);
1274
            }
1275
        } else {
1276
            $this->doHideFieldFromSingleView($key);
1277
        }
1278
    }
1279
1280
    /**
1281
     * @param $key
1282
     */
1283
    public function doShowFieldOnForm($key)
1284
    {
1285
        if (isset($this->vars[$key])) {
1286
            $this->vars[$key]['displayOnForm'] = true;
1287
        }
1288
    }
1289
1290
    /**
1291
     * Display an automatic SingleView of the object, based on the displayOnSingleView param of each vars
1292
     *
1293
     * @param  bool  $fetchOnly if set to TRUE, then the content will be return, if set to FALSE, the content will be outputed
1294
     * @param  bool  $userSide  for futur use, to do something different on the user side
1295
     * @param  array $actions
1296
     * @param  bool  $headerAsRow
1297
     * @return string content of the template if $fetchOnly or nothing if !$fetchOnly
1298
     */
1299
    public function displaySingleObject(
1300
        $fetchOnly = false,
1301
        $userSide = false,
1302
        $actions = [],
1303
        $headerAsRow = true
1304
    ) {
1305
        require_once SMARTOBJECT_ROOT_PATH . 'class/smartobjectsingleview.php';
1306
        $singleview = new SmartObjectSingleView($this, $userSide, $actions, $headerAsRow);
1307
        // add all fields mark as displayOnSingleView except the keyid
1308
        foreach ($this->vars as $key => $var) {
1309
            if ($key != $this->handler->keyName && $var['displayOnSingleView']) {
1310
                $is_header = ($key == $this->handler->identifierName);
1311
                $singleview->addRow(new SmartObjectRow($key, false, $is_header));
1312
            }
1313
        }
1314
1315
        if ($fetchOnly) {
1316
            $ret = $singleview->render($fetchOnly);
1317
1318
            return $ret;
1319
        } else {
1320
            $singleview->render($fetchOnly);
1321
        }
1322
    }
1323
1324
    /**
1325
     * @param $key
1326
     */
1327
    public function doDisplayFieldOnSingleView($key)
1328
    {
1329
        if (isset($this->vars[$key])) {
1330
            $this->vars[$key]['displayOnSingleView'] = true;
1331
        }
1332
    }
1333
1334
    /**
1335
     * @param      $field
1336
     * @param bool $required
1337
     */
1338
    public function doSetFieldAsRequired($field, $required = true)
1339
    {
1340
        $this->setVarInfo($field, 'required', $required);
1341
    }
1342
1343
    /**
1344
     * @param $field
1345
     */
1346
    public function doSetFieldForSorting($field)
1347
    {
1348
        $this->setVarInfo($field, 'sortby', true);
1349
    }
1350
1351
    /**
1352
     * @param $key
1353
     */
1354
    public function showFieldOnForm($key)
1355
    {
1356
        if (is_array($key)) {
1357
            foreach ($key as $v) {
1358
                $this->doShowFieldOnForm($v);
1359
            }
1360
        } else {
1361
            $this->doShowFieldOnForm($key);
1362
        }
1363
    }
1364
1365
    /**
1366
     * @param $key
1367
     */
1368
    public function displayFieldOnSingleView($key)
1369
    {
1370
        if (is_array($key)) {
1371
            foreach ($key as $v) {
1372
                $this->doDisplayFieldOnSingleView($v);
1373
            }
1374
        } else {
1375
            $this->doDisplayFieldOnSingleView($key);
1376
        }
1377
    }
1378
1379
    /**
1380
     * @param $key
1381
     */
1382
    public function doSetAdvancedFormFields($key)
1383
    {
1384
        if (isset($this->vars[$key])) {
1385
            $this->vars[$key]['advancedform'] = true;
1386
        }
1387
    }
1388
1389
    /**
1390
     * @param $key
1391
     */
1392
    public function setAdvancedFormFields($key)
1393
    {
1394
        if (is_array($key)) {
1395
            foreach ($key as $v) {
1396
                $this->doSetAdvancedFormFields($v);
1397
            }
1398
        } else {
1399
            $this->doSetAdvancedFormFields($key);
1400
        }
1401
    }
1402
1403
    /**
1404
     * @param $key
1405
     * @return mixed
1406
     */
1407 View Code Duplication
    public function getUrlLinkObj($key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1408
    {
1409
        $smartobjectLinkurlHandler = xoops_getModuleHandler('urllink', 'smartobject');
1410
        $urllinkid                 = null !== $this->getVar($key) ? $this->getVar($key) : 0;
1411
        if (0 != $urllinkid) {
1412
            return $smartobjectLinkurlHandler->get($urllinkid);
1413
        } else {
1414
            return $smartobjectLinkurlHandler->create();
1415
        }
1416
    }
1417
1418
    /**
1419
     * @param $urlLinkObj
1420
     * @return mixed
1421
     */
1422
    public function &storeUrlLinkObj($urlLinkObj)
1423
    {
1424
        $smartobjectLinkurlHandler = xoops_getModuleHandler('urllink', 'smartobject');
1425
1426
        return $smartobjectLinkurlHandler->insert($urlLinkObj);
1427
    }
1428
1429
    /**
1430
     * @param $key
1431
     * @return mixed
1432
     */
1433 View Code Duplication
    public function getFileObj($key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1434
    {
1435
        $smartobjectFileHandler = xoops_getModuleHandler('file', 'smartobject');
1436
        $fileid                 = null !== $this->getVar($key) ? $this->getVar($key) : 0;
1437
        if (0 != $fileid) {
1438
            return $smartobjectFileHandler->get($fileid);
1439
        } else {
1440
            return $smartobjectFileHandler->create();
1441
        }
1442
    }
1443
1444
    /**
1445
     * @param $fileObj
1446
     * @return mixed
1447
     */
1448
    public function &storeFileObj($fileObj)
1449
    {
1450
        $smartobjectFileHandler = xoops_getModuleHandler('file', 'smartobject');
1451
1452
        return $smartobjectFileHandler->insert($fileObj);
1453
    }
1454
}
1455