Update to SMF 1.1.2 - Installation Instructions for 1.1.1

Update to SMF 1.1.2
This patch file will update your forum to SMF 1.1.2.

File Edits ALT + Click to collapse all the operations

./index.php

Find: Select
$forum_version = 'SMF 1.1.1';
Replace With: Select
$forum_version = 'SMF 1.1.2';
Find: Select
* Software Version: SMF 1.1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *

./Sources/Display.php

Find: Select
* Software Version: SMF 1.1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
header('Pragma: ');
header('Cache-Control: max-age=' . (525600 * 60) . ', private');
Replace With: Select
header('Pragma: ');
Find: Select
if (empty($modSettings['enableCompressedOutput']) || filesize($filename) > 4194304)
header('Content-Length: ' . filesize($filename));
Add Before: Select
// If this has an "image extension" - but isn't actually an image - then ensure it isn't cached cause of silly IE.
if (!isset($_REQUEST['image']) && in_array(substr($real_filename, -4), array('.gif', '.jpg', '.bmp', '.png', 'jpeg', 'tiff')))
header('Cache-Control: no-cache');
else
header('Cache-Control: max-age=' . (525600 * 60) . ', private');

./Sources/Load.php

Find: Select
* Software Version: SMF 1.1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
// Preg_replace can handle complex characters only for higher PHP versions.
$space_chars = $utf8 ? (@version_compare(PHP_VERSION, '4.3.3') != -1 ? '\x{C2A0}\x{E28080}-\x{E2808F}\x{E280AF}\x{E2809F}\x{E38080}\x{EFBBBF}' : sprintf('%c%c%c%c%c-%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c', 0xC2, 0xA0, 0xE2, 0x80, 0x80, 0xE2, 0x80, 0x8F, 0xE2, 0x80, 0xAF, 0xE2, 0x80, 0x9F, 0xE3, 0x80, 0x80, 0xEF, 0xBB, 0xBF)) : '\xA0';
Replace With: Select
// Preg_replace can handle complex characters only for higher PHP versions.
$space_chars = $utf8 ? (@version_compare(PHP_VERSION, '4.3.3') != -1 ? '\x{A0}\x{2000}-\x{200F}\x{201F}\x{202F}\x{3000}\x{FEFF}' : pack('C*', 0xC2, 0xA0, 0xE2, 0x80, 0x80) . '-' . pack('C*', 0xE2, 0x80, 0x8F, 0xE2, 0x80, 0x9F, 0xE2, 0x80, 0xAF, 0xE2, 0x80, 0x9F, 0xE3, 0x80, 0x80, 0xEF, 0xBB, 0xBF)) : '\xA0';
Find: Select
$username = $user_settings['memberName'];
Replace With: Select
elseif (empty($_SESSION['ID_MSG_LAST_VISIT']))
$_SESSION['ID_MSG_LAST_VISIT'] = $user_settings['ID_MSG_LAST_VISIT'];

$username = $user_settings['memberName'];

./Sources/LogInOut.php

Find: Select
* Software Version: SMF 1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
// Whichever encryption it was using, let's make it use SMF's now ;).
Replace With: Select
// SMF's sha1 function can give a funny result on Linux (Not our fault!). If we've now got the real one let the old one be valid!
require_once($sourcedir . '/Subs-Compat.php');
$other_passwords[] = sha1_smf(strtolower($user_settings['memberName']) . un_htmlspecialchars(stripslashes($_REQUEST['passwrd'])));

// Whichever encryption it was using, let's make it use SMF's now ;).

./Sources/ManageBoards.php

Find: Select
* Software Version: SMF 1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
foreach ($context['board_order'] as $board)
if ($board['is_child'] == false && $board['selected'] == false)
{
$context['can_move_children'] = true;
$context['children'] = $boards[$_REQUEST['boardid']]['tree']['children'];
}
Replace With: Select
$context['children'] = $boards[$_REQUEST['boardid']]['tree']['children'];
foreach ($context['board_order'] as $board)
if ($board['is_child'] == false && $board['selected'] == false)
$context['can_move_children'] = true;

./Sources/ManageMembergroups.php

Find: Select
* Software Version: SMF 1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
$_POST['copyperm'] = (int) $_POST['copyperm'];
Replace With: Select
$_POST['copyperm'] = (int) $_POST['copyperm'];

// Don't allow copying of a real priviledged person!
require_once($sourcedir . '/ManagePermissions.php');
loadIllegalPermissions();
Find: Select
$setString .= "
($ID_GROUP, '$row[permission]', $row[addDeny]),";
Replace With: Select
if (empty($context['illegal_permissions']) || !in_array($row['permission'], $context['illegal_permissions']))
$setString .= "
($ID_GROUP, '$row[permission]', $row[addDeny]),";

./Sources/ManageNews.php

Find: Select
* Software Version: SMF 1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
WHERE emailAddress IN ('" . implode("', '", $send_list) . "')", __FILE__, __LINE__);
Replace With: Select
WHERE emailAddress IN ('" . implode("', '", addslashes__recursive($send_list)) . "')", __FILE__, __LINE__);

./Sources/ManagePermissions.php

