Completed
Push — master ( bb1ebf...0d7d1b )
by Michael
02:07
created

MyXoopsGroupFormCheckBox::renderOptionTree()   C

Complexity

Conditions 7
Paths 24

Size

Total Lines 44
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 30
nc 24
nop 4
dl 0
loc 44
rs 6.7272
c 0
b 0
f 0
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 43 and the first side effect is on line 27.

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 https://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
 * Module: SmartFAQ
22
 * Author: The SmartFactory <www.smartfactory.ca>
23
 */
24
25
// defined('XOOPS_ROOT_PATH') || exit('XOOPS root path not defined');
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...
26
27
require_once XOOPS_ROOT_PATH . '/class/xoopsform/formelement.php';
28
require_once XOOPS_ROOT_PATH . '/class/xoopsform/formhidden.php';
29
require_once XOOPS_ROOT_PATH . '/class/xoopsform/formhiddentoken.php';
30
require_once XOOPS_ROOT_PATH . '/class/xoopsform/formbutton.php';
31
require_once XOOPS_ROOT_PATH . '/class/xoopsform/formelementtray.php';
32
require_once XOOPS_ROOT_PATH . '/class/xoopsform/form.php';
33
34
/**
35
 * Renders a form for setting module specific group permissions
36
 *
37
 * @author      Kazumi Ono  <[email protected]>
38
 * @copyright   copyright (c) 2000-2003 XOOPS.org
39
 *
40
 * @package     kernel
41
 * @subpackage  form
42
 */
43
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...
44
{
45
46
    /**
47
     * Module ID
48
     * @var int
49
     */
50
    public $_modid;
51
    /**
52
     * Tree structure of items
53
     * @var array
54
     */
55
    public $_itemTree;
56
    /**
57
     * Name of permission
58
     * @var string
59
     */
60
    public $_permName;
61
    /**
62
     * Description of permission
63
     * @var string
64
     */
65
    public $_permDesc;
66
    /**
67
     * Appendix
68
     * @var array ('permname'=>,'itemid'=>,'itemname'=>,'selected'=>)
69
     */
70
    public $_appendix = array();
71
72
    /**
73
     * Constructor
74
     * @param string $title
75
     * @param string $modid
76
     * @param string $permname
77
     * @param string $permdesc
78
     */
79
    public function __construct($title, $modid, $permname, $permdesc)
80
    {
81
        //      $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...
82
        parent::__construct($title, 'groupperm_form', '', 'post');
83
        $this->_modid    = (int)$modid;
84
        $this->_permName = $permname;
85
        $this->_permDesc = $permdesc;
86
        $this->addElement(new XoopsFormHidden('modid', $this->_modid));
87
        $this->addElement(new XoopsFormHiddenToken($permname));
88
    }
89
90
    /**
91
     * Adds an item to which permission will be assigned
92
     *
93
     * @param string $itemName
94
     * @param int    $itemId
95
     * @param int    $itemParent
96
     * @access public
97
     */
98
    public function addItem($itemId, $itemName, $itemParent = 0)
99
    {
100
        $this->_itemTree[$itemParent]['children'][] = $itemId;
101
        $this->_itemTree[$itemId]['parent']         = $itemParent;
102
        $this->_itemTree[$itemId]['name']           = $itemName;
103
        $this->_itemTree[$itemId]['id']             = $itemId;
104
    }
105
106
    /**
107
     * Add appendix
108
     *
109
     * @access public
110
     * @param $permName
111
     * @param $itemId
112
     * @param $itemName
113
     */
114
    public function addAppendix($permName, $itemId, $itemName)
115
    {
116
        $this->_appendix[] = array(
117
            'permname' => $permName,
118
            'itemid'   => $itemId,
119
            'itemname' => $itemName,
120
            'selected' => false
121
        );
122
    }
123
124
    /**
125
     * Loads all child ids for an item to be used in javascript
126
     *
127
     * @param int   $itemId
128
     * @param array $childIds
129
     * @access private
130
     */
131
    public function _loadAllChildItemIds($itemId, &$childIds)
132
    {
133
        if (!empty($this->_itemTree[$itemId]['children'])) {
134
            $first_child = $this->_itemTree[$itemId]['children'];
135
            foreach ($first_child as $fcid) {
136
                array_push($childIds, $fcid);
137
                if (!empty($this->_itemTree[$fcid]['children'])) {
138
                    foreach ($this->_itemTree[$fcid]['children'] as $_fcid) {
139
                        array_push($childIds, $_fcid);
140
                        $this->_loadAllChildItemIds($_fcid, $childIds);
141
                    }
142
                }
143
            }
144
        }
145
    }
146
147
    /**
148
     * Renders the form
149
     *
150
     * @return string
151
     * @access public
152
     */
153
    public function render()
154
    {
155
        // load all child ids for javascript codes
156
        foreach (array_keys($this->_itemTree) as $item_id) {
157
            $this->_itemTree[$item_id]['allchild'] = array();
158
            $this->_loadAllChildItemIds($item_id, $this->_itemTree[$item_id]['allchild']);
159
        }
160
        $gpermHandler  = xoops_getHandler('groupperm');
161
        $memberHandler = xoops_getHandler('member');
162
        $glist         =& $memberHandler->getGroupList();
163
        foreach (array_keys($glist) as $i) {
164
            // get selected item id(s) for each group
165
            $selected = $gpermHandler->getItemIds($this->_permName, $i, $this->_modid);
166
            $ele      = new MyXoopsGroupFormCheckBox($glist[$i], 'perms[' . $this->_permName . ']', $i, $selected);
167
            $ele->setOptionTree($this->_itemTree);
168
169
            foreach ($this->_appendix as $key => $append) {
170
                $this->_appendix[$key]['selected'] = $gpermHandler->checkRight($append['permname'], $append['itemid'], $i, $this->_modid);
171
            }
172
            $ele->setAppendix($this->_appendix);
173
            $this->addElement($ele);
174
            unset($ele);
175
        }
176
177
        // GIJ start
178
        $jstray          = new XoopsFormElementTray(' &nbsp; ');
179
        $jsuncheckbutton = new XoopsFormButton('', 'none', _NONE, 'button');
180
        $jsuncheckbutton->setExtra("onclick=\"with(document.groupperm_form){for (i=0;i<length;i++) {if (elements[i].type=='checkbox') {elements[i].checked=false;}}}\"");
181
        $jscheckbutton = new XoopsFormButton('', 'all', _ALL, 'button');
182
        $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;}}}\"");
