$txt['displayedValue'])),
* Note that just saying array('first', 'second') will put 0 in the SQL for 'first'.
* - A password input box. Used for passwords, no less!
* array('password', 'nameInModSettingsAndSQL', 'OptionalInputBoxWidth'),
* - A permission - for picking groups who have a permission.
* array('permissions', 'manage_groups'),
* - A BBC selection box.
* array('bbc', 'sig_bbc'),
* - A list of boards to choose from
* array('boards', 'likes_boards'),
* Note that the storage in the database is as 1,2,3,4
*
* For each option:
* - type (see above), variable name, size/possible values.
* OR make type '' for an empty string for a horizontal rule.
* - SET preinput - to put some HTML prior to the input box.
* - SET postinput - to put some HTML following the input box.
* - SET invalid - to mark the data as invalid.
* - PLUS you can override label and help parameters by forcing their keys in the array, for example:
* array('text', 'invalidlabel', 3, 'label' => 'Actual Label')
*
* Simple Machines Forum (SMF)
*
* @package SMF
* @author Simple Machines http://www.simplemachines.org
* @copyright 2013 Simple Machines and individual contributors
* @license http://www.simplemachines.org/about/smf/license.php BSD
*
* @version 2.1 Alpha 1
*/
if (!defined('SMF'))
die('No direct access...');
/**
* This is the main dispatcher. Sets up all the available sub-actions, all the tabs and selects
* the appropriate one based on the sub-action.
*
* Requires the admin_forum permission.
* Redirects to the appropriate function based on the sub-action.
*
* @uses edit_settings adminIndex.
*/
function ModifySettings()
{
global $context, $txt, $scripturl, $boarddir;
// This is just to keep the database password more secure.
isAllowedTo('admin_forum');
// Load up all the tabs...
$context[$context['admin_menu_name']]['tab_data'] = array(
'title' => $txt['admin_server_settings'],
'help' => 'serversettings',
'description' => $txt['admin_basic_settings'],
);
checkSession('request');
// The settings are in here, I swear!
loadLanguage('ManageSettings');
$context['page_title'] = $txt['admin_server_settings'];
$context['sub_template'] = 'show_settings';
$subActions = array(
'general' => 'ModifyGeneralSettings',
'database' => 'ModifyDatabaseSettings',
'cookie' => 'ModifyCookieSettings',
'security' => 'ModifyGeneralSecuritySettings',
'cache' => 'ModifyCacheSettings',
'loads' => 'ModifyLoadBalancingSettings',
'phpinfo' => 'ShowPHPinfoSettings',
);
call_integration_hook('integrate_server_settings', array(&$subActions));
// By default we're editing the core settings
$_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : 'general';
$context['sub_action'] = $_REQUEST['sa'];
// Warn the user if there's any relevant information regarding Settings.php.
if ($_REQUEST['sa'] != 'cache')
{
// Warn the user if the backup of Settings.php failed.
$settings_not_writable = !is_writable($boarddir . '/Settings.php');
$settings_backup_fail = !@is_writable($boarddir . '/Settings_bak.php') || !@copy($boarddir . '/Settings.php', $boarddir . '/Settings_bak.php');
if ($settings_not_writable)
$context['settings_message'] = '
]*>~', '', substr($config_var[1], $divPos));
$config_var[1] = substr($config_var[1], 0, $divPos);
}
$context['config_vars'][$config_var[0]] = array(
'label' => $config_var[1],
'help' => isset($config_var[5]) ? $config_var[5] : '',
'type' => $config_var[3],
'size' => empty($config_var[4]) ? 0 : $config_var[4],
'data' => isset($config_var[4]) && is_array($config_var[4]) && $config_var[3] != 'select' ? $config_var[4] : array(),
'name' => $config_var[0],
'value' => $config_var[2] == 'file' ? $smcFunc['htmlspecialchars']($$varname) : (isset($modSettings[$config_var[0]]) ? $smcFunc['htmlspecialchars']($modSettings[$config_var[0]]) : (in_array($config_var[3], array('int', 'float')) ? 0 : '')),
'disabled' => !empty($context['settings_not_writable']) || !empty($config_var['disabled']),
'invalid' => false,
'subtext' => !empty($config_var['subtext']) ? $config_var['subtext'] : $subtext,
'javascript' => '',
'preinput' => !empty($config_var['preinput']) ? $config_var['preinput'] : '',
'postinput' => !empty($config_var['postinput']) ? $config_var['postinput'] : '',
);
// If this is a select box handle any data.
if (!empty($config_var[4]) && is_array($config_var[4]))
{
// If it's associative
$config_values = array_values($config_var[4]);
if (isset($config_values[0]) && is_array($config_values[0]))
$context['config_vars'][$config_var[0]]['data'] = $config_var[4];
else
{
foreach ($config_var[4] as $key => $item)
$context['config_vars'][$config_var[0]]['data'][] = array($key, $item);
}
}
}
}
// Two tokens because saving these settings requires both saveSettings and saveDBSettings
createToken('admin-ssc');
createToken('admin-dbsc');
}
/**
* Helper function, it sets up the context for database settings.
* @todo see rev. 10406 from 2.1-requests
*
* @param array $config_vars
*/
function prepareDBSettingContext(&$config_vars)
{
global $txt, $helptxt, $context, $modSettings, $sourcedir, $smcFunc;
loadLanguage('Help');
if (isset($_SESSION['adm-save']))
{
if ($_SESSION['adm-save'] === true)
$context['saved_successful'] = true;
else
$context['saved_failed'] = $_SESSION['adm-save'];
unset($_SESSION['adm-save']);
}
$context['config_vars'] = array();
$inlinePermissions = array();
$bbcChoice = array();
$board_list = false;
foreach ($config_vars as $config_var)
{
// HR?
if (!is_array($config_var))
$context['config_vars'][] = $config_var;
else
{
// If it has no name it doesn't have any purpose!
if (empty($config_var[1]))
continue;
// Special case for inline permissions
if ($config_var[0] == 'permissions' && allowedTo('manage_permissions'))
$inlinePermissions[] = $config_var[1];
elseif ($config_var[0] == 'permissions')
continue;
if ($config_var[0] == 'boards')
$board_list = true;
// Are we showing the BBC selection box?
if ($config_var[0] == 'bbc')
$bbcChoice[] = $config_var[1];
// We need to do some parsing of the value before we pass it in.
if (isset($modSettings[$config_var[1]]))
{
switch ($config_var[0])
{
case 'select':
$value = $modSettings[$config_var[1]];
break;
case 'boards':
$value = explode(',', $modSettings[$config_var[1]]);
break;
default:
$value = $smcFunc['htmlspecialchars']($modSettings[$config_var[1]]);
}
}
else
{
// Darn, it's empty. What type is expected?
switch ($config_var[0])
{
case 'int':
case 'float':
$value = 0;
break;
case 'select':
$value = !empty($config_var['multiple']) ? serialize(array()) : '';
break;
case 'boards':
$value = array();
break;
default:
$value = '';
}
}
$context['config_vars'][$config_var[1]] = array(
'label' => isset($config_var['text_label']) ? $config_var['text_label'] : (isset($txt[$config_var[1]]) ? $txt[$config_var[1]] : (isset($config_var[3]) && !is_array($config_var[3]) ? $config_var[3] : '')),
'help' => isset($helptxt[$config_var[1]]) ? $config_var[1] : '',
'type' => $config_var[0],
'size' => !empty($config_var[2]) && !is_array($config_var[2]) ? $config_var[2] : (in_array($config_var[0], array('int', 'float')) ? 6 : 0),
'data' => array(),
'name' => $config_var[1],
'value' => $value,
'disabled' => false,
'invalid' => !empty($config_var['invalid']),
'javascript' => '',
'var_message' => !empty($config_var['message']) && isset($txt[$config_var['message']]) ? $txt[$config_var['message']] : '',
'preinput' => isset($config_var['preinput']) ? $config_var['preinput'] : '',
'postinput' => isset($config_var['postinput']) ? $config_var['postinput'] : '',
);
// If this is a select box handle any data.
if (!empty($config_var[2]) && is_array($config_var[2]))
{
// If we allow multiple selections, we need to adjust a few things.
if ($config_var[0] == 'select' && !empty($config_var['multiple']))
{
$context['config_vars'][$config_var[1]]['name'] .= '[]';
$context['config_vars'][$config_var[1]]['value'] = unserialize($context['config_vars'][$config_var[1]]['value']);
}
// If it's associative
if (isset($config_var[2][0]) && is_array($config_var[2][0]))
$context['config_vars'][$config_var[1]]['data'] = $config_var[2];
else
{
foreach ($config_var[2] as $key => $item)
$context['config_vars'][$config_var[1]]['data'][] = array($key, $item);
}
}
// Finally allow overrides - and some final cleanups.
foreach ($config_var as $k => $v)
{
if (!is_numeric($k))
{
if (substr($k, 0, 2) == 'on')
$context['config_vars'][$config_var[1]]['javascript'] .= ' ' . $k . '="' . $v . '"';
else
$context['config_vars'][$config_var[1]][$k] = $v;
}
// See if there are any other labels that might fit?
if (isset($txt['setting_' . $config_var[1]]))
$context['config_vars'][$config_var[1]]['label'] = $txt['setting_' . $config_var[1]];
elseif (isset($txt['groups_' . $config_var[1]]))
$context['config_vars'][$config_var[1]]['label'] = $txt['groups_' . $config_var[1]];
}
// Set the subtext in case it's part of the label.
// @todo Temporary. Preventing divs inside label tags.
$divPos = strpos($context['config_vars'][$config_var[1]]['label'], '
]*>~', '', substr($context['config_vars'][$config_var[1]]['label'], $divPos));
$context['config_vars'][$config_var[1]]['label'] = substr($context['config_vars'][$config_var[1]]['label'], 0, $divPos);
}
}
}
// If we have inline permissions we need to prep them.
if (!empty($inlinePermissions) && allowedTo('manage_permissions'))
{
require_once($sourcedir . '/ManagePermissions.php');
init_inline_permissions($inlinePermissions, isset($context['permissions_excluded']) ? $context['permissions_excluded'] : array());
}
if ($board_list)
{
require_once($sourcedir . '/Subs-MessageIndex.php');
$context['board_list'] = getBoardList();
}
// What about any BBC selection boxes?
if (!empty($bbcChoice))
{
// What are the options, eh?
$temp = parse_bbc(false);
$bbcTags = array();
foreach ($temp as $tag)
$bbcTags[] = $tag['tag'];
$bbcTags = array_unique($bbcTags);
$totalTags = count($bbcTags);
// The number of columns we want to show the BBC tags in.
$numColumns = isset($context['num_bbc_columns']) ? $context['num_bbc_columns'] : 3;
// Start working out the context stuff.
$context['bbc_columns'] = array();
$tagsPerColumn = ceil($totalTags / $numColumns);
$col = 0; $i = 0;
foreach ($bbcTags as $tag)
{
if ($i % $tagsPerColumn == 0 && $i != 0)
$col++;
$context['bbc_columns'][$col][] = array(
'tag' => $tag,
// @todo 'tag_' . ?
'show_help' => isset($helptxt[$tag]),
);
$i++;
}
// Now put whatever BBC options we may have into context too!
$context['bbc_sections'] = array();
foreach ($bbcChoice as $bbc)
{
$context['bbc_sections'][$bbc] = array(
'title' => isset($txt['bbc_title_' . $bbc]) ? $txt['bbc_title_' . $bbc] : $txt['bbcTagsToUse_select'],
'disabled' => empty($modSettings['bbc_disabled_' . $bbc]) ? array() : $modSettings['bbc_disabled_' . $bbc],
'all_selected' => empty($modSettings['bbc_disabled_' . $bbc]),
);
}
}
call_integration_hook('integrate_prepare_db_settings', array(&$config_vars));
createToken('admin-dbsc');
}
/**
* Helper function. Saves settings by putting them in Settings.php or saving them in the settings table.
*
* - Saves those settings set from ?action=admin;area=serversettings.
* - Requires the admin_forum permission.
* - Contains arrays of the types of data to save into Settings.php.
*
* @param $config_vars
*/
function saveSettings(&$config_vars)
{
global $boarddir, $sc, $cookiename, $modSettings, $user_settings;
global $sourcedir, $context, $cachedir;
validateToken('admin-ssc');
// Fix the darn stupid cookiename! (more may not be allowed, but these for sure!)
if (isset($_POST['cookiename']))
$_POST['cookiename'] = preg_replace('~[,;\s\.$]+~' . ($context['utf8'] ? 'u' : ''), '', $_POST['cookiename']);
// Fix the forum's URL if necessary.
if (isset($_POST['boardurl']))
{
if (substr($_POST['boardurl'], -10) == '/index.php')
$_POST['boardurl'] = substr($_POST['boardurl'], 0, -10);
elseif (substr($_POST['boardurl'], -1) == '/')
$_POST['boardurl'] = substr($_POST['boardurl'], 0, -1);
if (substr($_POST['boardurl'], 0, 7) != 'http://' && substr($_POST['boardurl'], 0, 7) != 'file://' && substr($_POST['boardurl'], 0, 8) != 'https://')
$_POST['boardurl'] = 'http://' . $_POST['boardurl'];
}
// Any passwords?
$config_passwords = array(
'db_passwd',
'ssi_db_passwd',
);
// All the strings to write.
$config_strs = array(
'mtitle', 'mmessage',
'language', 'mbname', 'boardurl',
'cookiename',
'webmaster_email',
'db_name', 'db_user', 'db_server', 'db_prefix', 'ssi_db_user',
'boarddir', 'sourcedir',
'cachedir', 'cache_accelerator', 'cache_memcached',
);
// All the numeric variables.
$config_ints = array(
'cache_enable',
);
// All the checkboxes.
$config_bools = array(
'db_persist', 'db_error_send',
'maintenance',
);
// Now sort everything into a big array, and figure out arrays and etc.
$new_settings = array();
foreach ($config_passwords as $config_var)
{
if (isset($_POST[$config_var][1]) && $_POST[$config_var][0] == $_POST[$config_var][1])
$new_settings[$config_var] = '\'' . addcslashes($_POST[$config_var][0], '\'\\') . '\'';
}
foreach ($config_strs as $config_var)
{
if (isset($_POST[$config_var]))
$new_settings[$config_var] = '\'' . addcslashes($_POST[$config_var], '\'\\') . '\'';
}
foreach ($config_ints as $config_var)
{
if (isset($_POST[$config_var]))
$new_settings[$config_var] = (int) $_POST[$config_var];
}
foreach ($config_bools as $key)
{
if (!empty($_POST[$key]))
$new_settings[$key] = '1';
else
$new_settings[$key] = '0';
}
// Save the relevant settings in the Settings.php file.
require_once($sourcedir . '/Subs-Admin.php');
updateSettingsFile($new_settings);
// Now loop through the remaining (database-based) settings.
$new_settings = array();
foreach ($config_vars as $config_var)
{
// We just saved the file-based settings, so skip their definitions.
if (!is_array($config_var) || $config_var[2] == 'file')
continue;
// Rewrite the definition a bit.
$new_settings[] = array($config_var[3], $config_var[0]);
}
// Save the new database-based settings, if any.
if (!empty($new_settings))
saveDBSettings($new_settings);
}
/**
* Helper function for saving database settings.
* @todo see rev. 10406 from 2.1-requests
*
* @param array $config_vars
*/
function saveDBSettings(&$config_vars)
{
global $sourcedir, $context, $smcFunc;
static $board_list = null;
validateToken('admin-dbsc');
$inlinePermissions = array();
foreach ($config_vars as $var)
{
if (!isset($var[1]) || (!isset($_POST[$var[1]]) && $var[0] != 'check' && $var[0] != 'permissions' && ($var[0] != 'bbc' || !isset($_POST[$var[1] . '_enabledTags']))))
continue;
// Checkboxes!
elseif ($var[0] == 'check')
$setArray[$var[1]] = !empty($_POST[$var[1]]) ? '1' : '0';
// Select boxes!
elseif ($var[0] == 'select' && in_array($_POST[$var[1]], array_keys($var[2])))
$setArray[$var[1]] = $_POST[$var[1]];
elseif ($var[0] == 'select' && !empty($var['multiple']) && array_intersect($_POST[$var[1]], array_keys($var[2])) != array())
{
// For security purposes we validate this line by line.
$options = array();
foreach ($_POST[$var[1]] as $invar)
if (in_array($invar, array_keys($var[2])))
$options[] = $invar;
$setArray[$var[1]] = serialize($options);
}
// List of boards!
elseif ($var[0] == 'boards')
{
// We just need a simple list of valid boards, nothing more.
if ($board_list === null)
{
$board_list = array();
$request = $smcFunc['db_query']('', '
SELECT id_board
FROM {db_prefix}boards');
while ($row = $smcFunc['db_fetch_row']($request))
$board_list[$row[0]] = true;
$smcFunc['db_free_result']($request);
}
$options = array();
foreach ($_POST[$var[1]] as $invar => $dummy)
if (isset($board_list[$invar]))
$options[] = $invar;
$setArray[$var[1]] = implode(',', $options);
}
// Integers!
elseif ($var[0] == 'int')
$setArray[$var[1]] = (int) $_POST[$var[1]];
// Floating point!
elseif ($var[0] == 'float')
$setArray[$var[1]] = (float) $_POST[$var[1]];
// Text!
elseif ($var[0] == 'text' || $var[0] == 'large_text')
$setArray[$var[1]] = $_POST[$var[1]];
// Passwords!
elseif ($var[0] == 'password')
{
if (isset($_POST[$var[1]][1]) && $_POST[$var[1]][0] == $_POST[$var[1]][1])
$setArray[$var[1]] = $_POST[$var[1]][0];
}
// BBC.
elseif ($var[0] == 'bbc')
{
$bbcTags = array();
foreach (parse_bbc(false) as $tag)
$bbcTags[] = $tag['tag'];
if (!isset($_POST[$var[1] . '_enabledTags']))
$_POST[$var[1] . '_enabledTags'] = array();
elseif (!is_array($_POST[$var[1] . '_enabledTags']))
$_POST[$var[1] . '_enabledTags'] = array($_POST[$var[1] . '_enabledTags']);
$setArray[$var[1]] = implode(',', array_diff($bbcTags, $_POST[$var[1] . '_enabledTags']));
}
// Permissions?
elseif ($var[0] == 'permissions')
$inlinePermissions[] = $var[1];
}
if (!empty($setArray))
updateSettings($setArray);
// If we have inline permissions we need to save them.
if (!empty($inlinePermissions) && allowedTo('manage_permissions'))
{
require_once($sourcedir . '/ManagePermissions.php');
save_inline_permissions($inlinePermissions);
}
}
/**
* Allows us to see the servers php settings
*
* - loads the settings into an array for display in a template
* - drops cookie values just in case
*/
function ShowPHPinfoSettings()
{
global $context, $txt;
$info_lines = array();
$category = $txt['phpinfo_settings'];
// get the data
ob_start();
phpinfo();
// We only want it for its body, pigs that we are
$info_lines = preg_replace('~^.*(.*).*$~', '$1', ob_get_contents());
$info_lines = explode("\n", strip_tags($info_lines, "
"));
ob_end_clean();
// remove things that could be considered sensitive
$remove = '_COOKIE|Cookie|_GET|_REQUEST|REQUEST_URI|QUERY_STRING|REQUEST_URL|HTTP_REFERER';
// put all of it into an array
foreach ($info_lines as $line)
{
if (preg_match('~(' . $remove . ')~', $line))
continue;
// new category?
if (strpos($line, '') !== false)
$category = preg_match('~(.*)~', $line, $title) ? $category = $title[1] : $category;
// load it as setting => value or the old setting local master
if (preg_match('~]+>([^<]*) | ]+>([^<]*) | ~', $line, $val))
$pinfo[$category][$val[1]] = $val[2];
elseif (preg_match('~]+>([^<]*) | ]+>([^<]*) | ]+>([^<]*) | ~', $line, $val))
$pinfo[$category][$val[1]] = array($txt['phpinfo_localsettings'] => $val[2], $txt['phpinfo_defaultsettings'] => $val[3]);
}
// load it in to context and display it
$context['pinfo'] = $pinfo;
$context['page_title'] = $txt['admin_server_settings'];
$context['sub_template'] = 'php_info';
return;
}
?> |