Find: Select
* Software Version: SMF 1.1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
function SetQuickGroups()
{
global $db_prefix;

checkSession();
Replace With: Select
function SetQuickGroups()
{
global $db_prefix, $context;

checkSession();

loadIllegalPermissions();
Find: Select
foreach ($target_perm as $perm => $addDeny)
$insert_string .= "('$perm', $group_id, $addDeny),";
Replace With: Select
foreach ($target_perm as $perm => $addDeny)
{
// No dodgy permissions please!
if (!empty($context['illegal_permissions']) && in_array($perm, $context['illegal_permissions']))
continue;

$insert_string .= "('$perm', $group_id, $addDeny),";
}
Find: Select
WHERE ID_GROUP IN (" . implode(', ', $_POST['group']) . ")", __FILE__, __LINE__);
Replace With: Select
WHERE ID_GROUP IN (" . implode(', ', $_POST['group']) . ")
" . (empty($context['illegal_permissions']) ? '' : ' AND permission NOT IN (' . implode(', ', $context['illegal_permissions']) . ')'), __FILE__, __LINE__);
Find: Select
WHERE ID_GROUP IN (" . implode(', ', $_POST['group']) . ")
AND permission = '$permission'", __FILE__, __LINE__);
Replace With: Select
WHERE ID_GROUP IN (" . implode(', ', $_POST['group']) . ")
AND permission = '$permission'
" . (empty($context['illegal_permissions']) ? '' : ' AND permission NOT IN (' . implode(', ', $context['illegal_permissions']) . ')'), __FILE__, __LINE__);
Find: Select
// Add a permission (either 'set' or 'deny').
else
{
$addDeny = $_POST['add_remove'] == 'add' ? '1' : '0';
if ($permissionType == 'membergroup')
db_query("
REPLACE INTO {$db_prefix}permissions
(permission, ID_GROUP, addDeny)
VALUES
('$permission', " . implode(", $addDeny),
('$permission', ", $_POST['group']) . ", $addDeny)", __FILE__, __LINE__);
// Board permissions go into the other table.
else
db_query("
REPLACE INTO {$db_prefix}board_permissions
(permission, ID_GROUP, ID_BOARD, addDeny)
VALUES
('$permission', " . implode(", $_REQUEST[boardid], $addDeny),
('$permission', ", $_POST['group']) . ", $_REQUEST[boardid], $addDeny)", __FILE__, __LINE__);
}
Replace With: Select
// Add a permission (either 'set' or 'deny').
else
{
$addDeny = $_POST['add_remove'] == 'add' ? '1' : '0';
if ($permissionType == 'membergroup' && (empty($context['illegal_permissions']) || !in_array($permission, $context['illegal_permissions'])))
db_query("
REPLACE INTO {$db_prefix}permissions
(permission, ID_GROUP, addDeny)
VALUES
('$permission', " . implode(", $addDeny),
('$permission', ", $_POST['group']) . ", $addDeny)", __FILE__, __LINE__);
// Board permissions go into the other table.
elseif ($permissionType != 'membergroup')
db_query("
REPLACE INTO {$db_prefix}board_permissions
(permission, ID_GROUP, ID_BOARD, addDeny)
VALUES
('$permission', " . implode(", $_REQUEST[boardid], $addDeny),
('$permission', ", $_POST['group']) . ", $_REQUEST[boardid], $addDeny)", __FILE__, __LINE__);
}
Find: Select
function ModifyMembergroup2()
{
global $db_prefix, $modSettings;

// Never do this if there are no local permissions to be set.
if (empty($modSettings['permission_enable_by_board']) && !empty($_REQUEST['boardid']))
redirectexit('action=permissions');

checkSession();
Replace With: Select
function ModifyMembergroup2()
{
global $db_prefix, $modSettings, $context;

// Never do this if there are no local permissions to be set.
if (empty($modSettings['permission_enable_by_board']) && !empty($_REQUEST['boardid']))
redirectexit('action=permissions');

checkSession();

loadIllegalPermissions();
Find: Select
foreach ($perm_array as $permission => $value)
if ($value == 'on' || $value == 'deny')
$givePerms[$perm_type][] = "$permission', " . ($value == 'deny' ? '0' : '1');
Replace With: Select
foreach ($perm_array as $permission => $value)
if ($value == 'on' || $value == 'deny')
{
// Don't allow people to escalate themselves!
if (!empty($context['illegal_permissions']) && in_array($permission, $context['illegal_permissions']))
continue;

$givePerms[$perm_type][] = "$permission', " . ($value == 'deny' ? '0' : '1');
}
Find: Select
DELETE FROM {$db_prefix}permissions
WHERE ID_GROUP = $_GET[group]", __FILE__, __LINE__);
Replace With: Select
DELETE FROM {$db_prefix}permissions
WHERE ID_GROUP = $_GET[group]
" . (empty($context['illegal_permissions']) ? '' : ' AND permission NOT IN (' . implode(', ', $context['illegal_permissions']) . ')'), __FILE__, __LINE__);
Find: Select
function setPermissionLevel($level, $group, $board = 'null')
{
global $db_prefix;
Replace With: Select
function setPermissionLevel($level, $group, $board = 'null')
{
global $db_prefix, $context;

loadIllegalPermissions();
Find: Select
// Setting group permissions.
if ($board === 'null' && $group !== 'null')
{
$group = (int) $group;

if (empty($groupLevels['global'][$level]))
return;

db_query("
DELETE FROM {$db_prefix}permissions
WHERE ID_GROUP = $group", __FILE__, __LINE__);
Replace With: Select
// Make sure we're not granting someone too many permissions!
foreach ($groupLevels['global'][$level] as $k => $permission)
if (!empty($context['illegal_permissions']) && in_array($permission, $context['illegal_permissions']))
unset($groupLevels['global'][$level][$k]);

// Setting group permissions.
if ($board === 'null' && $group !== 'null')
{
$group = (int) $group;

if (empty($groupLevels['global'][$level]))
return;

db_query("
DELETE FROM {$db_prefix}permissions
WHERE ID_GROUP = $group
" . (empty($context['illegal_permissions']) ? '' : ' AND permission NOT IN (' . implode(', ', $context['illegal_permissions']) . ')'), __FILE__, __LINE__);
Find: Select
// No permissions? Not a great deal to do here.
if (!allowedTo('manage_permissions'))
return;

$insertRows = '';
foreach ($permissions as $permission)
{
if (!isset($_POST[$permission]))
continue;

foreach ($_POST[$permission] as $ID_GROUP => $value)
{
if (in_array($value, array('on', 'deny')))
$insertRows .= ', (' . (int) $ID_GROUP . ", '$permission', " . ($value == 'on' ? '1' : '0') . ')';
}
}

// Remove the old permissions...
db_query("
DELETE FROM {$db_prefix}permissions
WHERE permission IN ('" . implode("', '", $permissions) . "')", __FILE__, __LINE__);
Replace With: Select
// No permissions? Not a great deal to do here.
if (!allowedTo('manage_permissions'))
return;

// Check they can't do certain things.
loadIllegalPermissions();

$insertRows = '';
foreach ($permissions as $permission)
{
if (!isset($_POST[$permission]))
continue;

foreach ($_POST[$permission] as $ID_GROUP => $value)
{
if (in_array($value, array('on', 'deny')) && (empty($context['illegal_permissions']) || !in_array($permission, $context['illegal_permissions'])))
$insertRows .= ', (' . (int) $ID_GROUP . ", '$permission', " . ($value == 'on' ? '1' : '0') . ')';
}
}

// Remove the old permissions...
db_query("
DELETE FROM {$db_prefix}permissions
WHERE permission IN ('" . implode("', '", $permissions) . "')
" . (empty($context['illegal_permissions']) ? '' : ' AND permission NOT IN (' . implode(', ', $context['illegal_permissions']) . ')'), __FILE__, __LINE__);
Find: Select
?>
Replace With: Select
// Load permissions someone cannot grant.
function loadIllegalPermissions()
{
global $context;

$context['illegal_permissions'] = array();
if (!allowedTo('admin_forum'))
$context['illegal_permissions'][] = 'admin_forum';
if (!allowedTo('manage_membergroups'))
$context['illegal_permissions'][] = 'manage_membergroups';
if (!allowedTo('manage_permissions'))
$context['illegal_permissions'][] = 'manage_permissions';
}

?>

./Sources/ManageRegistration.php

Find: Select
* Software Version: SMF 1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
'disable_visual_verification' => isset($_POST['disable_visual_verification']) ? 1 : 0,
Replace With: Select
'disable_visual_verification' => isset($_POST['visual_verification_type']) ? (int) $_POST['visual_verification_type'] : 0,
Find: Select
$context['coppaPost'] = !empty($modSettings['coppaPost']) ? preg_replace('~<br(?: /)?' . '>~', "\n", $modSettings['coppaPost']) : '';
Replace With: Select
$context['coppaPost'] = !empty($modSettings['coppaPost']) ? preg_replace('~<br(?: /)?' . '>~', "\n", $modSettings['coppaPost']) : '';

// Generate a sample registration image.
$context['use_graphic_library'] = in_array('gd', get_loaded_extensions());
$context['verificiation_image_href'] = $scripturl . '?action=verificationcode;rand=' . md5(rand());

$character_range = array_merge(range('A', 'H'), array('K', 'M', 'N', 'P'), range('R', 'Z'));
$_SESSION['visual_verification_code'] = '';
for ($i = 0; $i < 5; $i++)
$_SESSION['visual_verification_code'] .= $character_range[array_rand($character_range)];

./Sources/ManageSearch.php

Find: Select
* Software Version: SMF 1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
elseif (!empty($_REQUEST['sa']) && $_REQUEST['sa'] == 'removecustom' && !empty($modSettings['search_custom_index_config']))
Replace With: Select
elseif (!empty($_REQUEST['sa']) && $_REQUEST['sa'] == 'removecustom')

./Sources/Packages.php

Find: Select
* Software Version: SMF 1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
elseif ($action['type'] == 'error')
$context['has_failure'] = true;
Replace With: Select
// Don't show redirects.
elseif ($action['type'] == 'redirect')
continue;
elseif ($action['type'] == 'error')
$context['has_failure'] = true;

./Sources/PersonalMessage.php

Find: Select
* Software Version: SMF 1.1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
$character_range = array_merge(range('A', 'H'), array('K', 'M', 'N', 'P', 'R'), range('T', 'Y'));
Replace With: Select
$character_range = array_merge(range('A', 'H'), array('K', 'M', 'N', 'P'), range('R', 'Z'));
Find: Select
return messagePostError(array(), htmlspecialchars($_REQUEST['to']), htmlspecialchars($_REQUEST['bcc']));
Replace With: Select
return messagePostError(array(), $func['htmlspecialchars']($_REQUEST['to']), $func['htmlspecialchars']($_REQUEST['bcc']));
Find: Select
if (!empty($modSettings['max_pm_recipients']) && count($recipients['to']) + count($recipients['bcc']) > $modSettings['max_pm_recipients'] && !AllowedTo(array('moderate_forum', 'send_mail', 'admin_forum')))
Replace With: Select
if (!empty($modSettings['max_pm_recipients']) && count($recipients['to']) + count($recipients['bcc']) > $modSettings['max_pm_recipients'] && !allowedTo(array('moderate_forum', 'send_mail', 'admin_forum')))
Find: Select
$input[$rec_type][$i] = un_htmlspecialchars($member);
$context['send_log']['failed'][] = sprintf($txt['pm_error_user_not_found'], $input[$rec_type][$i]);
Replace With: Select
$context['send_log']['failed'][] = sprintf($txt['pm_error_user_not_found'], $input[$rec_type][$i]);

./Sources/Post.php

Find: Select
* Software Version: SMF 1.1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
// Censor the message!
censorText($row['body']);

// Remove special formatting we don't want anymore.
un_preparsecode($row['body']);
$row['body'] = preg_replace('~<br(?: /)?' . '>~i', "\n", $row['body']);
Replace With: Select
// Remove special formatting we don't want anymore.
$row['body'] = un_preparsecode($row['body']);

// Censor the message!
censorText($row['body']);

$row['body'] = preg_replace('~<br(?: /)?' . '>~i', "\n", $row['body']);
Find: Select
m.ID_MSG, m.ID_MEMBER, m.posterTime, m.subject, m.smileysEnabled, m.body
Replace With: Select
m.ID_MSG, m.ID_MEMBER, m.posterTime, m.subject, m.smileysEnabled, m.body,
modifiedTime, modifiedName
Find: Select
// Changing the first subject updates other subjects to 'Re: new_subject'.
Replace With: Select
// If we didn't change anything this time but had before put back the old info.
if (!isset($msgOptions['modify_time']) && !empty($row['modifiedTime']))
{
$msgOptions['modify_time'] = $row['modifiedTime'];
$msgOptions['modify_name'] = $row['modifiedName'];
}

// Changing the first subject updates other subjects to 'Re: new_subject'.

./Sources/Profile.php

Find: Select
* Software Version: SMF 1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
if (trim($_POST['realName']) == '')
$post_errors[] = 'no_name';
Replace With: Select
if (trim($_POST['realName']) == '')
$post_errors[] = 'no_name';
elseif ($func['strlen']($_POST['realName']) > 60)
$post_errors[] = 'name_too_long';
Find: Select
$context['can_edit_ban'] = AllowedTo('manage_bans');
Replace With: Select
$context['can_edit_ban'] = allowedTo('manage_bans');

./Sources/Register.php

Find: Select
* Software Version: SMF 1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
$context['visual_verification'] = empty($modSettings['disable_visual_verification']);
Replace With: Select
$context['visual_verification'] = empty($modSettings['disable_visual_verification']) || $modSettings['disable_visual_verification'] != 1;
Find: Select
if (empty($modSettings['disable_visual_verification']) && (empty($_REQUEST['visual_verification_code']) || strtoupper($_REQUEST['visual_verification_code']) !== $_SESSION['visual_verification_code']))
{
$_SESSION['visual_errors'] = isset($_SESSION['visual_errors']) ? $_SESSION['visual_errors'] + 1 : 1;
if ($_SESSION['visual_errors'] > 3)
Replace With: Select
if ((empty($modSettings['disable_visual_verification']) || $modSettings['disable_visual_verification'] != 1) && (empty($_REQUEST['visual_verification_code']) || strtoupper($_REQUEST['visual_verification_code']) !== $_SESSION['visual_verification_code']))
{
$_SESSION['visual_errors'] = isset($_SESSION['visual_errors']) ? $_SESSION['visual_errors'] + 1 : 1;
if ($_SESSION['visual_errors'] > 3 && isset($_SESSION['visual_verification_code']))
Find: Select
if (trim($_POST['realName']) != '' && !isReservedName($_POST['realName'], $memID))
Replace With: Select
if (trim($_POST['realName']) != '' && !isReservedName($_POST['realName'], $memID) && $func['strlen']($_POST['realName']) <= 60)
Find: Select
// Visual verification needs to be enabled.
if (!empty($modSettings['disable_visual_verification']))
header('HTTP/1.1 401 Not Authorised');

// Somehow no code was generated or the session was lost.
elseif (empty($_SESSION['visual_verification_code']))
Replace With: Select
// Somehow no code was generated or the session was lost.
if (empty($_SESSION['visual_verification_code']))

./Sources/Reminder.php

Find: Select
* Software Version: SMF 1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
global $db_prefix, $context, $txt, $modSettings;
Replace With: Select
global $db_prefix, $context, $txt, $modSettings, $sourcedir;
Find: Select
SELECT validation_code, memberName
Replace With: Select
SELECT validation_code, memberName, emailAddress
Find: Select
list ($realCode, $username) = mysql_fetch_row($request);
mysql_free_result($request);
Replace With: Select
list ($realCode, $username, $email) = mysql_fetch_row($request);
mysql_free_result($request);

// Is the password actually valid?
require_once($sourcedir . '/Subs-Auth.php');
$passwordError = validatePassword($_POST['passwrd1'], $username, array($email));

// What - it's not?
if ($passwordError != null)
fatal_lang_error('profile_error_password_' . $passwordError, false);

./Sources/Search.php

Find: Select
* Software Version: SMF 1.1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
$stripped_query = preg_replace('~([\x0B\0' . ($context['utf8'] ? ($context['server']['complex_preg_chars'] ? '\x{C2A0}' : chr(0xC2) . chr(0xA0)) : '\xA0') . '\t\r\s\n(){}\\[\\]<>!@$%^*.,:+=`\~\?/\\\\]|&(amp|lt|gt|quot);)+~' . ($context['utf8'] ? 'u' : ''), ' ', $search_params['search']);
Replace With: Select
$stripped_query = preg_replace('~([\x0B\0' . ($context['utf8'] ? ($context['server']['complex_preg_chars'] ? '\x{A0}' : pack('C*', 0xC2, 0xA0)) : '\xA0') . '\t\r\s\n(){}\\[\\]<>!@$%^*.,:+=`\~\?/\\\\]|&(amp|lt|gt|quot);)+~' . ($context['utf8'] ? 'u' : ''), ' ', $search_params['search']);
Find: Select
'posted_in' => $participants[$message['ID_TOPIC']],
Replace With: Select
'posted_in' => !empty($participants[$message['ID_TOPIC']]),

./Sources/SplitTopics.php

Find: Select
* Software Version: SMF 1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
$target_board = count($boards) > 1 ? (int) $_POST['board'] : $boards[0];
Replace With: Select
$target_board = count($boards) > 1 ? (int) $_REQUEST['board'] : $boards[0];

./Sources/Subs-Compat.php

Find: Select
* Software Version: SMF 1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
if (!function_exists('sha1'))
{
function sha1($str)
Replace With: Select
if (1 == 1)
{
function sha1_smf($str)
Find: Select
return ($num << $cnt) | $a;
}
Replace With: Select
return ($num << $cnt) | $a;
}

if (!function_exists('sha1'))
{
function sha1($str)
{
return sha1_smf($str);
}
}

./Sources/Subs-Graphics.php

Find: Select
* Software Version: SMF 1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
function showCodeImage($code)
{
global $settings;

// Is this GD2? Needed for pixel size.
$testGD = get_extension_funcs('gd');
$gd2 = in_array('imagecreatetruecolor', $testGD) && function_exists('imagecreatetruecolor');
unset($testGD);

// The amount of pixels inbetween characters.
$character_spacing = 1;

// The color of the characters shown (red, green, blue).
$foreground_color = array(64, 101, 136);
$background_color = array(236, 237, 243);

// Has the theme author requested a custom color?
if (isset($settings['verification_foreground'], $settings['verification_background']))
{
$foreground_color = $settings['verification_foreground'];
$background_color = $settings['verification_background'];
}

if (!is_dir($settings['default_theme_dir'] . '/fonts'))
return false;

// Get a list of the available fonts.
$font_dir = dir($settings['default_theme_dir'] . '/fonts');
$font_list = array();
$ttfont_list = array();
while ($entry = $font_dir->read())
{
if (preg_match('~^(.+)\.gdf$~', $entry, $matches) === 1)
$font_list[] = $entry;
elseif (preg_match('~^(.+)\.ttf$~', $entry, $matches) === 1)
$ttfont_list[] = $entry;
}

if (empty($font_list))
return false;

// Create a list of characters to be shown.
$characters = array();
$loaded_fonts = array();
for ($i = 0; $i < strlen($code); $i++)
{
$characters[$i] = array(
'id' => $code{$i},
'font' => array_rand($font_list),
);

$loaded_fonts[$characters[$i]['font']] = null;
}

// Load all fonts and determine the maximum font height.
foreach ($loaded_fonts as $font_index => $dummy)
$loaded_fonts[$font_index] = imageloadfont($settings['default_theme_dir'] . '/fonts/' . $font_list[$font_index]);

// Determine the dimensions of each character.
$total_width = $character_spacing * strlen($code) + 10;
$max_height = 0;
foreach ($characters as $char_index => $character)
{
$characters[$char_index]['width'] = imagefontwidth($loaded_fonts[$character['font']]);
$characters[$char_index]['height'] = imagefontheight($loaded_fonts[$character['font']]);

$max_height = max($characters[$char_index]['height'], $max_height);
$total_width += $characters[$char_index]['width'];
}

// Create an image.
$code_image = imagecreate($total_width, $max_height);

// Draw the background.
$bg_color = imagecolorallocate($code_image, $background_color[0], $background_color[1], $background_color[2]);
imagefilledrectangle($code_image, 0, 0, $total_width - 1, $max_height - 1, $bg_color);

// Randomize the foreground color a little.
for ($i = 0; $i < 3; $i++)
$foreground_color[$i] = rand(max($foreground_color[$i] - 3, 0), min($foreground_color[$i] + 3, 255));
$fg_color = imagecolorallocate($code_image, $foreground_color[0], $foreground_color[1], $foreground_color[2]);

// Color for the dots.
for ($i = 0; $i < 3; $i++)
$dotbgcolor[$i] = $background_color[$i] < $foreground_color[$i] ? rand(0, max($foreground_color[$i] - 20, 0)) : rand(min($foreground_color[$i] + 20, 255), 255);
$randomness_color = imagecolorallocate($code_image, $dotbgcolor[0], $dotbgcolor[1], $dotbgcolor[2]);

// Fill in the characters.
$cur_x = 0;
foreach ($characters as $char_index => $character)
{
// Can we use true type fonts?
$can_do_ttf = function_exists('imagettftext');
if (!empty($can_do_ttf))
{
// GD2 handles font size differently.
$font_size = $gd2 ? rand(15, 18) : rand(18, 25);

// Work out the sizes - also fix the character width cause TTF not quite so wide!
$font_x = $cur_x + 5;
$font_y = $max_height - rand(2, 8);

// What font face?
if (!empty($ttfont_list))
{
$fontface = $settings['default_theme_dir'] . '/fonts/' . $ttfont_list[rand(0, count($ttfont_list) - 1)];
//log_error($fontface);
}

// What color are we to do it in?
$is_reverse = rand(0, 1);
$char_color = imagecolorallocate($code_image, rand(max($foreground_color[0] - 2, 0), $foreground_color[0]), rand(max($foreground_color[1] - 2, 0), $foreground_color[1]), rand(max($foreground_color[2] - 2, 0), $foreground_color[2]));

$angle = rand(-100, 100) / 10;
$show_letter = rand(0, 1) ? $character['id'] : strtolower($character['id']);
$fontcord = @imagettftext($code_image, 18, $angle, $font_x, $font_y, $char_color, $fontface, $show_letter);
if (empty($fontcord))
$can_do_ttf = false;
elseif ($is_reverse)
{
imagefilledpolygon($code_image, $fontcord, 4, $fg_color);
// Put the character back!
imagettftext($code_image, 18, $angle, $font_x, $font_y, $randomness_color, $fontface, $show_letter);
}

if ($can_do_ttf)
$cur_x = max($fontcord[2], $fontcord[4]) + 3;
}

if (!$can_do_ttf)
{
// Rotating the characters a little...
if (function_exists('imagerotate'))
{
$char_image = function_exists('imagecreatetruecolor') ? imagecreatetruecolor($character['width'], $character['height']) : imagecreate($character['width'], $character['height']);
$char_bgcolor = imagecolorallocate($char_image, $background_color[0], $background_color[1], $background_color[2]);
imagefilledrectangle($char_image, 0, 0, $character['width'] - 1, $character['height'] - 1, $char_bgcolor);
imagechar($char_image, $loaded_fonts[$character['font']], 0, 0, $character['id'], imagecolorallocate($char_image, rand(max($foreground_color[0] - 2, 0), $foreground_color[0]), rand(max($foreground_color[1] - 2, 0), $foreground_color[1]), rand(max($foreground_color[2] - 2, 0), $foreground_color[2])));
$rotated_char = imagerotate($char_image, rand(-100, 100) / 10, $char_bgcolor);
imagecopy($code_image, $rotated_char, $cur_x, 0, 0, 0, $character['width'], $character['height']);
imagedestroy($rotated_char);
imagedestroy($char_image);
}

// Sorry, no rotation available.
else
imagechar($code_image, $loaded_fonts[$character['font']], $cur_x, floor(($max_height - $character['height']) / 2), $character['id'], imagecolorallocate($code_image, rand(max($foreground_color[0] - 2, 0), $foreground_color[0]), rand(max($foreground_color[1] - 2, 0), $foreground_color[1]), rand(max($foreground_color[2] - 2, 0), $foreground_color[2])));
$cur_x += $character['width'] + $character_spacing;
}
}

// Make the background color transparent.
imagecolortransparent($code_image, $bg_color);

// Add some randomness to the background.
for ($i = rand(0, 2); $i < $max_height; $i += rand(1, 2))
for ($j = rand(0, 10); $j < $total_width; $j += rand(1, 15))
imagesetpixel($code_image, $j, $i, rand(0, 1) ? $fg_color : $randomness_color);

// Put in some lines too.
$num_lines = 2;
for ($i = 0; $i < $num_lines; $i++)
{
if (rand(0, 1))
{
$x1 = rand(0, $total_width);
$x2 = rand(0, $total_width);
$y1 = 0; $y2 = $max_height;
}
else
{
$y1 = rand(0, $max_height);
$y2 = rand(0, $max_height);
$x1 = 0; $x2 = $total_width;
}

imageline($code_image, $x1, $y1, $x2, $y2, rand (0, 1) ? $fg_color : $randomness_color);
}
Replace With: Select
function showCodeImage($code)
{
global $settings, $user_info, $modSettings;

// What type are we going to be doing?
$imageType = empty($modSettings['disable_visual_verification']) ? 0 : $modSettings['disable_visual_verification'];
// Special case to allow the admin center to show samples.
if ($user_info['is_admin'] && isset($_GET['type']))
$imageType = (int) $_GET['type'];
// Just incase PM is on, reg is off.
elseif ($imageType == 1)
$imageType = 0;

// Some quick references for what we do.
// Do we show no, low or high noise?
$noiseType = $imageType == 0 ? 'low' : ($imageType == 4 ? 'high' : 'none');
// Can we have more than one font in use?
$varyFonts = $imageType == 4 ? true : false;
// Just a plain white background?
$simpleBGColor = $imageType != 4 ? true : false;
// Plain black foreground?
$simpleFGColor = $imageType == 1 ? true : false;
// High much to rotate each character.
$rotationType = $imageType == 2 ? 'none' : ($imageType != 4 ? 'high' : 'low');
// Do we show some characters inversed?
$showReverseChars = $imageType == 4 ? true : false;
// Special case for not showing any characters.
$disableChars = $imageType == 1 ? true : false;
// What do we do with the font colours. Are they one color, close to one color or random?
$fontColorType = $imageType == 2 ? 'plain' : ($imageType == 4 ? 'random' : 'cyclic');
// Are the fonts random sizes?
$fontSizeRandom = $imageType == 4 ? true : false;
// How much space between characters?
$fontHorSpace = $imageType == 4 ? 'high' : ($imageType == 2 ? 'medium' : 'minus');
// Where do characters sit on the image? (Fixed position or random/very random)
$fontVerPos = $imageType == 2 ? 'fixed' : ($imageType == 4 ? 'vrandom' : 'random');
// Make font semi-transparent?
$fontTrans = $imageType == 3 || $imageType == 0 ? true : false;
// Give the image a border?
$hasBorder = $simpleBGColor;

// Is this GD2? Needed for pixel size.
$testGD = get_extension_funcs('gd');
$gd2 = in_array('imagecreatetruecolor', $testGD) && function_exists('imagecreatetruecolor');
unset($testGD);

// The amount of pixels inbetween characters.
$character_spacing = 1;

// What color is the background - generally white unless we're on "hard".
if ($simpleBGColor)
$background_color = array(255, 255, 255);
else
$background_color = isset($settings['verification_background']) ? $settings['verification_background'] : array(236, 237, 243);

// The color of the characters shown (red, green, blue).
if ($simpleFGColor)
$foreground_color = array(0, 0, 0);
else
{
$foreground_color = array(64, 101, 136);

// Has the theme author requested a custom color?
if (isset($settings['verification_foreground']))
$foreground_color = $settings['verification_foreground'];
}

if (!is_dir($settings['default_theme_dir'] . '/fonts'))
return false;

// Get a list of the available fonts.
$font_dir = dir($settings['default_theme_dir'] . '/fonts');
$font_list = array();
$ttfont_list = array();
while ($entry = $font_dir->read())
{
if (preg_match('~^(.+)\.gdf$~', $entry, $matches) === 1)
$font_list[] = $entry;
elseif (preg_match('~^(.+)\.ttf$~', $entry, $matches) === 1)
$ttfont_list[] = $entry;
}

if (empty($font_list))
return false;

// For non-hard things don't even change fonts.
if (!$varyFonts)
{
$font_list = array($font_list[0]);
// Try use Screenge if we can - it looks good!
if (in_array('Screenge.ttf', $ttfont_list))
$ttfont_list = array('Screenge.ttf');
else
$ttfont_list = empty($ttfont_list) ? array() : array($ttfont_list[0]);

}

// Create a list of characters to be shown.
$characters = array();
$loaded_fonts = array();
for ($i = 0; $i < strlen($code); $i++)
{
$characters[$i] = array(
'id' => $code{$i},
'font' => array_rand($font_list),
);

$loaded_fonts[$characters[$i]['font']] = null;
}

// Load all fonts and determine the maximum font height.
foreach ($loaded_fonts as $font_index => $dummy)
$loaded_fonts[$font_index] = imageloadfont($settings['default_theme_dir'] . '/fonts/' . $font_list[$font_index]);

// Determine the dimensions of each character.
$total_width = $character_spacing * strlen($code) + 20;
$max_height = 0;
foreach ($characters as $char_index => $character)
{
$characters[$char_index]['width'] = imagefontwidth($loaded_fonts[$character['font']]);
$characters[$char_index]['height'] = imagefontheight($loaded_fonts[$character['font']]);

$max_height = max($characters[$char_index]['height'] + 5, $max_height);
$total_width += $characters[$char_index]['width'];
}

// Create an image.
$code_image = imagecreate($total_width, $max_height);

// Draw the background.
$bg_color = imagecolorallocate($code_image, $background_color[0], $background_color[1], $background_color[2]);
imagefilledrectangle($code_image, 0, 0, $total_width - 1, $max_height - 1, $bg_color);

// Randomize the foreground color a little.
for ($i = 0; $i < 3; $i++)
$foreground_color[$i] = rand(max($foreground_color[$i] - 3, 0), min($foreground_color[$i] + 3, 255));
$fg_color = imagecolorallocate($code_image, $foreground_color[0], $foreground_color[1], $foreground_color[2]);

// Color for the dots.
for ($i = 0; $i < 3; $i++)
$dotbgcolor[$i] = $background_color[$i] < $foreground_color[$i] ? rand(0, max($foreground_color[$i] - 20, 0)) : rand(min($foreground_color[$i] + 20, 255), 255);
$randomness_color = imagecolorallocate($code_image, $dotbgcolor[0], $dotbgcolor[1], $dotbgcolor[2]);

// Fill in the characters.
if (!$disableChars)
{
$cur_x = 0;
foreach ($characters as $char_index => $character)
{
// Can we use true type fonts?
$can_do_ttf = function_exists('imagettftext');

// How much rotation will we give?
if ($rotationType == 'none')
$angle = 0;
else
$angle = rand(-100, 100) / ($rotationType == 'high' ? 6 : 10);

// What colour shall we do it?
if ($fontColorType == 'cyclic')
{
// Here we'll pick from a set of acceptance types.
$colours = array(
array(10, 120, 95),
array(46, 81, 29),
array(4, 22, 154),
array(131, 9, 130),
array(0, 0, 0),
array(143, 39, 31),
);
if (!isset($last_index))
$last_index = -1;
$new_index = $last_index;
while ($last_index == $new_index)
$new_index = rand(0, count($colours) - 1);
$char_fg_color = $colours[$new_index];
$last_index = $new_index;
}
elseif ($fontColorType == 'random')
$char_fg_color = array(rand(max($foreground_color[0] - 2, 0), $foreground_color[0]), rand(max($foreground_color[1] - 2, 0), $foreground_color[1]), rand(max($foreground_color[2] - 2, 0), $foreground_color[2]));
else
$char_fg_color = array($foreground_color[0], $foreground_color[1], $foreground_color[2]);

if (!empty($can_do_ttf))
{
// GD2 handles font size differently.
if ($fontSizeRandom)
$font_size = $gd2 ? rand(17, 19) : rand(18, 25);
else
$font_size = $gd2 ? 18 : 24;

// Work out the sizes - also fix the character width cause TTF not quite so wide!
$font_x = $fontHorSpace == 'minus' && $cur_x > 0 ? $cur_x - 3 : $cur_x + 5;
$font_y = $max_height - ($fontVerPos == 'vrandom' ? rand(2, 8) : ($fontVerPos == 'random' ? rand(3, 5) : 5));

// What font face?
if (!empty($ttfont_list))
$fontface = $settings['default_theme_dir'] . '/fonts/' . $ttfont_list[rand(0, count($ttfont_list) - 1)];

// What color are we to do it in?
$is_reverse = $showReverseChars ? rand(0, 1) : false;
$char_color = function_exists('imagecolorallocatealpha') && $fontTrans ? imagecolorallocatealpha($code_image, $char_fg_color[0], $char_fg_color[1], $char_fg_color[2], 50) : imagecolorallocate($code_image, $char_fg_color[0], $char_fg_color[1], $char_fg_color[2]);

$fontcord = @imagettftext($code_image, $font_size, $angle, $font_x, $font_y, $char_color, $fontface, $character['id']);
if (empty($fontcord))
$can_do_ttf = false;
elseif ($is_reverse)
{
imagefilledpolygon($code_image, $fontcord, 4, $fg_color);
// Put the character back!
imagettftext($code_image, $font_size, $angle, $font_x, $font_y, $randomness_color, $fontface, $character['id']);
}

if ($can_do_ttf)
$cur_x = max($fontcord[2], $fontcord[4]) + ($angle == 0 ? 0 : 3);
}

if (!$can_do_ttf)
{
// Rotating the characters a little...
if (function_exists('imagerotate'))
{
$char_image = function_exists('imagecreatetruecolor') ? imagecreatetruecolor($character['width'], $character['height']) : imagecreate($character['width'], $character['height']);
$char_bgcolor = imagecolorallocate($char_image, $background_color[0], $background_color[1], $background_color[2]);
imagefilledrectangle($char_image, 0, 0, $character['width'] - 1, $character['height'] - 1, $char_bgcolor);
imagechar($char_image, $loaded_fonts[$character['font']], 0, 0, $character['id'], imagecolorallocate($char_image, $char_fg_color[0], $char_fg_color[1], $char_fg_color[2]));
$rotated_char = imagerotate($char_image, rand(-100, 100) / 10, $char_bgcolor);
imagecopy($code_image, $rotated_char, $cur_x, 0, 0, 0, $character['width'], $character['height']);
imagedestroy($rotated_char);
imagedestroy($char_image);
}

// Sorry, no rotation available.
else
imagechar($code_image, $loaded_fonts[$character['font']], $cur_x, floor(($max_height - $character['height']) / 2), $character['id'], imagecolorallocate($code_image, $char_fg_color[0], $char_fg_color[1], $char_fg_color[2]));
$cur_x += $character['width'] + $character_spacing;
}
}
}
// If disabled just show a cross.
else
{
imageline($code_image, 0, 0, $total_width, $max_height, $fg_color);
imageline($code_image, 0, $max_height, $total_width, 0, $fg_color);
}

// Make the background color transparent on the hard image.
if (!$simpleBGColor)
imagecolortransparent($code_image, $bg_color);
if ($hasBorder)
imagerectangle($code_image, 0, 0, $total_width - 1, $max_height - 1, $fg_color);

// Add some noise to the background?
if ($noiseType != 'none')
{
for ($i = rand(0, 2); $i < $max_height; $i += rand(1, 2))
for ($j = rand(0, 10); $j < $total_width; $j += rand(1, 15))
imagesetpixel($code_image, $j, $i, rand(0, 1) ? $fg_color : $randomness_color);

// Put in some lines too?
if ($noiseType == 'high')
{
$num_lines = 2;
for ($i = 0; $i < $num_lines; $i++)
{
if (rand(0, 1))
{
$x1 = rand(0, $total_width);
$x2 = rand(0, $total_width);
$y1 = 0; $y2 = $max_height;
}
else
{
$y1 = rand(0, $max_height);
$y2 = rand(0, $max_height);
$x1 = 0; $x2 = $total_width;
}

imageline($code_image, $x1, $y1, $x2, $y2, rand (0, 1) ? $fg_color : $randomness_color);
}
}
}

./Sources/Subs-Members.php

Find: Select
* Software Version: SMF 1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
$regOptions['username'] = preg_replace('~[\t\n\r\x0B\0' . ($context['utf8'] ? ($context['server']['complex_preg_chars'] ? '\x{C2A0}' : chr(0xC2) . chr(0xA0)) : '\xA0') . ']+~' . ($context['utf8'] ? 'u' : ''), ' ', $regOptions['username']);
Replace With: Select
$regOptions['username'] = preg_replace('~[\t\n\r\x0B\0' . ($context['utf8'] ? ($context['server']['complex_preg_chars'] ? '\x{A0}' : pack('C*', 0xC2, 0xA0)) : '\xA0') . ']+~' . ($context['utf8'] ? 'u' : ''), ' ', $regOptions['username']);

./Sources/Subs-Package.php

Find: Select
* Software Version: SMF 1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
$temp_path = $boarddir . '/Packages/temp' . (isset($context['base_path']) ? $context['base_path'] : '');
Replace With: Select
$temp_path = $boarddir . '/Packages/temp/' . (isset($context['base_path']) ? $context['base_path'] : '');
Find: Select
$filename = $temp_path . '/$auto_' . $temp_auto++ . ($actionType == 'readme' || $actionType == 'redirect' ? '.txt' : ($actionType == 'code' ? '.php' : '.mod'));
package_put_contents($filename, $action->fetch('.'));
$filename = strtr($filename, array($temp_path . '/' => ''));
Replace With: Select
$filename = $temp_path . '$auto_' . $temp_auto++ . ($actionType == 'readme' || $actionType == 'redirect' ? '.txt' : ($actionType == 'code' ? '.php' : '.mod'));
package_put_contents($filename, $action->fetch('.'));
$filename = strtr($filename, array($temp_path => ''));
Find: Select
$this_action['source'] = $temp_path . '/' . $this_action['filename'];
Replace With: Select
$this_action['source'] = $temp_path . $this_action['filename'];
Find: Select
$actual_operation['searches'][$i]['preg_search'] .= '(\\n\\?\\>)?$';
$actual_operation['searches'][$i]['preg_replace'] = '$1';
Replace With: Select
$actual_operation['searches'][$i]['preg_replace'] = '';
Find: Select
// Replace it into nothing? That's not an option...unless
if ($search['add'] === '')
continue;
Replace With: Select
// Replace it into nothing? That's not an option...unless it's an undoing end.
if ($search['add'] === '' && ($search['position'] !== 'end' || !$undo))
continue;

./Sources/Subs-Post.php

Find: Select
* Software Version: SMF 1.1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
$non_breaking_space = $context['utf8'] ? ($context['server']['complex_preg_chars'] ? '\x{C2A0}' : chr(0xC2) . chr(0xA0)) : '\xA0';
Replace With: Select
$non_breaking_space = $context['utf8'] ? ($context['server']['complex_preg_chars'] ? '\x{A0}' : pack('C*', 0xC2, 0xA0)) : '\xA0';
Find: Select
$mistake_fixes = array(
// Find [table]s not followed by [tr].
'~\[table\](?![\s' . $non_breaking_space . ']*\[tr\])~is' . ($context['utf8'] ? 'u' : '') => '[table][tr]',
// Find [tr]s not followed by [td].
'~\[tr\](?![\s' . $non_breaking_space . ']*\[td\])~is' . ($context['utf8'] ? 'u' : '') => '[tr][td]',
// Find [/td]s not followed by something valid.
'~\[/td\](?![\s' . $non_breaking_space . ']*(?:\[td\]|\[/tr\]|\[/table\]))~is' . ($context['utf8'] ? 'u' : '') => '[/td][/tr]',
// Find [/tr]s not followed by something valid.
'~\[/tr\](?![\s' . $non_breaking_space . ']*(?:\[tr\]|\[/table\]))~is' . ($context['utf8'] ? 'u' : '') => '[/tr][/table]',
// Find [/td]s incorrectly followed by [/table].
'~\[/td\][\s' . $non_breaking_space . ']*\[/table\]~is' . ($context['utf8'] ? 'u' : '') => '[/td][/tr][/table]',
// Find [table]s, [tr]s, and [/td]s (possibly correctly) followed by [td].
'~\[(table|tr|/td)\]([\s' . $non_breaking_space . ']*)\[td\]~is' . ($context['utf8'] ? 'u' : '') => '[$1]$2[_td_]',
// Now, any [td]s left should have a [tr] before them.
'~\[td\]~is' => '[tr][td]',
// Look for [tr]s which are correctly placed.
'~\[(table|/tr)\]([\s' . $non_breaking_space . ']*)\[tr\]~is' . ($context['utf8'] ? 'u' : '') => '[$1]$2[_tr_]',
// Any remaining [tr]s should have a [table] before them.
'~\[tr\]~is' => '[table][tr]',
// Look for [/td]s followed by [/tr].
'~\[/td\]([\s' . $non_breaking_space . ']*)\[/tr\]~is' . ($context['utf8'] ? 'u' : '') => '[/td]$1[_/tr_]',
// Any remaining [/tr]s should have a [/td].
'~\[/tr\]~is' => '[/td][/tr]',
// Look for properly opened [li]s which aren't closed.
'~\[li\]([^\[\]]+?)\[li\]~is' => '[li]$1[_/li_][_li_]',
'~\[li\]([^\[\]]+?)$~is' => '[li]$1[/li]',
// Lists - find correctly closed items/lists.
'~\[/li\]([\s' . $non_breaking_space . ']*)\[/list\]~is' . ($context['utf8'] ? 'u' : '') => '[_/li_]$1[/list]',
// Find list items closed and then opened.
'~\[/li\]([\s' . $non_breaking_space . ']*)\[li\]~is' . ($context['utf8'] ? 'u' : '') => '[_/li_]$1[_li_]',
// Now, find any [list]s or [/li]s followed by [li].
'~\[(list(?: [^\]]*?)?|/li)\]([\s' . $non_breaking_space . ']*)\[li\]~is' . ($context['utf8'] ? 'u' : '') => '[$1]$2[_li_]',
// Any remaining [li]s weren't inside a [list].
'~\[li\]~i' => '[list][li]',
// Any remaining [/li]s weren't before a [/list].
'~\[/li\]~i' => '[/li][/list]',
// Put the correct ones back how we found them.
'~\[_(li|/li|td|tr|/tr)_\]~i' => '[$1]',
);
Replace With: Select
// Make sure all tags are lowercase.
$parts[$i] = preg_replace('~\[([/]?)(list|li|table|tr|td)([^\]]*)\]~e', '"[$1" . strtolower("$2") . "$3]"', $parts[$i]);

$mistake_fixes = array(
// Find [table]s not followed by [tr].
'~\[table\](?![\s' . $non_breaking_space . ']*\[tr\])~s' . ($context['utf8'] ? 'u' : '') => '[table][tr]',
// Find [tr]s not followed by [td].
'~\[tr\](?![\s' . $non_breaking_space . ']*\[td\])~s' . ($context['utf8'] ? 'u' : '') => '[tr][td]',
// Find [/td]s not followed by something valid.
'~\[/td\](?![\s' . $non_breaking_space . ']*(?:\[td\]|\[/tr\]|\[/table\]))~s' . ($context['utf8'] ? 'u' : '') => '[/td][/tr]',
// Find [/tr]s not followed by something valid.
'~\[/tr\](?![\s' . $non_breaking_space . ']*(?:\[tr\]|\[/table\]))~s' . ($context['utf8'] ? 'u' : '') => '[/tr][/table]',
// Find [/td]s incorrectly followed by [/table].
'~\[/td\][\s' . $non_breaking_space . ']*\[/table\]~s' . ($context['utf8'] ? 'u' : '') => '[/td][/tr][/table]',
// Find [table]s, [tr]s, and [/td]s (possibly correctly) followed by [td].
'~\[(table|tr|/td)\]([\s' . $non_breaking_space . ']*)\[td\]~s' . ($context['utf8'] ? 'u' : '') => '[$1]$2[_td_]',
// Now, any [td]s left should have a [tr] before them.
'~\[td\]~s' => '[tr][td]',
// Look for [tr]s which are correctly placed.
'~\[(table|/tr)\]([\s' . $non_breaking_space . ']*)\[tr\]~s' . ($context['utf8'] ? 'u' : '') => '[$1]$2[_tr_]',
// Any remaining [tr]s should have a [table] before them.
'~\[tr\]~s' => '[table][tr]',
// Look for [/td]s followed by [/tr].
'~\[/td\]([\s' . $non_breaking_space . ']*)\[/tr\]~s' . ($context['utf8'] ? 'u' : '') => '[/td]$1[_/tr_]',
// Any remaining [/tr]s should have a [/td].
'~\[/tr\]~s' => '[/td][/tr]',
// Look for properly opened [li]s which aren't closed.
'~\[li\]([^\[\]]+?)\[li\]~s' => '[li]$1[_/li_][_li_]',
'~\[li\]([^\[\]]+?)$~s' => '[li]$1[/li]',
// Lists - find correctly closed items/lists.
'~\[/li\]([\s' . $non_breaking_space . ']*)\[/list\]~s' . ($context['utf8'] ? 'u' : '') => '[_/li_]$1[/list]',
// Find list items closed and then opened.
'~\[/li\]([\s' . $non_breaking_space . ']*)\[li\]~s' . ($context['utf8'] ? 'u' : '') => '[_/li_]$1[_li_]',
// Now, find any [list]s or [/li]s followed by [li].
'~\[(list(?: [^\]]*?)?|/li)\]([\s' . $non_breaking_space . ']*)\[li\]~s' . ($context['utf8'] ? 'u' : '') => '[$1]$2[_li_]',
// Any remaining [li]s weren't inside a [list].
'~\[li\]~' => '[list][li]',
// Any remaining [/li]s weren't before a [/list].
'~\[/li\]~' => '[/li][/list]',
// Put the correct ones back how we found them.
'~\[_(li|/li|td|tr|/tr)_\]~' => '[$1]',
);
Find: Select
// Sadly Hotmail doesn't support character sets properly.
if ($hotmail_fix === null)
{
$hotmail_to = array();
foreach ($to_array as $i => $to_address)
{
if (preg_match('~@hotmail.[a-zA-Z\.]{2,6}$~i', $to_address) === 1)
Replace With: Select
// Sadly Hotmail & Yahoomail don't support character sets properly.
if ($hotmail_fix === null)
{
$hotmail_to = array();
foreach ($to_array as $i => $to_address)
{
if (preg_match('~@(yahoo|hotmail)\.[a-zA-Z\.]{2,6}$~i', $to_address) === 1)
Find: Select
$charset = isset($context['character_set']) ? $context['character_set'] : $txt['lang_character_set'];

list ($charset, $message, $encoding) = mimespecialchars($message, false, $hotmail_fix, $line_break);

// Sending HTML? Let's plop in some basic stuff, then.
if ($send_html)
{
// This should send a text message with MIME multipart/alternative stuff.
$mime_boundary = 'SMF-' . md5($message . time());
$headers .= 'Mime-Version: 1.0' . $line_break;
$headers .= 'Content-Type: multipart/alternative; boundary="' . $mime_boundary . '"' . $line_break;
$headers .= 'Content-Transfer-Encoding: ' . ($encoding == '' ? '7bit' : $encoding);

// Save the original message...
$orig_message = $message;

// But, then, dump it and use a plain one for dinosaur clients.
$message = un_htmlspecialchars(strip_tags(strtr($orig_message, array('</title>' => $line_break)))) . $line_break . '--' . $mime_boundary . $line_break;

// This is the plain text version. Even if no one sees it, we need it for spam checkers.
$message .= 'Content-Type: text/plain; charset=' . $charset . $line_break;
$message .= 'Content-Transfer-Encoding: ' . ($encoding == '' ? '7bit' : $encoding) . $line_break . $line_break;
$message .= un_htmlspecialchars(strip_tags(strtr($orig_message, array('</title>' => $line_break)))) . $line_break . "--" . $mime_boundary . $line_break;

// This is the actual HTML message, prim and proper. If we wanted images, they could be inlined here (with multipart/related, etc.)
$message .= 'Content-Type: text/html; charset=' . $charset . $line_break;
$message .= 'Content-Transfer-Encoding: ' . ($encoding == '' ? '7bit' : $encoding) . $line_break . $line_break;
$message .= $orig_message . $line_break . "--" . $mime_boundary . '--';
}
// Text is good too.
else
{
$headers .= 'Content-Type: text/plain; charset=' . $charset . $line_break;
if ($encoding != '')
$headers .= 'Content-Transfer-Encoding: ' . $encoding;
}
Replace With: Select
// Save the original message...
$orig_message = $message;

// The mime boundary separates the different alternative versions.
$mime_boundary = 'SMF-' . md5($message . time());

// Sending HTML? Let's plop in some basic stuff, then.
if ($send_html)
{
// This should send a text message with MIME multipart/alternative stuff.
$headers .= 'Mime-Version: 1.0' . $line_break;
$headers .= 'Content-Type: multipart/alternative; boundary="' . $mime_boundary . '"' . $line_break;
$headers .= 'Content-Transfer-Encoding: 7bit' . $line_break;

$no_html_message = un_htmlspecialchars(strip_tags(strtr($orig_message, array('</title>' => $line_break))));

// But, then, dump it and use a plain one for dinosaur clients.
list(, $plain_message) = mimespecialchars($no_html_message, false, true, $line_break);
$message = $plain_message . $line_break . '--' . $mime_boundary . $line_break;

// This is the plain text version. Even if no one sees it, we need it for spam checkers.
list($charset, $plain_charset_message, $encoding) = mimespecialchars($no_html_message, false, false, $line_break);
$message .= 'Content-Type: text/plain; charset=' . $charset . $line_break;
$message .= 'Content-Transfer-Encoding: ' . $encoding . $line_break . $line_break;
$message .= $plain_charset_message . $line_break . '--' . $mime_boundary . $line_break;

// This is the actual HTML message, prim and proper. If we wanted images, they could be inlined here (with multipart/related, etc.)
list($charset, $html_message, $encoding) = mimespecialchars($orig_message, false, $hotmail_fix, $line_break);
$message .= 'Content-Type: text/html; charset=' . $charset . $line_break;
$message .= 'Content-Transfer-Encoding: ' . ($encoding == '' ? '7bit' : $encoding) . $line_break . $line_break;
$message .= $html_message . $line_break . '--' . $mime_boundary . '--';
}
// Text is good too.
else
{
// Using mime, as it allows to send a plain unencoded alternative.
$headers .= 'Mime-Version: 1.0' . $line_break;
$headers .= 'Content-Type: multipart/alternative; boundary="' . $mime_boundary . '"' . $line_break;
$headers .= 'Content-Transfer-Encoding: 7bit' . $line_break;

// Send a plain message first, for the older web clients.
list(, $plain_message) = mimespecialchars($orig_message, false, true, $line_break);
$message = $plain_message . $line_break . '--' . $mime_boundary . $line_break;

// Now add an encoded message using the forum's character set.
list ($charset, $encoded_message, $encoding) = mimespecialchars($orig_message, false, false, $line_break);
$message .= 'Content-Type: text/plain; charset=' . $charset . $line_break;
$message .= 'Content-Transfer-Encoding: ' . $encoding . $line_break . $line_break;
$message .= $encoded_message . $line_break . '--' . $mime_boundary . '--';
}
Find: Select
return array($charset, preg_replace('~([\x80-' . ($context['server']['complex_preg_chars'] ? '\x{10FFFF}' : sprintf('%c%c%c', 0x10, 0xFF, 0xFF)) . '])~eu', '$entityConvert("\1")', $string), '7bit');
Replace With: Select
return array($charset, preg_replace('~([\x80-' . ($context['server']['complex_preg_chars'] ? '\x{10FFFF}' : pack('C*', 0xF7, 0xBF, 0xBF, 0xBF)) . '])~eu', '$entityConvert("\1")', $string), '7bit');
Find: Select
if (in_array($func['strtolower']($check_word[0]), $known_words) || pspell_check($pspell_link, $check_word[0]))
Replace With: Select
if (in_array($func['strtolower']($check_word[0]), $known_words) || pspell_check($pspell_link, $check_word[0]) || !isset($check_word[2]))

./Sources/Subs.php

Find: Select
* Software Version: SMF 1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
'test' => '([\d]{1,2}p[xt]|(?:x-)?small(?:er)?|(?:x-)?large[r]?)\]',
// !!! line-height
'before' => '<span style="font-size: $1; line-height: 1.3em;">',
'after' => '</span>',
),
array(
'tag' => 'size',
'type' => 'unparsed_equals',
'test' => '[\d]\]',
Replace With: Select
'test' => '([1-9][\d]?p[xt]|(?:x-)?small(?:er)?|(?:x-)?large[r]?)\]',
// !!! line-height
'before' => '<span style="font-size: $1; line-height: 1.3em;">',
'after' => '</span>',
),
array(
'tag' => 'size',
'type' => 'unparsed_equals',
'test' => '[1-9]\]',
Find: Select
$data = preg_replace('~(?<=[\?\s' . $non_breaking_space . '\[\]()*\\\;>]|^)([\w\-\.]{1,80}@[\w\-]+\.[\w\-\.]+[\w\-])(?=[?,\s' . $non_breaking_space . '\[\]()*\\\]|$|<br />|&nbsp;|&gt;|&lt;|&quot;|&#039;|\.(?:\.|;|&nbsp;|\s|$|<br />))~i' . ($context['utf8'] ? 'u' : ''), '[email]$1[/email]', $data);
$data = preg_replace('~(?<=<br />)([\w\-\.]{1,80}@[\w\-]+\.[\w\-\.]+[\w\-])(?=[?\.,;\s' . $non_breaking_space . '\[\]()*\\\]|$|<br />|&nbsp;|&gt;|&lt;|&quot;|&#039;)~i' . ($context['utf8'] ? 'u' : ''), '[email]$1[/email]', $data);
Replace With: Select
$data = preg_replace('~(?<=[\?\s' . $non_breaking_space . '\[\]()*\\\;>]|^)([\w\-\.]{1,80}@[\w\-]+\.[\w\-\.]+[\w\-])(?=[?,\s' . $non_breaking_space . '\[\]()*\\\]|$|<br />|&nbsp;|&gt;|&lt;|&quot;|&#039;|\.(?:\.|;|&nbsp;|\s|$|<br />))~' . ($context['utf8'] ? 'u' : ''), '[email]$1[/email]', $data);
$data = preg_replace('~(?<=<br />)([\w\-\.]{1,80}@[\w\-]+\.[\w\-\.]+[\w\-])(?=[?\.,;\s' . $non_breaking_space . '\[\]()*\\\]|$|<br />|&nbsp;|&gt;|&lt;|&quot;|&#039;)~' . ($context['utf8'] ? 'u' : ''), '[email]$1[/email]', $data);
Find: Select
$message = strtr($message, array(' ' => ' &nbsp;', "\r" => '', "\n" => '<br />', '<br /> ' => '<br />&nbsp;'));
Replace With: Select
$message = strtr($message, array(' ' => ' &nbsp;', "\r" => '', "\n" => '<br />', '<br /> ' => '<br />&nbsp;', '&#13;' => "\n"));
Find: Select
$non_breaking_space = $context['utf8'] ? ($context['server']['complex_preg_chars'] ? '\x{C2A0}' : chr(0xC2) . chr(0xA0)) : '\xA0';
Replace With: Select
$non_breaking_space = $context['utf8'] ? ($context['server']['complex_preg_chars'] ? '\x{A0}' : pack('C*', 0xC2, 0xA0)) : '\xA0';
Find: Select
<div style="white-space: normal;">The administrator doesn\'t want a copyright notice saying this is copyright 2006 by <a href="http://www.simplemachines.org/about/copyright.php" target="_blank">Simple Machines LLC</a>, and named <a href="http://www.simplemachines.org/">SMF</a>, so the forum will honor this request and be quiet.</div>';
Replace With: Select
<div style="white-space: normal;">The administrator doesn\'t want a copyright notice saying this is copyright 2006 - 2007 by <a href="http://www.simplemachines.org/about/copyright.php" target="_blank">Simple Machines LLC</a>, and named <a href="http://www.simplemachines.org/">SMF</a>, so the forum will honor this request and be quiet.</div>';
Find: Select
// Try the Linux host command, perhaps?
if (!isset($host) && strpos(strtolower(PHP_OS), 'win') === false && rand(0, 1) == 1)
Replace With: Select
// Try the Linux host command, perhaps?
if (!isset($host) && (strpos(strtolower(PHP_OS), 'win') === false || strpos(strtolower(PHP_OS), 'darwin') !== false) && rand(0, 1) == 1)
Find: Select
// This is nslookup; usually only Windows, but possibly some Unix?
if (!isset($host) && strpos(strtolower(PHP_OS), 'win') !== false && rand(0, 1) == 1)
Replace With: Select
// This is nslookup; usually only Windows, but possibly some Unix?
if (!isset($host) && strpos(strtolower(PHP_OS), 'win') !== false && strpos(strtolower(PHP_OS), 'darwin') === false && rand(0, 1) == 1)
Find: Select
$words = preg_replace('~([\x0B\0' . ($context['utf8'] ? ($context['server']['complex_preg_chars'] ? '\x{C2A0}' : chr(0xC2) . chr(0xA0)) : '\xA0') . '\t\r\s\n(){}\\[\\]<>!@$%^*.,:+=`\~\?/\\\\]|&(amp|lt|gt|quot);)+~' . ($context['utf8'] ? 'u' : ''), ' ', strtr($text, array('<br />' => ' ')));
Replace With: Select
$words = preg_replace('~([\x0B\0' . ($context['utf8'] ? ($context['server']['complex_preg_chars'] ? '\x{A0}' : pack('C*', 0xC2, 0xA0)) : '\xA0') . '\t\r\s\n(){}\\[\\]<>!@$%^*.,:+=`\~\?/\\\\]|&(amp|lt|gt|quot);)+~' . ($context['utf8'] ? 'u' : ''), ' ', strtr($text, array('<br />' => ' ')));

./Sources/Themes.php

Find: Select
* Software Version: SMF 1.1 *
Replace With: Select
* Software Version: SMF 1.1.2 *
Find: Select
checkSession('get');

$old_id = $settings['theme_id'];
// Once again, these are settings which need to be retained as they are template settings.
$template_settings = array('use_default_images', 'doctype', 'theme_version', 'use_tabs', 'use_buttons', 'seperate_sticky_lock');
$old_settings = array();
foreach ($template_settings as $setting)
if (isset($settings[$setting]))
$old_settings[$setting] = $settings[$setting];

loadTheme($_GET['th'], false);
Replace With: Select
checkSession('get');

$old_id = $settings['theme_id'];
$old_settings = $settings;

loadTheme($_GET['th'], false);
Find: Select
// Restore the existing theme.
loadTheme($old_id, false);
foreach ($old_settings as $setting => $value)
$settings[$setting] = $value;
Replace With: Select
// Restore the existing theme.
loadTheme($old_id, false);
$settings = $old_settings;
Find: Select
// Restore the current theme.
loadTheme($old_id, false);
foreach ($old_settings as $setting => $value)
$settings[$setting] = $value;
Replace With: Select
// Restore the current theme.
loadTheme($old_id, false);
$settings = $old_settings;
Find: Select
$context['smiley_sets'][$set] = $set_names[$i];

$old_id = $settings['theme_id'];
// Settings that need to be retained as they are template settings.
$template_settings = array('use_default_images', 'doctype', 'theme_version', 'use_tabs', 'use_buttons', 'seperate_sticky_lock');
$old_settings = array();
foreach ($template_settings as $setting)
if (isset($settings[$setting]))
$old_settings[$setting] = $settings[$setting];
Replace With: Select
$context['smiley_sets'][$set] = $set_names[$i];

$old_id = $settings['theme_id'];
$old_settings = $settings;

./Themes/default/Poll.template.php

Find: Select
// Version: 1.1; Poll
Replace With: Select
// Version: 1.1.2; Poll
Find: Select
if (document.forms.postmodify.elements[i].id.substr(0, 8) == "options[")
Replace With: Select
if (document.forms.postmodify.elements[i].id.substr(0, 8) == "options-")
Find: Select
<label for="options_', $choice['id'], '" ', (isset($context['poll_error']['poll_few']) ? ' style="color: red;"' : ''), '>', $txt['smf22'], ' ', $choice['number'], '</label>: <input type="text" name="options[', $choice['id'], ']" id="options_', $choice['id'], '" size="25" value="', $choice['label'], '" />';
Replace With: Select
<label for="options-', $choice['id'], '" ', (isset($context['poll_error']['poll_few']) ? ' style="color: red;"' : ''), '>', $txt['smf22'], ' ', $choice['number'], '</label>: <input type="text" name="options[', $choice['id'], ']" id="options-', $choice['id'], '" size="25" value="', $choice['label'], '" />';

./Themes/default/Profile.template.php

Find: Select
// Version: 1.1; Profile
Replace With: Select
// Version: 1.1.2; Profile
Find: Select
<td>', ($context['allow_edit_name'] ? '<input type="text" name="realName" size="30" value="' . $context['member']['name'] . '" />' : $context['member']['name']), '</td>
Replace With: Select
<td>', ($context['allow_edit_name'] ? '<input type="text" name="realName" size="30" value="' . $context['member']['name'] . '" maxlength="60" />' : $context['member']['name']), '</td>

./Themes/default/Register.template.php

Find: Select
// Version: 1.1; Register
Replace With: Select
// Version: 1.1.2; Register
Find: Select
function template_admin_settings()
{
global $context, $settings, $options, $scripturl, $txt, $modSettings;
Replace With: Select
function template_admin_settings()
{
global $context, $settings, $options, $scripturl, $txt, $modSettings;

// Javascript for the verification image.
if ($context['use_graphic_library'])
{
echo '
<script language="JavaScript" type="text/javascript"><!-- // --><![CDATA[
function refreshImages()
{
var imageType = document.getElementById(\'visual_verification_type_select\').value;
document.getElementById(\'verificiation_image\').src = \'', $context['verificiation_image_href'], ';type=\' + imageType;
}
// ]]></script>';
}
Find: Select
</tr><tr class="windowbg2">
<th width="50%" align="right">
<label for="disable_visual_verification_check">', $txt['admin_setting_disable_visual_verification'], '</label>:
</th>
<td width="50%" align="left">
<input type="checkbox" name="disable_visual_verification" id="disable_visual_verification_check" ', !empty($modSettings['disable_visual_verification']) ? 'checked="checked"' : '', ' class="check" />
</td>
Replace With: Select
</tr><tr class="windowbg2" valign="top">
<th width="50%" align="right">
<label for="visual_verification_type_select">
', $txt['admin_setting_image_verification_type'], ':<br />
<span class="smalltext" style="font-weight: normal;">
', $txt['admin_setting_image_verification_type_desc'], '
</span>
</label>
</th>
<td width="50%" align="left">
<select name="visual_verification_type" id="visual_verification_type_select" ', $context['use_graphic_library'] ? 'onchange="refreshImages();"' : '', '>
<option value="1" ', !empty($modSettings['disable_visual_verification']) && $modSettings['disable_visual_verification'] == 1 ? 'selected="selected"' : '', '>', $txt['admin_setting_image_verification_off'], '</option>
<option value="2" ', !empty($modSettings['disable_visual_verification']) && $modSettings['disable_visual_verification'] == 2 ? 'selected="selected"' : '', '>', $txt['admin_setting_image_verification_vsimple'], '</option>
<option value="3" ', !empty($modSettings['disable_visual_verification']) && $modSettings['disable_visual_verification'] == 3 ? 'selected="selected"' : '', '>', $txt['admin_setting_image_verification_simple'], '</option>
<option value="0" ', empty($modSettings['disable_visual_verification']) ? 'selected="selected"' : '', '>', $txt['admin_setting_image_verification_medium'], '</option>
<option value="4" ', !empty($modSettings['disable_visual_verification']) && $modSettings['disable_visual_verification'] == 4 ? 'selected="selected"' : '', '>', $txt['admin_setting_image_verification_high'], '</option>
</select><br />';
if ($context['use_graphic_library'])
echo '
<img src="', $context['verificiation_image_href'], ';type=', empty($modSettings['disable_visual_verification']) ? 0 : $modSettings['disable_visual_verification'], '" alt="', $txt['admin_setting_image_verification_sample'], '" id="verificiation_image" /><br />';
else
{
echo '
<span class="smalltext">', $txt['admin_setting_image_verification_nogd'], '</span>';
}
echo '
</td>

./Themes/default/spellcheck.js

Find: Select
aWords[aWords.length] = aResult[0].substr(iOffset1, iOffset2 - iOffset1 + 1) + '|' + (iOffset1 + RegExp.leftContext.length) + '|' + (iOffset2 + RegExp.leftContext.length);
Replace With: Select
aWords[aWords.length] = aResult[0].substr(iOffset1, iOffset2 - iOffset1 + 1) + '|' + (iOffset1 + sText.substr(0, aResult.index).length) + '|' + (iOffset2 + sText.substr(0, aResult.index).length);

./changelog.txt

This operation isn't vital to the installation of this mod.
Find: Select

SMF 1.1.1 December 17, 2006
Replace With: Select

SMF 1.1.2 10 February 2007
================================================================================
February 2007
--------------------------------------------------------------------------------
! Fixed a remaining, if not extremely difficult to exploit, issue with downloads on IE - reported by Jessica Hope. (Display.php)
! Fixed to/bcc fields in Personal Messages not being htmlspecialchar'd - reported by Aria-Security team. (PersonalMessage.php)
! People with the manage_permissions could maybe abuse it. (ManagePermissions.php, ManageMembergroups.php)
! The path was sometimes wrong when installing a package. (Subs-Package.php)
! Display name can now be no longer than 60 characters as people were taking it too far! (Profile.php, Profile template)
& New error string for the above. (Errors language files)
! Quick edit would lose the old modified time if you made no changes. (Post.php)
! Password reminder was not respecting password strength. (Reminder.php)
! Retain all current theme settings when editing a different theme. (Themes.php)
! Try to ensure ID_MSG_LAST_VISIT is always set. (Load.php)
! Always send an alternative plain us-ascii text version of the body along with each mail for basic support of older mail clients. (Subs-Post.php)
! Convert non-ascii characters to entities for mails sent to yahoo addresses to assure characters are being displayed properly in yahoo's client. (Subs-Post.php)
! People upgrading from non-sha1 supporting PHP to new sha1 supporting PHP were having problems. (Subs-Compat.php, LogInOut.php)


January 2007
--------------------------------------------------------------------------------
! An error sometimes got generated around visual verification. (Register.php)
! Fixed undefined index error in search. (Search.php)
! Fixed error when deleting boards in some instances. (ManageBoards.php)
! Merging a topic wouldn't always work if using $_GET. (SplitTopics.php)
* Javascript wasn't working right when adding a poll. (Poll template)
& Updated copyright dates. (index language files)
+ Added a setting for toggling the complexity of the visual verification image used on registration (etc). (ManageRegistration.php, Register.php, Subs-Graphics.php, Register template)
& Added language entries for above. (Login language files)
! Quick modifying HTML posts would mess up linebreaks. (Post.php)
! The package manager wasn't uninstalling "end" searches correctly. (Subs-Package.php)
! Package manager was wrongly labelling redirects. (Packages.php)
! Inside of html tags convert &#13; to a real newline. (Subs.php)
! Resend activation after email change did not work with Joomla bridge (Joomla bridge/smf.php)
! Fixed language synch for login module on non-forum pages (Joomla bridge/mod_smf_login.php)
! It was not possible to remove a partial custom index. (ManageSearch.php)
! Fixed a bug in PCRE causing regular expression compilation failures in UTF-8 mode. (Load.php, Search.php, Subs.php, Subs-Members.php, Subs-Post.php)
! If an email had a quote in it sending a newsletter would fail. (ManageNews.php)


December 2006
--------------------------------------------------------------------------------
! Wrong capitalization on a couple of function calls. (PersonalMessage.php, Profile.php)
! Some bridge registration functions were still using deprecated constants. (Mambo 4.6 bridge/smf_registration.php)
! Users should never be redirected by to registration and activation pages on login (Mambo/Joomla bridge/smf.php)
! Do not allow 0, 0px, or 0pt to be used in size tags. (Subs.php)
+ Added e107 bridge. (Several files)
! Fixed a bug with the to and bcc fields for PMs that could cause some problems when displaying an invalid name. (PersonalMessage.php)
+ Added delete member and change member data integration hooks to e107 bridge. (e107 bridge/smf.php)
+ Added an "Upgrade" tab to the Mambo/Joomla bridge config page. (several files)


./Themes/default/languages/Errors.dutch.php

This operation isn't vital to the installation of this mod.
Find: Select

// Version: 1.1; Errors
Replace With: Select

// Version: 1.1.2; Errors
This operation isn't vital to the installation of this mod.
Find: Select

$txt['profile_error_name_taken'] = 'De geselecteerde gebruikersnaam is al in gebruik';
Replace With: Select

$txt['profile_error_name_taken'] = 'De geselecteerde gebruikersnaam is al in gebruik';
// Untranslated!
$txt['profile_error_name_too_long'] = 'The selected name is too long. It should be no greater than 60 characters long';

./Themes/default/languages/Errors.english.php

This operation isn't vital to the installation of this mod.
Find: Select

// Version: 1.1; Errors
Replace With: Select

// Version: 1.1.2; Errors
This operation isn't vital to the installation of this mod.
Find: Select

$txt['profile_error_name_taken'] = 'The selected username has already been taken';
Replace With: Select

$txt['profile_error_name_taken'] = 'The selected username has already been taken';
$txt['profile_error_name_too_long'] = 'The selected name is too long. It should be no greater than 60 characters long';

./Themes/default/languages/Errors.german.php

This operation isn't vital to the installation of this mod.
Find: Select

// Version: 1.1; Errors
Replace With: Select

// Version: 1.1.2; Errors
This operation isn't vital to the installation of this mod.
Find: Select

$txt['profile_error_name_taken'] = 'Der ausgew&auml;hlte Benutzername existiert schon';
Replace With: Select

$txt['profile_error_name_taken'] = 'Der ausgew&auml;hlte Benutzername existiert schon';
// Untranslated!
$txt['profile_error_name_too_long'] = 'The selected name is too long. It should be no greater than 60 characters long';

./Themes/default/languages/Errors.spanish.php

This operation isn't vital to the installation of this mod.
Find: Select

// Version: 1.1; Errors
Replace With: Select

// Version: 1.1.2; Errors
This operation isn't vital to the installation of this mod.
Find: Select

$txt['profile_error_name_taken'] = 'El nombre de usuario especificado ya est&aacute; siendo utilizado por alguien m&aacute;s';
Replace With: Select

$txt['profile_error_name_taken'] = 'El nombre de usuario especificado ya est&aacute; siendo utilizado por alguien m&aacute;s';
// Untranslated!
$txt['profile_error_name_too_long'] = 'The selected name is too long. It should be no greater than 60 characters long';

./Themes/default/languages/Login.dutch.php

This operation isn't vital to the installation of this mod.
Find: Select

// Version: 1.1; Login
Replace With: Select

// Version: 1.1.2; Login
This operation isn't vital to the installation of this mod.
Find: Select

$txt['admin_setting_disable_visual_verification'] = 'Schakel de visuele verificatie bij registraties uit';
Replace With: Select

// Untranslated!
$txt['admin_setting_image_verification_type'] = 'Complexity of visual verification image';
$txt['admin_setting_image_verification_type_desc'] = 'The more complex the image the harder it is for bots to bypass';
$txt['admin_setting_image_verification_off'] = 'Disabled';
$txt['admin_setting_image_verification_vsimple'] = 'Very Simple - Plain text on image';
$txt['admin_setting_image_verification_simple'] = 'Simple - Overlapping coloured letters, no noise';
$txt['admin_setting_image_verification_medium'] = 'Medium - Overlapping coloured letters, with noise';
$txt['admin_setting_image_verification_high'] = 'High - Angled letters, considerable noise';
$txt['admin_setting_image_verification_sample'] = 'Sample';
$txt['admin_setting_image_verification_nogd'] = '<b>Note:</b> as this server does not have the GD library installed the different complexity settings will have no effect.';

./Themes/default/languages/Login.english.php

This operation isn't vital to the installation of this mod.
Find: Select

// Version: 1.1; Login
Replace With: Select

// Version: 1.1.2; Login
This operation isn't vital to the installation of this mod.
Find: Select

$txt['admin_setting_disable_visual_verification'] = 'Disable the use of the visual verification on registration';
Replace With: Select

$txt['admin_setting_image_verification_type'] = 'Complexity of visual verification image';
$txt['admin_setting_image_verification_type_desc'] = 'The more complex the image the harder it is for bots to bypass';
$txt['admin_setting_image_verification_off'] = 'Disabled';
$txt['admin_setting_image_verification_vsimple'] = 'Very Simple - Plain text on image';
$txt['admin_setting_image_verification_simple'] = 'Simple - Overlapping coloured letters, no noise';
$txt['admin_setting_image_verification_medium'] = 'Medium - Overlapping coloured letters, with noise';
$txt['admin_setting_image_verification_high'] = 'High - Angled letters, considerable noise';
$txt['admin_setting_image_verification_sample'] = 'Sample';
$txt['admin_setting_image_verification_nogd'] = '<b>Note:</b> as this server does not have the GD library installed the different complexity settings will have no effect.';

./Themes/default/languages/Login.german.php

This operation isn't vital to the installation of this mod.
Find: Select

// Version: 1.1; Login
Replace With: Select

// Version: 1.1.2; Login
This operation isn't vital to the installation of this mod.
Find: Select

//!!! Untranslated
$txt['admin_setting_disable_visual_verification'] = 'Disable the use of the visual verification on registration';
Replace With: Select

// Untranslated!
$txt['admin_setting_image_verification_type'] = 'Complexity of visual verification image';
$txt['admin_setting_image_verification_type_desc'] = 'The more complex the image the harder it is for bots to bypass';
$txt['admin_setting_image_verification_off'] = 'Disabled';
$txt['admin_setting_image_verification_vsimple'] = 'Very Simple - Plain text on image';
$txt['admin_setting_image_verification_simple'] = 'Simple - Overlapping coloured letters, no noise';
$txt['admin_setting_image_verification_medium'] = 'Medium - Overlapping coloured letters, with noise';
$txt['admin_setting_image_verification_high'] = 'High - Angled letters, considerable noise';
$txt['admin_setting_image_verification_sample'] = 'Sample';
$txt['admin_setting_image_verification_nogd'] = '<b>Note:</b> as this server does not have the GD library installed the different complexity settings will have no effect.';

./Themes/default/languages/Login.spanish.php

This operation isn't vital to the installation of this mod.
Find: Select

// Version: 1.1; Login
Replace With: Select

// Version: 1.1.2; Login
This operation isn't vital to the installation of this mod.
Find: Select

//!!! Untranslated
$txt['admin_setting_disable_visual_verification'] = 'Disable the use of the visual verification on registration';
Replace With: Select

// Untranslated!
$txt['admin_setting_image_verification_type'] = 'Complexity of visual verification image';
$txt['admin_setting_image_verification_type_desc'] = 'The more complex the image the harder it is for bots to bypass';
$txt['admin_setting_image_verification_off'] = 'Disabled';
$txt['admin_setting_image_verification_vsimple'] = 'Very Simple - Plain text on image';
$txt['admin_setting_image_verification_simple'] = 'Simple - Overlapping coloured letters, no noise';
$txt['admin_setting_image_verification_medium'] = 'Medium - Overlapping coloured letters, with noise';
$txt['admin_setting_image_verification_high'] = 'High - Angled letters, considerable noise';
$txt['admin_setting_image_verification_sample'] = 'Sample';
$txt['admin_setting_image_verification_nogd'] = '<b>Note:</b> as this server does not have the GD library installed the different complexity settings will have no effect.';

./Themes/default/languages/Themes.english.php

This operation isn't vital to the installation of this mod.
Find: Select

$txt['hide_post_group_desc'] = 'Enabling this will not display a members post group title on the message view if they are assigned to a non-post based group.';
Replace With: Select

$txt['hide_post_group_desc'] = 'Enabling this will not display a member\'s post group title on the message view if they are assigned to a non-post based group.';

./Themes/default/languages/index.dutch.php

This operation isn't vital to the installation of this mod.
Find: Select

// Version: 1.1; index
Replace With: Select

// Version: 1.1.2; index
This operation isn't vital to the installation of this mod.
Find: Select

<a href="http://www.simplemachines.org/about/copyright.php" title="Free Forum Software" target="_blank">SMF &copy; 2006, Simple Machines LLC</a>';
Replace With: Select

<a href="http://www.simplemachines.org/about/copyright.php" title="Free Forum Software" target="_blank">SMF &copy; 2006-2007, Simple Machines LLC</a>';

./Themes/default/languages/index.english.php

This operation isn't vital to the installation of this mod.
Find: Select

// Version: 1.1; index
Replace With: Select

// Version: 1.1.2; index
This operation isn't vital to the installation of this mod.
Find: Select

<a href="http://www.simplemachines.org/about/copyright.php" title="Free Forum Software" target="_blank">SMF &copy; 2006, Simple Machines LLC</a>';
Replace With: Select

<a href="http://www.simplemachines.org/about/copyright.php" title="Free Forum Software" target="_blank">SMF &copy; 2006-2007, Simple Machines LLC</a>';

./Themes/default/languages/index.german.php

This operation isn't vital to the installation of this mod.
Find: Select

// Version: 1.1; index
Replace With: Select

// Version: 1.1.2; index
This operation isn't vital to the installation of this mod.
Find: Select

<a href="http://www.simplemachines.org/about/copyright.php" title="Free Forum Software" target="_blank">SMF &copy; 2006, Simple Machines LLC</a>';
Replace With: Select

<a href="http://www.simplemachines.org/about/copyright.php" title="Free Forum Software" target="_blank">SMF &copy; 2006-2007, Simple Machines LLC</a>';

./Themes/default/languages/index.spanish.php

This operation isn't vital to the installation of this mod.
Find: Select

// Version: 1.1; index
Replace With: Select

// Version: 1.1.2; index
This operation isn't vital to the installation of this mod.
Find: Select

<a href="http://www.simplemachines.org/about/copyright.php" title="Free Forum Software" target="_blank">SMF &copy; 2006, Simple Machines LLC</a>';
Replace With: Select

<a href="http://www.simplemachines.org/about/copyright.php" title="Free Forum Software" target="_blank">SMF &copy; 2006-2007, Simple Machines LLC</a>';
Advertisement: