diff --git a/e107_admin/userclass2.php b/e107_admin/userclass2.php index 423c5dc54..bbd2ad180 100644 --- a/e107_admin/userclass2.php +++ b/e107_admin/userclass2.php @@ -707,6 +707,7 @@ $ns->tablerender(UCSLAN_21, $text); //----------------------------------- case 'test' : if (!check_class(e_UC_MAINADMIN)) break; + break; // ...And disable for everyone at present if (isset($_POST['add_db_fields'])) { // Add the extra DB fields $message = "Add DB fields: "; @@ -803,10 +804,10 @@ $ns->tablerender(UCSLAN_21, $text); $checked_class_list = implode(',',$_POST['classes_select']); $text = "
"; - $text .= $e_userclass->vetted_tree('classes_select',array($e_userclass,'checkbox'), $checked_class_list); + $text .= $e_userclass->vetted_tree('classes_select', array($e_userclass,'checkbox'), $checked_class_list, 'is-checkbox'); $text .= "Classes: ".$checked_class_list; $text .= ""; - $text .= $e_userclass->vetted_tree('normalised_classes_select',array($e_userclass,'checkbox'), $e_userclass->normalise_classes($checked_class_list)); + $text .= $e_userclass->vetted_tree('normalised_classes_select', array($e_userclass,'checkbox'), $e_userclass->normalise_classes($checked_class_list), 'is-checkbox'); $text .= "Normalised Classes: ".$e_userclass->normalise_classes($checked_class_list); $text .= "
"; $ns->tablerender('Nested checkboxes, showing the effect of the normalise() routine', $text); diff --git a/e107_handlers/form_handler.php b/e107_handlers/form_handler.php index 8c740b97a..8d5fba1f6 100644 --- a/e107_handlers/form_handler.php +++ b/e107_handlers/form_handler.php @@ -880,12 +880,24 @@ class e_form '; } + + /** + * Callback function used with $this->uc_checkbox + * + * @see user_class->select() for parameters + */ function _uc_checkbox_cb($treename, $classnum, $current_value, $nest_level, $field_options) { if($classnum == e_UC_BLANK) return ''; - $tmp = explode(',', $current_value); //TODO add support for when $current_value is an array. + if (!is_array($current_value)) + { + $tmp = explode(',', $current_value); + } + + $classIndex = abs($classnum); // Handle negative class values + $classSign = (substr($classnum, 0, 1) == '-') ? '-' : ''; $class = $style = ''; if($nest_level == 0) @@ -898,7 +910,7 @@ class e_form } $descr = varset($field_options['description']) ? ' ('.$this->_uc->uc_get_classdescription($classnum).')' : ''; - return "
".$this->checkbox($treename.'[]', $classnum, in_array($classnum, $tmp), $field_options).$this->label($this->_uc->uc_get_classname($classnum).$descr, $treename.'[]', $classnum)."
\n"; + return "
".$this->checkbox($treename.'[]', $classnum, in_array($classnum, $tmp), $field_options).$this->label($this->_uc->uc_get_classname($classIndex).$descr, $treename.'[]', $classnum)."
\n"; } diff --git a/e107_handlers/userclass_class.php b/e107_handlers/userclass_class.php index 9ab1b7a57..c8be92ad9 100644 --- a/e107_handlers/userclass_class.php +++ b/e107_handlers/userclass_class.php @@ -384,8 +384,10 @@ class user_class filter - only show those classes where member is in a class permitted to view them - e.g. as the new 'visible to' field - added for 0.8 force - show all classes (subject to the other options, including matchclass) - added for 2.0 + all - alias for 'force' no-excludes - if present, doesn't show the 'not member of' list + is-checkbox - if present, suppresses the construct round the 'not member of' list editable - can only appear on its own - returns list of those classes the user can edit (manage) @@ -412,7 +414,14 @@ class user_class // Inverted Classes if(strpos($optlist, 'no-excludes') !== TRUE) { - $text .= "\n\n"; + if (strpos($optlist, 'is-checkbox') !== FALSE) + { + $text .= "\n".UC_LAN_INVERTLABEL."
\n"; + } + else + { + $text .= "\n\n"; + } foreach ($show_classes as $k => $v) { if($k != e_UC_PUBLIC && $k != e_UC_NOBODY && $k != e_UC_READONLY) // remove everyone, nobody and readonly from list. @@ -441,9 +450,33 @@ class user_class public function uc_required_class_list($optlist = '', $just_ids = FALSE) { $ret = array(); - if (!$optlist) $optlist = 'public,guest,nobody,member,classes'; // Set defaults to simplify ongoing processing + $opt_arr = array(); - if ($optlist == 'editable') + if ($optlist) + { + $opt_arr = explode(',',$optlist); + } + foreach ($opt_arr as &$v) + { + $v = trim($v); + } + $opt_arr = array_flip($opt_arr); // This also eliminates duplicates which could arise from applying the other options, although shouldn't matter + + if (isset($opt_arr['no-excludes'])) unset($opt_arr['no-excludes']); + if (isset($opt_arr['is-checkbox'])) unset($opt_arr['is-checkbox']); + + if (count($opt_arr) == 0) + { + $opt_arr = array('public' => 1, 'guest' => 1, 'nobody' => 1, 'member' => 1, 'classes' => 1); + } + + if (isset($opt_arr['all'])) + { + unset($opt_arr['all']); + $opt_arr['force'] = 1; + } + + if (isset($opt_arr['editable'])) { $temp = array_flip(explode(',',$this->get_editable_classes())); if ($just_ids) return $temp; @@ -454,14 +487,7 @@ class user_class return $temp; } - //TODO - $optlist == all - $opt_arr = explode(',',$optlist); - foreach ($opt_arr as $k => $v) - { - $opt_arr[$k] = trim($v); - } - $opt_arr = array_flip($opt_arr); // This also eliminates duplicates which could arise from applying the other options, although shouldn't matter if (isset($opt_arr['force'])) unset($opt_arr['filter']); @@ -498,7 +524,7 @@ class user_class ) ) { - $ret[$uc_id] = $just_ids ? '1' : $this->class_tree[$uc_id]['userclass_name']; + $ret[$uc_id] = $just_ids ? '1' : $this->class_tree[$uc_id]['userclass_name']; } } } @@ -551,22 +577,32 @@ class user_class /** * Used by @see{vetted_tree()} to generate lower levels of tree + * + * @param string $listnum - class number of the parent. Is negative if the class is 'Everyone except...' (Must be a string because 0 == -0) + * @param integer $nest_level - indicates our level in the tree - 0 is the top level; increases as we descend the tree. Positive value. + * @param string $current_value - comma-separated list of integers indicating classes selected. (Spaces not permitted) + * @param array $perms - list of classes we are allowed to display + * @param string $opt_options - passed to callback function; not otherwise used */ - protected function vetted_sub_tree($treename, $callback,$listnum,$nest_level,$current_value, $perms, $opt_options) + protected function vetted_sub_tree($treename, $callback, $listnum, $nest_level, $current_value, $perms, $opt_options) { $ret = ''; $nest_level++; - if(isset($this->class_tree[$listnum]['class_children'])) + $listIndex = abs($listnum); + $classSign = (substr($listnum, 0, 1) == '-') ? '-' : '+'; + //echo "Subtree: {$listnum}, {$nest_level}, {$current_value}, {$classSign}:{$listIndex}
"; + if(isset($this->class_tree[$listIndex]['class_children'])) { - foreach ($this->class_tree[$listnum]['class_children'] as $p) + foreach ($this->class_tree[$listIndex]['class_children'] as $p) { - + $classValue = $classSign.$p; // Looks like we don't need to differentiate between function and class calls if (isset($perms[$p])) { - $ret .= call_user_func($callback,$treename, $p,$current_value,$nest_level, $opt_options); + $ret .= call_user_func($callback, $treename, $classValue, $current_value, $nest_level, $opt_options); } - $ret .= $this->vetted_sub_tree($treename, $callback,$p,$nest_level,$current_value, $perms, $opt_options); + + $ret .= $this->vetted_sub_tree($treename, $callback, $classValue, $nest_level, $current_value, $perms, $opt_options); } @@ -587,9 +623,10 @@ class user_class * Alternative callbacks can be used to achieve different layouts/styles * @param integer|string $current_value - single class number for single-select dropdown; comma separated array of class numbers for checkbox list or multi-select * @param string $optlist works the same as for @see uc_dropdown() + * @param string $opt_options - passed to callback function; not otherwise used * @return string - formatted HTML for tree */ - public function vetted_tree($treename, $callback='', $current_value='', $optlist = '',$opt_options = '') + public function vetted_tree($treename, $callback='', $current_value='', $optlist = '', $opt_options = '') { $ret = ''; if (!$callback) $callback=array($this,'select'); @@ -598,21 +635,43 @@ class user_class $perms = $this->uc_required_class_list($optlist,TRUE); // List of classes which we can display if (isset($perms[e_UC_BLANK])) { - $ret .= call_user_func($callback,$treename, e_UC_BLANK, $current_value,0, $opt_options); + $ret .= call_user_func($callback, $treename, e_UC_BLANK, $current_value, 0, $opt_options); } foreach ($this->class_parents as $p) { - if (isset($perms[$p])) { - $ret .= call_user_func($callback,$treename, $p,$current_value,0, $opt_options); + $ret .= call_user_func($callback, $treename, $p, $current_value, 0, $opt_options); } - $ret .= $this->vetted_sub_tree($treename, $callback,$p,0, $current_value, $perms, $opt_options); + $ret .= $this->vetted_sub_tree($treename, $callback, $p, 0, $current_value, $perms, $opt_options); } + // Inverted classes. (negative values for exclusion). - //FIXME - inverted class functionality lost during development. - + if(strpos($optlist, 'no-excludes') !== TRUE) + { + if (strpos($optlist, 'is-checkbox') !== FALSE) + { + $ret .= "\n".UC_LAN_INVERTLABEL."
\n"; + } + else + { + $ret .= "\n\n"; + } + foreach ($this->class_parents as $k => $p) // Currently key and data are the same + { + //echo "Class parent: {$k}:{$p}
"; + if($k != e_UC_PUBLIC && $k != e_UC_NOBODY && $k != e_UC_READONLY) // remove everyone, nobody and readonly from list. + { + if (isset($perms[$p])) + { + $ret .= call_user_func($callback, $treename, '-'.$p, $current_value, 0, $opt_options); + } + } + $ret .= $this->vetted_sub_tree($treename, $callback, '-'.$p, 0, $current_value, $perms, $opt_options); + } + $ret .= "
\n"; + } return $ret; } @@ -623,17 +682,21 @@ class user_class * Can be used as a basis for similar functions * * @param string $treename - name of tree elements (not used with select; used with checkboxes, for example) - * @param integer $classnum - user class being displayed. - * - special value e_UC_BLANK adds a blank option in the list. + * @param string $classnum - user class being displayed. This may be negative to indicate 'everyone but...' + * - special numeric part e_UC_BLANK adds a blank option in the list. * @param integer|string $current_value - single class number for single-select dropdown; comma separated array of class numbers for checkbox list or multi-select * @param integer $nest_level - 'depth' of this item in the tree. Zero is base level. May be used to indent or highlight dependent on level + * @param string $opt_options - passed to callback function; not otherwise used + * * @return string - option list */ - public function select($treename, $classnum, $current_value, $nest_level) + public function select($treename, $classnum, $current_value, $nest_level, $opt_options = '') { - if ($classnum == e_UC_BLANK) return "\n"; + $classIndex = abs($classnum); // Handle negative class values + $classSign = (substr($classnum, 0, 1) == '-') ? '-' : ''; + if ($classIndex == e_UC_BLANK) return "\n"; $tmp = explode(',',$current_value); - $sel = in_array($classnum,$tmp) ? " selected='selected'" : ''; + $sel = in_array($classnum, $tmp) ? " selected='selected'" : ''; if ($nest_level == 0) { $prefix = ''; @@ -649,7 +712,7 @@ class user_class $prefix = '  '.str_repeat('--',$nest_level-1).'>'; $style = ''; } - return "\n"; + return "\n"; } @@ -657,9 +720,11 @@ class user_class * Callback for vetted_tree - displays indented checkboxes with class name only * See @link select for parameter details */ - public function checkbox($treename, $classnum, $current_value, $nest_level) + public function checkbox($treename, $classnum, $current_value, $nest_level, $opt_options = '') { - if ($classnum == e_UC_BLANK) return ''; + $classIndex = abs($classnum); // Handle negative class values + $classSign = (substr($classnum, 0, 1) == '-') ? '-' : ''; + if ($classIndex == e_UC_BLANK) return ''; $tmp = explode(',',$current_value); $chk = in_array($classnum, $tmp) ? " checked='checked'" : ''; if ($nest_level == 0) @@ -670,7 +735,7 @@ class user_class { $style = " style='text-indent:".(1.2*$nest_level)."em'"; } - return "
".$this->class_tree[$classnum]['userclass_name']."
\n"; + return "
".$this->class_tree[$classIndex]['userclass_name']."
\n"; } @@ -678,9 +743,11 @@ class user_class * Callback for vetted_tree - displays indented checkboxes with class name, and description in brackets * See @link select for parameter details */ - public function checkbox_desc($treename, $classnum, $current_value, $nest_level) + public function checkbox_desc($treename, $classnum, $current_value, $nest_level, $opt_options = '') { - if ($classnum == e_UC_BLANK) return ''; + $classIndex = abs($classnum); // Handle negative class values + $classSign = (substr($classnum, 0, 1) == '-') ? '-' : ''; + if ($classIndex == e_UC_BLANK) return ''; $tmp = explode(',',$current_value); $chk = in_array($classnum, $tmp) ? " checked='checked'" : ''; if ($nest_level == 0) @@ -695,9 +762,9 @@ class user_class $id = "{$treename}_{$classnum}"; return "
\n"; + ".e107::getForm()->checkbox($treename.'[]', $classnum , $chk, "id=".$id)." ".$this->class_tree[$classIndex]['userclass_name'].' ('.$this->class_tree[$classIndex]['userclass_description'].")\n"; - return "
".$this->class_tree[$classnum]['userclass_name'].' ('.$this->class_tree[$classnum]['userclass_description'].")
\n"; + return "
".$this->class_tree[$classIndex]['userclass_name'].' ('.$this->class_tree[$classIndex]['userclass_description'].")
\n"; }