Bored? Looking to kill some time? Want to chat with other SMF users? Join us in IRC chat or Discord
* @version 2.0.15
* @version 2.0.16
// Initate the database connection and define some database functions to use.
// Register an error handler.
set_error_handler('error_handler');
// Register an error handler.
set_error_handler('error_handler');
// Quickly catch random exceptions.
set_exception_handler(function ($e) use ($db_show_debug)
{
if (isset($db_show_debug) && $db_show_debug === true && allowedTo('admin_forum'))
fatal_error(nl2br($e), false);
else
fatal_error($e->getMessage(), false);
});
// Quickly catch random exceptions.
set_exception_handler(function ($e) use ($db_show_debug)
{
$error_type = 'general';
// PHP 7 converts fatal errors to special Throwable types. Log them as such.
if (is_a($e, 'Error'))
$error_type = 'critical';
if (isset($db_show_debug) && $db_show_debug === true && allowedTo('admin_forum'))
{
// Only log the message; the rest (such as the stack trace) is just fluff in the log.
log_error($e->getMessage(), $error_type);
fatal_error(nl2br($e), false);
}
else
fatal_error($e->getMessage(), $error_type);
});
* @version 2.0.14
* @version 2.0.16
// Try to create the image cache directory if it doesn't exist
if (!file_exists($this->cache))
{
if (!mkdir($this->cache) || !copy(dirname($this->cache) . '/index.php', $this->cache . '/index.php'))
return false;
}
if (empty($_GET['hash']) || empty($_GET['request'])
|| ($_GET['request'] === 'http:') || ($_GET['request'] === 'https:')
if (md5($request . $this->secret) != $hash)
if (hash_hmac('sha1', $request, $this->secret) != $hash)
if (!$this->isCached($request)) {
return $this->cacheImage($request);
}
if (!$this->isCached($request))
return $this->cacheImage($request);
if (!$response) {
// Throw a 404
header('HTTP/1.0 404 Not Found');
if ($response === null)
{
// Throw a 404
header('HTTP/1.1 404 Not Found');
if (!$response) {
header('Location: ' . $request, false, 301);
}
if ($response === false)
header('Location: ' . $request, false, 301);
header('Content-type: ' . $cached['content_type']);
header('Content-length: ' . $cached['size']);
// Check whether the ETag was sent back, and cache based on that...
$eTag = '"' . substr(sha1($request) . $cached['time'], 0, 64) . '"';
if (!empty($_SERVER['HTTP_IF_NONE_MATCH']) && strpos($_SERVER['HTTP_IF_NONE_MATCH'], $eTag) !== false)
{
header('HTTP/1.1 304 Not Modified');
exit;
}
echo base64_decode($cached['body']);
// Add some caching
header('Cache-control: public');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 525600 * 60) . ' GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($cached_file)) . ' GMT');
header('ETag: ' . $eTag);
* Returns the request's hashed filepath
*
* @access public
* Returns the request's hashed filepath
*
* @access protected
* @return bool|int Whether the specified image was cached or error code when accessing
* @return bool|null Whether the specified image was cached; null if not found or not an image.
if (empty($response)) {
return false;
}
if ($responseCode != 200) {
return false;
}
if (empty($response) || $responseCode != 200)
return null;
// Version: 2.0;
// Version: 2.0.16;
$txt['admin_agreement'] = 'Show and require agreement letter when registering';
$txt['admin_agreement'] = 'Require new members to accept the registration agreement';
$txt['admin_agreement_minor_edit'] = 'This is a minor edit';
$txt['reset_agreement_desc'] = 'This will force all members to re-read and accept the registration agreement in order to continue using the forum.';
$txt['admin_privacy_policy'] = 'Require new members to accept the privacy policy';
$txt['reset_privacy_policy_desc'] = 'This will force all members to re-read and accept the privacy policy in order to continue using the forum.';
$txt['admin_agreement_info'] = 'Last updated: %1$s.';
$txt['database_prefix']
$txt['privacy_policy'] = 'Privacy Policy';
$txt['privacy_policy_desc'] = 'This privacy policy describes the promises you make to your users regarding how you will use their personal data. It is shown when a user registers an account on this forum and has to be accepted before the user can continue registration.';
// Version: 2.0;
// Version: 2.0.16;
TOPICSUBJECT: The subject of the topic being announced.
MESSAGE: The message body of the first post of the announced topic.
TOPICLINK: A link to the topic being announced.
UNSUBSCRIBELINK: Link to unsubscribe from announcements.
'subject' => 'New announcement: {TOPICSUBJECT}',
'body' => '{MESSAGE}
To unsubscribe from these announcements, login to the forum and uncheck "Receive forum announcements and important notifications by email." in your profile.
You can view the full announcement by following this link:
{TOPICLINK}
{REGARDS}',
),
'notify_boards_once_body' => array(
'subject' => 'New announcement: {TOPICSUBJECT}',
'body' => '{MESSAGE}
You can view the full announcement by following this link:
{TOPICLINK}
To unsubscribe from these announcements, follow this link:
{UNSUBSCRIBELINK}
For more control over the email notifications you receive, login to the forum and go to the Notification area in your profile.
{REGARDS}',
),
'notify_boards_once_body' => array(
http://www.simplemachines.org/community/?action=profile;u=2676
https://www.simplemachines.org/community/?action=profile;u=2676
http://www.simplemachines.org/community/?action=profile;u=63186
https://www.simplemachines.org/community/?action=profile;u=63186
http://www.simplemachines.org/community/?action=profile;u=46625
https://www.simplemachines.org/community/?action=profile;u=46625
http://www.simplemachines.org/community/?action=profile;u=72038
https://www.simplemachines.org/community/?action=profile;u=72038
// Version: 2.0;
// Version: 2.0.16;
?>
// Registration Agreement
$txt['error_no_agreement'] = 'There is no registration agreement to display!';
$txt['error_no_privacy_policy'] = 'A privacy policy has not been created for this forum.';
// Unsubscribe
$txt['unsubscribe_invalid'] = 'The unsubscribe link that brought you here does not appear to be valid.';
// Version: 2.0;
// Version: 2.0.16;
This box shows recently updated announcements from <a href="http://www.simplemachines.org/" target="_blank" class="new_win">www.simplemachines.org</a>.
This box shows recently updated announcements from <a href="https://www.simplemachines.org/" target="_blank" class="new_win">www.simplemachines.org</a>.
$helptxt['allow_disableAnnounce'] = 'This will allow users to opt out of notification of topics you announce by checking the "announce topic" checkbox when posting.';
$helptxt['allow_disableAnnounce'] = 'This will allow users to opt out of notification of topics you announce by checking the "announce topic" checkbox when posting.<br /><br />This setting must be enabled in order to comply with the rules of the <a href="https://ec.europa.eu/commission/priorities/justice-and-fundamental-rights/data-protection/2018-reform-eu-data-protection-rules_en" class="bbc_link">GDPR</a>.';
$helptxt['announcements_default'] = 'This simply controls whether the the checkbox on the registration form starts as checked or unchecked.<br /><br />This setting must be disabled in order to comply with the rules of the <a href="https://ec.europa.eu/commission/priorities/justice-and-fundamental-rights/data-protection/2018-reform-eu-data-protection-rules_en" class="bbc_link">GDPR</a>.';
$helptxt['notify_tokens'] = 'When this setting is enabled, the unsubscribe link included in every notification email includes a unique token to identify an unsubscribe request as legitimate. Without this, users must instead log into the forum to verify their identities before being allowed to unsubscribe.<br /><br />This setting must be enabled in order to comply with the rules of the <a href="https://ec.europa.eu/commission/priorities/justice-and-fundamental-rights/data-protection/2018-reform-eu-data-protection-rules_en" class="bbc_link">GDPR</a>.';
$helptxt['secureCookies'] = 'Enabling this option will force the cookies created for users on your forum to be marked as secure. Only enable this option if you are using HTTPS throughout your site as it will break cookie handling otherwise!';
$helptxt['cookie_no_auth_secret'] = 'This option forces SMF to use a weaker form of authentication for login cookies. It should only be enabled if you need backwards compatibility with login integration mods that have not yet been updated to support SMF 2.0.16 and higher.';
$helptxt['coppaAge'] = 'The value specified in this box will determine the minimum age that new members must be to be granted immediate access to the forums.
$helptxt['requireAgreement'] = 'This setting must be enabled in order to comply with the rules of the <a href="https://ec.europa.eu/commission/priorities/justice-and-fundamental-rights/data-protection/2018-reform-eu-data-protection-rules_en" class="bbc_link">GDPR</a>.';
$helptxt['requirePolicyAgreement'] = 'This setting must be enabled in order to comply with the rules of the <a href="https://ec.europa.eu/commission/priorities/justice-and-fundamental-rights/data-protection/2018-reform-eu-data-protection-rules_en" class="bbc_link">GDPR</a>.';
$helptxt['latest_support'] = 'This panel shows you some of the most common problems and questions on your server configuration. Don\'t worry, this information isn\'t logged or anything.<br /><br />If this stays as "Retrieving support information...", your computer probably cannot connect to <a href="http://www.simplemachines.org/" target="_blank" class="new_win">www.simplemachines.org</a>.';
$helptxt['latest_packages'] = 'Here you can see some of the most popular and some random packages or mods, with quick and easy installations.<br /><br />If this section doesn\'t show up, your computer probably cannot connect to <a href="http://www.simplemachines.org/" target="_blank" class="new_win">www.simplemachines.org</a>.';
$helptxt['latest_themes'] = 'This area shows a few of the latest and most popular themes from <a href="http://www.simplemachines.org/" target="_blank" class="new_win">www.simplemachines.org</a>. It may not show up properly if your computer can\'t find <a href="http://www.simplemachines.org/" target="_blank" class="new_win">www.simplemachines.org</a>, though.';
$helptxt['latest_support'] = 'This panel shows you some of the most common problems and questions on your server configuration. Don\'t worry, this information isn\'t logged or anything.<br /><br />If this stays as "Retrieving support information...", your computer probably cannot connect to <a href="https://www.simplemachines.org/" target="_blank" class="new_win">www.simplemachines.org</a>.';
$helptxt['latest_packages'] = 'Here you can see some of the most popular and some random packages or mods, with quick and easy installations.<br /><br />If this section doesn\'t show up, your computer probably cannot connect to <a href="https://www.simplemachines.org/" target="_blank" class="new_win">www.simplemachines.org</a>.';
$helptxt['latest_themes'] = 'This area shows a few of the latest and most popular themes from <a href="https://www.simplemachines.org/" target="_blank" class="new_win">www.simplemachines.org</a>. It may not show up properly if your computer can\'t find <a href="https://www.simplemachines.org/" target="_blank" class="new_win">www.simplemachines.org</a>, though.';
// Version: 2.0;
// Version: 2.0.16;
$txt['db_sqlite_warning'] = 'Only recommended for small, low volume and/or intranet-type forums
. In future versions, this will be removed!
<a href="http://www.simplemachines.org/community/index.php" target="_blank">
<a href="https://www.simplemachines.org/community/index.php" target="_blank">
[url=http://www.simplemachines.org/community/index.php]
[url=https://www.simplemachines.org/community/index.php]
http://www.simplemachines.org/about/stats.php
https://www.simplemachines.org/about/stats.php
<a href="http://www.simplemachines.org/redirect/mod_security">More information about disabling mod_security</a>';
<a href="https://www.simplemachines.org/redirect/mod_security">More information about disabling mod_security</a>';
<a href="http://www.simplemachines.org/redirect/mod_security">More information about disabling mod_security</a><br />
<a href="https://www.simplemachines.org/redirect/mod_security">More information about disabling mod_security</a><br />
please visit the <a href="http://www.simplemachines.org">Simple Machines Website</a>
please visit the <a href="https://www.simplemachines.org">Simple Machines Website</a>
<a href="http://www.simplemachines.org">Simple Machines</a> website to ensure you are installing
<a href="https://www.simplemachines.org">Simple Machines</a> website to ensure you are installing
// Version: 2.0;
// Version: 2.0.16;
// Registration form.
$txt['privacy_policy'] = 'Privacy Policy';
$txt['agreement_policy_agree'] = 'I accept the terms of the agreement and privacy policy.';
$txt['agreement_policy_agree_coppa_above'] = 'I accept the terms of the agreement and privacy policy, and I am at least %1$d years old.';
$txt['agreement_policy_agree_coppa_below'] = 'I accept the terms of the agreement and privacy policy, and I am younger than %1$d years old.';
// Version: 2.0;
// Version: 2.0.16;
$txt['disallow_sendBody']
$txt['notify_tokens'] = 'Use token-based unsubscribe links in notification emails<div class="smalltext">Allows users to unsubscribe without logging in.</div>';
$txt['core_settings_switch_on']
$txt['core_settings_item_gdpr'] = 'GDPR Compliance';
$txt['core_settings_item_gdpr_desc'] = 'Enabling this feature will configure a number of settings on your forum to make it compliant with the European Union\'s <a href="https://ec.europa.eu/commission/priorities/justice-and-fundamental-rights/data-protection/2018-reform-eu-data-protection-rules_en" class="bbc_link">General Data Protection Regulation</a>.';
$txt['core_settings_privacy_policy_warning'] = 'The GDPR requires you to have a privacy policy for your forum. After you enable this setting, you will be take to a page where you can create one.';
// Version: 2.0;
// Version: 2.0.16;
// Version: 2\.0\.15;
// Version: 2.0.16;
// Version: 2.0.14;
// Version: 2.0.16;
$txt['activate_code']
$txt['notifyboard_subscribed'] = '%1$s has been subscribed to new topic notifications for this board.';
$txt['notifyboard_unsubscribed'] = '%1$s has been unsubscribed from new topic notifications for this board.';
$txt['notifytopic_subscribed'] = '%1$s has been subscribed to new reply notifications for this topic.';
$txt['notifytopic_unsubscribed'] = '%1$s has been unsubscribed from new reply notifications for this topic.';
$txt['notify_announcements'] = 'Allow the administrators to send me important news by email';
$txt['notifyannouncements_prompt'] = 'Do you want to receive forum newsletters, announcements and important notifications by email?';
$txt['notifyannouncements_subscribed'] = '%1$s has been subscribed to forum newsletters, announcements and important notifications.';
$txt['notifyannouncements_unsubscribed'] = '%1$s has been unsubscribed from forum newsletters, announcements and important notifications.';
$txt['unsubscribe_announcements_plain'] = 'To unsubscribe from forum newsletters, announcements and important notifications, follow this link:<br />%1$s';
$txt['unsubscribe_announcements_html'] = '<span style="font-size:small"><a href="%1$s">Unsubscribe</a> from forum newsletters, announcements and important notifications.</span>';
* @version 2.0.15
* @version 2.0.16
'reservednames' =>
'policy' => array($txt['privacy_policy'], 'admin_forum'),
'http://wiki.simplemachines.org/'
'https://wiki.simplemachines.org/'
'http://wiki.simplemachines.org/smf/features2'
'https://wiki.simplemachines.org/smf/features2'
'http://wiki.simplemachines.org/smf/options2'
'https://wiki.simplemachines.org/smf/options2'
'http://wiki.simplemachines.org/smf/themes2'
'https://wiki.simplemachines.org/smf/themes2'
'http://wiki.simplemachines.org/smf/packages2'
'https://wiki.simplemachines.org/smf/packages2'
'http://www.simplemachines.org/community/'
'https://www.simplemachines.org/community/'
'http://www.simplemachines.org/redirect/english_support'
'https://www.simplemachines.org/redirect/english_support'
'http://www.simplemachines.org/redirect/international_support_boards'
'https://www.simplemachines.org/redirect/international_support_boards'
* @version 2.0.4
* @version 2.0.16
// Ignore errors if we're ignoring them or they are strict notices from PHP 5 (which cannot be solved without breaking PHP 4.)
if (error_reporting() == 0 || (defined('E_STRICT') && $error_level == E_STRICT && (empty($modSettings['enableErrorLogging']) || $modSettings['enableErrorLogging'] != 2)))
return;
// Error was suppressed with the @-operator.
if (error_reporting() == 0)
return true;
// Ignore errors that should should not be logged.
$error_match = error_reporting() & $error_level;
if (empty($error_match) || empty($modSettings['enableErrorLogging']))
return false;
// Send these notices introduced by PHP 7.2 to where the sun don't shine!
if (strpos($error_string, 'create_function()') !== false)
return true;
* @version 2.0
* @version 2.0.16
// Make sure we're dealing with integers only.
// Only proven admins can remove admins.
if ($context['group']['id'] == 1)
validateSession();
// Must be adding new members to the group...
elseif (isset($_REQUEST['add']) && (!empty($_REQUEST['toAdd']) || !empty($_REQUEST['member_add'])) && $context['group']['assignable'])
{
checkSession();
// Demand an admin password before adding new admins -- every time, no matter what.
if ($context['group']['id'] == 1)
validateSession(true);
* @version 2.0.14
* @version 2.0.16
$check = sha1($user_settings['passwd'] . $user_settings['password_salt']) == $password;
$check = hash_hmac('sha1', sha1($user_settings['passwd'] . $user_settings['password_salt']), get_auth_secret()) == $password;
if (!empty($modSettings['force_ssl']) && $image_proxy_enabled && stripos($user_settings['avatar'], 'http://') !== false)
$user_settings['avatar'] = strtr($boardurl, array('http://' => 'https://')) . '/proxy.php?request=' . urlencode($user_settings['avatar']) . '&hash=' . md5($user_settings['avatar'] . $image_proxy_secret);
if (!empty($user_settings['avatar']))
$user_settings['avatar'] = get_proxied_url($user_settings['avatar']);
global $user_profile, $modSettings, $board_info, $smcFunc;
global $boardurl, $image_proxy_enabled, $image_proxy_secret
, $user_info
if ($image_proxy_enabled && !empty($row['avatar']) && stripos($row['avatar'], 'http://') !== false)
$row['avatar'] = $boardurl . '/proxy.php?request=' . urlencode($row['avatar']) . '&hash=' . md5($row['avatar'] . $image_proxy_secret);
if (!empty($row['avatar']))
$row['avatar'] = get_proxied_url($row['avatar']);
if (!$initialize)
return;
// Perhaps we've changed the agreement or privacy policy? Only redirect if:
// 1. They're not a guest or admin
// 2. This isn't called from SSI
// 3. This isn't an XML request
// 4. They're not trying to do any of the following actions:
// 4a. View or accept the agreement and/or policy
// 4b. Login or logout
// 4c. Get a feed (RSS, ATOM, etc.)
if (!$user_info['is_guest'] && !$user_info['is_admin'] && SMF != 'SSI' && !isset($_REQUEST['xml']) && (!isset($_REQUEST['action']) || !in_array($_REQUEST['action'], array('agreement', 'acceptagreement', 'login2', 'logout', '.xml'))))
{
$agreement_lang = !empty($modSettings['agreement_updated_' . $user_info['language']]) ? $user_info['language'] : 'default';
$policy_lang = !empty($modSettings['policy_' . $user_info['language']]) ? $user_info['language'] : $language;
// Do they need to accept the latest registration agreement?
if (!empty($modSettings['requireAgreement']) && !empty($modSettings['agreement_updated_' . $agreement_lang]) && (empty($options['agreement_accepted']) || $modSettings['agreement_updated_' . $agreement_lang] > $options['agreement_accepted']))
{
$agreement_subaction = 'agreement';
}
// Do they need to consent to the latest privacy policy?
if (!empty($modSettings['requirePolicyAgreement']) && !empty($modSettings['policy_updated_' . $policy_lang]) && (empty($options['policy_accepted']) || $modSettings['policy_updated_' . $policy_lang] > $options['policy_accepted']))
{
$agreement_subaction = !empty($agreement_subaction) ? 'both' : 'policy';
}
// Send them to the right place
if (!empty($agreement_subaction))
redirectexit('action=agreement;sa=' . $agreement_subaction);
}
?>
function get_auth_secret()
{
global $auth_secret, $sourcedir;
if (empty($auth_secret))
{
// Best.
if (function_exists('random_bytes'))
$auth_secret = bin2hex(random_bytes(32));
// Equally good, if installed.
elseif (function_exists('mcrypt_create_iv'))
$auth_secret = bin2hex(mcrypt_create_iv(32));
// Good enough.
elseif (function_exists('openssl_random_pseudo_bytes'))
$auth_secret = bin2hex(openssl_random_pseudo_bytes(32));
// Less than ideal, but we're out of options.
else
$auth_secret = hash('sha256', mt_rand());
// It is important to store this in Settings.php, not the database.
require_once($sourcedir . '/Subs-Admin.php');
updateSettingsFile(array('auth_secret' => '\'' . $auth_secret . '\''));
}
return $auth_secret;
}
* @version 2.0.7
* @version 2.0.16
// This function will do the conversion later on.
$entity_replace = create_function('$string', '
$num = substr($string, 0, 1) === \'x\' ? hexdec(substr($string, 1)) : (int) $string;
return $num < 0x20 || $num > 0x10FFFF || ($num >= 0xD800 && $num <= 0xDFFF) ? \'\' : ($num < 0x80 ? \'&#\' . $num . \';\' : ($num < 0x800 ? chr(192 | $num >> 6) . chr(128 | $num & 63) : ($num < 0x10000 ? chr(224 | $num >> 12) . chr(128 | $num >> 6 & 63) . chr(128 | $num & 63) : chr(240 | $num >> 18) . chr(128 | $num >> 12 & 63) . chr(128 | $num >> 6 & 63) . chr(128 | $num & 63))));');
// Loop through all tables that need converting.
// Loop through all tables that need converting.
$insertion_variables['changes_' . $column_name] = preg_replace_callback('~&#(\d{1,7}|x[0-9a-fA-F]{1,6});~', 'fixchar__callback', $column_value);
$insertion_variables['changes_' . $column_name] = preg_replace_callback('~&#(\d{1,7}|x[0-9a-fA-F]{1,6});~', 'fixchardb__callback', $column_value);
* @version 2.0.14
* @version 2.0.16
// Force them to have it?
if (empty($context['email_force']))
// Force them to have it?
if (empty($context['email_force']) || !empty($modSettings['force_gdpr']))
// Finally - emails!
if (!empty($_POST['emails']))
// Finally - emails!
if (!empty($_POST['emails']) && empty($modSettings['force_gdpr']))
// Prepare the message for sending it as HTML
// Include an unsubscribe link if necessary.
if (!$context['send_pm'] && !empty($modSettings['notify_tokens']))
{
require_once($sourcedir . '/Notify.php');
$include_unsubscribe = true;
$_POST['message'] .= "\n\n" . '{$member.unsubscribe}';
}
$from_member = array(
'{$member.email}',
'{$member.link}',
'{$member.id}',
'{$member.name}'
,
'{$member.unsubscribe}',
$to_member = array(
$email,
// Non-members can't subscribe or unsubscribe from anything...
$unsubscribe_link = '';
!empty($_POST['send_html']) ? '<a href="mailto:' . $email . '">' . $email . '</a>' : $email,
'??',
$email
,
$unsubscribe_link,
// Replace the member-dependant variables
if (!empty($include_unsubscribe))
{
$token = createUnsubscribeToken($row['id_member'], $row['email_address'], 'announcements');
$unsubscribe_link = sprintf($txt['unsubscribe_announcements_' . (!empty($_POST['send_html']) ? 'html' : 'plain')], $scripturl . '?action=notifyannouncements;u=' . $row['id_member'] . ';token=' . $token);
}
else
$unsubscribe_link = '';
* @version 2.0
* @version 2.0.16
'agreement' => array('EditAgreement', 'admin_forum'),
'policy' => array('EditPrivacyPolicy', 'admin_forum'),
'agreement' => array(
'description' => $txt['registration_agreement_desc'],
),
'policy' => array(
'description' => $txt['privacy_policy_desc'],
),
global $txt, $context, $sourcedir, $scripturl, $smcFunc
, $modSettings
'memberGroup' => empty($_POST['group']) || !allowedTo('manage_membergroups') ? 0 : (int) $_POST['group'],
);
if (empty($_POST['requireAgreement']) && empty($modSettings['force_gdpr']))
$regOptions['theme_vars']['agreement_accepted'] = time();
if (empty($_POST['requirePolicyAgreement']) && empty($modSettings['force_gdpr']))
$regOptions['theme_vars']['policy_accepted'] = time();
global $txt, $boarddir, $context, $modSettings, $smcFunc, $settings;
global $txt, $boarddir, $context, $modSettings, $smcFunc, $user_info;
$context['force_gdpr'] = !empty($modSettings['force_gdpr']);
if (isset($_POST['agreement']))
$agreement_lang = empty($context['current_agreement']) ? 'default' : substr($context['current_agreement'], 1);
$context['agreement'] = file_exists($boarddir . '/agreement' . $context['current_agreement'] . '.txt') ? str_replace("\r", '', file_get_contents($boarddir . '/agreement' . $context['current_agreement'] . '.txt')) : '';
if (isset($_POST['agreement']) && str_replace("\r", '', $_POST['agreement']) != $context['agreement'])
updateSettings(array('requireAgreement' => !empty($_POST['requireAgreement'])));
}
$context['agreement'] = file_exists($boarddir . '/agreement' . $context['current_agreement'] . '.txt') ? htmlspecialchars(file_get_contents($boarddir . '/agreement' . $context['current_agreement'] . '.txt')) : '';
$context['warning'] = is_writable($boarddir . '/agreement' . $context['current_agreement'] . '.txt') ? '' : $txt['agreement_not_writable'];
$context['require_agreement'] = !empty($modSettings['requireAgreement']);
if (!isset($_POST['minor_edit']) || !empty($modSettings['force_gdpr']))
{
$agreement_settings['agreement_updated_' . $agreement_lang] = time();
// Writing it counts as agreeing to it, right?
$smcFunc['db_insert']('replace',
'{db_prefix}themes',
array('id_member' => 'int', 'id_theme' => 'int', 'variable' => 'string', 'value' => 'string'),
array($user_info['id'], 1, 'agreement_accepted', time()),
array('id_member', 'id_theme', 'variable')
);
logAction('agreement_updated', array('language' => $context['editable_agreements'][$context['current_agreement']]), 'admin');
logAction('agreement_accepted', array('applicator' => $user_info['id']), 'user');
updateSettings($agreement_settings);
}
$context['agreement'] = str_replace("\r", '', $_POST['agreement']);
}
$context['agreement_info'] = sprintf($txt['admin_agreement_info'], empty($modSettings['agreement_updated_' . $agreement_lang]) ? $txt['never'] : timeformat($modSettings['agreement_updated_' . $agreement_lang]));
$context['agreement'] = $smcFunc['htmlspecialchars']($context['agreement']);
$context['warning'] = is_writable($boarddir . '/agreement' . $context['current_agreement'] . '.txt') ? '' : $txt['agreement_not_writable'];
global $txt, $context, $scripturl, $modSettings, $sourcedir;
global $language, $boarddir;
// This is really quite wanting.
require_once($sourcedir . '/ManageServer.php');
// Do we have at least default versions of the agreement and privacy policy?
$agreement = file_exists($boarddir . '/agreement.' . $language . '.txt') || file_exists($boarddir . '/agreement.txt');
$policy = !empty($modSettings['policy_' . $language]);
array('check', 'send_welcomeEmail'),
'',
array('check', 'requireAgreement', 'text_label' => $txt['admin_agreement'], 'value' => !empty($modSettings['force_gdpr']) ? 1 : $modSettings['requireAgreement'], 'disabled' => !empty($modSettings['force_gdpr'])),
array('warning', empty($agreement) ? 'error_no_agreement' : ''),
array('check', 'requirePolicyAgreement', 'text_label' => $txt['admin_privacy_policy'], 'value' => !empty($modSettings['force_gdpr']) ? 1 : $modSettings['requireAgreement'], 'disabled' => !empty($modSettings['force_gdpr'])),
array('warning', empty($policy) ? 'error_no_privacy_policy' : ''),
array('text', 'coppaPhone'),
'',
array('check', 'announcements_default', 'disabled' => empty($modSettings['allow_disableAnnounce']) || !empty($modSettings['force_gdpr']), 'value' => !empty($modSettings['force_gdpr']) ? 0 : (empty($modSettings['allow_disableAnnounce']) ? 1 : !empty($modSettings['announcements_default']))),
$_POST['coppaPost'] = str_replace("\n", '<br />', empty($_POST['coppaPost']) ? '' : $_POST['coppaPost']);
// GDPR requires these settings to have certain values
if (!empty($modSettings['force_gdpr']))
{
$_POST['requireAgreement'] = 1;
$_POST['requirePolicyAgreement'] = 1;
$_POST['announcements_default'] = 0;
}
elseif (empty($modSettings['allow_disableAnnounce']))
$_POST['announcements_default'] = 1;
?>
// Sure, you can sell my personal info for profit (...or not)
function EditPrivacyPolicy()
{
global $txt, $boarddir, $context, $modSettings, $smcFunc, $user_info;
$context['force_gdpr'] = !empty($modSettings['force_gdpr']);
// By default, edit the current language's policy
$context['current_policy_lang'] = $user_info['language'];
// We need a policy for every language
getLanguages();
foreach ($context['languages'] as $lang)
{
$context['editable_policies'][$lang['filename']] = $lang['name'];
// Are we editing this one?
if (isset($_POST['policy_lang']) && $_POST['policy_lang'] == $lang['filename'])
$context['current_policy_lang'] = $lang['filename'];
}
$context['policy'] = empty($modSettings['policy_' . $context['current_policy_lang']]) ? '' : $modSettings['policy_' . $context['current_policy_lang']];
if (isset($_POST['policy']))
{
checkSession();
// Make sure there are no creepy-crawlies in it
$policy_text = $smcFunc['htmlspecialchars'](str_replace("\r", '', $_POST['policy']));
$policy_settings = array(
'policy_' . $context['current_policy_lang'] => $policy_text,
);
if ($policy_text != $context['policy'] && (!isset($_POST['minor_edit']) || !empty($modSettings['force_gdpr'])))
{
$policy_settings['policy_updated_' . $context['current_policy_lang']] = time();
// Writing it counts as agreeing to it, right?
$smcFunc['db_insert']('replace',
'{db_prefix}themes',
array('id_member' => 'int', 'id_theme' => 'int', 'variable' => 'string', 'value' => 'string'),
array($user_info['id'], 1, 'policy_accepted', time()),
array('id_member', 'id_theme', 'variable')
);
logAction('policy_updated', array('language' => $context['editable_policies'][$context['current_policy_lang']]), 'admin');
logAction('policy_accepted', array('applicator' => $user_info['id']), 'user');
}
updateSettings($policy_settings);
$context['policy'] = $policy_text;
}
$context['policy_info'] = sprintf($txt['admin_agreement_info'], empty($modSettings['policy_updated_' . $context['current_policy_lang']]) ? $txt['never'] : timeformat($modSettings['policy_updated_' . $context['current_policy_lang']]));
$context['sub_template'] = 'edit_privacy_policy';
$context['page_title'] = $txt['privacy_policy'];
}
* @version 2.0.15
* @version 2.0.16
global $context, $scripturl, $txt, $sourcedir, $modSettings, $cookiename
, $cookie_no_auth_secret
array('secureCookies', $txt['secureCookies'], 'db', 'check', false, 'secureCookies', 'disabled' => !isset($_SERVER['HTTPS']) || !(strtolower($_SERVER['HTTPS']) == 'on' || strtolower($_SERVER['HTTPS']) == '1')),
array('cookie_no_auth_secret', $txt['cookie_no_auth_secret'], 'db', 'check', false, 'cookie_no_auth_secret', 'disabled' => empty($modSettings['integrate_verify_user'])),
saveSettings($config_vars);
// If the cookie name was changed, reset the cookie.
// If this setting will be ignored anyway, disable it.
if (empty($modSettings['integrate_verify_user']) && !empty($cookie_no_auth_secret))
$_POST['cookie_no_auth_secret'] = 0;
$config_bools = array(
'db_persist', 'db_error_send',
'maintenance', 'image_proxy_enabled',
'cookie_no_auth_secret',
$url = 'http://download.simplemachines.org/
$url = 'https://download.simplemachines.org/
read_tgz_file('http://download.simplemachines.org/fetch_language.php?version=' . urlencode(strtr($forum_version, array('SMF ' => ''))) . ';fetch=' . urlencode($_GET['did']), $boarddir, false, true, $install_files)
read_tgz_file('https://download.simplemachines.org/fetch_language.php?version=' . urlencode(strtr($forum_version, array('SMF ' => ''))) . ';fetch=' . urlencode($_GET['did']), $boarddir, false, true, $install_files)
read_tgz_file('http://download.simplemachines.org/fetch_language.php?version=' . urlencode(strtr($forum_version, array('SMF ' => ''))) . ';fetch=' . urlencode($_GET['did']), null)
read_tgz_file('https://download.simplemachines.org/fetch_language.php?version=' . urlencode(strtr($forum_version, array('SMF ' => ''))) . ';fetch=' . urlencode($_GET['did']), null)
* @version 2.0.14
* @version 2.0.16
function ModifyCoreFeatures($return_config = false)
{
global $txt, $scripturl, $context, $settings, $sc, $modSettings;
global $language;
recacheSpiderNames();
'),
),
// Quick setting to toggle into GDPR compliance
'gdpr' => array(
'url' => 'action=admin;area=regcenter;sa=policy',
'settings' => array(
'force_gdpr' => 1,
// DEVELOPERS: Add values to toggle here
),
'setting_callback' => create_function('$value', '
global $modSettings;
$returnSettings = array();
if ($value)
{
$returnSettings[\'requireAgreement\'] = 1;
$returnSettings[\'requirePolicyAgreement\'] = 1;
$returnSettings[\'allow_disableAnnounce\'] = 1;
$returnSettings[\'announcements_default\'] = 0;
$returnSettings[\'notify_tokens\'] = 1;
}
return $returnSettings;
'),
'save_callback' => create_function('$value', '
global $modSettings, $language, $context;
if ($value && empty($modSettings[\'policy_\' . $language]))
redirectexit(\'action=admin;area=regcenter;sa=policy;\' . $context[\'session_var\'] . \'=\' . $context[\'session_id\']);
'),
),
if ($context['is_new_install'])
updateSettings(array('admin_features' => ''));
$context['show_privacy_policy_warning'] = empty($modSettings['policy_' . $language]);
* @version 2.0.12
* @version 2.0.16
$context['hoursdisable'] = 24;
// Actions whose log entries cannot be deleted.
$context['uneditable_actions'] = !empty($modSettings['force_gdpr']) ? array('agreement_updated', 'policy_updated') : array();
id_log = {int:moderate_log}
AND log_time < {int:twenty_four_hours_wait}
AND action NOT IN ({array_string:uneditable})
'twenty_four_hours_wait' => time() - $context['hoursdisable'] * 3600,
'moderate_log' => $context['log_type'],
'uneditable' => $context['uneditable_actions'],
AND id_action IN ({array_string:delete_actions})
AND log_time < {int:twenty_four_hours_wait}
AND action NOT IN ({array_string:uneditable})
'delete_actions' => array_unique($_POST['delete']),
'moderate_log' => $context['log_type'],
'uneditable' => $context['uneditable_actions'],
'value' => $txt['modlog_' . ($context['log_type'] == 3 ? 'admin' : 'moderation') . '_log_desc']
. (!empty($modSettings['force_gdpr']) && $context['log_type'] == 3 ? '<br />' . $txt['modlog_admin_log_gdpr_no_delete'] : '')
* @version 2.0.8
* @version 2.0.16
// First, output the xml header.
// Descriptive filenames = good
$xml_filename = array(preg_replace('/\s+/', '_', $feed_title), $_GET['sa']);
if ($_GET['sa'] === 'profile')
$xml_filename[] = 'u=' . (isset($_GET['u']) ? (int) $_GET['u'] : $user_info['id']);
if (!empty($boards))
$xml_filename[] = 'boards=' . implode(',', $boards);
elseif (!empty($board))
$xml_filename[] = 'board=' . $board;
$xml_filename[] = $xml_format;
$xml_filename = strtr(un_htmlspecialchars(implode('-', $xml_filename)), '"', '') ;
header('Content-Disposition: ' . (isset($_GET['download']) ? 'attachment' : 'inline') . '; filename="' . $xml_filename . '.xml"');
if (!empty($cdata_override))
return $data;
// Do we even need to do this?
if (strpbrk($data, '<>&') == false)
return $data;
elseif ($smcFunc['substr']($data, $pos, 1) == ']')
{
$cdata .= ']]>]<![CDATA[';
$pos++;
elseif ($smcFunc['substr']($data, $pos, 3) == ']]>')
{
$cdata .= ']]]]><![CDATA[>';
$pos = $pos + 3;
global $scripturl, $memberContext, $user_profile, $modSettings, $user_info
, $smcFunc, $language
* @version 2.0
* @version 2.0.16
*/
// Turn on/off notifications...
void AnnouncementsNotify()
- is called to turn off/on notification for newsletters, announcements, etc.
- uses the Notify template. (notify_board sub template.)
- asks for a sub action (on/off) if none was specified.
- shows a success message after it is done.
- is accessed via ?action=notifyannoucements.
void getMemberWithToken(type = '')
- verifies a subscribe/unsubscribe token, then returns some basic member info.
- the type parameter is used to indicate what sort of notification the token is for.
- shows a fatal error message to the user and dies if the token is invalid.
void createUnsubscribeToken(int memID, string email, type = '', itemID = 0)
- builds a subscribe/unsubscribe token.
- each token is unique to a member's email and to the thing they want to unsubscribe from
// Make sure they aren't a guest or something - guests can't really receive notifications!
is_not_guest();
isAllowedTo('mark_any_notify');
// Are they trying a token-based anonymous request?
if (isset($_REQUEST['u']) && isset($_REQUEST['token']))
{
$member_info = getMemberWithToken('topic');
$skipCheckSession = true;
}
// Otherwise, this is for the current user.
else
{
// Make sure they aren't a guest or something - guests can't really receive notifications!
is_not_guest();
isAllowedTo('mark_any_notify');
$member_info = $user_info;
}
LIMIT 1',
array(
'current_member' => $user_info['id'],
LIMIT 1',
array(
'current_member' => $member_info['id'],
// Set the template variables...
$context['topic_href'] =
if ($member_info['id'] !== $user_info['id'])
$context['notify_info'] = array(
'u' => $member_info['id'],
'token' => $_REQUEST['token'],
);
checkSession('get');
// Attempt to turn notifications on.
if (empty($skipCheckSession))
$smcFunc['db_insert']('ignore',
'{db_prefix}log_notify',
array('id_member' => 'int', 'id_topic' => 'int'),
array($user_info['id'], $topic),
array('id_member', 'id_topic')
);
$smcFunc['db_insert']('ignore',
'{db_prefix}log_notify',
array('id_member' => 'int', 'id_topic' => 'int'),
array($member_info['id'], $topic),
array('id_member', 'id_topic')
);
checkSession('get');
// Just turn notifications off.
if (empty($skipCheckSession))
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_notify
WHERE id_member = {int:current_member}
AND id_topic = {int:current_topic}',
array(
'current_member' => $user_info['id'],
'current_topic' => $topic,
)
);
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_notify
WHERE id_member = {int:current_member}
AND id_topic = {int:current_topic}',
array(
'current_member' => $member_info['id'],
'current_topic' => $topic,
)
);
// Send them back to the topic.
// If this request wasn't for the current user, just show a confirmation message.
if ($member_info['id'] !== $user_info['id'])
{
loadTemplate('Notify');
$context['page_title'] = $txt['notification'];
$context['sub_template'] = 'notify_pref_changed';
$context['notify_success_msg'] = sprintf($txt['notifytopic' . ($_GET['sa'] == 'on' ? '_subscribed' : '_unsubscribed')], $member_info['email']);
return;
}
// Permissions are an important part of anything ;).
is_not_guest();
isAllowedTo('mark_notify');
// Unsubscribing with a token.
if (isset($_REQUEST['u']) && isset($_REQUEST['token']))
{
$member_info = getMemberWithToken('board');
$skipCheckSession = true;
}
// No token, so try with the current user.
else
{
// Permissions are an important part of anything ;).
is_not_guest();
isAllowedTo('mark_notify');
$member_info = $user_info;
}
LIMIT 1',
array(
'current_board' => $board,
'current_member' => $user_info['id'],
LIMIT 1',
array(
'current_board' => $board,
'current_member' => $member_info['id'],
// Set the template variables...
$context['board_href'] =
if ($member_info['id'] !== $user_info['id'])
$context['notify_info'] = array(
'u' => $member_info['id'],
'token' => $_REQUEST['token'],
);
checkSession('get');
// Turn notification on. (note this just blows smoke if it's already on.)
if (empty($skipCheckSession))
$smcFunc['db_insert']('ignore',
'{db_prefix}log_notify',
array('id_member' => 'int', 'id_board' => 'int'),
array($user_info['id'], $board),
array('id_member', 'id_board')
);
$smcFunc['db_insert']('ignore',
'{db_prefix}log_notify',
array('id_member' => 'int', 'id_board' => 'int'),
array($member_info['id'], $board),
array('id_member', 'id_board')
);
checkSession('get');
// Turn notification off for this board.
if (empty($skipCheckSession))
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_notify
WHERE id_member = {int:current_member}
AND id_board = {int:current_board}',
array(
'current_board' => $board,
'current_member' => $user_info['id'],
)
);
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_notify
WHERE id_member = {int:current_member}
AND id_board = {int:current_board}',
array(
'current_board' => $board,
'current_member' => $member_info['id'],
)
);
// Back to the board!
// Probably a guest, so just show a confirmation message.
if ($member_info['id'] !== $user_info['id'])
{
loadTemplate('Notify');
$context['page_title'] = $txt['notification'];
$context['sub_template'] = 'notify_pref_changed';
$context['notify_success_msg'] = sprintf($txt['notifyboard' . ($_GET['sa'] == 'on' ? '_subscribed' : '_unsubscribed')], $member_info['email']);
return;
}
?>
function AnnouncementsNotify()
{
global $scripturl, $txt, $board, $user_info, $context, $smcFunc;
if (isset($_REQUEST['u']) && isset($_REQUEST['token']))
{
$member_info = getMemberWithToken('announcements');
$skipCheckSession = true;
}
else
{
is_not_guest();
$member_info = $user_info;
}
loadTemplate('Notify');
$context['page_title'] = $txt['notification'];
// Ask what they want to do.
if (empty($_GET['sa']))
{
$context['sub_template'] = 'notify_announcements';
if ($member_info['id'] !== $user_info['id'])
$context['notify_info'] = array(
'u' => $member_info['id'],
'token' => $_REQUEST['token'],
);
return;
}
// We don't tolerate imposters around here.
if (empty($skipCheckSession))
checkSession('get');
// Update their announcement notification preference.
updateMemberData($member_info['id'], array('notify_announcements' => $_GET['sa'] == 'on' ? '1' : '0'));
$context['sub_template'] = 'notify_pref_changed';
$context['notify_success_msg'] = sprintf($txt['notifyannouncements' . ($_GET['sa'] == 'on' ? '_subscribed' : '_unsubscribed')], $member_info['email']);
}
// Verifies the token, then returns some member info
function getMemberWithToken($type)
{
global $smcFunc, $board, $topic, $modSettings;
// Keep it sanitary, folks
$id_member = !empty($_REQUEST['u']) ? (int) $_REQUEST['u'] : 0;
// We can't do anything without these
if (empty($id_member) || empty($_REQUEST['token']))
fatal_lang_error('unsubscribe_invalid', false);
// Get the user info we need
$request = $smcFunc['db_query']('', '
SELECT id_member AS id, email_address AS email
FROM {db_prefix}members
WHERE id_member = {int:id_member}',
array(
'id_member' => $id_member,
)
);
if ($smcFunc['db_num_rows']($request) == 0)
fatal_lang_error('unsubscribe_invalid', false);
$member_info = $smcFunc['db_fetch_assoc']($request);
$smcFunc['db_free_result']($request);
// What token are we expecting?
$expected_token = createUnsubscribeToken($member_info['id'], $member_info['email'], $type, in_array($type, array('board', 'topic')) && !empty($$type) ? $$type : 0);
// Don't do anything if the token they gave is wrong
if ($_REQUEST['token'] !== $expected_token)
fatal_lang_error('unsubscribe_invalid', false);
// At this point, we know we have a legitimate unsubscribe request
return $member_info;
}
function createUnsubscribeToken($memID, $email, $type = '', $itemID = 0)
{
$token_items = implode(' ', array($memID, $email, $type, $itemID));
// When the message is public and the key is secret, an HMAC is the appropriate tool.
$token = hash_hmac('sha256', $token_items, get_auth_secret(), true);
// When using an HMAC, 80 bits (10 bytes) is plenty for security.
$token = substr($token, 0, 10);
// Use base64 (with URL-friendly characters) to make the token shorter.
return strtr(base64_encode($token), array('+' => '_', '/' => '-', '=' => ''));
}
* @version 2.0.15
* @version 2.0.16
// If we're in non-boring view do something exciting!
$context['labels'] = !empty($context['labels']) ? (array) $context['labels'] : array();
'fully_labeled' => count($context['message_labels'][$subject['id_pm']]) == count($context['labels']),
'fully_labeled' => (!empty($context['message_labels'][$subject['id_pm']]) ? count($context['message_labels'][$subject['id_pm']]) : 0) == count($context['labels']),
'fully_labeled' => count($context['message_labels'][$message['id_pm']]) == count($context['labels']),
'fully_labeled' => (!empty($context['message_labels'][$message['id_pm']]) ? count($context['message_labels'][$message['id_pm']]) : 0) == count($context['labels']),
// The link tree - gotta have this :o
// Limit the Criteria and Actions to this.
$context['rule_limiters'] = array(
'criteria' => 10,
'actions' => 10,
);
// Let's do the criteria first - it's also hardest!
$criteria = array();
$criteriaCount = 0;
// Members need to be found.
// Too many rules in this rule.
if ($criteriaCount++ >= $context['rule_limiters']['criteria'])
break;
$isOr = $_POST['rule_logic'] == 'or' ? 1 : 0;
foreach ($_POST['acttype'] as $ind => $type)
{
// Picking a valid label?
if ($type == 'lab' && (!isset($_POST['labdef'][$ind]) || !isset($context['labels'][$_POST['labdef'][$ind] - 1])))
continue;
// Record what we're doing.
$isOr = $_POST['rule_logic'] == 'or' ? 1 : 0;
$actionCount = 0;
foreach ($_POST['acttype'] as $ind => $type)
{
// Picking a valid label?
if ($type == 'lab' && (!ctype_digit((string) $ind) || !isset($_POST['labdef'][$ind]) || $_POST['labdef'][$ind] == '' || !isset($context['labels'][$_POST['labdef'][$ind] - 1])))
continue;
// Too many actions in this rule.
if ($actionCount++ >= $context['rule_limiters']['actions'])
break;
// Record what we're doing.
* @version 2.0.14
* @version 2.0.16
'TOPICLINK' => $scripturl . '?topic=' . $topic . '.0',
'UNSUBSCRIBELINK' => $scripturl . '?action=notifyannouncements',
$emaildata = loadEmailTemplate('new_announcement'
// Tokens allow people to unsubscribe without logging in
if (!empty($modSettings['notify_tokens']))
{
require_once($sourcedir . '/Notify.php');
$token = createUnsubscribeToken($row['id_member'], $row['email_address'], 'announcements');
$replacements['UNSUBSCRIBELINK'] .= ';u=' . $row['id_member'] . ';token=' . $token;
}
// Figure out which email to send off
// Make a token for the unsubscribe link
if (!empty($modSettings['notify_tokens']))
{
require_once($sourcedir . '/Notify.php');
$token = createUnsubscribeToken($rowmember['id_member'], $rowmember['email_address'], 'board', $rowmember['id_board']);
$replacements['UNSUBSCRIBELINK'] .= ';u=' . $rowmember['id_member'] . ';token=' . $token;
}
* @version 2.0.14
* @version 2.0.16
require_once($sourcedir . '/ManageAttachments.php');
require_once($sourcedir . '/Subs-Package.php');
require_once($sourcedir . '/Subs-Package.php');
$url = parse_url($_POST['userpicpersonal']);
$url = parse_url($_POST['userpicpersonal']);
$profile_vars['avatar'] = str_replace('%20', '', preg_replace('~action(?:=|%3d)(?!dlattach)~i', 'action-', $_POST['userpicpersonal']));
$mime_valid = check_mime_type($profile_vars['avatar'], 'image/', true);
// Should we check dimensions?
elseif (empty($mime_valid))
return 'bad_avatar';
$sizes = @getimagesize($_FILES['attachment']['tmp_name']);
// No size, then it's probably not a valid pic.
// No size, then it's probably not a valid pic.
$mime_valid = check_mime_type($_FILES['attachment']['tmp_name'], 'image/', true);
$sizes = empty($mime_valid) ? false : @getimagesize($_FILES['attachment']['tmp_name']);
// No size, then it's probably not a valid pic.
* @version 2.0.9
* @version 2.0.16
$buffer = preg_replace_callback('~"' . preg_quote($scripturl, '/') . '\?((?:board|topic)=[^#"]+?)(#[^"]*?)?"~', 'pathinfo_insert__preg_callback', $buffer);
}
// Be nice and try to inject session tokens into login forms since many older themes don't.
if ($user_info['is_guest'])
$buffer = preg_replace_callback(
'~(<form[^<]+action=login2(.+))</form>~iUs' . (!empty($context['utf8']) ? 'u' : ''),
function ($m) use ($context)
{
$repl = '';
if (strpos($m[0], $context['session_var']) === false)
$repl .= '<input type="hidden" name="' . $context['session_var'] . '" value="' . $context['session_id'] . '"/>';
return $m[1] . $repl . '</form>';
},
$buffer
);
* @version 2.0.14
* @version 2.0.16
$possible_bools = array_diff($possible_bools, $exclude_fields);
// Set the options needed for registration.
$possible_bools = array_diff($possible_bools, $exclude_fields);
// Set the options needed for registration.
$context['show_coppa'] = !empty($modSettings['coppaAge']);
// Under age restrictions?
if ($context['show_coppa'])
{
$context['skip_coppa'] = false;
$context['coppa_agree_above'] = sprintf($txt['agreement_agree_coppa_above'], $modSettings['coppaAge']);
$context['coppa_agree_below'] = sprintf($txt['agreement_agree_coppa_below'], $modSettings['coppaAge']);
}
$context['show_coppa'] = !empty($modSettings['coppaAge']);
$context['require_policy_agreement'] = !empty($modSettings['requirePolicyAgreement']);
// Under age restrictions?
if ($context['show_coppa'])
{
$context['skip_coppa'] = false;
$context['coppa_agree_above'] = sprintf($txt['agreement' . ($context['require_policy_agreement'] ? '_policy' : '') . '_agree_coppa_above'], $modSettings['coppaAge']);
$context['coppa_agree_below'] = sprintf($txt['agreement' . ($context['require_policy_agreement'] ? '_policy' : '') . '_agree_coppa_below'], $modSettings['coppaAge']);
}
// Any custom fields we want filled in?
require_once($sourcedir . '/Profile.php');
loadCustomFields(0, 'register');
// If you have to agree to the privacy policy, it needs to be loaded from the database.
if ($context['require_policy_agreement'])
{
// Have we got a localized one?
if (!empty($modSettings['policy_' . $user_info['language']]))
$context['policy'] = parse_bbc($modSettings['policy_' . $user_info['language']]);
elseif (!empty($modSettings['policy_' . $language]))
$context['policy'] = parse_bbc($modSettings['policy_' . $language]);
else
{
loadLanguage('Errors');
$context['policy'] = $txt['error_no_privacy_policy'];
}
}
// !!! Why isn't this a simple set operation?
// Were there any errors?
$context['registration_errors'] = array();
$context['announcements_ask'] = !empty($modSettings['force_gdpr']) || !empty($modSettings['allow_disableAnnounce']);
$context['notify_announcements'] = isset($_POST['notify_announcements']) ? (bool) $_POST['notify_announcements'] : !empty($modSettings['announcements_default']);
* @version 2.0.14
* @version 2.0.16
global $smcFunc, $modSettings, $sourcedir, $db_type
, $image_proxy_enabled, $cachedir
// Log we've done it...
// Cleanup old proxied images.
if (!empty($image_proxy_enabled) && $handle = opendir($cachedir . '/images'))
{
while (false !== ($file = readdir($handle)))
{
// Remove images older than 5 days.
if (filemtime($cachedir . '/images/' . $file) < time() - (5 * 86400))
unlink($cachedir . '/images/' . $file);
}
closedir($handle);
}
* @version 2.0.15
* @version 2.0.16
$query_where[] = 'm.body' . (in_array($regularWord, $query_params['excluded_words']) ? ' NOT' : '') . (empty($modSettings['search_match_words']) || $no_regexp ? ' LIKE ' : 'RLIKE') . '{string:complex_body_' . $count . '}';
$query_params['complex_body_' . $count++] = empty($modSettings['search_match_words']) || $no_regexp ? '%' . strtr($regularWord, array('_' => '\\_', '%' => '\\%')) . '%' : '[[:<:]]' . addcslashes(preg_replace(array('/([\[\]$.+*?|{}()])/'), array('[$1]'), $regularWord), '\\\'') . '[[:>:]]';
$query_where[] = 'm.body' . (in_array($regularWord, $query_params['excluded_words']) ? ' NOT' : '') . (empty($modSettings['search_match_words']) || $search_data['no_regexp'] ? ' LIKE ' : 'RLIKE') . '{string:complex_body_' . $count . '}';
$query_params['complex_body_' . $count++] = empty($modSettings['search_match_words']) || $search_data['no_regexp'] ? '%' . strtr($regularWord, array('_' => '\\_', '%' => '\\%')) . '%' : '[[:<:]]' . addcslashes(preg_replace(array('/([\[\]$.+*?|{}()])/'), array('[$1]'), $regularWord), '\\\'') . '[[:>:]]';
$query_where[] = 'subject NOT ' . (empty($modSettings['search_match_words']) || $no_regexp ? ' LIKE ' : 'RLIKE') . '{string:exclude_subject_phrase_' . $count . '}';
$query_params['exclude_subject_phrase_' . $count++] = empty($modSettings['search_match_words']) || $no_regexp ? '%' . strtr($phrase, array('_' => '\\_', '%' => '\\%')) . '%' : '[[:<:]]' . addcslashes(preg_replace(array('/([\[\]$.+*?|{}()])/'), array('[$1]'), $phrase), '\\\'') . '[[:>:]]';
$query_where[] = 'subject NOT ' . (empty($modSettings['search_match_words']) || $search_data['no_regexp'] ? ' LIKE ' : 'RLIKE') . '{string:exclude_subject_phrase_' . $count . '}';
$query_params['exclude_subject_phrase_' . $count++] = empty($modSettings['search_match_words']) || $search_data['no_regexp'] ? '%' . strtr($phrase, array('_' => '\\_', '%' => '\\%')) . '%' : '[[:<:]]' . addcslashes(preg_replace(array('/([\[\]$.+*?|{}()])/'), array('[$1]'), $phrase), '\\\'') . '[[:>:]]';
$query_where[] = 'subject NOT ' . (empty($modSettings['search_match_words']) || $no_regexp ? ' LIKE ' : 'RLIKE') . '{string:exclude_subject_words_' . $count . '}';
$query_params['exclude_subject_words_' . $count++] = empty($modSettings['search_match_words']) || $no_regexp ? '%' . strtr($excludedWord, array('_' => '\\_', '%' => '\\%')) . '%' : '[[:<:]]' . addcslashes(preg_replace(array('/([\[\]$.+*?|{}()])/'), array('[$1]'), $excludedWord), '\\\'') . '[[:>:]]';
$query_where[] = 'subject NOT ' . (empty($modSettings['search_match_words']) || $search_data['no_regexp'] ? ' LIKE ' : 'RLIKE') . '{string:exclude_subject_words_' . $count . '}';
$query_params['exclude_subject_words_' . $count++] = empty($modSettings['search_match_words']) || $search_data['no_regexp'] ? '%' . strtr($excludedWord, array('_' => '\\_', '%' => '\\%')) . '%' : '[[:<:]]' . addcslashes(preg_replace(array('/([\[\]$.+*?|{}()])/'), array('[$1]'), $excludedWord), '\\\'') . '[[:>:]]';
* @version 2.0.3
* @version 2.0.16
if (!empty($modSettings['securityDisable']) || (!empty($_SESSION['admin_time']) && $_SESSION['admin_time'] + $refreshTime >= time()))
if (!$force && (!empty($modSettings['securityDisable']) || (!empty($_SESSION['admin_time']) && $_SESSION['admin_time'] + $refreshTime >= time())))
* @version 2.0.15
* @version 2.0.16
fclose($fp);
}
}
// Even though on normal installations the filemtime should prevent this being used by the installer incorrectly
// it seems that there are times it might not. So let's MAKE it dump the cache.
if (function_exists('opcache_invalidate'))
opcache_invalidate(dirname(__FILE__) . '/Settings.php', true);
* @version 2.0.15
* @version 2.0.16
function setLoginCookie($cookie_length, $id, $password = '')
{
global $cookiename
, $cookie_no_auth_secret
// Get the data and path to set it on.
// Fallback option to support outdated mods. This will be removed in future versions!
$no_auth_secret = !empty($cookie_no_auth_secret) && !empty($modSettings['integrate_verify_user']);
// Ensure the cookie can't be forged.
if ($password !== '' && !$no_auth_secret)
$password = hash_hmac('sha1', $password, get_auth_secret());
* @version 2.0
* @version 2.0.16
c.id_cat, c.name AS cat_name,' : '') . '
c.id_cat, c.name AS cat_name, cat_order,' : '') . '
$categories[$row_board['id_cat']] = array(
'id' => $row_board['id_cat'],
'name' => $row_board['cat_name'],
'order' => $row_board['cat_order'],
if (!empty($boardIndexOptions['set_latest_post']) && !empty($latest_post['ref']))
$context['latest_post'] = $latest_post['ref'];
return $boardIndexOptions['include_categories'] ? $categories : $this_category;
}
if (!empty($boardIndexOptions['set_latest_post']) && !empty($latest_post['ref']))
$context['latest_post'] = $latest_post['ref'];
// Sort the categories, maintaining index association.
// Don't do it in the query, that would use a temporary table and be very slow.
if ($boardIndexOptions['include_categories'])
uasort($categories, 'cmpBoardIndex');
return $boardIndexOptions['include_categories'] ? $categories : $this_category;
}
function cmpBoardIndex($a, $b)
{
if ($a['order'] == $b['order'])
{
return 0;
}
return ($a['order'] < $b['order']) ? -1 : 1;
}
* @version 2.0.14
* @version 2.0.16
// Checck for MySQLi first...
if (function_exists('mysqli_connect'))
// Check for MySQLi first...
// !!! This driver does not work on PHP < 5.4.0.
if (function_exists('mysqli_connect') && version_compare(PHP_VERSION, '5.4') >= 0)
// Checck for MySQLi first...
if (function_exists('mysqli_connect'))
// Check for MySQLi first...
// !!! This driver does not work on PHP < 5.4.0.
// !!! This passthrough is needed for the search functions.
if (function_exists('mysqli_connect') && version_compare(PHP_VERSION, '5.4') >= 0)
'db_error' => 'mysqli_error',
'db_error' => array($this, 'show_error'),
if (isset($mysql_set_mode) && $mysql_set_mode === true)
$smcFunc['db_query']('', 'SET sql_mode = \'\', AUTOCOMMIT = 1',
array(),
false
);
return $connection;
if (isset($mysql_set_mode) && $mysql_set_mode === true)
$smcFunc['db_query']('', 'SET sql_mode = \'\', AUTOCOMMIT = 1',
array(),
$connection
);
return $connection;
global $db_unbuffered, $db_callback, $modSettings;
global $db_unbuffered, $db_persist, $db_callback, $modSettings;
/**
* Database error!
/**
* Database error!
*
* @param object $connection = null
*/
public function show_error($connection = null)
{
global $db_connection;
// Decide which connection to use
$connection = $connection === null ? $db_connection : $connection;
// This is the error message...
return mysqli_errno($connection);
}
/**
* Database error!
* @version 2.0.12
* @version 2.0.16
* @version 2.0.14
* @version 2.0.16
// If it's enabled, increase the registrations for today.
// Log their acceptance of the agreement and privacy policy, for future reference.
foreach (array('agreement_accepted', 'policy_accepted') as $key)
if (!empty($theme_vars[$key]))
logAction($key, array('applicator' => $memberID), 'user');
* @version 2.0.14
* @version 2.0.16
'type_major' => !empty($parts[6]) ? (int) $parts[5] : 0,
'type_major' => !empty($parts[5]) ? (int) $parts[5] : 0,
if (!is_writable($dir . '/' . $entryname))
$package_ftp->chmod($ftp_file, 0777);
if (!is_writable($dir . '/' . $ftp_file))
$package_ftp->chmod($ftp_file, 0777);
?>
// Checks whether a file or data retrieved by fetch_web_data has the expected MIME type.
// Returns 1 if the detected MIME type matches the pattern, 0 if it doesn't, or 2 if we can't check.
function check_mime_type($data, $type_pattern, $is_path = false)
{
// On Windows, the Fileinfo extension may not be enabled by default.
if (!extension_loaded('fileinfo'))
{
// Maybe we can load it dynamically?
$loaded = false;
$safe = ini_get('safe_mode');
$dl_ok = ini_get('enable_dl');
if (empty($safe) && !empty($dl_ok))
$loaded = @dl(((PHP_SHLIB_SUFFIX === 'dll') ? 'php_' : '') . 'fileinfo.' . PHP_SHLIB_SUFFIX);
// Oh well. We tried.
if (!$loaded)
return 2;
}
// Just some nice, simple data to analyze.
if (empty($is_path))
$mime_type = finfo_buffer(finfo_open(FILEINFO_MIME), $data);
// A file, or maybe a URL?
else
{
// Local file.
if (file_exists($data))
$mime_type = mime_content_type($data);
// URL.
elseif (url_exists($data))
$mime_type = finfo_buffer(finfo_open(FILEINFO_MIME), fetch_web_data($data));
// Non-existent files obviously don't have the right MIME type.
else
return 0;
}
return (int) @preg_match('~' . $type_pattern . '~', $mime_type);
}
* @version 2.0.14
* @version 2.0.16
if ($modSettings['mail_type'] == 1 && $modSettings['smtp_username'] != '' && $modSettings['smtp_password'] != '')
// Start off by using the stored mail server.
$helo = $modSettings['smtp_host'];
// Try and determine this server's name.
if (function_exists('gethostname') && gethostname() !== false)
$helo = gethostname();
elseif (function_exists('php_uname'))
$helo = php_uname('n');
elseif (!empty($_SERVER['SERVER_NAME']))
$helo = $_SERVER['SERVER_NAME'];
// !!! These should send the CURRENT server's name, not the mail server's!
// EHLO could be understood to mean encrypted hello...
// EHLO could be understood to mean encrypted hello...
// EHLO could be understood to mean encrypted hello...
if (server_parse('EHLO ' . $modSettings['smtp_host'], $socket, null) == '250')
// EHLO could be understood to mean encrypted hello...
if (server_parse('EHLO ' . $helo, $socket, null) == '250')
elseif (!server_parse('HELO ' . $modSettings['smtp_host'], $socket, '250'))
elseif (!server_parse('HELO ' . $helo, $socket, '250'))
// Just say "helo".
if (!server_parse('HELO ' . $modSettings['smtp_host'], $socket, '250'))
// Just say "helo".
if (!server_parse('HELO ' . $helo, $socket, '250'))
'UNSUBSCRIBELINK' => $scripturl . '?action=notify;topic=' . $row['id_topic'] . '.0',
);
// Make a token for the unsubscribe link
if (!empty($modSettings['notify_tokens']))
{
require_once($sourcedir . '/Notify.php');
$token = createUnsubscribeToken($row['id_member'], $row['email_address'], 'topic', $row['id_topic']);
$replacements['UNSUBSCRIBELINK'] .= ';u=' . $row['id_member'] . ';token=' . $token;
}
$message_type = 'notification_reply';
// Do they want the body of the message sent too?
// Make a token for the unsubscribe link
if (!empty($modSettings['notify_tokens']))
{
require_once($sourcedir . '/Notify.php');
$token = createUnsubscribeToken($row['id_member'], $row['email_address'], 'topic', $row['id_topic']);
$replacements['UNSUBSCRIBELINK'] .= ';u=' . $row['id_member'] . ';token=' . $token;
}
* @version 2.0.14
* @version 2.0.16
global $forum_copyright, $context, $boardurl,
global $forum_copyright, $context, $scripturl,
$forum_copyright = sprintf($forum_copyright, $forum_version);
// It feels icky putting this here, but it's the only good way to do this without
// requiring all custom themes to be updated in order to comply with the GDPR.
if (!empty($modSettings['force_gdpr']))
$forum_copyright .= ' | <a id="button_agreement" href="' . $scripturl . '?action=agreement"><span>' . $txt['terms_and_policies'] . '</span></a>';
<noembed><a href="$1" target="_blank" class="new_win">$1</a></noembed></object>'
<noembed><a href="$1" target="_blank" rel="noopener noreferrer" class="bbc_link bbc_flash_disabled new_win">$1</a></noembed></object>'
<noembed><a href="$1" target="_blank" class="new_win">$1</a></noembed>'),
<noembed><a href="$1" target="_blank" rel="noopener noreferrer" class="bbc_link bbc_flash_disabled new_win">$1</a></noembed>'),
'disabled_content' => '<a href="$1" target="_blank" class="new_win">$1</a>',
'disabled_content' => '<a href="$1" target="_blank" rel="noopener noreferrer" class="bbc_link bbc_flash_disabled new_win">$1</a>',
'<a href="$1" class="bbc_ftp new_win" target="_blank">$1</a>',
'<a href="$1" class="bbc_ftp new_win" target="_blank" rel="noopener noreferrer">$1</a>',
'<a href="$1" class="bbc_ftp new_win" target="_blank">',
'<a href="$1" class="bbc_ftp new_win" target="_blank" rel="noopener noreferrer">',
'content' => '<img src="$1" alt="{alt}"{width}{height} class="bbc_img resized" />',
'validate' => function (&$tag, &$data, $disabled)
{
global $image_proxy_enabled, $image_proxy_secret, $boardurl;
$data = strtr($data, array('<br>' => ''));
if (strpos($data, 'http://') !== 0 && strpos($data, 'https://') !== 0)
$data = 'http://' . $data;
if (substr($data, 0, 8) != 'https://' && $image_proxy_enabled)
$data = $boardurl . '/proxy.php?request=' . urlencode($data) . '&hash=' . md5($data . $image_proxy_secret);
},
'content' => '<img src="$1" alt="{alt}"{width}{height} class="bbc_img resized" />',
'validate' => function (&$tag, &$data, $disabled)
{
$data = strtr($data, array('<br>' => ''));
if (strpos($data, 'http://') !== 0 && strpos($data, 'https://') !== 0)
$data = 'http://' . $data;
$data = get_proxied_url($data);
},
'content' => '<img src="$1" alt="" class="bbc_img" />',
'validate' => function (&$tag, &$data, $disabled)
{
global $image_proxy_enabled, $image_proxy_secret, $boardurl;
$data = strtr($data, array('<br>' => ''));
if (strpos($data, 'http://') !== 0 && strpos($data, 'https://') !== 0)
$data = 'http://' . $data;
if (substr($data, 0, 8) != 'https://' && $image_proxy_enabled)
$data = $boardurl . '/proxy.php?request=' . urlencode($data) . '&hash=' . md5($data . $image_proxy_secret);
},
'content' => '<img src="$1" alt="" class="bbc_img" />',
'validate' => function (&$tag, &$data, $disabled)
{
$data = strtr($data, array('<br>' => ''));
if (strpos($data, 'http://') !== 0 && strpos($data, 'https://') !== 0)
$data = 'http://' . $data;
$data = get_proxied_url($data);
},
'tag' => 'url',
'type' => 'unparsed_content',
'content' => '<a href="$1" class="bbc_link" target="_blank">$1</a>',
'tag' => 'url',
'type' => 'unparsed_content',
'content' => '<a href="$1" class="bbc_link" target="_blank" rel="noopener noreferrer">$1</a>',
'tag' => 'url',
'type' => 'unparsed_equals',
'before' => '<a href="$1" class="bbc_link" target="_blank">',
'tag' => 'url',
'type' => 'unparsed_equals',
'before' => '<a href="$1" class="bbc_link" target="_blank" rel="noopener noreferrer">',
global $user_info, $user_settings, $context, $modSettings, $settings, $topic, $board, $smcFunc, $sourcedir
, $remember_old_url;
$remember_old_url = true
global $context, $settings, $modSettings, $txt, $smcFunc
, $remember_old_url
if (strpos($_SERVER['REQUEST_URL'], 'action=dlattach') === false && strpos($_SERVER['REQUEST_URL'], 'action=viewsmfile') === false)
// !!! $remember_old_url is set in writeLog().
if (!empty($remember_old_url))
if (substr($user_info['avatar']['url'], 0, 8) != 'https://' && $image_proxy_enabled)
$context['user']['avatar']['href'] = $boardurl . '/proxy.php?request=' . urlencode($user_info['avatar']['url']) . '&hash=' . md5($user_info['avatar']['url'] . $image_proxy_secret);
else
$context['user']['avatar']['href'] = $user_info['avatar']['url'];
$context['user']['avatar']['href'] = get_proxied_url($user_info['avatar']['url']);
// Start up the session URL fixer.
ob_start('ob_sessrewrite');
ob_start(function ($buffer) {
global $context;
if (!$context['user']['is_guest'])
return $buffer;
return preg_replace_callback('~(<form[^<]+action=login2(.+))</form>~iUs' . (!empty($context['utf8']) ? 'u' : ''), function($m) use ($context) {
$repl = '';
if (strpos($m[0], $context['session_var']) === false)
$repl .= '<input type="hidden" name="' . $context['session_var'] . '" value="' . $context['session_id'] . '"/>';
return $m[1] . $repl . '</form>';
}, $buffer);
});
// No point in doing anything else, if the log isn't even enabled.
if (empty($modSettings['modlog_enabled']) || !isset($log_types[$log_type]))
// No point in doing anything else, if the log isn't even enabled.
// ...except in certain special cases:
$always_log = !empty($modSettings['force_gdpr']) ? array('agreement_accepted', 'policy_accepted', 'agreement_updated', 'policy_updated') : array();
if ((empty($modSettings['modlog_enabled']) && !in_array($action, $always_log)) || !isset($log_types[$log_type]))
$modSettings['rand_seed'] = microtime() * 1000000;
$modSettings['rand_seed'] = (double) microtime() * 1000000;
// Strips out invalid html entities, replaces others with html style { codes.
/**
* Converts html entities to utf8 equivalents
* special db wrapper for mysql based on the limitation of mysql/mb3
*
* Callback function for preg_replace_callback
* Uses capture group 1 in the supplied array
* Does basic checks to keep characters inside a viewable range.
*
* @param array $matches An array of matches (relevant info should be the 2nd item in the array)
* @return string The fixed string or return the old when limitation of mysql is hit
*/
function fixchardb__callback($matches)
{
global $db_type;
if (!isset($matches[1]))
return '';
$num = $matches[1][0] === 'x' ? hexdec(substr($matches[1], 1)) : (int) $matches[1];
// it's to big for mb3?
if ($num > 0xFFFF && $db_type == 'mysql')
return $matches[0];
else
return fixchar__callback($matches);
}
?>
/**
* Gets the appropriate URL to use for images (or whatever) when using SSL
*
* The returned URL may or may not be a proxied URL, depending on the situation.
* Mods can implement alternative proxies using the 'integrate_proxy' hook.
*
* @param string $url The original URL of the requested resource
* @return string The URL to use
*/
function get_proxied_url($url)
{
global $boardurl, $image_proxy_enabled, $image_proxy_secret, $user_info;
// Only use the proxy if enabled, and never for robots
if (empty($image_proxy_enabled) || !empty($user_info['possibly_robot']))
return $url;
$parsedurl = parse_url($url);
// Don't bother with HTTPS URLs, schemeless URLs, or obviously invalid URLs
if (empty($parsedurl['scheme']) || empty($parsedurl['host']) || empty($parsedurl['path']) || $parsedurl['scheme'] === 'https')
return $url;
// We don't need to proxy our own resources
if ($parsedurl['host'] === parse_url($boardurl, PHP_URL_HOST))
return strtr($url, array('http://' => 'https://'));
// By default, use SMF's own image proxy script
$proxied_url = strtr($boardurl, array('http://' => 'https://')) . '/proxy.php?request=' . urlencode($url) . '&hash=' . hash_hmac('sha1', $url, $image_proxy_secret);
// Allow mods to easily implement an alternative proxy
call_integration_hook('integrate_proxy', array($url, &$proxied_url));
return $proxied_url;
}
* @version 2.0.13
* @version 2.0.16
if (isset($_GET['th']) && $_GET['th'] == 0)
$_GET['th'] = $modSettings['theme_guests'];
updateMemberData((int) $_REQUEST['u'], array('id_theme' => (int) $_GET['th']));
if (!empty($_GET['vrt']))
{
// An identifier of zero means that the user wants the forum default theme.
updateMemberData((int) $_REQUEST['u'], array('id_theme' => (int) $_GET['th']));
if (!empty($_GET['vrt']))
{
// Set the identifier to the forum default.
if (isset($_GET['th']) && $_GET['th'] == 0)
$_GET['th'] = $modSettings['theme_guests'];
* @version 2.0.12
* @version 2.0.16
'Michael "Oldiesmann" Eshom',
'Michele "Illori" Davis',
// Former Project Managers
'Jessica "Suki" González',
'Will "Kindred" Wagner',
'Norv',
// Lead Developer
'Jon "Sesquipedalian" Stovell',
// Developers
'John "live627" Rayes',
'Jeremy "SleePy" Darwood',
'Shawn Bulen',
// Former Developers
'Hendrik Jan "Compuart" Visser',
'Colin Schoen',
'emanuele',
$user_info['is_admin'] ? 'Matt "Grudge" Wolf': 'Grudge',
'Michael "Oldiesmann" Eshom',
'JimM',
// Lead Support Specialist
'Aleksi "Lex" Kilpinen',
// Support Specialists
'br360',
'GigaWatt',
'Will "Kindred" Wagner',
'Steve',
'ziycon',
// Former Support Specialists
'Brad "IchBin™" Grow',
// Lead Customizer
'Sami "SychO" Mazouz',
// Customizers
'Diego Andrés',
'Gary M. Gadsdon',
'Jonathan "vbgamer45" Valentin',
// Former Customizers
'Gary M. Gadsdon',
'Jason "JBlaze" Clemons',
'Gwenwyfar',
'Jason "JBlaze" Clemons',
'Jerry',
'Jonathan "vbgamer45" Valentin',
'Jerry',
'Joker™',
'Matthew "Labradoodle-360" Kerle',
'Mick.',
'NanoSector',
'nend',
'Joshua "groundup" Dickerson',
// Doc Coordinator
'Irisado',
// Doc Writers
// Former Doc Writers
'Kindred',
// Marketing Coordinator
// Marketing
// Former Marketing
'Will "Kindred" Wagner',
'Relyana',
// Lead Localizer
'Francisco "d3vcho" Domínguez',
// Localizers
'Nikola "Dzonny" Novaković',
// Former Localizers
* @version 2.0.15
* @version 2.0.16
document.getElementById("switch_" + itemID).title = itemValueHandle.value == 1 ? \'', $txt['core_settings_switch_off'], '\' : \'', $txt['core_settings_switch_on'], '\';
document.getElementById("switch_" + itemID).title = itemValueHandle.value == 1 ? \'', $txt['core_settings_switch_off'], '\' : \'', $txt['core_settings_switch_on'], '\';';
* @version 2.0.15
* @version 2.0.16
<span class="lowerframe"><span></span></span>
<input type="hidden" name="hash_passwrd" value="" />
<span class="lowerframe"><span></span></span>
<input type="hidden" name="hash_passwrd" value="" /><input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
* @version 2.0
* @version 2.0.16
function template_email_members()
{
global $context, $settings, $options, $txt, $scripturl
, $modSettings
<input type="text" name="exclude_members" id="exclude_members" value="" size="30" class="input_text" />
<span id="exclude_members_container"></span>
</dd>
</dl>
';
if (empty($modSettings['force_gdpr']))
echo '
<dt>
<strong>', $txt['admin_news_select_email'], ':</strong><br />
<span class="smalltext">', $txt['admin_news_select_email_desc'], '</span>
</dt>
';
if (empty($modSettings['force_gdpr']))
echo '
* @version 2.0
* @version 2.0.16
href="', $scripturl, '?action=notify;sa=', $context['notification_set'] ? 'off' : 'on', ';topic=', $context['current_topic'], '.', $context['start'], ';', $context['session_var'], '=', $context['session_id'], '"
href="', $scripturl, '?action=notify;sa=', $context['notification_set'] ? 'off' : 'on', ';topic=', $context['current_topic'], '.', $context['start'], ';', (!empty($context['notify_info']['token']) ? 'u=' . $context['notify_info']['u'] . ';token=' . $context['notify_info']['token'] : $context['session_var'] . '=' . $context['session_id']), '"
href="', $scripturl, '?action=notifyboard;sa=', $context['notification_set'] ? 'off' : 'on', ';board=', $context['current_board'], '.', $context['start'], ';', $context['session_var'], '=', $context['session_id'], '"
href="', $scripturl, '?action=notifyboard;sa=', $context['notification_set'] ? 'off' : 'on', ';board=', $context['current_board'], '.', $context['start'], ';', (!empty($context['notify_info']['token']) ? 'u=' . $context['notify_info']['u'] . ';token=' . $context['notify_info']['token'] : $context['session_var'] . '=' . $context['session_id']), '"
?>
function template_notify_announcements()
{
global $context, $settings, $options, $txt, $scripturl;
echo '
<div class="cat_bar">
<h3 class="catbg">
<span class="ie6_header floatleft"><img src="', $settings['images_url'], '/email_sm.gif" alt="" class="icon" />', $txt['notify'], '</span>
</h3>
</div>
<span class="upperframe"><span></span></span>
<div class="roundframe centertext">
<p>', $txt['notifyannouncements_prompt'], '</p>
<p>
<strong><a href="', $scripturl, '?action=notifyannouncements;sa=on;', (!empty($context['notify_info']['token']) ? 'u=' . $context['notify_info']['u'] . ';token=' . $context['notify_info']['token'] : $context['session_var'] . '=' . $context['session_id']), '">', $txt['yes'], '</a> - <a href="', $scripturl, '?action=notifyannouncements;sa=off;', (!empty($context['notify_info']['token']) ? 'u=' . $context['notify_info']['u'] . ';token=' . $context['notify_info']['token'] : $context['session_var'] . '=' . $context['session_id']), '">', $txt['no'], '</a></strong>
</p>
</div>
<span class="lowerframe"><span></span></span>';
}
function template_notify_pref_changed()
{
global $context, $settings, $options, $txt, $scripturl;
echo '
<div class="cat_bar">
<h3 class="catbg">
<span class="ie6_header floatleft"><img src="', $settings['images_url'], '/email_sm.gif" alt="" class="icon" />', $txt['notify'], '</span>
</h3>
</div>
<span class="upperframe"><span></span></span>
<div class="roundframe centertext">
<p>', $context['notify_success_msg'], '</p>
</div>
<span class="lowerframe"><span></span></span>';
}
* @version 2.0
* @version 2.0.16
criteriaNum++
if (criteriaNum++ >= ', $context['rule_limiters']['criteria'], ')
return false;
echo '<\' + \'/select><\' + \'/span><span id="criteriaAddHere"><\' + \'/span>\');
if (criteriaNum + 1 > ', $context['rule_limiters']['criteria'], ')
document.getElementById(\'addonjs1\').style.display = \'none\';
actionNum++
if (actionNum++ >= ', $context['rule_limiters']['actions'], ')
return false;
echo '<\' + \'/select><\' + \'/span><span id="actionAddHere"><\' + \'/span>\');
if (actionNum + 1 > ', $context['rule_limiters']['actions'], ')
document.getElementById(\'addonjs2\').style.display = \'none\';
echo '
document.getElementById("addonjs1").style.display = "";
if (count($context['rule']['criteria']) <= $context['rule_limiters']['criteria'])
echo '
document.getElementById("addonjs1").style.display = "";';
if (count($context['rule']['actions']) <= $context['rule_limiters']['actions'])
echo '
* @version 2.0
* @version 2.0.16
<form action="', $scripturl, '?action=register" method="post" accept-charset="', $context['character_set'], '" id="registration">
';
if (!empty($context['agreement']))
echo '
<p>', $context['agreement'], '</p>
</div>
<span class="lowerframe"><span></span></span>
<div>', $context['agreement'], '</div>
</div>
<span class="lowerframe"><span></span></span>';
if (!empty($context['policy']))
echo '
<div class="cat_bar">
<h3 class="catbg">', $txt['privacy_policy'], '</h3>
</div>
<span class="upperframe"><span></span></span>
<div class="roundframe">
<div>', $context['policy'], '</div>
</div>
<span class="lowerframe"><span></span></span>';
echo '
<input type="submit" name="accept_agreement" value="', $txt['agreement_agree'], '" class="button_submit" />
<input type="submit" name="accept_agreement" value="', $txt['agreement' . ($context['require_policy_agreement'] ? '_policy' : '') . '_agree'], '" class="button_submit" />
class="input_text openid_login" />
</dd>
</dl>';
}
if (!empty($context['announcements_ask']))
echo '
<dl class="register_form" id="notify_announcements_group">
<dt><strong><label for="notify_announcements">', $txt['notify_announcements'], ':</label></strong></dt>
<dd>
<input type="checkbox" name="notify_announcements" id="notify_announcements" tabindex="', $context['tabindex']++, '" class="input_check"', (!empty($context['notify_announcements']) ? ' checked="checked"' : ''), ' />
</dd>
</dl>';
<input type="checkbox" name="emailActivate" id="emailActivate_check" tabindex="', $context['tabindex']++, '"', !empty($modSettings['registration_method']) && $modSettings['registration_method'] == 1 ? ' checked="checked"' : '', ' onclick="onCheckChange();" class="input_check" />
</dd>
<dt>
<strong><label for="requireAgreement">', $txt['admin_register_require_agreement'], ':</label></strong>
</dt>
<dd>
<input type="checkbox" name="requireAgreement" id="requireAgreement_check" tabindex="', $context['tabindex']++, '"', !empty($modSettings['requireAgreement']) || !empty($modSettings['force_gdpr']) ? ' checked="checked"' : '', !empty($modSettings['force_gdpr']) ? ' disabled="disabled"' : '', ' class="input_check" />', !empty($modSettings['force_gdpr']) ? '
<input type="hidden" name="requireAgreement" value=1>' : '', '
</dd>
<dt>
<strong><label for="requirePolicyAgreement">', $txt['admin_register_require_policy'], ':</label></strong>
</dt>
<dd>
<input type="checkbox" name="requirePolicyAgreement" id="requirePolicyAgreement_check" tabindex="', $context['tabindex']++, '"', !empty($modSettings['requirePolicyAgreement']) || !empty($modSettings['force_gdpr']) ? ' checked="checked"' : '', !empty($modSettings['force_gdpr']) ? ' disabled="disabled"' : '', ' class="input_check" />', !empty($modSettings['force_gdpr']) ? '
<input type="hidden" name="requirePolicyAgreement" value=1>' : '', '
</dd>
<p>
<label for="requireAgreement"><input type="checkbox" name="requireAgreement" id="requireAgreement"', $context['require_agreement'] ? ' checked="checked"' : '', ' tabindex="', $context['tabindex']++, '" value="1" class="input_check" /> ', $txt['admin_agreement'], '.</label>
</p>
<div class="righttext">
<input type="submit" value="', $txt['save'], '" tabindex="', $context['tabindex']++, '" class="button_submit" />
<div class="information">
<span>', $context['agreement_info'], '</span>
</div>
<div class="righttext">', empty($context['force_gdpr']) ? '
<label for="minor_edit"><input type="checkbox" value="" id="minor_edit" name="minor_edit" tabindex="' . $context['tabindex']++ . '" class="input_check" /> ' . $txt['admin_agreement_minor_edit'] . '</label>' : '', '
<input type="submit" value="', $txt['save'], '" tabindex="', $context['tabindex']++, '" class="button_submit" onclick="return resetAgreementConfirm()" />
<input type="hidden" name="sa" value="agreement" />
<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
<script>
function resetAgreementConfirm()
{
if (document.getElementById("minor_edit").checked)
return true;
else if (document.getElementById(\'agreement\').value != ' . JavaScriptEscape(un_htmlspecialchars($context['agreement'])) . ')
return confirm(' . JavaScriptEscape($txt['reset_agreement_desc']) . ');
}
</script>
?>
// Form for editing the privacy policy shown to people registering to the forum.
function template_edit_privacy_policy()
{
global $context, $settings, $options, $scripturl, $txt;
// Just a big box to edit the text file ;).
echo '
<div class="cat_bar">
<h3 class="catbg">', $txt['privacy_policy'], '</h3>
</div>';
echo '
<div class="windowbg2" id="privacy_policy">
<span class="topslice"><span></span></span>
<div class="content">';
// Is there more than one language to choose from?
if (count($context['editable_policies']) > 1)
{
echo '
<div class="information">
<form action="', $scripturl, '?action=admin;area=regcenter" id="change_policy" method="post" accept-charset="', $context['character_set'], '" style="display: inline;">
<strong>', $txt['admin_agreement_select_language'], ':</strong>
<select name="policy_lang" onchange="document.getElementById(\'change_policy\').submit();" tabindex="', $context['tabindex']++, '">';
foreach ($context['editable_policies'] as $lang => $name)
echo '
<option value="', $lang, '" ', $context['current_policy_lang'] == $lang ? 'selected="selected"' : '', '>', $name, '</option>';
echo '
</select>
<div class="righttext">
<input type="hidden" name="sa" value="policy" />
<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
<input type="submit" name="change" value="', $txt['admin_agreement_select_language_change'], '" tabindex="', $context['tabindex']++, '" class="button_submit" />
</div>
</form>
</div>';
}
echo '
<form action="', $scripturl, '?action=admin;area=regcenter" method="post" accept-charset="', $context['character_set'], '">';
// Show the actual policy in an oversized text box.
echo '
<p class="policy">
<textarea cols="70" rows="20" name="policy" id="agreement">', $context['policy'], '</textarea>
</p>
<div class="information">
<span>', $context['policy_info'], '</span>
</div>
<div class="righttext">', empty($context['force_gdpr']) ? '
<label for="minor_edit"><input type="checkbox" value="" id="minor_edit" name="minor_edit" tabindex="' . $context['tabindex']++ . '" class="input_check" /> ' . $txt['admin_agreement_minor_edit'] . '</label>' : '', '
<input type="submit" value="', $txt['save'], '" tabindex="', $context['tabindex']++, '" class="button_submit" onclick="return resetPolicyConfirm()" />
<input type="hidden" name="policy_lang" value="', $context['current_policy_lang'], '" />
<input type="hidden" name="sa" value="policy" />
<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
<script>
function resetPolicyConfirm()
{
if (document.getElementById("minor_edit").checked)
return true;
else if (document.getElementById(\'agreement\').value != ' . JavaScriptEscape(un_htmlspecialchars($context['policy'])) . ')
return confirm(' . JavaScriptEscape($txt['reset_privacy_policy_desc']) . ');
}
</script>
</div>
</form>
</div>
<span class="botslice"><span></span></span>
</div>
<br class="clear" />';
}
* @version 2.0
* @version 2.0.16
function template_wap_boardindex()
{
global $context, $settings, $options, $scripturl
, $txt
<p><a href="', $scripturl, '?board=', $board['id'], '.0;wap">', $board['name'], '</a><br /></p>';
echo '
</card>';
}
echo '
<card>
<p', $txt['wireless_options'], '</p>';
if ($context['user']['is_guest'])
echo '
<p><a href="', $scripturl, '?action=login;wap">', $txt['wireless_options_login'], '</a></p>';
else
{
if ($context['allow_pm'])
echo '
<p><a href="', $scripturl, '?action=pm;wap">', empty($context['user']['unread_messages']) ? $txt['wireless_pm_inbox'] : sprintf($txt['wireless_pm_inbox_new'], $context['user']['unread_messages']), '</a></p>';
echo '
<p><a href="', $scripturl, '?action=unread;wap">', $txt['wireless_recent_unread_posts'], '</a></p>
<p><a href="', $scripturl, '?action=unreadreplies;wap">', $txt['wireless_recent_unread_replies'], '</a></p>
<p><a href="', $scripturl, '?action=logout;', $context['session_var'], '=', $context['session_id'], ';wap">', $txt['wireless_options_logout'], '</a></p>
</card>';
}
<postfield name="user" value="$user" />
<postfield name="passwrd" value="$passwrd" />
<postfield name="cookieneverexp" value="1" />
<postfield name="', $context['session_var'], '" value="', $context['session_id'], '" />
var n, sReturn = '';
for (var i = 0, iTextLen = this.length; i < iTextLen; i++)
{
n = this.charCodeAt(i);
if (n < 128)
sReturn += String.fromCharCode(n)
else if (n < 2048)
sReturn += String.fromCharCode(192 | n >> 6) + String.fromCharCode(128 | n & 63);
else if (n < 65536)
sReturn += String.fromCharCode(224 | n >> 12) + String.fromCharCode(128 | n >> 6 & 63) + String.fromCharCode(128 | n & 63);
else
sReturn += String.fromCharCode(240 | n >> 18) + String.fromCharCode(128 | n >> 12 & 63) + String.fromCharCode(128 | n >> 6 & 63) + String.fromCharCode(128 | n & 63);
}
return sReturn;
return this;
auto_1.php |
This file should not be able to execute standalone.You may have to run the following queries manually.
Query: Select <?php
|
Move the included file "Agreement.php" to "./Sources". |
Move the included file "Agreement.template.php" to "./Themes/default". |
Move the included file "Agreement.english.php" to "./Themes/default/languages". |
Move the included file "feature_gdpr.png" to "./Themes/default/images/admin". |