183
        $jstray->addElement($jsuncheckbutton);
184
        $jstray->addElement($jscheckbutton);
185
        $this->addElement($jstray);
186
        // GIJ end
187
188
        $tray = new XoopsFormElementTray('');
189
        $tray->addElement(new XoopsFormButton('', 'reset', _CANCEL, 'reset'));
190
        $tray->addElement(new XoopsFormButton('', 'submit', _SUBMIT, 'submit'));
191
        $this->addElement($tray);
192
193
        $ret      = '<h4>' . $this->getTitle() . '</h4>' . $this->_permDesc . '<br>';
194
        $ret      .= "<form name='" . $this->getName() . "' id='" . $this->getName() . "' action='" . $this->getAction() . "' method='" . $this->getMethod() . "'" . $this->getExtra() . ">\n<table width='100%' class='outer' cellspacing='1'>\n";
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
        $elements =& $this->getElements();
196
        foreach (array_keys($elements) as $i) {
197
            if (!is_object($elements[$i])) {
198
                $ret .= $elements[$i];
199
            } elseif (!$elements[$i]->isHidden()) {
200
                $ret .= "<tr valign='top' align='left'><td class='head'>" . $elements[$i]->getCaption();
201
                if ($elements[$i]->getDescription() != '') {
202
                    $ret .= '<br><br><span style="font-weight: normal;">' . $elements[$i]->getDescription() . '</span>';
203
                }
204
                $ret .= "</td>\n<td class='even'>\n" . $elements[$i]->render() . "\n</td></tr>\n";
205
            } else {
206
                $ret .= $elements[$i]->render();
207
            }
208
        }
209
        $ret .= '</table></form>';
210
211
        return $ret;
212
    }
213
}
214
215
/**
216
 * Renders checkbox options for a group permission form
217
 *
218
 * @author      Kazumi Ono  <[email protected]>
219
 * @copyright   copyright (c) 2000-2003 XOOPS.org
220
 *
221
 * @package     kernel
222
 * @subpackage  form
223
 */
