1: <?php
2: /**
3: * XOOPS form element
4: *
5: * You may not change or alter any portion of this comment or credits
6: * of supporting developers from this source code or any supporting source code
7: * which is considered copyrighted (c) material of the original comment or credit authors.
8: * This program is distributed in the hope that it will be useful,
9: * but WITHOUT ANY WARRANTY; without even the implied warranty of
10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11: *
12: * @copyright (c) 2000-2016 XOOPS Project (www.xoops.org)
13: * @license GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
14: * @package kernel
15: * @subpackage form
16: * @since 2.0.0
17: */
18:
19: defined('XOOPS_ROOT_PATH') || exit('Restricted access');
20:
21: xoops_load('XoopsFormElement');
22: xoops_load('XoopsFormHidden');
23: xoops_load('XoopsFormHiddenToken');
24: xoops_load('XoopsForm');
25: xoops_load('XoopsFormElementTray');
26: xoops_load('XoopsFormButton');
27:
28: /**
29: * Renders a form for setting module specific group permissions
30: */
31: class XoopsGroupPermForm extends XoopsForm
32: {
33: /**
34: * Module ID
35: *
36: * @var int
37: */
38: public $_modid;
39: /**
40: * Tree structure of items
41: *
42: * @var array
43: */
44: public $_itemTree = array();
45: /**
46: * Name of permission
47: *
48: * @var string
49: */
50: public $_permName;
51: /**
52: * Description of permission
53: *
54: * @var string
55: */
56: public $_permDesc;
57:
58: /**
59: * Whether to include anonymous users
60: *
61: * @var bool
62: */
63: public $_showAnonymous;
64:
65: /**
66: * Constructor
67: * @param $title
68: * @param $modid
69: * @param $permname
70: * @param $permdesc
71: * @param string $url
72: * @param bool $anonymous
73: */
74: public function __construct($title, $modid, $permname, $permdesc, $url = '', $anonymous = true)
75: {
76: parent::__construct($title, 'groupperm_form', XOOPS_URL . '/modules/system/admin/groupperm.php', 'post');
77: $this->_modid = (int)$modid;
78: $this->_permName = $permname;
79: $this->_permDesc = $permdesc;
80: $this->addElement(new XoopsFormHidden('modid', $this->_modid));
81: $this->addElement(new XoopsFormHiddenToken($permname));
82: if ($url != '') {
83: $this->addElement(new XoopsFormHidden('redirect_url', $url));
84: }
85: $this->_showAnonymous = $anonymous;
86: }
87:
88: /**
89: * Adds an item to which permission will be assigned
90: *
91: * @param string $itemName
92: * @param int $itemId
93: * @param int $itemParent
94: * @access public
95: */
96: public function addItem($itemId, $itemName, $itemParent = 0)
97: {
98: $this->_itemTree[$itemParent]['children'][] = $itemId;
99: $this->_itemTree[$itemId]['parent'] = $itemParent;
100: $this->_itemTree[$itemId]['name'] = $itemName;
101: $this->_itemTree[$itemId]['id'] = $itemId;
102: }
103:
104: /**
105: * Loads all child ids for an item to be used in javascript
106: *
107: * @param int $itemId
108: * @param array $childIds
109: * @access private
110: */
111: public function _loadAllChildItemIds($itemId, &$childIds)
112: {
113: if (!empty($this->_itemTree[$itemId]['children'])) {
114: $first_child = $this->_itemTree[$itemId]['children'];
115: foreach ($first_child as $fcid) {
116: $childIds[] = $fcid;
117: if (!empty($this->_itemTree[$fcid]['children'])) {
118: foreach ($this->_itemTree[$fcid]['children'] as $_fcid) {
119: $childIds[] = $_fcid;
120: $this->_loadAllChildItemIds($_fcid, $childIds);
121: }
122: }
123: }
124: }
125: }
126:
127: /**
128: * Renders the form
129: *
130: * @return string
131: * @access public
132: */
133: public function render()
134: {
135: // load all child ids for javascript codes
136: foreach (array_keys($this->_itemTree) as $item_id) {
137: $this->_itemTree[$item_id]['allchild'] = array();
138: $this->_loadAllChildItemIds($item_id, $this->_itemTree[$item_id]['allchild']);
139: }
140: /** @var XoopsGroupPermHandler $gperm_handler */
141: $gperm_handler = xoops_getHandler('groupperm');
142: /** @var XoopsMemberHandler $member_handler */
143: $member_handler = xoops_getHandler('member');
144: $glist = $member_handler->getGroupList();
145: foreach (array_keys($glist) as $i) {
146: if ($i == XOOPS_GROUP_ANONYMOUS && !$this->_showAnonymous) {
147: continue;
148: }
149: // get selected item id(s) for each group
150: $selected = $gperm_handler->getItemIds($this->_permName, $i, $this->_modid);
151: $ele = new XoopsGroupFormCheckBox($glist[$i], 'perms[' . $this->_permName . ']', $i, $selected);
152: $ele->setOptionTree($this->_itemTree);
153: $this->addElement($ele);
154: unset($ele);
155: }
156: $tray = new XoopsFormElementTray('');
157: $tray->addElement(new XoopsFormButton('', 'submit', _SUBMIT, 'submit'));
158: $tray->addElement(new XoopsFormButton('', 'reset', _CANCEL, 'reset'));
159: $this->addElement($tray);
160:
161: $ret = '<h4>' . $this->getTitle() . '</h4>';
162: if ($this->_permDesc) {
163: $ret .= $this->_permDesc . '<br><br>';
164: }
165: $ret .= '<form title="' . str_replace('"', '', $this->getTitle()) . '" name="' . $this->getName() . '" id="' . $this->getName() . '" action="' . $this->getAction() . '" method="' . $this->getMethod() . '"' . $this->getExtra() . '>' . '<table width="100%" class="outer" cellspacing="1" valign="top">';
166: $elements =& $this->getElements();
167: $hidden = '';
168: foreach (array_keys($elements) as $i) {
169: if (!is_object($elements[$i])) {
170: $ret .= $elements[$i];
171: } elseif (!$elements[$i]->isHidden()) {
172: $ret .= '<tr valign="top" align="left"><td class="head">' . $elements[$i]->getCaption();
173: if ($elements[$i]->getDescription() != '') {
174: $ret .= "<br><br><span style='font-weight: normal;'>" . $elements[$i]->getDescription() . '</span>';
175: }
176: $ret .= '</td>' . '<td class="even">' . $elements[$i]->render() . '</td></tr>' . '';
177: } else {
178: $hidden .= $elements[$i]->render();
179: }
180: }
181: $ret .= '</table>' . $hidden . '</form>';
182: $ret .= $this->renderValidationJS(true);
183:
184: return $ret;
185: }
186: }
187:
188: /**
189: * Renders checkbox options for a group permission form
190: */
191: class XoopsGroupFormCheckBox extends XoopsFormElement
192: {
193: /**
194: * Pre-selected value(s)
195: *
196: * @var array ;
197: */
198: public $_value = array();
199: /**
200: * Group ID
201: *
202: * @var int
203: */
204: public $_groupId;
205: /**
206: * Option tree
207: *
208: * @var array
209: */
210: public $_optionTree = array();
211:
212: /**
213: * Constructor
214: * @param $caption
215: * @param $name
216: * @param $groupId
217: * @param null $values
218: */
219: public function __construct($caption, $name, $groupId, $values = null)
220: {
221: $this->setCaption($caption);
222: $this->setName($name);
223: if (isset($values)) {
224: $this->setValue($values);
225: }
226: $this->_groupId = $groupId;
227: }
228:
229: /**
230: * Sets pre-selected values
231: *
232: * @param mixed $value A group ID or an array of group IDs
233: * @access public
234: */
235: public function setValue($value)
236: {
237: if (is_array($value)) {
238: foreach ($value as $v) {
239: $this->setValue($v);
240: }
241: } else {
242: $this->_value[] = $value;
243: }
244: }
245:
246: /**
247: * Sets the tree structure of items
248: *
249: * @param array $optionTree
250: * @access public
251: */
252: public function setOptionTree(&$optionTree)
253: {
254: $this->_optionTree = &$optionTree;
255: }
256:
257: /**
258: * Renders checkbox options for this group
259: *
260: * @return string
261: * @access public
262: */
263: public function render()
264: {
265: $ele_name = $this->getName();
266: $ret = '<table class="outer"><tr><td class="odd"><table><tr>';
267: $cols = 1;
268: foreach ($this->_optionTree[0]['children'] as $topitem) {
269: if ($cols > 4) {
270: $ret .= '</tr><tr>';
271: $cols = 1;
272: }
273: $tree = '<td valign="top">';
274: $prefix = '';
275: $this->_renderOptionTree($tree, $this->_optionTree[$topitem], $prefix);
276: $ret .= $tree . '</td>';
277: ++$cols;
278: }
279: $ret .= '</tr></table></td><td class="even" valign="top">';
280: $option_ids = array();
281: foreach (array_keys($this->_optionTree) as $id) {
282: if (!empty($id)) {
283: $option_ids[] = "'" . $ele_name . '[groups][' . $this->_groupId . '][' . $id . ']' . "'";
284: }
285: }
286: $checkallbtn_id = $ele_name . '[checkallbtn][' . $this->_groupId . ']';
287: $option_ids_str = implode(', ', $option_ids);
288: $ret .= _ALL . " <input id=\"" . $checkallbtn_id . "\" type=\"checkbox\" value=\"\" onclick=\"var optionids = new Array(" . $option_ids_str . "); xoopsCheckAllElements(optionids, '" . $checkallbtn_id . "');\" />";
289: $ret .= '</td></tr></table>';
290:
291: return $ret;
292: }
293:
294: /**
295: * Renders checkbox options for an item tree
296: *
297: * @param string $tree
298: * @param array $option
299: * @param string $prefix
300: * @param array $parentIds
301: * @access private
302: */
303: public function _renderOptionTree(&$tree, $option, $prefix, $parentIds = array())
304: {
305: $ele_name = $this->getName();
306: $tree .= $prefix . "<input type=\"checkbox\" name=\"" . $ele_name . '[groups][' . $this->_groupId . '][' . $option['id'] . "]\" id=\"" . $ele_name . '[groups][' . $this->_groupId . '][' . $option['id'] . "]\" onclick=\"";
307: // If there are parent elements, add javascript that will
308: // make them selecteded when this element is checked to make
309: // sure permissions to parent items are added as well.
310: foreach ($parentIds as $pid) {
311: $parent_ele = $ele_name . '[groups][' . $this->_groupId . '][' . $pid . ']';
312: $tree .= "var ele = xoopsGetElementById('" . $parent_ele . "'); if(ele.checked != true) {ele.checked = this.checked;}";
313: }
314: // If there are child elements, add javascript that will
315: // make them unchecked when this element is unchecked to make
316: // sure permissions to child items are not added when there
317: // is no permission to this item.
318: foreach ($option['allchild'] as $cid) {
319: $child_ele = $ele_name . '[groups][' . $this->_groupId . '][' . $cid . ']';
320: $tree .= "var ele = xoopsGetElementById('" . $child_ele . "'); if(this.checked != true) {ele.checked = false;}";
321: }
322: $tree .= '" value="1"';
323: if (in_array($option['id'], $this->_value)) {
324: $tree .= ' checked';
325: }
326: $tree .= ' />' . $option['name'] . "<input type=\"hidden\" name=\"" . $ele_name . '[parents][' . $option['id'] . "]\" value=\"" . implode(':', $parentIds) . "\" /><input type=\"hidden\" name=\"" . $ele_name . '[itemname][' . $option['id'] . "]\" value=\"" . htmlspecialchars($option['name'], ENT_QUOTES) . "\" /><br>\n";
327: if (isset($option['children'])) {
328: foreach ($option['children'] as $child) {
329: $parentIds[] = $option['id'];
330: $this->_renderOptionTree($tree, $this->_optionTree[$child], $prefix . '&nbsp;-', $parentIds);
331: }
332: }
333: }
334: }
335: