Completed
Push — master ( c1777d...d193e2 )
by Michael
13:22
created

MyXoopsGroupFormCheckBox::_renderOptionTree()   B

Complexity

Conditions 7
Paths 24

Size

Total Lines 57
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 43
nc 24
nop 4
dl 0
loc 57
rs 7.6759
c 0
b 0
f 0

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 39 and the first side effect is on line 21.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/*
3
 * You may not change or alter any portion of this comment or credits
4
 * of supporting developers from this source code or any supporting source code
5
 * which is considered copyrighted (c) material of the original comment or credit authors.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
 */
11
12
/**
13
 * @copyright    XOOPS Project http://xoops.org/
14
 * @license      GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
15
 * @package
16
 * @since
17
 * @author       XOOPS Development Team, Kazumi Ono (AKA onokazu)
18
 */
19
20
21
defined('XOOPS_ROOT_PATH') || exit('XOOPS root path not defined');
22
23
require_once XOOPS_ROOT_PATH . '/class/xoopsform/formelement.php';
24
require_once XOOPS_ROOT_PATH . '/class/xoopsform/formhidden.php';
25
require_once XOOPS_ROOT_PATH . '/class/xoopsform/formhiddentoken.php';
26
require_once XOOPS_ROOT_PATH . '/class/xoopsform/formbutton.php';
27
require_once XOOPS_ROOT_PATH . '/class/xoopsform/formelementtray.php';
28
require_once XOOPS_ROOT_PATH . '/class/xoopsform/form.php';
29
30
/**
31
 * Renders a form for setting module specific group permissions
32
 *
33
 * @author       Kazumi Ono    <[email protected]>
34
 * @copyright    copyright (c) 2000-2003 XOOPS.org
35
 *
36
 * @package      kernel
37
 * @subpackage   form
38
 */
39
class MyXoopsGroupPermForm extends XoopsForm
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
40
{
41
    /**
42
     * Module ID
43
     * @var int
44
     */
45
    public $_modid;
46
    /**
47
     * Tree structure of items
48
     * @var array
49
     */
50
    public $_itemTree = array();
51
    /**
52
     * Name of permission
53
     * @var string
54
     */
55
    public $_permName;
56
    /**
57
     * Description of permission
58
     * @var string
59
     */
60
    public $_permDesc;
61
    /**
62
     * Appendix
63
     * @var array ('permname'=>,'itemid'=>,'itemname'=>,'selected'=>)
64
     */
65
    public $_appendix = array();
66
67
    /**
68
     * Constructor
69
     * @param $title
70
     * @param $modid
71
     * @param $permname
72
     * @param $permdesc
73
     */
74
    public function __construct($title, $modid, $permname, $permdesc)
75
    {
76
        //      $this->XoopsForm($title, 'groupperm_form', XOOPS_URL.'/modules/system/admin/groupperm.php', 'post'); GIJ
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% 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...
77
        parent::__construct($title, 'groupperm_form', '', 'post');
78
        $this->_modid    = (int)$modid;
79
        $this->_permName = $permname;
80
        $this->_permDesc = $permdesc;
81
        $this->addElement(new XoopsFormHidden('modid', $this->_modid));
82
        $this->addElement(new XoopsFormHiddenToken($permname));
83
    }
84
85
    /**
86
     * Adds an item to which permission will be assigned
87
     *
88
     * @param string $itemName
89
     * @param int    $itemId
90
     * @param int    $itemParent
91
     * @access public
92
     */
93
    public function addItem($itemId, $itemName, $itemParent = 0)
94
    {
95
        $this->_itemTree[$itemParent]['children'][] = $itemId;
96
        $this->_itemTree[$itemId]['parent']         = $itemParent;
97
        $this->_itemTree[$itemId]['name']           = $itemName;
98
        $this->_itemTree[$itemId]['id']             = $itemId;
99
    }
100
101
    /**
102
     * Add appendix
103
     *
104
     * @access public
105
     * @param $permName
106
     * @param $itemId
107
     * @param $itemName
108
     */
109
    public function addAppendix($permName, $itemId, $itemName)
110
    {
111
        $this->_appendix[] = array(
112
            'permname' => $permName,
113
            'itemid'   => $itemId,
114
            'itemname' => $itemName,
115
            'selected' => false
116
        );
117
    }
118
119
    /**
120
     * Loads all child ids for an item to be used in javascript
121
     *
122
     * @param int   $itemId
123
     * @param array $childIds
124
     * @access private
125
     */
126
    public function _loadAllChildItemIds($itemId, &$childIds)
127
    {
128
        if (!empty($this->_itemTree[$itemId]['children'])) {
129
            $first_child = $this->_itemTree[$itemId]['children'];
130
            foreach ($first_child as $fcid) {
131
                array_push($childIds, $fcid);
132
                if (!empty($this->_itemTree[$fcid]['children'])) {
133
                    foreach ($this->_itemTree[$fcid]['children'] as $_fcid) {
134
                        array_push($childIds, $_fcid);
135
                        $this->_loadAllChildItemIds($_fcid, $childIds);
136
                    }
137
                }
138
            }
139
        }
140
    }
141
142
    /**
143
     * Renders the form
144
     *
145
     * @return string
146
     * @access public
147
     */
148
    public function render()
149
    {
150
        global $xoopsGTicket;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
151
152
        // load all child ids for javascript codes
153
        foreach (array_keys($this->_itemTree) as $item_id) {
154
            $this->_itemTree[$item_id]['allchild'] = array();
155
            $this->_loadAllChildItemIds($item_id, $this->_itemTree[$item_id]['allchild']);
156
        }
157
        $gpermHandler  = xoops_getHandler('groupperm');
158
        $memberHandler = xoops_getHandler('member');
159
        $glist         = $memberHandler->getGroupList();
160
        foreach (array_keys($glist) as $i) {
161
            // get selected item id(s) for each group
162
            $selected = $gpermHandler->getItemIds($this->_permName, $i, $this->_modid);
163
            $ele      = new MyXoopsGroupFormCheckBox($glist[$i], 'perms[' . $this->_permName . ']', $i, $selected);
164
            $ele->setOptionTree($this->_itemTree);
165
166
            foreach ($this->_appendix as $key => $append) {
167
                $this->_appendix[$key]['selected'] = $gpermHandler->checkRight($append['permname'], $append['itemid'], $i, $this->_modid);
168
            }
169
            $ele->setAppendix($this->_appendix);
170
            $this->addElement($ele);
171
            unset($ele);
172
        }
173
174
        // GIJ start
175
        $jstray          = new XoopsFormElementTray(' &nbsp; ');
176
        $jsuncheckbutton = new XoopsFormButton('', 'none', _NONE, 'button');
177
        $jsuncheckbutton->setExtra("onclick=\"with(document.groupperm_form){for (i=0;i<length;i++) {if (elements[i].type=='checkbox') {elements[i].checked=false;}}}\"");
178
        $jscheckbutton = new XoopsFormButton('', 'all', _ALL, 'button');
179
        $jscheckbutton->setExtra("onclick=\"with(document.groupperm_form){for (i=0;i<length;i++) {if(elements[i].type=='checkbox' && (elements[i].name.indexOf('module_admin')<0 || elements[i].name.indexOf('[groups][1]')>=0)) {elements[i].checked=true;}}}\"");
180
        $jstray->addElement($jsuncheckbutton);
181
        $jstray->addElement($jscheckbutton);
182
        $this->addElement($jstray);
183
        // GIJ end
184
185
        $tray = new XoopsFormElementTray('');
186
        $tray->addElement(new XoopsFormButton('', 'reset', _CANCEL, 'reset'));
187
        $tray->addElement(new XoopsFormButton('', 'submit', _SUBMIT, 'submit'));
188
        $this->addElement($tray);
189
190
        $ret      = '<h4>' . $this->getTitle() . '</h4>' . $this->_permDesc . '<br>';
191
        $ret      .= "<form name='"
192
                     . $this->getName()
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
193
                     . "' id='"
194
                     . $this->getName()
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
195
                     . "' action='"
196
                     . $this->getAction()
197
                     . "' method='"
198
                     . $this->getMethod()
199
                     . "'"
200
                     . $this->getExtra()
201
                     . ">\n<table width='100%' class='outer' cellspacing='1'>\n";
202
        $elements =& $this->getElements();
203
        foreach (array_keys($elements) as $i) {
204
            if (!is_object($elements[$i])) {
205
                $ret .= $elements[$i];
206
            } elseif (!$elements[$i]->isHidden()) {
207
                $ret .= "<tr valign='top' align='left'><td class='head'>" . $elements[$i]->getCaption();
208
                if ($elements[$i]->getDescription() != '') {
209
                    $ret .= '<br><br><span style="font-weight: normal;">' . $elements[$i]->getDescription() . '</span>';
210
                }
211
                $ret .= "</td>\n<td class='even'>\n" . $elements[$i]->render() . "\n</td></tr>\n";
212
            } else {
213
                $ret .= $elements[$i]->render();
214
            }
215
        }
216
        $ret .= '</table>' . $xoopsGTicket->getTicketHtml(__LINE__, 1800, 'myblocksadmin') . '</form>';
217
218
        return $ret;
219
    }
220
}
221
222
/**
223
 * Renders checkbox options for a group permission form
224
 *
225
 * @author       Kazumi Ono    <[email protected]>
226
 * @copyright    copyright (c) 2000-2003 XOOPS.org
227
 *
228
 * @package      kernel
229
 * @subpackage   form
230
 */
231
class MyXoopsGroupFormCheckBox extends XoopsFormElement
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
232
{
233
    /**
234
     * Pre-selected value(s)
235
     * @var array;
236
     */
237
    public $_value;
238
    /**
239
     * Group ID
240
     * @var int
241
     */
242
    public $_groupId;
243
    /**
244
     * Option tree
245
     * @var array
246
     */
247
    public $_optionTree;
248
    /**
249
     * Appendix
250
     * @var array ('permname'=>,'itemid'=>,'itemname'=>,'selected'=>)
251
     */
252
    public $_appendix = array();
253
254
    /**
255
     * Constructor
256
     * @param      $caption
257
     * @param      $name
258
     * @param      $groupId
259
     * @param null $values
260
     */
261
    public function __construct($caption, $name, $groupId, $values = null)
262
    {
263
        $this->setCaption($caption);
264
        $this->setName($name);
265
        if (isset($values)) {
266
            $this->setValue($values);
267
        }
268
        $this->_groupId = $groupId;
269
    }
270
271
    /**
272
     * Sets pre-selected values
273
     *
274
     * @param mixed $value A group ID or an array of group IDs
275
     * @access public
276
     */
277
    public function setValue($value)
278
    {
279
        if (is_array($value)) {
280
            foreach ($value as $v) {
281
                $this->setValue($v);
282
            }
283
        } else {
284
            $this->_value[] = $value;
285
        }
286
    }
287
288
    /**
289
     * Sets the tree structure of items
290
     *
291
     * @param array $optionTree
292
     * @access public
293
     */
294
    public function setOptionTree(&$optionTree)
295
    {
296
        $this->_optionTree =& $optionTree;
297
    }
298
299
    /**
300
     * Sets appendix of checkboxes
301
     *
302
     * @access public
303
     * @param $appendix
304
     */
305
    public function setAppendix($appendix)
306
    {
307
        $this->_appendix = $appendix;
308
    }
309
310
    /**
311
     * Renders checkbox options for this group
312
     *
313
     * @return string
314
     * @access public
315
     */
316
    public function render()
317
    {
318
        $ret = '';
319
320
        if (count($this->_appendix) > 0) {
321
            $ret  .= '<table class="outer"><tr>';
322
            $cols = 1;
323
            foreach ($this->_appendix as $append) {
324
                if ($cols > 4) {
325
                    $ret  .= '</tr><tr>';
326
                    $cols = 1;
327
                }
328
                $checked = $append['selected'] ? 'checked' : '';
329
                $name    = 'perms[' . $append['permname'] . ']';
330
                $itemid  = $append['itemid'];
0 ignored issues
show
Unused Code introduced by
$itemid is not used, you could remove the assignment.

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

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

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

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

Loading history...
331
                $itemid  = $append['itemid'];
332
                $ret     .= "<td class=\"odd\"><input type=\"checkbox\" name=\"{$name}[groups][$this->_groupId][$itemid]\" id=\"{$name}[groups][$this->_groupId][$itemid]\" value=\"1\" $checked />{$append['itemname']}<input type=\"hidden\" name=\"{$name}[parents][$itemid]\" value=\"\" /><input type=\"hidden\" name=\"{$name}[itemname][$itemid]\" value=\"{$append['itemname']}\" /><br></td>";
333
                ++$cols;
334
            }
335
            $ret .= '</tr></table>';
336
        }
337
338
        $ret  .= '<table class="outer"><tr>';
339
        $cols = 1;
340
        if (!empty($this->_optionTree[0]['children'])) {
341
            foreach ($this->_optionTree[0]['children'] as $topitem) {
342
                if ($cols > 4) {
343
                    $ret  .= '</tr><tr>';
344
                    $cols = 1;
345
                }
346
                $tree   = '<td class="odd">';
347
                $prefix = '';
348
                $this->_renderOptionTree($tree, $this->_optionTree[$topitem], $prefix);
349
                $ret .= $tree . '</td>';
350
                ++$cols;
351
            }
352
        }
353
        $ret .= '</tr></table>';
354
355
        return $ret;
356
    }
357
358
    /**
359
     * Renders checkbox options for an item tree
360
     *
361
     * @param string $tree
362
     * @param array  $option
363
     * @param string $prefix
364
     * @param array  $parentIds
365
     * @access private
366
     */
367
    public function _renderOptionTree(&$tree, $option, $prefix, $parentIds = array())
368
    {
369
        $tree .= $prefix
370
                 . "<input type=\"checkbox\" name=\""
371
                 . $this->getName()
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
372
                 . '[groups]['
373
                 . $this->_groupId
374
                 . ']['
375
                 . $option['id']
376
                 . "]\" id=\""
377
                 . $this->getName()
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
378
                 . '[groups]['
379
                 . $this->_groupId
380
                 . ']['
381
                 . $option['id']
382
                 . "]\" onclick=\"";
383
        // If there are parent elements, add javascript that will
384
        // make them selecteded when this element is checked to make
385
        // sure permissions to parent items are added as well.
386
        foreach ($parentIds as $pid) {
387
            $parent_ele = $this->getName() . '[groups][' . $this->_groupId . '][' . $pid . ']';
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
388
            $tree       .= "var ele = xoopsGetElementById('" . $parent_ele . "'); if (ele.checked !== true) {ele.checked = this.checked;}";
389
        }
390
        // If there are child elements, add javascript that will
391
        // make them unchecked when this element is unchecked to make
392
        // sure permissions to child items are not added when there
393
        // is no permission to this item.
394
        foreach ($option['allchild'] as $cid) {
395
            $child_ele = $this->getName() . '[groups][' . $this->_groupId . '][' . $cid . ']';
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
396
            $tree      .= "var ele = xoopsGetElementById('" . $child_ele . "'); if (this.checked !== true) {ele.checked = false;}";
397
        }
398
        $tree .= '" value="1"';
399
        if (isset($this->_value) && in_array($option['id'], $this->_value)) {
400
            $tree .= ' checked';
401
        }
402
        $tree .= ' />'
403
                 . $option['name']
404
                 . "<input type=\"hidden\" name=\""
405
                 . $this->getName()
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
406
                 . '[parents]['
407
                 . $option['id']
408
                 . "]\" value=\""
409
                 . implode(':', $parentIds)
410
                 . "\" /><input type=\"hidden\" name=\""
411
                 . $this->getName()
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
412
                 . '[itemname]['
413
                 . $option['id']
414
                 . "]\" value=\""
415
                 . htmlspecialchars($option['name'])
416
                 . "\" /><br>\n";
417
        if (isset($option['children'])) {
418
            foreach ($option['children'] as $child) {
419
                array_push($parentIds, $option['id']);
420
                $this->_renderOptionTree($tree, $this->_optionTree[$child], $prefix . '&nbsp;-', $parentIds);
421
            }
422
        }
423
    }
424
}
425