224
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...
225
{
226
227
    /**
228
     * Pre-selected value(s)
229
     * @var array;
230
     */
231
    public $_value;
232
    /**
233
     * Group ID
234
     * @var int
235
     */
236
    public $_groupId;
237
    /**
238
     * Option tree
239
     * @var array
240
     */
241
    public $_optionTree;
242
    /**
243
     * Appendix
244
     * @var array ('permname'=>,'itemid'=>,'itemname'=>,'selected'=>)
245
     */
246
    public $_appendix = array();
247
248
    /**
249
     * Constructor
250
     * @param      $caption
251
     * @param      $name
252
     * @param      $groupId
253
     * @param null $values
254
     */
255
    public function __construct($caption, $name, $groupId, $values = null)
256
    {
257
        $this->setCaption($caption);
258
        $this->setName($name);
259
        if (null !== $values) {
260
            $this->setValue($values);
261
        }
262
        $this->_groupId = $groupId;
263
    }
264
265
    /**
266
     * Sets pre-selected values
267
     *
268
     * @param mixed $value A group ID or an array of group IDs
269
     * @access public
270
     */
271
    public function setValue($value)
272
    {
273
        if (is_array($value)) {
274
            foreach ($value as $v) {
275
                $this->setValue($v);
276
            }
277
        } else {
278
            $this->_value[] = $value;
279
        }
280
    }
281
282
    /**
283
     * Sets the tree structure of items
284
     *
285
     * @param array $optionTree
286
     * @access public
287
     */
288
    public function setOptionTree(&$optionTree)
289
    {
290
        $this->_optionTree =& $optionTree;
291
    }
292
293
    /**
294
     * Sets appendix of checkboxes
295
     *
296
     * @access public
297
     * @param $appendix
298
     */
299
    public function setAppendix($appendix)
300
    {
301
        $this->_appendix = $appendix;
302
    }
303
304
    /**
305
     * Renders checkbox options for this group
306
     *
307
     * @return string
308
     * @access public
309
     */
310
    public function render()
311
    {
312
        $ret = '';
313
314
        if (count($this->_appendix) > 0) {
315
            $ret  .= '<table class="outer"><tr>';
316
            $cols = 1;
317
            foreach ($this->_appendix as $append) {
318
                if ($cols > 4) {
319
                    $ret  .= '</tr><tr>';
320
                    $cols = 1;
321
                }
322
                $checked = $append['selected'] ? 'checked' : '';
323
                $name    = 'perms[' . $append['permname'] . ']';
324
                $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...
325
                $itemid  = $append['itemid'];
326
                $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>";
327
                ++$cols;
328
            }
329
            $ret .= '</tr></table>';
330
        }
331
332
        $ret  .= '<table class="outer"><tr>';
333
        $cols = 1;
334
        foreach ($this->_optionTree[0]['children'] as $topitem) {
335
            if ($cols > 4) {
336
                $ret  .= '</tr><tr>';
337
                $cols = 1;
338
            }
339
            $tree   = '<td class="odd">';
340
            $prefix = '';
341
            $this->renderOptionTree($tree, $this->_optionTree[$topitem], $prefix);
342
            $ret .= $tree . '</td>';
343
            ++$cols;
344
        }
345
        $ret .= '</tr></table>';
346
347
        return $ret;
348
    }
349
350
    /**
351
     * Renders checkbox options for an item tree
352
     *
353
     * @param string $tree
354
     * @param array  $option
355
     * @param string $prefix
356
     * @param array  $parentIds
357
     * @access private
358
     */
359
    private function renderOptionTree(&$tree, $option, $prefix, $parentIds = array())
360
    {
361
        $tree .= $prefix . '<input type="checkbox" name="' . $this->getName() . '[groups][' . $this->_groupId . '][' . $option['id'] . ']" id="' . $this->getName() . '[groups][' . $this->_groupId . '][' . $option['id'] . ']" onclick="';
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
362
        // If there are parent elements, add javascript that will
363
        // make them selecteded when this element is checked to make
364
        // sure permissions to parent items are added as well.
365
        foreach ($parentIds as $pid) {
366
            $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...
367
            $tree       .= "var ele = xoopsGetElementById('" . $parent_ele . "'); if (ele.checked !== true) {ele.checked = this.checked;}";
368
        }
369
        // If there are child elements, add javascript that will
370
        // make them unchecked when this element is unchecked to make
371
        // sure permissions to child items are not added when there
372
        // is no permission to this item.
373
        foreach ($option['allchild'] as $cid) {
374
            $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...
375
            $tree      .= "var ele = xoopsGetElementById('" . $child_ele . "'); if (this.checked !== true) {ele.checked = false;}";
376
        }
377
        $tree .= '" value="1"';
378
        if (null !== $this->_value && in_array($option['id'], $this->_value)) {
379
            $tree .= ' checked';
380
        }
381
        $tree .= '>'
382
                 . $option['name']
383
                 . '<input type="hidden" name="'
384
                 . $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...
385
                 . '[parents]['
386
                 . $option['id']
387
                 . ']" value="'
388
                 . implode(':', $parentIds)
389
                 . '"><input type="hidden" name="'
390
                 . $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...
391
                 . '[itemname]['
392
                 . $option['id']
393
                 . ']" value="'
394
                 . htmlspecialchars($option['name'])
395
                 . "\"><br>\n";
396
        if (isset($option['children'])) {
397
            foreach ($option['children'] as $child) {
398
                array_push($parentIds, $option['id']);
399
                $this->renderOptionTree($tree, $this->_optionTree[$child], $prefix . '&nbsp;-', $parentIds);
400
            }
401
        }
402
    }
403
}
404