3 /* Reminder: always indent with 4 spaces (no tabs). */
4 // +---------------------------------------------------------------------------+
6 // +---------------------------------------------------------------------------+
7 // | config.class.php |
9 // | Controls the UI and database for configuration settings |
10 // +---------------------------------------------------------------------------+
11 // | Copyright (C) 2007-2011 by the following authors: |
13 // | Authors: Aaron Blankstein - kantai AT gmail DOT com |
14 // | Akeda Bagus - admin AT gedex DOT web DOT id |
15 // | Tom Homer - tomhomer AT gmail DOT com |
16 // +---------------------------------------------------------------------------+
18 // | This program is free software; you can redistribute it and/or |
19 // | modify it under the terms of the GNU General Public License |
20 // | as published by the Free Software Foundation; either version 2 |
21 // | of the License, or (at your option) any later version. |
23 // | This program is distributed in the hope that it will be useful, |
24 // | but WITHOUT ANY WARRANTY; without even the implied warranty of |
25 // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
26 // | GNU General Public License for more details. |
28 // | You should have received a copy of the GNU General Public License |
29 // | along with this program; if not, write to the Free Software Foundation, |
30 // | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
32 // +---------------------------------------------------------------------------+
36 * Path to db-config.php file
42 * Array of configurations
48 * Array of configuration tabs, used by autocomplete
54 * Array of configuration features (security rights)
60 * Array of configuration types
66 * Whether support new theme format for the later Geeklog 2.0 or not
72 * List of validation rules. Append entries for validation as
73 * ('field_name' => '/^perl_compat_regexp$/') that have to match
74 * with preg_match(). Use these rules with config::_validates()
79 var $validate = array();
82 * List of validation errors.
87 var $validationErrors = array();
90 * Values that failed validation
95 var $validationErrorValues = array();
98 * Changed values that pass the validation.
99 * If validationErrors is not empty, changed values should be saved
100 * for later submission
105 var $tmpValues = array();
108 * Changed configuration array (such as mail settings) that pass the validation.
109 * If validationErrors is not empty, changed values should be saved
110 * for later submission
115 var $changedArray = array();
120 function __construct()
122 $this->config_array = array();
124 $this->conf_tab_arr = null;
125 $this->conf_ft_arr = null;
126 $this->conf_type = array();
130 * This method will return an instance of the config class. If an
131 * instance with the given group/reference name does not exist, then it
132 * will create a new one. This function insures that there is only one
133 * instance for a given group name.
135 * @param string group_name This is simply the group name that this
136 * config object will control - for the main gl
137 * settings this is 'Core'
139 * @return config The newly created or referenced config object
141 public static function &get_instance()
146 $instance = new config();
157 $this->__construct();
161 * This method sets the secure configuration file (database related
162 * settings) for the configuration class to read. This should only need to
163 * be called for the 'Core' group. It also must be called before
166 * @param string sf The filename and path of the secure db settings
169 function set_configfile($sf)
171 $this->dbconfig_file = $sf;
175 * This method reads the secure configuration file and loads
176 * lib-database.php. This needs to be called in the 'Core' group before
177 * &init_config() can be used. It only needs to be called once
180 function load_baseconfig()
182 global $_DB, $_TABLES, $_CONF;
184 include $this->dbconfig_file;
185 $this->config_array['Core'] =& $_CONF;
187 include_once $_CONF['path_system'] . 'lib-database.php';
189 // for backward compatibility
190 $_CONF['ostype'] = PHP_OS;
194 * This method initializes the configuration array (i.e. $_CONF) and
195 * will return a reference to the newly created array. The class keeps
196 * track of this reference, and the set function will mutate it.
198 * @return array(string => mixed) This is a reference to the
201 function &initConfig()
205 // Figure out tabs first
206 $sql = "SELECT name, value, group_name, type, subgroup, tab FROM {$_TABLES['conf_values']} WHERE 1=1";
207 $result = DB_query($sql);
209 $curr_group_name = '';
211 while ($row = DB_fetchArray($result)) {
212 // For backwards compatibility, add in a tab for plugins that support the old config
213 if ($row['type'] != 'tab' && $row['tab'] == '' && ($row['group_name'] != $curr_group_name || $row['subgroup'] != $curr_subgroup)) {
214 $curr_group_name = $row['group_name'];
215 $curr_subgroup = $row['subgroup'];
216 $tab_name = 'tab_default_' . $curr_subgroup;
218 $this->conf_type['tab'][$row[2]][$tab_name] = "config.{$row[2]}.{$tab_name}";
219 $this->conf_type['tree'][$row[2]][$row[4]][$tab_name] = "config.{$row[2]}.{$tab_name}";
221 if (!isset($this->conf_tab_arr[$tab_name])) {
222 $this->conf_tab_arr[$row[2]][$row[4]][$tab_name] = array();
223 $tabs[$row[2]][$row[4]][$tab_id] = $tab_name;
228 // group the tab type
229 if ($row[3] == 'tab') {
230 $this->conf_type['tab'][$row[2]][$row[0]] = "config.{$row[2]}.{$row[0]}";
231 $this->conf_type['tree'][$row[2]][$row[4]][$row[0]] = "config.{$row[2]}.{$row[0]}";
233 if (!isset($this->conf_tab_arr[$row[0]])) {
234 $this->conf_tab_arr[$row[2]][$row[4]][$row[0]] = array();
235 $tabs[$row[2]][$row[4]][$row[5]] = $row[0];
242 // Now figure out other info since tabs are now specified
243 $sql = "SELECT name, value, group_name, type, subgroup, tab FROM {$_TABLES['conf_values']} WHERE type <> 'tab'";
244 $result = DB_query($sql);
245 $false_str = serialize(false);
246 while ($row = DB_fetchArray($result)) {
247 // Set any null tab to 0 since they now have been defaulted above
252 // group the subgroup type
253 if ($row[3] == 'subgroup') {
254 $this->conf_type['subgroup'][$row[2]][$row[0]] = $row[0];
258 // group the fieldset type
259 if ($row[3] == 'fieldset') {
260 $this->conf_type['fieldset'][$row[2]][$row[0]] = $row[0];
264 if ($row[1] !== 'unset') {
265 if (!array_key_exists($row[2], $this->config_array) ||
266 !array_key_exists($row[0], $this->config_array[$row[2]])) {
267 $value = @unserialize($row[1]);
268 if (($value === false) && ($row[1] != $false_str)) {
269 if (function_exists('COM_errorLog')) {
270 COM_errorLog("Unable to unserialize {$row[1]} for {$row[2]}:{$row[0]}");
273 $this->config_array[$row[2]][$row[0]] = $value;
275 if ( strpos($row[3], '@') === 0 ) { // if @
276 if ( is_array($value) && !empty($value) ) {
277 $this->conf_tab_arr[$row[2]][$row[4]]
278 [$tabs[$row[2]][$row[4]][$row[5]]][$row[5]][$row[0]] = array_keys($value);
281 $this->conf_tab_arr[$row[2]][$row[4]]
282 [$tabs[$row[2]][$row[4]][$row[5]]][$row[5]][$row[0]] = $row[0];
287 // set to autocomplete only
288 $this->conf_tab_arr[$row[2]][$row[4]]
289 [$tabs[$row[2]][$row[4]][$row[5]]][$row[5]][$row[0]] = $row[0];
292 $this->_post_configuration();
294 return $this->config_array;
298 * Get configurations for particular group.
300 * @param string $group Group name
301 * @return bool|array Array of configurations for specified group
302 * or returns false if group doesn't exist
304 function &get_config($group)
308 if (array_key_exists($group, $this->config_array)) {
310 // an ugly little hack to ensure backward compatibility ...
311 if ($group == 'Core') {
312 global $_DB_mysqldump_path;
314 $_DB_mysqldump_path = $this->config_array[$group]['mysqldump_path'];
317 return $this->config_array[$group];
324 * Check if group exists or not
326 * @param string $group Group name
327 * @return bool True if group exists
329 function group_exists($group)
331 return array_key_exists($group, $this->config_array);
335 * This method sets a configuration variable to a value in the database
336 * and in the current array. If the variable does not already exist,
337 * nothing will happen.
339 * @param string $name Name of the config parameter to set
340 * @param mixed $value The value to set the config parameter to
343 function set($name, $value, $group='Core')
347 $escaped_val = addslashes(serialize($value));
348 $escaped_name = addslashes($name);
349 $escaped_grp = addslashes($group);
350 $sql = "UPDATE {$_TABLES['conf_values']} " .
351 "SET value = '{$escaped_val}' WHERE " .
352 "name = '{$escaped_name}' AND group_name = '{$escaped_grp}'";
353 $this->_DB_escapedQuery($sql);
354 $this->config_array[$group][$name] = $value;
355 $this->_post_configuration();
359 * This method sets the default of a configuration variable to a value in
360 * the database but not in the current array.
361 * If the variable does not already exist, nothing will happen.
363 * @param string $name Name of the config parameter to set
364 * @param mixed $value The value to set the config parameter to
365 * @param string $group Config group name ('Core' or plugin name)
368 function set_default($name, $value, $group = 'Core')
372 $escaped_val = addslashes(serialize($value));
373 $escaped_name = addslashes($name);
374 $escaped_grp = addslashes($group);
375 $sql = "UPDATE {$_TABLES['conf_values']} " .
376 "SET default_value = '{$escaped_val}' WHERE " .
377 "name = '{$escaped_name}' AND group_name = '{$escaped_grp}'";
378 $this->_DB_escapedQuery($sql);
382 * This method restores the default value (specified in the default_value field)
383 * of a configuration variable.
385 * @param string $name Configuration variable's name
386 * @param string $group Group name of configuration variable
387 * @param int $sg Subgroup of configuration variable
388 * @param string $tab_id Tab id
389 * @return bool True on succeed
391 function restore_param($name, $group, $sg = null, $tab_id = null)
395 // check if current user other than Root has access to
396 $tab_name = $this->_get_tab_name($group, $tab_id);
397 $ft = $this->conf_type['tab'][$group][$tab_name];
398 if ( !SEC_inGroup('Root') && !SEC_hasRights($ft) ) {
402 $escaped_name = addslashes($name);
403 $escaped_grp = addslashes($group);
405 $result = DB_query("SELECT value, default_value FROM {$_TABLES['conf_values']} WHERE name = '{$escaped_name}' AND group_name = '{$escaped_grp}'");
406 list($value, $default_value) = DB_fetchArray($result);
408 $sql = "UPDATE {$_TABLES['conf_values']} ";
409 if ($value == 'unset') {
410 $default_value = addslashes($default_value);
411 $sql .= "SET value = '{$default_value}', default_value = 'unset:{$default_value}'";
413 $sql .= "SET value = default_value";
415 $sql .= " WHERE name = '{$escaped_name}' AND group_name = '{$escaped_grp}'";
416 $this->_DB_escapedQuery($sql);
422 * This method sets a configuration variable's value to 'unset'.
424 * @param string $name Configuration variable's name
425 * @param string $group Group name of configuration variable
426 * @param int $sg Subgroup of configuration variable
427 * @param string $tab_id Tab id
428 * @return bool True on succeed
430 function unset_param($name, $group, $sg = null, $tab_id = '')
434 // check if current user other than Root has access to
435 $tab_name = $this->_get_tab_name($group, $tab_id);
436 $ft = $this->conf_type['tab'][$group][$tab_name];
437 if ( !SEC_inGroup('Root') && !SEC_hasRights($ft) ) {
441 $escaped_name = addslashes($name);
442 $escaped_grp = addslashes($group);
443 $default_value = DB_getItem($_TABLES['conf_values'], 'default_value',
444 "name = '{$escaped_name}' AND group_name = '{$escaped_grp}'");
445 $sql = "UPDATE {$_TABLES['conf_values']} SET value = 'unset'";
446 if (substr($default_value, 0, 6) == 'unset:') {
447 $default_value = addslashes(substr($default_value, 6));
448 $sql .= ", default_value = '{$default_value}'";
450 $sql .= " WHERE name = '{$escaped_name}' AND group_name = '{$escaped_grp}'";
451 $this->_DB_escapedQuery($sql);
457 * Adds a configuration variable to the config object
459 * @param string $param_name name of the parameter to add
460 * @param mixed $default_value the default value of the parameter
461 * (also will be the initial value)
462 * @param string $type the type of the configuration variable
464 * If the configuration variable is an array, prefix this string with
465 * '@' if the administrator should NOT be able to add or remove keys
466 * '*' if the administrator should be able to add named keys
467 * '%' if the administrator should be able to add numbered keys
468 * These symbols can be repeated like such: @@text if the configuration
469 * variable is an array of arrays of text.
470 * The base variable types are:
471 * 'text' textbox displayed string value stored
472 * 'select' selectbox displayed string value stored
473 * 'hidden' no display string value stored
475 * @param string $subgroup subgroup of the variable
476 * (the second row of tabs on the user interface)
477 * @param string $fieldset the fieldset to display the variable under
478 * @param array $selection_array possible selections for the 'select' type
479 * this MUST be passed if you use the 'select'
481 * @param int $sort sort rank on the user interface (ascending)
483 * @param boolean $set whether or not this parameter is set to config_array property
484 * @param string $group group of the variable
485 * @param string $tab the tab to display the variable under
487 function add($param_name, $default_value, $type, $subgroup, $fieldset=null,
488 $selection_array=null, $sort=0, $set=true, $group='Core', $tab=null)
492 $Qargs = array($param_name,
493 $set ? serialize($default_value) : 'unset',
497 ($selection_array === null ?
498 -1 : $selection_array),
500 ($fieldset === null ?
502 serialize($default_value)
505 $columns = 'name, value, type, subgroup, group_name, selectionArray, sort_order, fieldset, default_value';
507 // special handling of $tab for backward compatibility
512 $Qargs = array_map('addslashes', $Qargs);
514 // Now add in config item
515 $sql = "INSERT INTO {$_TABLES['conf_values']} ($columns) VALUES ("
526 $sql .= ",{$Qargs[9]}";
530 $this->_DB_escapedQuery($sql);
533 $this->config_array[$group][$param_name] = $default_value;
538 * Permanently deletes a parameter
539 * @param string $param_name This is the name of the parameter to delete
540 * @param string $group Configuraton group name
542 function del($param_name, $group)
544 DB_delete($GLOBALS['_TABLES']['conf_values'],
545 array('name', 'group_name'),
546 array(addslashes($param_name), addslashes($group)));
547 unset($this->config_array[$group][$param_name]);
551 * Gets extended (GUI related) information from the database
552 * @param string subgroup filters by subgroup
553 * @return array(string => string => array(string => mixed))
554 * Array keys are fieldset => parameter named => information array
556 function _get_extended($subgroup, $group)
558 global $_TABLES, $LANG_confignames, $LANG_configselects;
560 $q_string = "SELECT name, type, selectionArray, "
561 . "tab, value, default_value, fieldset FROM {$_TABLES['conf_values']}" .
562 " WHERE group_name='{$group}' AND subgroup='{$subgroup}' " .
563 " AND (type <> 'tab' AND type <> 'subgroup') " .
564 " ORDER BY tab,fieldset,sort_order ASC";
566 $Qresult = DB_query($q_string);
568 if (!array_key_exists($group, $LANG_configselects)) {
569 $LANG_configselects[$group] = array();
571 if (!array_key_exists($group, $LANG_confignames)) {
572 $LANG_confignames[$group] = array();
574 while ($row = DB_fetchArray($Qresult)) {
577 if ($cur[3] == '') {$cur[3] = 0;} // If tab is null then old plugin so set default tab
579 if (substr($cur[5], 0, 6) == 'unset:') {
584 $res[$cur[3]][$cur[0]] =
585 array('display_name' =>
586 (array_key_exists($cur[0], $LANG_confignames[$group]) ?
587 $LANG_confignames[$group][$cur[0]]
590 (($cur[4] == 'unset') ?
594 //isset($LANG_configselects[$group][$cur[2]]) : null),
595 $LANG_configselects[$group][$cur[2]] : null),
597 (($cur[4] == 'unset') ?
598 'unset' : unserialize($cur[4])),
599 'fieldset' => $cur[6],
607 * Changes any config settings that depend on other configuration settings.
608 * Called by config::initConfig and config::set
612 function _post_configuration()
616 if (empty($_USER['theme'])) {
617 if (! empty($this->config_array['Core']['theme'])) {
618 $theme = $this->config_array['Core']['theme'];
621 $theme = $_USER['theme'];
624 if (! empty($theme)) {
625 if (! empty($this->config_array['Core']['path_themes'])) {
626 $this->config_array['Core']['path_layout'] = $this->config_array['Core']['path_themes'] . $theme . '/';
628 if (! empty($this->config_array['Core']['site_url'])) {
629 $this->config_array['Core']['layout_url'] = $this->config_array['Core']['site_url'] . '/layout/' . $theme;
633 $methods = array('standard', 'openid', '3rdparty', 'oauth');
634 $methods_disabled = 0;
635 foreach ($methods as $m) {
636 if (isset($this->config_array['Core']['user_login_method'][$m]) &&
637 !$this->config_array['Core']['user_login_method'][$m]) {
641 if ($methods_disabled == count($methods)) {
642 // just to make sure people don't lock themselves out of their site
643 $this->config_array['Core']['user_login_method']['standard'] = true;
645 // TBD: ensure that we have a Root user able to log in with the
646 // enabled login method(s)
651 * Get configuration groups for current logged user.
652 * Plugins being disabled are ignored. Configurations
653 * that user doesn't access to are ignored.
655 * @return array Array of configuraton groups.
657 function _get_groups()
659 global $_TABLES, $_RIGHTS;
661 $groups = array_keys($this->config_array);
662 $num_groups = count($groups);
663 for ($i = 0; $i < $num_groups; $i++) {
665 // Only collect plugins that are enabled
667 $enabled = DB_getItem($_TABLES['plugins'], 'pi_enabled',
669 if (isset($enabled) && ($enabled == 0)) {
675 // check if current user other than Root has access to
676 $tabs = array_values($this->conf_type['tab'][$g]);
677 if ( !SEC_inGroup('Root') && !SEC_hasRights($tabs, 'OR') ) {
686 * Get configuration subgroups for particular configuration group.
688 * @param string $group Configuration group name
689 * @return array Array of subgroups that belong to configuration $group
691 function _get_sgroups($group)
695 $q_string = "SELECT name,subgroup FROM {$_TABLES['conf_values']} WHERE "
696 . "type = 'subgroup' AND group_name = '$group' "
697 . "ORDER BY subgroup";
700 $res = DB_query($q_string);
701 while ($row = DB_fetchArray($res)) {
702 // check if current user has access to current subgroup
703 $tabs = array_values($this->conf_type['tree'][$group][$row['subgroup']]);
704 if ( !SEC_inGroup('Root') && !SEC_hasRights($tabs, 'OR') ) {
707 $retval[$row['name']] = $row['subgroup'];
715 * Get tab name based on sepecified group name and tab id.
717 * @param string $group Group name
718 * @param int $tab_id tab id
720 function _get_tab_name($group, $tab_id) {
723 return DB_getItem($_TABLES['conf_values'], 'name',
724 "type = 'tab' AND tab = $tab_id AND group_name = '$group'");
729 * Get fieldset name based on sepecified tab id.
731 * @param string $tab_id tab id
732 * @param int $fs_id fieldset id
734 function _get_fs_name($tab_id, $fs_id) {
737 return DB_getItem($_TABLES['conf_values'], 'name',
738 "type = 'fieldset' AND fieldset = $fs_id AND tab = '$tab_id'");
743 * This function is responsible for creating the configuration GUI
745 * @oaram string $grp This is the group name to load the gui for.
746 * @param string sg This is the subgroup name to load the gui for.
747 * If nothing is passed, it will display the first
749 * @param mixed $change_result
750 * This is an array of what changes were made to the
751 * configuration - if it is passed, it will display
752 * the "Changes" message box.
754 function get_ui($grp, $sg='0', $change_result=null)
756 global $_CONF, $LANG_CONFIG, $LANG_configsubgroups, $LANG_tab, $LANG_fs,
759 if(!array_key_exists($grp, $LANG_configsubgroups)) {
760 $LANG_configsubgroups[$grp] = array();
763 // denied users that don't have access to configuration
764 $groups = $this->_get_groups();
765 if (empty($groups)) {
766 return config::_UI_perm_denied();
769 if (!isset($sg) OR empty($sg)) {
772 // get default subgroup for non Root user
773 if ( !SEC_inGroup('Root') ) {
774 $default_sg = $this->_get_sgroups($grp);
775 if ( !empty($default_sg) ) {
776 $default_sg = array_values($default_sg);
777 $sg = $default_sg[0];
779 return config::_UI_perm_denied();
784 $t = COM_newTemplate($_CONF['path_layout'] . 'admin/config');
785 $t->set_file(array('main' => 'configuration.thtml',
786 'menugroup' => 'menu_element.thtml'));
788 $link_message = $LANG01[139];
789 $t->set_var('noscript', COM_getNoScript(false, '', $link_message));
790 // Hide the Configuration as Javascript is currently required. If JS is enabled then the JS below will un-hide it
791 $js = 'document.getElementById("geeklog_config_editor").style.display="";';
792 $_SCRIPTS->setJavaScript($js, true);
794 $t->set_var('gltoken_name', CSRF_TOKEN);
795 $t->set_var('gltoken', SEC_createToken());
797 // set javascript variable for autocomplete
798 $js = $this->_UI_autocomplete_data();
799 // set javascript variable for image spinner
800 $js .= $this->_UI_js_image_spinner();
801 $js .= "var frmGroupAction = '" . $_CONF['site_admin_url'] . "/configuration.php';";
802 $_SCRIPTS->setJavaScript($js, true);
804 $this->flag_version_2 = version_compare($_CONF['supported_version_theme'], '2.0.0', '>=');
806 if ($this->flag_version_2 == true) {
807 $_SCRIPTS->setJavaScriptFile('admin.configuration', '/javascript/admin.configuration.js');
809 $_SCRIPTS->setJavaScriptFile('admin.configuration', '/javascript/ver.1.8/admin.configuration.js');
813 $t->set_var('search_configuration_label', $LANG_CONFIG['search_configuration_label']);
814 if (isset($_POST['search-configuration-cached'])) {
815 $t->set_var('search_configuration_value', $_POST['search-configuration-cached']);
817 $t->set_var('search_configuration_value', '');
819 if (isset($_POST['tab-id-cached'])) {
820 $t->set_var('tab_id_value', $_POST['tab-id-cached']);
822 $t->set_var('tab_id_value', '');
825 $t->set_var('lang_save_changes', $LANG_CONFIG['save_changes']);
826 $t->set_var('lang_reset_form', $LANG_CONFIG['reset_form']);
828 $t->set_var('open_group', $grp);
831 if (count($groups) > 0) {
832 $t->set_block('menugroup', 'subgroup-selector', 'subgroups');
833 foreach ($groups as $group) {
834 $t->set_var("select_id", ($group === $grp ? 'id="current"' : ''));
835 $t->set_var("group_select_value", $group);
836 $t->set_var("group_display", ucwords($group));
837 $subgroups = $this->_get_sgroups($group);
839 foreach ($subgroups as $sgname => $sgroup) {
840 if ($grp == $group AND $sg == $sgroup) {
841 $t->set_var('group_active_name', ucwords($group));
842 if (isset($LANG_configsubgroups[$group][$sgname])) {
843 $t->set_var('subgroup_active_name',
844 $LANG_configsubgroups[$group][$sgname]);
845 } else if (isset($LANG_configsubgroups[$group][$sgroup])) {
846 $t->set_var('subgroup_active_name',
847 $LANG_configsubgroups[$group][$sgroup]);
849 $t->set_var('subgroup_active_name', $sgname);
851 $t->set_var('select_id', 'id="current"');
853 $t->set_var('select_id', '');
855 $t->set_var('subgroup_name', $sgroup);
856 if (isset($LANG_configsubgroups[$group][$sgname])) {
857 $t->set_var('subgroup_display_name',
858 $LANG_configsubgroups[$group][$sgname]);
860 $t->set_var('subgroup_display_name', $sgname);
862 if ($innerloopcntr == 1) {
863 $t->parse('subgroups', "subgroup-selector");
865 $t->parse('subgroups', "subgroup-selector", true);
869 $t->set_var('cntr',$outerloopcntr);
870 $t->parse("menu_elements", "menugroup", true);
874 $t->set_var('hide_groupselection','none');
877 $t->set_var('open_sg', $sg);
878 $t->set_block('main','tab','sg_contents');
879 $t->set_block('tab', 'notes', 'tab_notes');
881 $ext_info = $this->_get_extended($sg, $grp);
883 foreach ($ext_info as $tab => $params) {
888 foreach ($params as $name => $e) {
889 if ($e['type'] == 'fieldset' AND $e['fieldset'] != $current_fs) {
891 if ($current_fs != '') {
893 if ($this->flag_version_2 == true) {
894 $tab_contents .= '</div></fieldset><!-- END fieldset -->';
896 $tab_contents .= '</table></fieldset><!-- END fieldset -->';
901 $tab_contents .= '<!-- BEGIN fieldset --><fieldset><legend>' . $LANG_fs[$grp][$e['display_name']] . '</legend>';
902 $current_fs = $e['fieldset'];
906 if ($this->flag_version_2 == true) {
907 $tab_contents .= '<div class="inputTable">';
909 $tab_contents .= '<table class="inputTable">';
915 if ($this->flag_version_2 == true) {
917 $this->_UI_get_conf_element_2($grp, $name,
921 $e['selectionArray'], false,
925 $this->_UI_get_conf_element($grp, $name,
929 $e['selectionArray'], false,
935 if ($this->flag_version_2 == true) {
936 $tab_contents .= '</div>';
938 $tab_contents .= '</table>';
943 $tab_contents .= '</fieldset><!-- END fieldset -->';
946 // check if current user has access to current tab
947 $tab_name = "config.{$grp}." . $this->_get_tab_name($grp, $tab);
948 if ( !SEC_inGroup('Root') && !SEC_hasRights($tab_name) ) {
952 $tab_display = $this->_UI_get_tab($grp, $tab_contents, $tab, $t);
955 $tab_li .= '<li><a href="#tab-' . $tab . '">' . $tab_display . '</a></li>';
958 $t->set_var('tab_li', $tab_li);
960 $_SCRIPTS->setJavaScriptLibrary('jquery.ui.autocomplete');
961 $_SCRIPTS->setJavaScriptLibrary('jquery.ui.tabs');
963 $t->set_var('config_menu',$this->_UI_configmanager_menu($grp,$sg));
966 if ($change_result != null AND $change_result !== array()) {
967 $t->set_var('lang_changes_made', $LANG_CONFIG['changes_made'] . ':');
968 $t->set_var('change_block',$this->_UI_get_change_block($change_result, $grp, $sg));
970 $t->set_var('show_changeblock','none');
972 if ( !empty($this->validationErrors) ) {
973 $t->set_var('lang_changes_made', '');
974 $t->set_var('show_changeblock', '');
975 $t->set_var('change_block',$this->_UI_get_change_block(NULL, $grp, $sg));
976 $t->set_var('lang_error_validation_occurs', $LANG_CONFIG['error_validation_occurs'] . ' :');
977 $t->set_var('error_validation_class', ' error_validation');
980 $display = $t->finish($t->parse("OUTPUT", "main"));
981 $display = COM_createHTMLDocument($display, array('what' => 'none', 'pagetitle' => $LANG_CONFIG['title'], 'rightblock' => false));
987 * Get messages to display when changes were made to the configuration.
989 * @param array $changes Array of changes. Keys are configuration
991 * @param string $group Configuration group
992 * @param int $sg Configuration subgroup
993 * @return string string of HTML to be displayed on message box
995 function _UI_get_change_block($changes, $group = null, $sg = null)
1000 if ( empty($this->validationErrors) ) {
1001 if ($changes != null AND $changes !== array()) {
1002 foreach ($changes as $param_name => $success) {
1003 if ( isset($this->changedArray[$group][$param_name]) ) {
1004 foreach ($this->changedArray[$group][$param_name] as $_param_name => $_success) {
1005 $anchors[] = ' <a href="#' . $param_name . '[' . $_param_name . ']' .
1006 '" class="select_config"' .
1007 (($group !== null) ? ' group="' . $group . '"' : '') .
1008 (($sg !== null) ? ' subgroup="' . $sg . '"' : '') .
1009 '>' . $param_name . '[' . $_param_name . ']' . '</a>';
1012 $anchors[] = ' <a href="#' . $param_name . '" class="select_config"' .
1013 (($group !== null) ? ' group="' . $group . '"' : '') .
1014 (($sg !== null) ? ' subgroup="' . $sg . '"' : '') .
1015 '>' . $param_name . '</a>';
1020 foreach ( $this->validationErrors as $grp => $errors ) {
1021 foreach ( $errors as $param_name => $error ) {
1022 $anchors[] = ' <a href="#' . $param_name . '" class="select_config"' .
1023 (($group !== null) ? ' group="' . $group . '"' : '') .
1024 (($sg !== null) ? ' subgroup="' . $sg . '"' : '') .
1025 '>' . $param_name . '</a>';
1030 if ( !empty($anchors) ) {
1031 $display = implode(',', $anchors);
1038 * Set tab from configuration where tab = $tab_id under the group $group
1039 * with content $contents to template $t
1041 * @param string $group Configuration group
1042 * @param string $contents Contents
1043 * @param int $tab_id tab id
1044 * @param object $t Template object
1045 * @return string tab name to display based on current language
1047 function _UI_get_tab($group, $contents, $tab_id, &$t)
1049 global $_TABLES, $LANG_tab, $LANG_CONFIG;
1051 if (!array_key_exists($group, $LANG_tab)) {
1052 $LANG_tab[$group] = array();
1054 $t->set_var('tab_contents', $contents);
1055 $tab_index = DB_getItem($_TABLES['conf_values'], 'name',
1056 "type = 'tab' AND tab = $tab_id AND group_name = '$group'");
1058 if (empty($tab_index)) {
1059 if (empty($LANG_tab[$group][$tab_id])) {
1060 $tab_display = $LANG_CONFIG['default_tab_name'];
1062 $tab_display = $LANG_tab[$group][$tab_id];
1064 } else if (isset($LANG_tab[$group][$tab_index])) {
1065 $tab_display = $LANG_tab[$group][$tab_index];
1067 $tab_display = $tab_index;
1069 $t->set_var('tab_id', "tab-{$tab_id}");
1070 $t->set_var('tab_display', $tab_display);
1071 $t->set_var('tab_notes', '');
1072 $t->parse('sg_contents', 'tab', true);
1075 return $tab_display;
1079 * Set fieldset from configuration where fieldset = $fs_id under the group $group
1080 * with content $contents to template $t
1082 * @param string $group
1083 * @param string $contents Contents
1085 * @param object $t Template object
1088 function _UI_get_fs($group, $contents, $fs_id, &$t)
1090 global $_TABLES, $LANG_fs;
1092 if (!array_key_exists($group, $LANG_fs)) {
1093 $LANG_fs[$group] = array();
1095 $t->set_var('fs_contents', $contents);
1096 $fs_index = DB_getItem($_TABLES['conf_values'], 'name',
1097 "type = 'fieldset' AND fieldset = $fs_id AND group_name = '$group'");
1098 if (empty($fs_index)) {
1099 $t->set_var('fs_display', $LANG_fs[$group][$fs_id]);
1100 } else if (isset($LANG_fs[$group][$fs_index])) {
1101 $t->set_var('fs_display', $LANG_fs[$group][$fs_index]);
1103 $t->set_var('fs_display', $fs_index);
1105 $t->set_var('fs_notes', '');
1106 $t->parse('sg_contents', 'fieldset', true);
1110 * Returns a page for permission denied
1112 * @return string HTML for permission denied page
1114 function _UI_perm_denied()
1116 global $_USER, $MESSAGE;
1118 $display = COM_showMessageText($MESSAGE[29], $MESSAGE[30]);
1119 $display = COM_createHTMLDocument($display, array('pagetitle' => $MESSAGE[30]));
1120 COM_accessLog("User {$_USER['username']} tried to illegally access the config administration screen.");
1126 * Get a parsed config element based on group $group, name $name,
1127 * type $type, value to be shown $val and label $display_name to be shown
1128 * on the left based on language.
1130 * @param string $group Configuration group.
1131 * @param string $name Configuration name on table.
1132 * @param string $display_name Configuration display name based on language.
1133 * @param string $type Configuration type such as select, text, textarea, @select, etc.
1134 * @param string $val Value of configuration
1135 * @param mixed $selectionArray Array of option of select element
1136 * @param bool $deleteable If configuration is deleteable
1137 * @param bool $allow_reset Allow set and unset of configuration
1140 function _UI_get_conf_element($group, $name, $display_name, $type, $val,
1141 $selectionArray = null , $deletable = false,
1142 $allow_reset = false)
1144 global $_CONF, $LANG_CONFIG;
1146 $t = COM_newTemplate($GLOBALS['_CONF']['path_layout'] . 'admin/config');
1147 $t -> set_file('element', 'config_element.thtml');
1149 $blocks = array('delete-button', 'text-element', 'placeholder-element',
1150 'select-element', 'list-element', 'unset-param',
1151 'keyed-add-button', 'unkeyed-add-button', 'text-area',
1152 'validation_error_block');
1153 foreach ($blocks as $block) {
1154 $t->set_block('element', $block);
1157 $t->set_var('lang_restore', $LANG_CONFIG['restore']);
1158 $t->set_var('lang_enable', $LANG_CONFIG['enable']);
1159 $t->set_var('lang_add_element', $LANG_CONFIG['add_element']);
1161 $t->set_var('name', $name);
1162 $t->set_var('id_name', str_replace(array('[', ']'), array('_', ''), $name));
1163 $t->set_var('display_name', $display_name);
1166 if ( isset($this->tmpValues[$group][$name]) ) {
1167 $val = $this->tmpValues[$group][$name];
1170 if (!is_array($val)) {
1171 if (is_float($val)) {
1173 * @todo FIXME: for Locales where the comma is the decimal
1174 * separator, patch output to a decimal point
1175 * to prevent it being cut off by COM_applyFilter
1177 $t->set_var('value', str_replace(',', '.', $val));
1179 $t->set_var('value', htmlspecialchars($val));
1183 // if there is a error message to shown
1184 if ( isset($this->validationErrors[$group][$name]) ) {
1185 $t->set_var('validation_error_message', $this->validationErrors[$group][$name]);
1186 $t->set_var('error_block', $t->parse('output', 'validation_error_block'));
1187 $t->set_var('error_class', ' input_error');
1188 $t->set_var('value', $this->validationErrorValues[$group][$name]);
1190 $t->set_var('error_class', '');
1191 $t->set_var('error_block', '');
1195 $t->set_var('delete', $t->parse('output', 'delete-button'));
1198 $t->set_var('unset_link',
1199 "(<a href=\"#{$name}\" class=\"unset_param\" title='"
1200 . $LANG_CONFIG['disable'] . "'>X</a>)");
1202 if (($a = strrchr($name, '[')) !== FALSE) {
1203 $on = substr($a, 1, -1);
1204 $o = str_replace(array('[', ']'), array('_', ''), $name);
1209 if (! is_numeric($on)) {
1210 $this->_set_ConfigHelp($t, $group, $o);
1213 if ($type == "unset") {
1214 return $t->finish($t->parse('output', 'unset-param'));
1215 } elseif ($type == "text") {
1216 return $t->finish($t->parse('output', 'text-element'));
1217 } elseif ($type == "textarea") {
1218 return $t->finish($t->parse('output', 'text-area'));
1219 } elseif ($type == "placeholder") {
1220 return $t->finish($t->parse('output', 'placeholder-element'));
1221 } elseif ($type == 'select') {
1222 // if $name is like "blah[0]", separate name and index
1223 $n = explode('[', $name);
1226 if (count($n) == 2) {
1227 $i = explode(']', $n[1]);
1230 $type_name = $type . '_' . $name;
1231 if ($group == 'Core') {
1232 $fn = 'configmanager_' . $type_name . '_helper';
1234 $fn = 'plugin_configmanager_' . $type_name . '_' . $group;
1236 if (function_exists($fn)) {
1237 if ($index === null) {
1238 $selectionArray = $fn();
1240 $selectionArray = $fn($index);
1242 } else if (is_array($selectionArray)) {
1243 // leave sorting to the function otherwise
1244 uksort($selectionArray, 'strcasecmp');
1246 if (! is_array($selectionArray)) {
1247 return $t->finish($t->parse('output', 'text-element'));
1250 $t->set_block('select-element', 'select-options', 'myoptions');
1251 foreach ($selectionArray as $sName => $sVal) {
1252 if (is_bool($sVal)) {
1253 $t->set_var('opt_value', $sVal ? 'b:1' : 'b:0');
1255 $t->set_var('opt_value', $sVal);
1257 $t->set_var('opt_name', $sName);
1258 $t->set_var('selected', ($val == $sVal ? 'selected="selected"' : ''));
1259 $t->parse('myoptions', 'select-options', true);
1261 if ($index == 'placeholder') {
1262 $t->set_var('hide_row', ' style="display:none;"');
1264 return $t->parse('output', 'select-element');
1265 } elseif (strpos($type, '@') === 0) {
1267 foreach ($val as $valkey => $valval) {
1268 $result .= config::_UI_get_conf_element($group,
1269 $name . '[' . $valkey . ']',
1270 $display_name . '[' . $valkey . ']',
1271 substr($type, 1), $valval, $selectionArray,
1275 } elseif (strpos($type, "*") === 0 || strpos($type, "%") === 0) {
1276 $t->set_var('arr_name', $name);
1277 $t->set_var('array_type', $type);
1278 $button = $t->parse('output', (strpos($type, "*") === 0 ?
1279 'keyed-add-button' :
1280 'unkeyed-add-button'));
1281 $t->set_var('my_add_element_button', $button);
1283 if ($type == '%select') {
1284 $result .= config::_UI_get_conf_element($group,
1285 $name . '[placeholder]', 'placeholder',
1286 substr($type, 1), 'placeholder', $selectionArray,
1289 foreach ($val as $valkey => $valval) {
1290 $result .= config::_UI_get_conf_element($group,
1291 $name . '[' . $valkey . ']', $valkey,
1292 substr($type, 1), $valval, $selectionArray,
1295 $t->set_var('my_elements', $result);
1296 // if the values are indexed numerically, add a class to the table
1297 // for identification. The UI code can take advantage of it
1298 if ($val === array_values($val)) {
1299 $t->set_var('arr_table_class_list', 'numerical_config_list');
1301 return $t->parse('output', 'list-element');
1306 * Get a parsed config element based on group $group, name $name,
1307 * type $type, value to be shown $val and label $display_name to be shown
1308 * on the left based on language.
1310 * @param string $group Configuration group.
1311 * @param string $name Configuration name on table.
1312 * @param string $display_name Configuration display name based on language.
1313 * @param string $type Configuration type such as select, text, textarea, @select, etc.
1314 * @param string $val Value of configuration
1315 * @param mixed $selectionArray Array of option of select element
1316 * @param bool $deleteable If configuration is deleteable
1317 * @param bool $allow_reset Allow set and unset of configuration
1320 function _UI_get_conf_element_2($group, $name, $display_name, $type, $val,
1321 $selectionArray = null , $deletable = false,
1322 $allow_reset = false)
1324 global $_CONF, $LANG_CONFIG;
1326 $t = COM_newTemplate($GLOBALS['_CONF']['path_layout'] . 'admin/config');
1327 $t -> set_file('element', 'config_element_2.thtml');
1329 $blocks = array('delete-button', 'text-element', 'placeholder-element',
1330 'select-element', 'list-element', 'unset-param',
1331 'keyed-add-button', 'unkeyed-add-button', 'text-area',
1332 'validation_error_block');
1333 foreach ($blocks as $block) {
1334 $t->set_block('element', $block);
1337 $t->set_var('lang_restore', $LANG_CONFIG['restore']);
1338 $t->set_var('lang_enable', $LANG_CONFIG['enable']);
1339 $t->set_var('lang_add_element', $LANG_CONFIG['add_element']);
1341 $t->set_var('name', $name);
1342 $t->set_var('id_name', str_replace(array('[', ']'), array('_', ''), $name));
1343 $t->set_var('display_name', $display_name);
1346 if ( isset($this->tmpValues[$group][$name]) ) {
1347 $val = $this->tmpValues[$group][$name];
1350 if (!is_array($val)) {
1351 if (is_float($val)) {
1353 * @todo FIXME: for Locales where the comma is the decimal
1354 * separator, patch output to a decimal point
1355 * to prevent it being cut off by COM_applyFilter
1357 $t->set_var('value', str_replace(',', '.', $val));
1359 $t->set_var('value', htmlspecialchars($val));
1363 // if there is a error message to shown
1364 if ( isset($this->validationErrors[$group][$name]) ) {
1365 $t->set_var('validation_error_message', $this->validationErrors[$group][$name]);
1366 $t->set_var('error_block', $t->parse('output', 'validation_error_block'));
1367 $t->set_var('error_class', ' input_error');
1368 $t->set_var('value', $this->validationErrorValues[$group][$name]);
1370 $t->set_var('error_class', '');
1371 $t->set_var('error_block', '');
1375 $t->set_var('delete', $t->parse('output', 'delete-button'));
1378 $t->set_var('unset_link',
1379 "(<a href=\"#{$name}\" class=\"unset_param\" title='"
1380 . $LANG_CONFIG['disable'] . "'>X</a>)");
1382 if (($a = strrchr($name, '[')) !== FALSE) {
1383 $on = substr($a, 1, -1);
1384 $o = str_replace(array('[', ']'), array('_', ''), $name);
1389 if (! is_numeric($on)) {
1390 $this->_set_ConfigHelp($t, $group, $o);
1393 // if $name is like "blah[0]", separate name and index
1394 $n = explode('[', $name);
1398 $i = explode(']', $n[$nc-1]);
1401 if (!empty($index) && ($index == 'placeholder' || $display_name == 'skeleton')) {
1402 $t->set_var('hide_row', ' style="display:none;"');
1405 $prefix = substr($type, 0, 1);
1406 if ($type == "unset") {
1407 return $t->finish($t->parse('output', 'unset-param'));
1408 } elseif ($type == "text") {
1409 return $t->finish($t->parse('output', 'text-element'));
1410 } elseif ($type == "textarea") {
1411 return $t->finish($t->parse('output', 'text-area'));
1412 } elseif ($type == "placeholder") {
1413 return $t->finish($t->parse('output', 'placeholder-element'));
1414 } elseif ($type == 'select') {
1416 // if $name is like "blah[0]", separate name and index
1417 $n = explode('[', $name);
1419 $type_name = $type . '_' . $name;
1420 if ($group == 'Core') {
1421 $fn = 'configmanager_' . $type_name . '_helper';
1423 $fn = 'plugin_configmanager_' . $type_name . '_' . $group;
1425 if (function_exists($fn)) {
1426 if ($index === null) {
1427 $selectionArray = $fn();
1429 $selectionArray = $fn($index);
1431 } else if (is_array($selectionArray)) {
1432 // leave sorting to the function otherwise
1433 uksort($selectionArray, 'strcasecmp');
1435 if (! is_array($selectionArray)) {
1436 return $t->finish($t->parse('output', 'text-element'));
1439 $t->set_block('select-element', 'select-options', 'myoptions');
1440 foreach ($selectionArray as $sName => $sVal) {
1441 if (is_bool($sVal)) {
1442 $t->set_var('opt_value', $sVal ? 'b:1' : 'b:0');
1444 $t->set_var('opt_value', $sVal);
1446 $t->set_var('opt_name', $sName);
1447 $t->set_var('selected', ($val == $sVal ? 'selected="selected"' : ''));
1448 $t->parse('myoptions', 'select-options', true);
1450 return $t->parse('output', 'select-element');
1451 } elseif ($prefix == '@') {
1453 foreach ($val as $valkey => $valval) {
1454 $result .= config::_UI_get_conf_element_2($group,
1455 $name . '[' . $valkey . ']',
1456 $display_name . '[' . $valkey . ']',
1457 substr($type, 1), $valval, $selectionArray,
1461 } elseif ($prefix == '*' || $prefix == '%') {
1462 $t->set_var('arr_name', $name);
1463 $t->set_var('array_type', $type);
1464 $button = $t->parse('output', ($prefix == '*' ?
1465 'keyed-add-button' :
1466 'unkeyed-add-button'));
1467 $t->set_var('my_add_element_button', $button);
1470 $base_type = str_replace(array('*', '%'), '', $type);
1471 if (in_array($base_type, array('select', 'text', 'placeholder'))) {
1472 $result .= config::_UI_get_conf_element_2($group,
1473 $name . '[placeholder]', 'skeleton',
1474 substr($type, 1), 'placeholder', $selectionArray,
1478 if ($display_name == 'skeleton') {
1481 if (!is_array($val)) {
1485 foreach ($val as $valkey => $valval) {
1486 $result .= config::_UI_get_conf_element_2($group,
1487 $name . '[' . $valkey . ']', $valkey,
1488 substr($type, 1), $valval, $selectionArray,
1491 $t->set_var('my_elements', $result);
1492 // if the values are indexed numerically, add a class to the div
1493 // for identification. The UI code can take advantage of it
1494 $t->set_var('arr_class_list', ($prefix == '%' ?
1495 'numerical_config_list' :
1496 'named_config_list'));
1497 return $t->parse('output', 'list-element');
1502 * This function takes $_POST input and evaluates it
1504 * @param array(string=>mixed) $change_array this is the $_POST array
1505 * @param string $group Group name
1506 * @return array(string=>boolean) this is the change_array
1508 function updateConfig($change_array, $group)
1512 require_once 'validator.class.php';
1514 if ($group == 'Core') {
1516 * $_CONF['theme'] and $_CONF['language'] are overwritten with
1517 * the user's preferences in lib-common.php. Re-read values from
1518 * the database so that we're comparing the correct values below.
1520 $value = DB_getItem($_TABLES['conf_values'], 'value',
1521 "group_name='Core' AND name='theme'");
1522 $this->config_array['Core']['theme'] = unserialize($value);
1523 $value = DB_getItem($_TABLES['conf_values'], 'value',
1524 "group_name='Core' AND name='language'");
1525 $this->config_array['Core']['language'] = unserialize($value);
1528 * Same with $_CONF['cookiedomain'], which is overwritten in
1529 * in lib-sessions.php (if empty).
1531 $value = DB_getItem($_TABLES['conf_values'], 'value',
1532 "group_name='Core' AND name='cookiedomain'");
1533 $this->config_array['Core']['cookiedomain'] = unserialize($value);
1536 $this->_extract_permissible_conf($change_array, $group, $change_array['sub_group']);
1538 $pass_validation = array();
1539 $success_array = array();
1540 if (!is_array($this->validationErrors)) {
1541 $this->validationErrors = array();
1544 foreach ($this->config_array[$group] as $param_name => $param_value) {
1545 if (array_key_exists($param_name, $change_array)) {
1546 $change_array[$param_name] =
1547 $this->_validate_input($param_name, $group, $change_array[$param_name]);
1549 // we should avoid string conversion
1550 // see http://www.php.net/manual/en/language.types.string.php#language.types.string.conversion
1551 if ( is_string($change_array[$param_name]) &&
1552 !is_string($param_value) )
1554 if (strcmp($change_array[$param_name], $param_value) !== 0 &&
1555 $this->_validates($param_name, $group, $change_array[$param_name]))
1557 $pass_validation[$param_name] = $change_array[$param_name];
1559 } else if ( is_array($change_array[$param_name]) ) {
1560 /* if array such as mail settings */
1562 if (count($this->config_array[$group][$param_name]) != count($change_array[$param_name])) {
1565 foreach ( $change_array[$param_name] as $_param_name => $_param_value ) {
1566 if (!isset($this->config_array[$group][$param_name][$_param_name])) {
1568 } elseif ( $change_array[$param_name][$_param_name] != $this->config_array[$group][$param_name][$_param_name] ) {
1572 if ( $this->_validates($param_name . '[' . $_param_name . ']', $group, $change_array[$param_name][$_param_name], $change_array[$param_name]) ) {
1573 $this->changedArray[$group][$param_name][$_param_name] = true;
1579 $pass_validation[$param_name] = $change_array[$param_name];
1582 if ($change_array[$param_name] != $param_value &&
1583 $this->_validates($param_name, $group, $change_array[$param_name]))
1585 $pass_validation[$param_name] = $change_array[$param_name];
1591 // after validation set the field
1592 if ( empty($this->validationErrors) ) {
1593 // only set if there is no validation error
1594 foreach ( $pass_validation as $param => $val ) {
1595 $this->set($param, $val, $group);
1596 $success_array[$param] = true;
1599 // temporaly save the changed values
1600 foreach ( $pass_validation as $param => $val ) {
1601 $this->tmpValues[$group][$param] = $val;
1605 return $success_array;
1609 * Extracts allowed conf from posted data. Used by updateConfig
1611 * @param array(string=>mixed) $change_array this is the $_POST array
1612 * @param string $group Configuration group
1613 * @param int $sg_id Subgroup id
1615 function _extract_permissible_conf(&$change_array, $group, $sg_id = null) {
1616 $permissible_conf = array();
1617 foreach ($this->conf_tab_arr[$group] as $sg => $tabs) {
1618 if ( $sg_id && $sg_id != $sg ) continue;
1620 foreach ($tabs as $tab_name => $tab) {
1621 foreach ($tab as $tab_id => $configs) {
1622 $tab_ft = $this->conf_type['tab'][$group][$tab_name];
1623 if ( SEC_inGroup('Root') || SEC_hasRights($tab_ft) ) {
1624 $permissible_conf = array_merge(array_intersect_key($change_array, $configs), $permissible_conf);
1629 $change_array = array_intersect_key($change_array, $permissible_conf);
1638 function _validate_input($config, $group, &$input_val)
1640 if (is_array($input_val)) {
1644 foreach ($input_val as $key => $val) {
1645 if ($key !== 'placeholder' && $key !== 'nameholder') {
1646 $r[$key] = $this->_validate_input($config, $group, $val);
1647 if (is_numeric($key)) {
1648 if ($key > $max_key) {
1656 if ($is_num && ($max_key >= 0) && ($max_key + 1 != count($r))) {
1659 foreach ($r as $val) {
1665 $r = COM_stripslashes($input_val);
1666 if ($r == 'b:0' OR $r == 'b:1') {
1669 //if (is_numeric($r)) {
1670 if (is_numeric($r) && $this->_validate_numeric($config, $group)) {
1679 * Returns true if configuration field should be numeric.
1681 * @param string $config Configuration variable
1682 * @param string $group Configuration group
1683 * @return boolean True if numeric
1686 function _validate_numeric($config, $group) {
1687 global $_CONF_VALIDATE;
1689 if ( isset($_CONF_VALIDATE[$group][$config]) &&
1690 !empty($_CONF_VALIDATE[$group][$config]) )
1692 foreach ($_CONF_VALIDATE[$group][$config] as $index => $validator) {
1693 if ($index == 'rule') {
1694 if (is_array($validator)) {
1695 $rule_type = $validator[0];
1697 $rule_type = $validator;
1699 if (in_array($rule_type, array( 'numeric', 'range', 'decimal', 'comparison'))) {
1708 // No rule found then return true as validation will happen the old way by just using is_numeric
1713 * Returns true if configuration field pass given validation rule.
1715 * @param string $config Configuration variable
1716 * @param string $group Configuration group
1717 * @param mixed $value Submitted value
1718 * @param mixed $relatedValue value that related such as mail settings
1719 * @return boolean True if there are no errors
1722 function _validates($config, $group, &$value, &$relatedValue = null) {
1723 global $_CONF_VALIDATE, $LANG_VALIDATION;
1725 $_validator =& validator::getInstance();
1727 if ( isset($_CONF_VALIDATE[$group][$config]) &&
1728 !empty($_CONF_VALIDATE[$group][$config]) )
1734 foreach ($_CONF_VALIDATE[$group][$config] as $index => $validator) {
1735 if (!is_array($validator)) {
1736 if ( $index == 'message' && is_string($validator) ) continue;
1738 $validator = array('rule' => $validator);
1740 if ( $index == 'rule' ) {
1741 $validator = array('rule' => $validator);
1744 if ( isset($_CONF_VALIDATE[$group][$config]['message']) &&
1745 is_string($_CONF_VALIDATE[$group][$config]['message']) )
1747 $validator['message'] = $_CONF_VALIDATE[$group][$config]['message'];
1748 unset($_CONF_VALIDATE[$group][$config]['message']);
1750 $validator = array_merge($default, $validator);
1752 if (isset($validator['message'])) {
1753 $message = $validator['message'];
1754 } else if ( is_string($validator['rule']) && isset($LANG_VALIDATION[$validator['rule']]) ) {
1755 $message = $LANG_VALIDATION[$validator['rule']];
1756 } else if ( is_array($validator['rule']) && isset($LANG_VALIDATION[$validator['rule'][0]]) ) {
1757 $message = $LANG_VALIDATION[$validator['rule'][0]];
1759 $message = $LANG_VALIDATION['default'];
1762 if ( is_array($validator['rule']) ) {
1763 $rule = $validator['rule'][0];
1764 unset($validator['rule'][0]);
1765 $ruleParams = array_merge(array($value), array_values($validator['rule']));
1767 $rule = $validator['rule'];
1768 $ruleParams = array($value);
1772 $custom_function = 'custom_validation_' . strtolower($rule);
1773 if ( function_exists($custom_function) ) {
1774 $ruleParams[] = $validator;
1775 $ruleParams[0] = array($config => $ruleParams[0]);
1777 if ( is_array($relatedValue) && !empty($relatedValue) ) {
1778 $ruleParams[] = $relatedValue;
1781 $valid = $custom_function($rule, $ruleParams);
1782 } elseif (method_exists($_validator, $rule)) {
1783 $valid = $_validator->dispatchMethod($rule, $ruleParams);
1784 } elseif (!is_array($validator['rule'])) {
1785 $valid = preg_match($rule, $value);
1788 if (!$valid || (is_string($valid) && strlen($valid) > 0)) {
1789 if (is_string($valid) && strlen($valid) > 0) {
1790 $validator['message'] = $valid;
1791 } elseif (!isset($validator['message'])) {
1792 $validator['message'] = $message;
1795 $this->validationErrors[$group][$config] = $validator['message'];
1796 $this->validationErrorValues[$group][$config] = $value;
1808 * Builds configuration menu
1810 * @param $conf_group Configuration group
1811 * @param $sg Configuration subgroup
1813 function _UI_configmanager_menu($conf_group,$sg=0)
1815 global $_CONF, $LANG_ADMIN, $LANG_CONFIG,
1816 $LANG_configsections, $LANG_configsubgroups;
1818 $retval = COM_startBlock($LANG_CONFIG['sections'], '',
1819 COM_getBlockTemplate('configmanager_block', 'header'));
1820 $link_array = array();
1822 $groups = $this->_get_groups();
1823 if (count($groups) > 0) {
1824 foreach ($groups as $group) {
1825 if (empty($LANG_configsections[$group]['label'])) {
1826 $group_display = ucwords($group);
1828 $group_display = $LANG_configsections[$group]['label'];
1830 // Create a menu item for each config group - disable the link for the current selected one
1831 if ($this->flag_version_2 == true) {
1832 if ($conf_group == $group) {
1833 $link = "<li class=\"configoption_off\">$group_display</li>";
1835 $link = "<li class=\"configoption\"><a href=\"#\" onclick='open_group(\"$group\");return false;'>$group_display</a></li>";
1838 if ($conf_group == $group) {
1839 $link = "<div>$group_display</div>";
1841 $link = "<div><a href=\"#\" onclick='open_group(\"$group\");return false;'>$group_display</a></div>";
1844 if ($group == 'Core') {
1847 $link_array[$group_display] = $link;
1852 uksort($link_array, 'strcasecmp');
1853 foreach ($link_array as $link) {
1857 if ($this->flag_version_2 == true) {
1858 $retval .= '<li class="configoption"><a href="' . $_CONF['site_admin_url'] . '">'
1859 . $LANG_ADMIN['admin_home'] . '</a></li>';
1861 $retval .= '<div><a href="' . $_CONF['site_admin_url'] . '">'
1862 . $LANG_ADMIN['admin_home'] . '</a></div>';
1864 $retval .= COM_endBlock(COM_getBlockTemplate('configmanager_block',
1868 /* Now display the sub-group menu for the selected config group */
1869 if (empty($LANG_configsections[$conf_group]['title'])) {
1870 $subgroup_title = ucwords($conf_group);
1872 $subgroup_title = $LANG_configsections[$conf_group]['title'];
1874 $retval .= COM_startBlock($subgroup_title, '',
1875 COM_getBlockTemplate('configmanager_subblock', 'header'));
1877 $sgroups = $this->_get_sgroups($conf_group);
1878 if (count($sgroups) > 0) {
1880 foreach ($sgroups as $sgname => $sgroup) {
1881 if (isset($LANG_configsubgroups[$conf_group][$sgname])) {
1882 $group_display = $LANG_configsubgroups[$conf_group][$sgname];
1883 } else if (isset($LANG_configsubgroups[$conf_group][$sgroup])) {
1884 $group_display = $LANG_configsubgroups[$conf_group][$sgroup];
1886 $group_display = $sgname;
1888 // Create a menu item for each sub config group - disable the link for the current selected one
1889 if ($this->flag_version_2 == true) {
1890 if ($sgroup == $sg) {
1891 $retval .= "<li class=\"configoption_off\">$group_display</li>";
1893 $retval .= "<li class=\"configoption\"><a href=\"#\" onclick='open_subgroup(\"$conf_group\",\"$sgroup\");return false;'>$group_display</a></li>";
1896 if ($sgroup == $sg) {
1897 $retval .= "<div>$group_display</div>";
1899 $retval .= "<div><a href=\"#\" onclick='open_subgroup(\"$conf_group\",\"$sgroup\");return false;'>$group_display</a></div>";
1905 $retval .= COM_endBlock(COM_getBlockTemplate('configmanager_block',
1912 * Build JSON for autocomplete
1913 * @return string JS variable in string
1915 function _UI_autocomplete_data() {
1916 global $_CONF, $LANG_configsections, $LANG_confignames, $LANG_fs, $LANG_tab, $LANG_CONFIG;
1918 $permitted_groups = $this->_get_groups();
1921 foreach ($this->conf_type['tree'] as $group => $subgroups) {
1922 if ( !in_array($group, $permitted_groups) ) {
1926 foreach ($subgroups as $sg => $tabs) {
1927 foreach ($tabs as $tab => $tab_ft) {
1928 if ( !SEC_inGroup('Root') && !SEC_hasRights($tab_ft) ) {
1932 // Figure out if tab name is set, if not assume old plugin and default the name
1933 if (isset($LANG_tab[$group][$tab])) {
1934 $tab_label = $LANG_tab[$group][$tab];
1936 $tab_label = $LANG_CONFIG['default_tab_name'];
1939 foreach ($this->conf_tab_arr[$group][$sg][$tab] as $tab_id => $configs) {
1940 foreach ($configs as $conf => $conf_var) {
1941 // Check to see if label exists for config name
1942 if (array_key_exists($conf, $LANG_confignames[$group])) {
1943 $label = $LANG_confignames[$group][$conf];
1945 // Maybe a fieldset, check to see if fieldset label exits
1946 if (array_key_exists($conf, $LANG_fs[$group])) {
1947 $label = $LANG_fs[$group][$conf];
1949 // No label found, set name
1954 if ( is_array($conf_var) ) {
1955 foreach ( $conf_var as $_conf_var ) {
1956 $retval["$group.$tab.$conf.$_conf_var"] = '{' .
1957 'value: "' . $conf . '[' . $_conf_var . ']", ' .
1958 'label: "' . str_replace('"', '\"', $label) . '[' . $_conf_var . ']", ' .
1960 str_replace('"', '\"', $LANG_configsections[$group]['label']) . ' » ' .
1961 str_replace('"', '\"', $tab_label) . '", ' .
1962 'tab_id: ' . $tab_id . ', ' .
1963 'subgroup: ' . $sg . ', ' .
1964 'group: "' . $group . '"' .
1968 $retval["$group.$tab.$conf"] = '{' .
1969 'value: "' . $conf . '", ' .
1970 'label: "' . str_replace('"', '\"', $label) . '", ' .
1972 str_replace('"', '\"', $LANG_configsections[$group]['label']) .' » ' .
1973 str_replace('"', '\"', $tab_label) . '", ' .
1974 'tab_id: ' . $tab_id . ', ' .
1975 'subgroup: ' . $sg . ', ' .
1976 'group: "' . $group . '"' .
1984 $retval = implode(',', $retval);
1986 return "var autocomplete_data = [{$retval}];";
1990 * Set image spinner path in javascript variable
1991 * @return string JS variable in string
1993 function _UI_js_image_spinner() {
1994 $image = $GLOBALS['_CONF']['layout_url'] . '/jquery_ui/images/ui-anim_basic_16x16.gif';
1996 return 'var imgSpinner = "' . $image . '";';
2000 * Helper function: Fix escaped SQL requests for MS SQL, if necessary
2003 function _DB_escapedQuery($sql)
2005 global $_DB, $_DB_dbms;
2007 if ($_DB_dbms == 'mssql') {
2008 $sql = str_replace("\\'", "''", $sql);
2009 $sql = str_replace('\\"', '"', $sql);
2010 $_DB->dbQuery($sql, 0, 1);
2017 * Helper function: Set the URL to the help section for a config option
2019 * @param string $t Template
2020 * @param string $group 'Core' or plugin name
2021 * @param string $option name of the config option
2024 function _set_ConfigHelp(&$t, $group, $option)
2029 if (!isset($docUrl)) {
2035 $configtext = PLG_getConfigTooltip($group, $option);
2036 if (empty($configtext)) {
2037 if ($group == 'Core') {
2040 if (empty($docUrl[$group])) {
2041 if ($group == 'Core') {
2042 if (!empty($GLOBALS['_CONF']['site_url']) &&
2043 !empty($GLOBALS['_CONF']['path_html'])) {
2044 $baseUrl = $GLOBALS['_CONF']['site_url'];
2045 $doclang = COM_getLanguageName();
2046 $cfg = 'docs/' . $doclang . '/config.html';
2047 if (file_exists($GLOBALS['_CONF']['path_html'] . $cfg)) {
2048 $url = $baseUrl . '/' . $cfg;
2050 $url = $baseUrl . '/docs/english/config.html';
2053 $url = 'http://www.geeklog.net/docs/english/config.html';
2055 $docUrl['Core'] = $url;
2057 $docUrl[$group] = PLG_getDocumentationUrl($group, 'config');
2059 $_SCRIPTS->setJavaScript('var glConfigDocUrl = "' . $docUrl[$group] . '";', true);
2061 $descUrl = $docUrl[$group];
2063 if (!empty($descUrl)) {
2064 if (strpos($descUrl, '#') === false) {
2065 $descUrl .= '#desc_' . $option;
2068 $t->set_var('doc_url', $descUrl);
2070 if ($this->flag_version_2 == true) {
2071 // Does hack need to be used?
2072 if (gettype($configtext) == "NULL") {
2073 $t->set_var('doc_link',
2074 '(<a href="javascript:void(0);" id="desc_' . $option . '" class="tooltip">?</a>)');
2076 $t->set_var('doc_link',
2077 '(<a href="javascript:void(0);" id="desc_' . $option . '">?</a>)');
2080 // Does hack need to be used?
2081 if (gettype($configtext) == "NULL") {
2082 $t->set_var('doc_link',
2083 '(<a href="' . $descUrl . '" target="help" class="tooltip">?</a>)');
2085 $t->set_var('doc_link',
2086 '(<a href="' . $descUrl . '" target="help">?</a>)');
2091 $t->set_var('doc_url', '');
2092 $retval = "(" . COM_getTooltip("?", $configtext, '', $option,'information') . ")";
2093 $t->set_var('doc_link', $retval);
2099 * Get features that has ft_name like 'config%'.
2100 * Used by lib-common to declare $_CONF_FT
2101 * @return array features that has ft_name like 'config%'
2103 function _get_config_features() {
2106 if ( is_null($this->conf_ft_arr) ) {
2107 $result = DB_query("SELECT ft_name FROM {$_TABLES['features']} WHERE ft_name LIKE 'config.%'");
2108 $this->conf_ft_arr = array();
2109 $nrows = DB_numRows($result);
2111 for ($i = 0; $i < $nrows; $i++) {
2112 $A = DB_fetchArray($result, false);
2113 $this->conf_ft_arr[$i] = $A['ft_name'];
2118 return $this->conf_ft_arr;