ThemeTabForm   F
last analyzed

Complexity

Total Complexity 73

Size/Duplication

Total Lines 523
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 148
c 0
b 0
f 0
dl 0
loc 523
rs 2.56
wmc 73

28 Methods

Rating   Name   Duplication   Size   Complexity  
A setSummary() 0 4 2
A getElementByName() 0 11 3
A startFormTabs() 0 6 1
A getAction() 0 4 2
A renderValidationJS() 0 20 5
A render() 0 3 1
A getElements() 0 13 4
A getMethod() 0 3 2
B setElementValues() 0 9 7
A getTitle() 0 3 2
A endTabs() 0 4 1
A startTab() 0 4 1
A getName() 0 3 2
A getElementValue() 0 8 3
A getElementNames() 0 9 2
A getElementValues() 0 13 4
A __construct() 0 17 2
A insertBreak() 0 2 1
A endFormTabs() 0 5 1
A getSummary() 0 3 2
A setRequired() 0 3 1
A setExtra() 0 4 2
B assign() 0 49 10
A getExtra() 0 5 2
A getRequired() 0 3 1
A setElementValue() 0 5 3
A addElement() 0 13 5
A display() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like ThemeTabForm 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.

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 ThemeTabForm, and based on these observations, apply Extract Interface, too.

1
<?php declare(strict_types=1);
2
3
namespace XoopsModules\Publisher\Form;
4
5
/*
6
 You may not change or alter any portion of this comment or credits
7
 of supporting developers from this source code or any supporting source code
8
 which is considered copyrighted (c) material of the original comment or credit authors.
9
10
 This program is distributed in the hope that it will be useful,
11
 but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 */
14
/**
15
 *  Publisher class
16
 *
17
 * @copyright       XOOPS Project (https://xoops.org)
18
 * @license         https://www.fsf.org/copyleft/gpl.html GNU public license
19
 * @since           1.0
20
 * @author          trabis <[email protected]>
21
 * @author          John Neill <[email protected]>
22
 */
23
require_once \dirname(__DIR__, 2) . '/include/common.php';
24
25
/**
26
 * XoopsThemeTabForm
27
 *
28
 * @author    John
29
 * @copyright Copyright (c) 2009
30
 */
31
class ThemeTabForm extends \XoopsForm
32
{
33
    public $formTabs = [];
34
    /**
35
     * "action" attribute for the html form
36
     *
37
     * @var string
38
     */
39
    public $action;
40
    /**
41
     * "method" attribute for the form.
42
     *
43
     * @var string
44
     */
45
    public $method;
46
    /**
47
     * "name" attribute of the form
48
     *
49
     * @var string
50
     */
51
    public $name;
52
    /**
53
     * title for the form
54
     *
55
     * @var string
56
     */
57
    public $title;
58
    /**
59
     * summary for the form (WGAC2 Requirement)
60
     *
61
     * @var string
62
     */
63
    public $summary = '';
64
    /**
65
     * array of {@link XoopsFormElement} objects
66
     *
67
     * @var array
68
     */
69
    public $elements = [];
70
    /**
71
     * extra information for the <form> tag
72
     *
73
     * @var array
74
     */
75
    public $extra = [];
76
    /**
77
     * required elements
78
     *
79
     * @var array
80
     */
81
    public $required = [];
82
83
    /**
84
     * @param string $title
85
     * @param string $name
86
     * @param string $action
87
     * @param string $method
88
     * @param bool   $addtoken
89
     * @param string $summary
90
     */
91
    public function __construct($title, $name, $action, $method = 'post', $addtoken = false, $summary = '')
92
    {
93
        //        global $xoTheme;
94
        //        $GLOBALS['xoTheme']->addScript(PUBLISHER_URL . '/assets/js/ui.core.js');
95
        //        $GLOBALS['xoTheme']->addScript(PUBLISHER_URL . '/assets/js/ui.tabs.js');
96
        //        $GLOBALS['xoTheme']->addStylesheet(PUBLISHER_URL . '/assets/css/jquery-ui-1.7.1.custom.css');
97
98
        $GLOBALS['xoTheme']->addScript('browse.php?Frameworks/jquery/plugins/jquery.ui.js');
99
        $GLOBALS['xoTheme']->addStylesheet(XOOPS_URL . '/modules/system/css/ui/' . \xoops_getModuleOption('jquery_theme', 'system') . '/ui.all.css');
0 ignored issues
show
Deprecated Code introduced by
The function xoops_getModuleOption() has been deprecated. ( Ignorable by Annotation )

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

99
        $GLOBALS['xoTheme']->addStylesheet(XOOPS_URL . '/modules/system/css/ui/' . /** @scrutinizer ignore-deprecated */ \xoops_getModuleOption('jquery_theme', 'system') . '/ui.all.css');
Loading history...
100
101
        $this->title   = $title;
102
        $this->name    = $name;
103
        $this->action  = $action;
104
        $this->method  = $method;
105
        $this->summary = $summary;
106
        if ($addtoken) {
107
            $this->addElement(new \XoopsFormHiddenToken());
108
        }
109
    }
110
111
    //function render() {}
112
113
    public function assign(\XoopsTpl $tpl): void
114
    {
115
        $i        = -1;
116
        $tab      = -1;
117
        $elements = [];
118
        if (\count($this->getRequired()) > 0) {
119
            $this->elements[] = "<tr class='foot'><td colspan='2'>* = " . \_REQUIRED . '</td></tr>';
120
        }
121
        foreach ($this->getElements() as $ele) {
122
            ++$i;
123
            if (\is_string($ele) && 'addTab' === $ele) {
124
                ++$tab;
125
                continue;
126
            }
127
            if (\is_string($ele) && 'endTabs' === $ele) {
128
                $tab = -1;
129
                continue;
130
            }
131
            if (\is_string($ele)) {
132
                $elements[$i]['body'] = $ele;
133
                $elements[$i]['tab']  = $tab;
134
                continue;
135
            }
136
            $eleName                  = $ele->getName();
137
            $eleDescription           = $ele->getDescription();
138
            $n                        = $eleName ?: $i;
139
            $elements[$n]['name']     = $eleName;
140
            $elements[$n]['caption']  = $ele->getCaption();
141
            $elements[$n]['body']     = $ele->render();
142
            $elements[$n]['hidden']   = (bool)$ele->isHidden();
143
            $elements[$n]['required'] = $ele->isRequired();
144
            if ('' != $eleDescription) {
145
                $elements[$n]['description'] = $eleDescription;
146
            }
147
            $elements[$n]['tab'] = $tab;
148
        }
149
        $js = $this->renderValidationJS();
150
        $tpl->assign(
151
            $this->getName(),
152
            [
153
                'title'      => $this->getTitle(),
154
                'id'         => 'tab_' . \preg_replace('/[^a-z0-9]+/i', '', $this->getTitle()),
155
                'name'       => $this->getName(),
156
                'action'     => $this->getAction(),
157
                'method'     => $this->getMethod(),
158
                'extra'      => 'onsubmit="return xoopsFormValidate_' . $this->getName() . '();"' . $this->getExtra(),
159
                'javascript' => $js,
160
                'tabs'       => $this->formTabs,
161
                'elements'   => $elements,
162
            ]
163
        );
164
    }
165
166
    /**
167
     * XoopsThemeTabForm::startTab()
168
     *
169
     * @param mixed $tabText
170
     */
171
    public function startTab($tabText): void
172
    {
173
        $temp = $this->startFormTabs($tabText);
174
        $this->addElement($temp);
175
    }
176
177
    /**
178
     * XoopsThemeTabForm::endTab()
179
     */
180
    public function endTabs(): void
181
    {
182
        $temp = $this->endFormTabs();
183
        $this->addElement($temp);
184
    }
185
186
    /**
187
     * Creates a tab with title text and starts that tabs page
188
     *
189
     * @param $tabText - This is what is displayed on the tab
0 ignored issues
show
Documentation Bug introduced by
The doc comment - at position 0 could not be parsed: Unknown type name '-' at position 0 in -.
Loading history...
190
     *
191
     * @return string
192
     */
193
    public function startFormTabs($tabText)
194
    {
195
        $this->formTabs[] = $tabText;
196
        $ret              = 'addTab';
197
198
        return $ret;
199
    }
200
201
    /**
202
     * Ends a tab page
203
     *
204
     * @return string
205
     */
206
    public function endFormTabs()
207
    {
208
        $ret = 'endTabs';
209
210
        return $ret;
211
    }
212
213
    /**
214
     * @param bool $encode
215
     *
216
     * @return string
217
     */
218
    public function getSummary($encode = false)
219
    {
220
        return $encode ? \htmlspecialchars($this->summary, \ENT_QUOTES | ENT_HTML5) : $this->summary;
221
    }
222
223
    /**
224
     * return the title of the form
225
     *
226
     * @param bool $encode To sanitizer the text?
227
     *
228
     * @return string
229
     */
230
    public function getTitle($encode = false)
231
    {
232
        return $encode ? \htmlspecialchars($this->title, \ENT_QUOTES | ENT_HTML5) : $this->title;
233
    }
234
235
    /**
236
     * get the "name" attribute for the <form> tag
237
     * Deprecated, to be refactored
238
     *
239
     * @param bool $encode To sanitizer the text?
240
     *
241
     * @return string
242
     */
243
    public function getName($encode = true)
244
    {
245
        return $encode ? \htmlspecialchars($this->name, \ENT_QUOTES | ENT_HTML5) : $this->name;
246
    }
247
248
    /**
249
     * get the "action" attribute for the <form> tag
250
     *
251
     * @param bool $encode To sanitizer the text?
252
     *
253
     * @return string
254
     */
255
    public function getAction($encode = true)
256
    {
257
        // Convert &amp; to & for backward compatibility
258
        return $encode ? \htmlspecialchars(\str_replace('&amp;', '&', $this->action), \ENT_QUOTES | ENT_HTML5) : $this->action;
259
    }
260
261
    /**
262
     * get the "method" attribute for the <form> tag
263
     *
264
     * @return string
265
     */
266
    public function getMethod()
267
    {
268
        return ('get' === \mb_strtolower($this->method)) ? 'get' : 'post';
269
    }
270
271
    /**
272
     * Add an element to the form
273
     *
274
     * @param string|\XoopsFormElement $formElement reference to a {@link XoopsFormElement}
275
     * @param bool                     $required    is this a "required" element?
276
     */
277
    public function addElement($formElement, $required = false): void
278
    {
279
        if (\is_string($formElement)) {
280
            $this->elements[] = &$formElement;
281
        } elseif (\is_subclass_of($formElement, 'xoopsformelement')) {
282
            $this->elements[] = &$formElement;
283
            if ($required) {
284
                if (\method_exists($formElement, 'setRequired')) {
285
                    $formElement->setRequired(true);
286
                } else {
287
                    $formElement->required = true;
0 ignored issues
show
Bug introduced by
The property required does not exist on XoopsFormElement. Did you mean _required?
Loading history...
288
                }
289
                $this->required[] = &$formElement;
290
            }
291
        }
292
    }
293
294
    /**
295
     * get an array of forms elements
296
     *
297
     * @param bool $recurse get elements recursively?
298
     *
299
     * @return array array of {@link XoopsFormElement}s
300
     */
301
    public function &getElements($recurse = false)
302
    {
303
        if (!$recurse) {
304
            return $this->elements;
305
        }
306
        $ret = [];
307
        foreach ($this->elements as $i => $iValue) {
308
            if (\is_object($this->elements[$i])) {
309
                $ret[] = &$this->elements[$i];
310
            }
311
        }
312
313
        return $ret;
314
    }
315
316
    /**
317
     * get an array of "name" attributes of form elements
318
     *
319
     * @return array array of form element names
320
     */
321
    public function getElementNames()
322
    {
323
        $ret      = [];
324
        $elements = &$this->getElements(true);
325
        foreach ($elements as $iValue) {
326
            $ret[] = $iValue->getName();
327
        }
328
329
        return $ret;
330
    }
331
332
    /**
333
     * get a reference to a {@link XoopsFormElement} object by its "name"
334
     *
335
     * @param string $name "name" attribute assigned to a {@link XoopsFormElement}
336
     *
337
     * @return bool|\XoopsFormElement reference to a {@link XoopsFormElement}, false if not found
338
     */
339
    public function &getElementByName($name)
340
    {
341
        $elements = &$this->getElements(true);
342
        foreach ($elements as $i => $iValue) {
343
            if ($name == $iValue->getName(false)) {
344
                return $iValue;
345
            }
346
        }
347
        $elt = null;
348
349
        return $elt;
350
    }
351
352
    /**
353
     * Sets the "value" attribute of a form element
354
     *
355
     * @param string $name  the "name" attribute of a form element
356
     * @param string $value the "value" attribute of a form element
357
     */
358
    public function setElementValue($name, $value): void
359
    {
360
        $ele = &$this->getElementByName($name);
361
        if (\is_object($ele) && \method_exists($ele, 'setValue')) {
362
            $ele->setValue($value);
363
        }
364
    }
365
366
    /**
367
     * Sets the "value" attribute of form elements in a batch
368
     *
369
     * @param array $values array of name/value pairs to be assigned to form elements
370
     */
371
    public function setElementValues($values): void
372
    {
373
        if (\is_array($values) && !empty($values)) {
374
            // will not use getElementByName() for performance..
375
            $elements = &$this->getElements(true);
376
            foreach ($elements as $i => $iValue) {
377
                $name = $iValue->getName(false);
378
                if ($name && isset($values[$name]) && \method_exists($iValue, 'setValue')) {
379
                    $iValue->setValue($values[$name]);
380
                }
381
            }
382
        }
383
    }
384
385
    /**
386
     * Gets the "value" attribute of a form element
387
     *
388
     * @param string $name   the "name" attribute of a form element
389
     * @param bool   $encode To sanitizer the text?
390
     *
391
     * @return string the "value" attribute assigned to a form element, null if not set
392
     */
393
    public function getElementValue($name, $encode = false)
394
    {
395
        $ele = &$this->getElementByName($name);
396
        if (\is_object($ele) && \method_exists($ele, 'getValue')) {
397
            return $ele->getValue($encode);
398
        }
399
400
        return null;
401
    }
402
403
    /**
404
     * gets the "value" attribute of all form elements
405
     *
406
     * @param bool $encode To sanitizer the text?
407
     *
408
     * @return array array of name/value pairs assigned to form elements
409
     */
410
    public function getElementValues($encode = false)
411
    {
412
        // will not use getElementByName() for performance..
413
        $elements = &$this->getElements(true);
414
        $values   = [];
415
        foreach ($elements as $i => $iValue) {
416
            $name = $iValue->getName(false);
417
            if ($name && \method_exists($iValue, 'getValue')) {
418
                $values[$name] = $iValue->getValue($encode);
419
            }
420
        }
421
422
        return $values;
423
    }
424
425
    /**
426
     * set the extra attributes for the <form> tag
427
     *
428
     * @param string $extra extra attributes for the <form> tag
429
     * @return string|void
430
     */
431
    public function setExtra($extra)
432
    {
433
        if (!empty($extra)) {
434
            $this->extra[] = $extra;
435
        }
436
    }
437
438
    /**
439
     * set the summary tag for the <form> tag
440
     *
441
     * @param string $summary
442
     */
443
    public function setSummary($summary): void
444
    {
445
        if (!empty($summary)) {
446
            $this->summary = \strip_tags($summary);
447
        }
448
    }
449
450
    /**
451
     * get the extra attributes for the <form> tag
452
     *
453
     * @return string
454
     */
455
    public function &getExtra()
456
    {
457
        $extra = empty($this->extra) ? '' : ' ' . \implode(' ', $this->extra);
458
459
        return $extra;
460
    }
461
462
    /**
463
     * make an element "required"
464
     *
465
     * @param \XoopsFormElement $formElement reference to a {@link XoopsFormElement}
466
     */
467
    public function setRequired(\XoopsFormElement $formElement): void
468
    {
469
        $this->required[] = &$formElement;
470
    }
471
472
    /**
473
     * get an array of "required" form elements
474
     *
475
     * @return array array of {@link XoopsFormElement}s
476
     */
477
    public function &getRequired()
478
    {
479
        return $this->required;
480
    }
481
482
    /**
483
     * insert a break in the form
484
     * This method is abstract. It must be overwritten in the child classes.
485
     *
486
     * @param string|null $extra extra information for the break
487
     *
488
     * @abstract
489
     */
490
    public function insertBreak($extra = null): void
491
    {
492
    }
493
494
    /**
495
     * returns renderered form
496
     * This method is abstract. It must be overwritten in the child classes.
497
     *
498
     * @abstract
499
     */
500
    public function render()
501
    {
502
        return '';
503
    }
504
505
    /**
506
     * displays rendered form
507
     */
508
    public function display(): void
509
    {
510
        echo $this->render();
511
    }
512
513
    /**
514
     * Renders the Javascript function needed for client-side for validation
515
     * Form elements that have been declared "required" and not set will prevent the form from being
516
     * submitted. Additionally, each element class may provide its own "renderValidationJS" method
517
     * that is supposed to return custom validation code for the element.
518
     * The element validation code can assume that the JS "myform" variable points to the form, and must
519
     * execute <i>return false</i> if validation fails.
520
     * A basic element validation method may contain something like this:
521
     * <code>
522
     * function renderValidationJS() {
523
     *            $name = $this->getName();
524
     *            return "if (myform.{$name}.value != 'valid') { " .
525
     *              "myform.{$name}.focus(); window.alert( '$name is invalid' ); return false;" .
526
     *              " }";
527
     * }
528
     * </code>
529
     *
530
     * @param bool $withtags Include the < javascript > tags in the returned string
531
     *
532
     * @return string
533
     */
534
    public function renderValidationJS($withtags = true)
535
    {
536
        $js = '';
537
        if ($withtags) {
538
            $js .= "\n<!-- Start Form Validation JavaScript //-->\n<script type='text/javascript'>\n<!--//\n";
539
        }
540
        $formname = $this->getName();
541
        $js       .= "function xoopsFormValidate_{$formname}() { var myform = window.document.{$formname}; ";
542
        $elements = &$this->getElements(true);
543
        foreach ($elements as $elt) {
544
            if (\method_exists($elt, 'renderValidationJS')) {
545
                $js .= $elt->renderValidationJS();
546
            }
547
        }
548
        $js .= "return true;\n}\n";
549
        if ($withtags) {
550
            $js .= "//--></script>\n";
551
        }
552
553
        return $js;
554
    }
555
}
556