Advertisement:

Navigation

Readme

SMF 2.0.18
SMF 2.0.18 adds php 7.4 support & fixes several bugs in 2.0.17.

File Edits

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

Operation #1
Find: [Select]
// Version: 2.0.16;
Replace With: [Select]
// Version: 2.0.18;
This operation isn't vital to the installation of this mod.

Operation #2
Find: [Select]
<a href="https://www.simplemachines.org/about/smf/license.php" title="License" target="_blank" class="new_win">SMF &copy; 2019</a>, <a href="https://www.simplemachines.org" title="Simple Machines" target="_blank" class="new_win">Simple Machines</a>';
Replace With: [Select]
<a href="https://www.simplemachines.org/about/smf/license.php" title="License" target="_blank" class="new_win">SMF &copy; 2021</a>, <a href="https://www.simplemachines.org" title="Simple Machines" target="_blank" class="new_win">Simple Machines</a>';
This operation isn't vital to the installation of this mod.

./index.php

Operation #1
Find: [Select]
* @version 2.0.17
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
$forum_version = 'SMF 2.0.17';
@ini_set('memory_limit', '128M');

// Get everything started up...
define('SMF', 1);
if (function_exists('set_magic_quotes_runtime'))
@set_magic_quotes_runtime(0);
error_reporting(defined('E_STRICT') ? E_ALL | E_STRICT : E_ALL);
Replace With: [Select]
$forum_version = 'SMF 2.0.18';
@ini_set('memory_limit', '128M');

// Get everything started up...
define('SMF', 1);
if (version_compare(PHP_VERSION, '7.4.0') == -1 && function_exists('set_magic_quotes_runtime'))
@set_magic_quotes_runtime(0);
error_reporting(defined('E_STRICT') ? E_ALL | E_STRICT : E_ALL);

./SSI.php

Operation #1
Find: [Select]
* @version 2.0.17
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
$ssi_magic_quotes_runtime = function_exists('get_magic_quotes_gpc') && get_magic_quotes_runtime();
if (function_exists('set_magic_quotes_runtime'))
@set_magic_quotes_runtime(0);
$time_start = microtime();
Replace With: [Select]
$ssi_magic_quotes_runtime = version_compare(PHP_VERSION, '7.4.0') == -1 && function_exists('get_magic_quotes_gpc') && get_magic_quotes_runtime();
if (version_compare(PHP_VERSION, '7.4.0') == -1 && function_exists('set_magic_quotes_runtime'))
@set_magic_quotes_runtime(0);
$time_start = microtime();

Operation #3
Find: [Select]
if (function_exists('set_magic_quotes_runtime'))
@set_magic_quotes_runtime($ssi_magic_quotes_runtime);
Replace With: [Select]
if (version_compare(PHP_VERSION, '7.4.0') == -1 && function_exists('set_magic_quotes_runtime'))
@set_magic_quotes_runtime($ssi_magic_quotes_runtime);

Operation #4
Find: [Select]
// This user has voted on all the polls.
if ($row === false)
Replace With: [Select]
// This user has voted on all the polls.
if (empty($row))

./Sources/Agreement.php

Operation #1
Find: [Select]
* @version 2.0.16
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
fatal_lang_error('no_privacy_policy', false);
Replace With: [Select]
fatal_lang_error('error_no_privacy_policy', false);

./Sources/Class-Graphics.php

Operation #1
Find: [Select]
* @version 2.0
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
$this->Buf[2 + $i] = ord($data{$i});

$data = substr($data, $count);
Replace With: [Select]
$this->Buf[2 + $i] = ord($data[$i]);

$data = substr($data, $count);

Operation #3
Find: [Select]
$bmp .= $data{$i};
// Otherwise, this is background...
else
Replace With: [Select]
$bmp .= $data[$i];
// Otherwise, this is background...
else

./Sources/DbExtra-mysql.php

Operation #1
Find: [Select]
* @version 2.0.15
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
$schema_create .= ',' . $crlf . ' ' . $keyname . ' (' . implode($columns, ', ') . ')';
}
Replace With: [Select]
$schema_create .= ',' . $crlf . ' ' . $keyname . ' (' . implode(', ', $columns) . ')';
}

./Sources/Subs-Db-mysql.php

Operation #1
Find: [Select]
function smf_db_insert($method = 'replace', $table, $columns, $data, $keys, $disable_trans = false, $connection = null)
Replace With: [Select]
function smf_db_insert($method, $table, $columns, $data, $keys, $disable_trans = false, $connection = null)

./Sources/Subs-Db-postgresql.php

Operation #1
Find: [Select]
function smf_db_insert($method = 'replace', $table, $columns, $data, $keys, $disable_trans = false, $connection = null)
Replace With: [Select]
function smf_db_insert($method, $table, $columns, $data, $keys, $disable_trans = false, $connection = null)

./Sources/Subs-Db-sqlite.php

Operation #1
Find: [Select]
function smf_db_insert($method = 'replace', $table, $columns, $data, $keys, $disable_trans = false, $connection = null)
Replace With: [Select]
function smf_db_insert($method, $table, $columns, $data, $keys, $disable_trans = false, $connection = null)

./Sources/Display.php

Operation #1
Find: [Select]
* @version 2.0.12
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'name' => $row['poster_name'],
'href' => $pollinfo['id_member'] == 0 ? '' : $scripturl . '?action=profile;u=' . $pollinfo['id_member'],
'link' => $pollinfo['id_member'] == 0 ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $pollinfo['id_member'] . '">' . $row['poster_name'] . '</a>'
Replace With: [Select]
'name' => $pollinfo['poster_name'],
'href' => $pollinfo['id_member'] == 0 ? '' : $scripturl . '?action=profile;u=' . $pollinfo['id_member'],
'link' => $pollinfo['id_member'] == 0 ? $pollinfo['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $pollinfo['id_member'] . '">' . $pollinfo['poster_name'] . '</a>'

Operation #3
Find: [Select]
$fixchar = create_function('$n', '
if ($n < 32)
return \'\';
elseif ($n < 128)
return chr($n);
Replace With: [Select]
$fixchar = function($n)
{
if ($n < 32)
return '';
elseif ($n < 128)
return chr($n);

Operation #4
Find: [Select]
return chr(240 | $n >> 18) . chr(128 | $n >> 12 & 63) . chr(128 | $n >> 6 & 63) . chr(128 | $n & 63);');

$disposition = !isset($_REQUEST['image']) ? 'attachment' : 'inline';
Replace With: [Select]
return chr(240 | $n >> 18) . chr(128 | $n >> 12 & 63) . chr(128 | $n >> 6 & 63) . chr(128 | $n & 63);
};

$disposition = !isset($_REQUEST['image']) ? 'attachment' : 'inline';

Operation #5
Find: [Select]
$callback = create_function('$buffer', 'return preg_replace(\'~[\r]?\n~\', "\r\n", $buffer);');
elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Mac') !== false)
$callback = create_function('$buffer', 'return preg_replace(\'~[\r]?\n~\', "\r", $buffer);');
else
$callback = create_function('$buffer', 'return preg_replace(\'~[\r]?\n~\', "\n", $buffer);');
}
Replace With: [Select]
$callback = function($buffer){return preg_replace('~[\r]?\n~', "\r\n", $buffer);};
elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Mac') !== false)
$callback = function($buffer){return preg_replace('~[\r]?\n~', "\r", $buffer);};
else
$callback = function($buffer){return preg_replace('~[\r]?\n~', "\n", $buffer);};
}

./Sources/Groups.php

Operation #1
Find: [Select]
* @version 2.0.16
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'function' => create_function('$group', '
global $scripturl, $context;

$output = \'<a href="\' . $scripturl . \'?action=\' . $context[\'current_action\'] . (isset($context[\'admin_area\']) ? \';area=\' . $context[\'admin_area\'] : \'\') . \';sa=members;group=\' . $group[\'id\'] . \'" \' . ($group[\'color\'] ? \'style="color: \' . $group[\'color\'] . \';"\' : \'\') . \'>\' . $group[\'name\'] . \'</a>\';

if ($group[\'desc\'])
$output .= \'<div class="smalltext">\' . $group[\'desc\'] . \'</div>\';

return $output;
'),
'style' => 'width: 50%;',
),
Replace With: [Select]
'function' => function($group) use ($scripturl, $context)
{
$output = '<a href="' . $scripturl . '?action=' . $context['current_action'] . (isset($context['admin_area']) ? ';area=' . $context['admin_area'] : '') . ';sa=members;group=' . $group['id'] . '" ' . ($group['color'] ? 'style="color: ' . $group['color'] . ';"' : '') . '>' . $group['name'] . '</a>';

if ($group['desc'])
$output .= '<div class="smalltext">' . $group['desc'] . '</div>';

return $output;
},
'style' => 'width: 50%;',
),

Operation #3
Find: [Select]
'function' => create_function('$group', '
global $txt;

return empty($group[\'moderators\']) ? \'<em>\' . $txt[\'membergroups_new_copy_none\'] . \'</em>\' : implode(\', \', $group[\'moderators\']);
'),
),
),
Replace With: [Select]
'function' => function($group) use ($txt)
{
return empty($group['moderators']) ? '<em>' . $txt['membergroups_new_copy_none'] . '</em>' : implode(', ', $group['moderators']);
},
),
),

./Sources/Load.php

Operation #1
Find: [Select]
* @version 2.0.17
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
if (empty($modSettings['defaultMaxMembers']) || $modSettings['defaultMaxMembers'] <= 0 || $modSettings['defaultMaxMembers'] > 999)
$modSettings['defaultMaxMembers'] = 30;
Replace With: [Select]
if (empty($modSettings['defaultMaxMembers']) || $modSettings['defaultMaxMembers'] <= 0 || $modSettings['defaultMaxMembers'] > 999)
$modSettings['defaultMaxMembers'] = 30;

// Covers null and !isset cases
if (empty($modSettings['requirePolicyAgreement']))
$modSettings['requirePolicyAgreement'] = 0;

Operation #3
Find: [Select]
session_set_save_handler('sessionOpen', 'sessionClose', 'sessionRead', 'sessionWrite', 'sessionDestroy', 'sessionGC');
Replace With: [Select]
@ini_set('session.serialize_handler', 'php_serialize');

if (ini_get('session.serialize_handler') != 'php_serialize')
@ini_set('session.serialize_handler', 'php');

session_set_save_handler('sessionOpen', 'sessionClose', 'sessionRead', 'sessionWrite', 'sessionDestroy', 'sessionGC');

Operation #4
Find: [Select]
$utf8 = (empty($modSettings['global_character_set']) ? $txt['lang_character_set'] : $modSettings['global_character_set']) === 'UTF-8' && (strpos(strtolower(PHP_OS), 'win') === false || @version_compare(PHP_VERSION, '4.2.3') != -1);

// Set a list of common functions.
$ent_list = empty($modSettings['disableEntityCheck']) ? '&(#\d{1,7}|quot|amp|lt|gt|nbsp);' : '&(#021|quot|amp|lt|gt|nbsp);';
$ent_check = empty($modSettings['disableEntityCheck']) ? array('preg_replace_callback(\'~(&#(\d{1,7}|x[0-9a-fA-F]{1,6});)~\', \'entity_fix__callback\', ', ')') : array('', '');

// 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{AD}\x{2000}-\x{200F}\x{201F}\x{202F}\x{3000}\x{FEFF}' : "\xC2\xA0\xC2\xAD\xE2\x80\x80-\xE2\x80\x8F\xE2\x80\x9F\xE2\x80\xAF\xE2\x80\x9F\xE3\x80\x80\xEF\xBB\xBF") : '\x00-\x08\x0B\x0C\x0E-\x19\xA0';

$smcFunc += array(
'entity_fix' => 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 === 0x202E || $num === 0x202D ? \'\' : \'&#\' . $num . \';\';'),
'htmlspecialchars' => create_function('$string, $quote_style = ENT_COMPAT, $charset = \'ISO-8859-1\'', '
global $smcFunc;
return ' . ($utf8 ? '$smcFunc[\'fix_utf8mb4\'](' : '') . strtr($ent_check[0], array('&' => '&amp;')) . 'htmlspecialchars($string, $quote_style, ' . ($utf8 ? '\'UTF-8\'' : '$charset') . ')' . $ent_check[1] . ($utf8 ? ')' : '') . ';'),
'fix_utf8mb4' => create_function('$string', '
$i = 0;
$len = strlen($string);
$new_string = \'\';
while ($i < $len)
{
$ord = ord($string[$i]);
if ($ord < 128)
{
$new_string .= $string[$i];
$i++;
}
elseif ($ord < 224)
{
$new_string .= $string[$i] . $string[$i+1];
$i += 2;
}
elseif ($ord < 240)
{
$new_string .= $string[$i] . $string[$i+1] . $string[$i+2];
$i += 3;
}
elseif ($ord < 248)
{
// Magic happens.
$val = (ord($string[$i]) & 0x07) << 18;
$val += (ord($string[$i+1]) & 0x3F) << 12;
$val += (ord($string[$i+2]) & 0x3F) << 6;
$val += (ord($string[$i+3]) & 0x3F);
$new_string .= \'&#\' . $val . \';\';
$i += 4;
}
}
return $new_string;'),
'htmltrim' => create_function('$string', '
global $smcFunc;
return preg_replace(\'~^(?:[ \t\n\r\x0B\x00' . $space_chars . ']|&nbsp;)+|(?:[ \t\n\r\x0B\x00' . $space_chars . ']|&nbsp;)+$~' . ($utf8 ? 'u' : '') . '\', \'\', ' . implode('$string', $ent_check) . ');'),
'strlen' => create_function('$string', '
global $smcFunc;
return strlen(preg_replace(\'~' . $ent_list . ($utf8 ? '|.~u' : '~') . '\', \'_\', ' . implode('$string', $ent_check) . '));'),
'strpos' => create_function('$haystack, $needle, $offset = 0', '
global $smcFunc;
$haystack_arr = preg_split(\'~(&#' . (empty($modSettings['disableEntityCheck']) ? '\d{1,7}' : '021') . ';|&quot;|&amp;|&lt;|&gt;|&nbsp;|.)~' . ($utf8 ? 'u' : '') . '\', ' . implode('$haystack', $ent_check) . ', -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
$haystack_size = count($haystack_arr);
if (strlen($needle) === 1)
{
Replace With: [Select]
$utf8 = (empty($modSettings['global_character_set']) ? (!empty($txt['lang_character_set']) ? $txt['lang_character_set'] : '') : $modSettings['global_character_set']) === 'UTF-8' && (strpos(strtolower(PHP_OS), 'win') === false || @version_compare(PHP_VERSION, '4.2.3') != -1);

// Set a list of common functions.
$ent_list = empty($modSettings['disableEntityCheck']) ? '&(#\d{1,7}|quot|amp|lt|gt|nbsp);' : '&(#021|quot|amp|lt|gt|nbsp);';
$ent_check = empty($modSettings['disableEntityCheck']) ? function($string)
{
$string = preg_replace_callback('~(&amp;#(\d{1,7}|x[0-9a-fA-F]{1,6});)~', 'entity_fix__callback', $string);
return $string;
} : function($string)
{
return $string;
};
$fix_utf8mb4 = function($string) use ($utf8, $smcFunc)
{
if (!$utf8)
return $string;

$i = 0;
$len = strlen($string);
$new_string = '';
while ($i < $len)
{
$ord = ord($string[$i]);
if ($ord < 128)
{
$new_string .= $string[$i];
$i++;
}
elseif ($ord < 224)
{
$new_string .= $string[$i] . $string[$i + 1];
$i += 2;
}
elseif ($ord < 240)
{
$new_string .= $string[$i] . $string[$i + 1] . $string[$i + 2];
$i += 3;
}
elseif ($ord < 248)
{
// Magic happens.
$val = (ord($string[$i]) & 0x07) << 18;
$val += (ord($string[$i + 1]) & 0x3F) << 12;
$val += (ord($string[$i + 2]) & 0x3F) << 6;
$val += (ord($string[$i + 3]) & 0x3F);
$new_string .= '&#' . $val . ';';
$i += 4;
}
}
return $new_string;
};

// 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{AD}\x{2000}-\x{200F}\x{201F}\x{202F}\x{3000}\x{FEFF}' : "\xC2\xA0\xC2\xAD\xE2\x80\x80-\xE2\x80\x8F\xE2\x80\x9F\xE2\x80\xAF\xE2\x80\x9F\xE3\x80\x80\xEF\xBB\xBF") : '\x00-\x08\x0B\x0C\x0E-\x19\xA0';

$smcFunc += array(
'entity_fix' => function($string)
{
$num = $string[0] === 'x' ? hexdec(substr($string, 1)) : (int) $string;
return $num < 0x20 || $num > 0x10FFFF || ($num >= 0xD800 && $num <= 0xDFFF) || $num === 0x202E || $num === 0x202D ? '' : '&#' . $num . ';';
},
'htmlspecialchars' => function($string, $quote_style = ENT_COMPAT, $charset = 'ISO-8859-1') use ($ent_check, $utf8, $fix_utf8mb4)
{
return $fix_utf8mb4($ent_check(htmlspecialchars($string, $quote_style, $utf8 ? 'UTF-8' : $charset)));
},
'fix_utf8mb4' => $fix_utf8mb4,
'htmltrim' => function($string) use ($utf8, $ent_check)
{
// Preg_replace space characters depend on the character set in use
$space_chars = $utf8 ? '\p{Z}\p{C}' : '\x00-\x20\x80-\xA0';

return preg_replace('~^(?:[' . $space_chars . ']|&nbsp;)+|(?:[' . $space_chars . ']|&nbsp;)+$~' . ($utf8 ? 'u' : ''), '', $ent_check($string));
},
'strlen' => function($string) use ($ent_list, $utf8, $ent_check)
{
return strlen(preg_replace('~' . $ent_list . ($utf8 ? '|.~u' : '~'), '_', $ent_check($string)));
},
'strpos' => function($haystack, $needle, $offset = 0) use ($utf8, $ent_check, $ent_list, $modSettings)
{
$haystack_arr = preg_split('~(' . $ent_list . '|.)~' . ($utf8 ? 'u' : ''), $ent_check($haystack), -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

if (strlen($needle) === 1)
{

Operation #5
Find: [Select]
$needle_arr = preg_split(\'~(&#' . (empty($modSettings['disableEntityCheck']) ? '\d{1,7}' : '021') . ';|&quot;|&amp;|&lt;|&gt;|&nbsp;|.)~' . ($utf8 ? 'u' : '') . '\', ' . implode('$needle', $ent_check) . ', -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
$needle_size = count($needle_arr);

$result = array_search($needle_arr[0], array_slice($haystack_arr, $offset));
while (is_int($result))
{
$offset += $result;
Replace With: [Select]
$needle_arr = preg_split('~(' . $ent_list . '|.)~' . ($utf8 ? 'u' : '') . '', $ent_check($needle), -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
$needle_size = count($needle_arr);

$result = array_search($needle_arr[0], array_slice($haystack_arr, $offset));
while ((int) $result === $result)
{
$offset += $result;

Operation #6
Find: [Select]
}'),
'substr' => create_function('$string, $start, $length = null', '
global $smcFunc;
$ent_arr = preg_split(\'~(&#' . (empty($modSettings['disableEntityCheck']) ? '\d{1,7}' : '021') . ';|&quot;|&amp;|&lt;|&gt;|&nbsp;|.)~' . ($utf8 ? 'u' : '') . '\', ' . implode('$string', $ent_check) . ', -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
return $length === null ? implode(\'\', array_slice($ent_arr, $start)) : implode(\'\', array_slice($ent_arr, $start, $length));'),
'strtolower' => $utf8 ? (function_exists('mb_strtolower') ? create_function('$string', '
return mb_strtolower($string, \'UTF-8\');') : create_function('$string', '
global $sourcedir;
require_once($sourcedir . \'/Subs-Charset.php\');
return utf8_strtolower($string);')) : 'strtolower',
'strtoupper' => $utf8 ? (function_exists('mb_strtoupper') ? create_function('$string', '
return mb_strtoupper($string, \'UTF-8\');') : create_function('$string', '
global $sourcedir;
require_once($sourcedir . \'/Subs-Charset.php\');
return utf8_strtoupper($string);')) : 'strtoupper',
'truncate' => create_function('$string, $length', (empty($modSettings['disableEntityCheck']) ? '
global $smcFunc;
$string = ' . implode('$string', $ent_check) . ';' : '') . '
preg_match(\'~^(' . $ent_list . '|.){\' . $smcFunc[\'strlen\'](substr($string, 0, $length)) . \'}~'. ($utf8 ? 'u' : '') . '\', $string, $matches);
$string = $matches[0];
while (strlen($string) > $length)
$string = preg_replace(\'~(?:' . $ent_list . '|.)$~'. ($utf8 ? 'u' : '') . '\', \'\', $string);
return $string;'),
'ucfirst' => $utf8 ? create_function('$string', '
global $smcFunc;
return $smcFunc[\'strtoupper\']($smcFunc[\'substr\']($string, 0, 1)) . $smcFunc[\'substr\']($string, 1);') : 'ucfirst',
'ucwords' => $utf8 ? create_function('$string', '
global $smcFunc;
$words = preg_split(\'~([\s\r\n\t]+)~\', $string, -1, PREG_SPLIT_DELIM_CAPTURE);
for ($i = 0, $n = count($words); $i < $n; $i += 2)
$words[$i] = $smcFunc[\'ucfirst\']($words[$i]);
return implode(\'\', $words);') : 'ucwords',
);
Replace With: [Select]
}
},
'substr' => function($string, $start, $length = null) use ($utf8, $ent_check, $ent_list, $modSettings)
{
$ent_arr = preg_split('~(' . $ent_list . '|.)~' . ($utf8 ? 'u' : '') . '', $ent_check($string), -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
return $length === null ? implode('', array_slice($ent_arr, $start)) : implode('', array_slice($ent_arr, $start, $length));
},
'strtolower' => $utf8 ? function($string) use ($sourcedir)
{
if (!function_exists('mb_strtolower'))
{
require_once($sourcedir . '/Subs-Charset.php');
return utf8_strtolower($string);
}

return mb_strtolower($string, 'UTF-8');
} : 'strtolower',
'strtoupper' => $utf8 ? function($string)
{
global $sourcedir;

if (!function_exists('mb_strtolower'))
{
require_once($sourcedir . '/Subs-Charset.php');
return utf8_strtoupper($string);
}

return mb_strtoupper($string, 'UTF-8');
} : 'strtoupper',
'truncate' => function($string, $length) use ($utf8, $ent_check, $ent_list, &$smcFunc)
{
$string = $ent_check($string);
preg_match('~^(' . $ent_list . '|.){' . $smcFunc['strlen'](substr($string, 0, $length)) . '}~' . ($utf8 ? 'u' : ''), $string, $matches);
$string = $matches[0];
while (strlen($string) > $length)
$string = preg_replace('~(?:' . $ent_list . '|.)$~' . ($utf8 ? 'u' : ''), '', $string);
return $string;
},
'ucfirst' => $utf8 ? function($string) use (&$smcFunc)
{
return $smcFunc['strtoupper']($smcFunc['substr']($string, 0, 1)) . $smcFunc['substr']($string, 1);
} : 'ucfirst',
'ucwords' => $utf8 ? function($string) use (&$smcFunc)
{
$words = preg_split('~([\s\r\n\t]+)~', $string, -1, PREG_SPLIT_DELIM_CAPTURE);
for ($i = 0, $n = count($words); $i < $n; $i += 2)
$words[$i] = $smcFunc['ucfirst']($words[$i]);
return implode('', $words);
} : 'ucwords',
);

Operation #7
Find: [Select]

// Check first the integration, then the cookie, and last the session.
Replace With: [Select]
global $cookie_no_auth_secret;

// Check first the integration, then the cookie, and last the session.

Operation #8
Find: [Select]
$check = hash_hmac('sha1', sha1($user_settings['passwd'] . $user_settings['password_salt']), get_auth_secret()) == $password;
else
$check = false;
Replace With: [Select]
$check = empty($cookie_no_auth_secret) ? hash_hmac('sha1', sha1($user_settings['passwd'] . $user_settings['password_salt']), get_auth_secret()) == $password : sha1($user_settings['passwd'] . $user_settings['password_salt']) == $password;
else
$check = false;

Operation #9
Find: [Select]
elseif (file_exists($cachedir . '/data_' . $key . '.php') && filesize($cachedir . '/data_' . $key . '.php') > 10)
{
@include($cachedir . '/data_' . $key . '.php');
if (!empty($expired) && isset($value))
{
Replace With: [Select]
elseif (file_exists($cachedir . '/data_' . $key . '.php'))
{
// Turns out that include does not honor locking, but we need it to.
// This can be accomplished by placing a small wrapper around it:
$tmp = fopen($cachedir . '/data_' . $key . '.php', 'rb');
@flock($tmp, LOCK_SH);
@include($cachedir . '/data_' . $key . '.php');
@flock($tmp, LOCK_UN);
fclose($tmp);

if (!empty($expired) && isset($value))
{

./Sources/ManageAttachments.php

Operation #1
Find: [Select]
* @version 2.0.12
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'function' => create_function('$rowData', '
global $modSettings, $context, $scripturl;

$link = \'<a href="\';

// In case of a custom avatar URL attachments have a fixed directory.
if ($rowData[\'attachment_type\'] == 1)
$link .= sprintf(\'%1$s/%2$s\', $modSettings[\'custom_avatar_url\'], $rowData[\'filename\']);

// By default avatars are downloaded almost as attachments.
elseif ($context[\'browse_type\'] == \'avatars\')
$link .= sprintf(\'%1$s?action=dlattach;type=avatar;attach=%2$d\', $scripturl, $rowData[\'id_attach\']);

// Normal attachments are always linked to a topic ID.
else
$link .= sprintf(\'%1$s?action=dlattach;topic=%2$d.0;attach=%3$d\', $scripturl, $rowData[\'id_topic\'], $rowData[\'id_attach\']);

$link .= \'"\';

// Show a popup on click if it\'s a picture and we know its dimensions.
if (!empty($rowData[\'width\']) && !empty($rowData[\'height\']))
$link .= sprintf(\' onclick="return reqWin(this.href\' . ($rowData[\'attachment_type\'] == 1 ? \'\' : \' + \\\';image\\\'\') . \', %1$d, %2$d, true);"\', $rowData[\'width\'] + 20, $rowData[\'height\'] + 20);

$link .= sprintf(\'>%1$s</a>\', preg_replace(\'~&amp;#(\\\\d{1,7}|x[0-9a-fA-F]{1,6});~\', \'&#\\\\1;\', htmlspecialchars($rowData[\'filename\'])));

// Show the dimensions.
if (!empty($rowData[\'width\']) && !empty($rowData[\'height\']))
$link .= sprintf(\' <span class="smalltext">%1$dx%2$d</span>\', $rowData[\'width\'], $rowData[\'height\']);

return $link;
'),
),
'sort' => array(
Replace With: [Select]
'function' => function($rowData) use ($modSettings, $context, $scripturl)
{
$link = '<a href="';

// In case of a custom avatar URL attachments have a fixed directory.
if ($rowData['attachment_type'] == 1)
$link .= sprintf('%1$s/%2$s', $modSettings['custom_avatar_url'], $rowData['filename']);

// By default avatars are downloaded almost as attachments.
elseif ($context['browse_type'] == 'avatars')
$link .= sprintf('%1$s?action=dlattach;type=avatar;attach=%2$d', $scripturl, $rowData['id_attach']);

// Normal attachments are always linked to a topic ID.
else
$link .= sprintf('%1$s?action=dlattach;topic=%2$d.0;attach=%3$d', $scripturl, $rowData['id_topic'], $rowData['id_attach']);

$link .= '"';

// Show a popup on click if it's a picture and we know its dimensions.
if (!empty($rowData['width']) && !empty($rowData['height']))
$link .= sprintf(' onclick="return reqWin(this.href' . ($rowData['attachment_type'] == 1 ? '' : '+ \';image\'') . ', %1$d, %2$d, true);"', $rowData['width'] + 20, $rowData['height'] + 20);

$link .= sprintf('>%1$s</a>', preg_replace('~&amp;#(\\\\d{1,7}|x[0-9a-fA-F]{1,6});~', '&#\\\\1;', htmlspecialchars($rowData['filename'])));

// Show the dimensions.
if (!empty($rowData['width']) && !empty($rowData['height']))
$link .= sprintf(' <span class="smalltext">%1$dx%2$d</span>', $rowData['width'], $rowData['height']);

return $link;
},
),
'sort' => array(

Operation #3
Find: [Select]
'function' => create_function('$rowData','
global $txt;

return sprintf(\'%1$s%2$s\', round($rowData[\'size\'] / 1024, 2), $txt[\'kilobyte\']);
'),
'class' => 'windowbg',
),
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
return sprintf('%1$s%2$s', round($rowData['size'] / 1024, 2), $txt['kilobyte']);
},
'class' => 'windowbg',
),

Operation #4
Find: [Select]
'function' => create_function('$rowData', '
global $scripturl;

// In case of an attachment, return the poster of the attachment.
if (empty($rowData[\'id_member\']))
return htmlspecialchars($rowData[\'poster_name\']);

// Otherwise it must be an avatar, return the link to the owner of it.
else
return sprintf(\'<a href="%1$s?action=profile;u=%2$d">%3$s</a>\', $scripturl, $rowData[\'id_member\'], $rowData[\'poster_name\']);
'),
),
'sort' => array(
Replace With: [Select]
'function' => function($rowData) use ($scripturl)
{
// In case of an attachment, return the poster of the attachment.
if (empty($rowData['id_member']))
return htmlspecialchars($rowData['poster_name']);

// Otherwise it must be an avatar, return the link to the owner of it.
else
return sprintf('<a href="%1$s?action=profile;u=%2$d">%3$s</a>', $scripturl, $rowData['id_member'], $rowData['poster_name']);
},
),
'sort' => array(

Operation #5
Find: [Select]
'function' => create_function('$rowData', '
global $txt, $context, $scripturl;

// The date the message containing the attachment was posted or the owner of the avatar was active.
$date = empty($rowData[\'poster_time\']) ? $txt[\'never\'] : timeformat($rowData[\'poster_time\']);

// Add a link to the topic in case of an attachment.
if ($context[\'browse_type\'] !== \'avatars\')
$date .= sprintf(\'<br />%1$s <a href="%2$s?topic=%3$d.msg%4$d#msg%4$d">%5$s</a>\', $txt[\'in\'], $scripturl, $rowData[\'id_topic\'], $rowData[\'id_msg\'], $rowData[\'subject\']);

return $date;
'),
'class' => 'windowbg',
),
Replace With: [Select]
'function' => function($rowData) use ($txt, $context, $scripturl)
{
// The date the message containing the attachment was posted or the owner of the avatar was active.
$date = empty($rowData['poster_time']) ? $txt['never'] : timeformat($rowData['poster_time']);

// Add a link to the topic in case of an attachment.
if ($context['browse_type'] !== 'avatars')
$date .= sprintf('<br />%1$s <a href="%2$s?topic=%3$d.msg%4$d#msg%4$d">%5$s</a>', $txt['in'], $scripturl, $rowData['id_topic'], $rowData['id_msg'], $rowData['subject']);

return $date;
},
'class' => 'windowbg',
),

Operation #6
Find: [Select]
'function' => create_function('$rowData','
global $txt;

return comma_format($rowData[\'downloads\']);
'),
'class' => 'windowbg',
),
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
return comma_format($rowData['downloads']);
},
'class' => 'windowbg',
),

Operation #7
Find: [Select]
'function' => create_function('$rowData', '
return \'<input type="radio" name="current_dir" value="\' . $rowData[\'id\'] . \'" \' . ($rowData[\'current\'] ? \'checked="checked"\' : \'\') . \' class="input_radio" />\';
'),
'style' => 'text-align: center; width: 15%;',
),
Replace With: [Select]
'function' => function($rowData)
{
return '<input type="radio" name="current_dir" value="' . $rowData['id'] . '" ' . ($rowData['current'] ? 'checked="checked"' : '') . ' class="input_radio" />';
},
'style' => 'text-align: center; width: 15%;',
),

Operation #8
Find: [Select]
'function' => create_function('$rowData', '
return \'<input type="text" size="30" name="dirs[\' . $rowData[\'id\'] . \']" value="\' . $rowData[\'path\'] . \'" class="input_text" style="width: 100%" />\';
'),
'style' => 'text-align: center; width: 30%;',
),
Replace With: [Select]
'function' => function($rowData)
{
return '<input type="text" size="30" name="dirs[' . $rowData['id'] . ']" value="' . $rowData['path'] . '" class="input_text" style="width: 100%" />';
},
'style' => 'text-align: center; width: 30%;',
),

./Sources/ManageBans.php

Operation #1
Find: [Select]
* @version 2.0
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'function' => create_function('$rowData', '
global $context;

return timeformat($rowData[\'ban_time\'], empty($context[\'ban_time_format\']) ? true : $context[\'ban_time_format\']);
'),
),
'sort' => array(
Replace With: [Select]
'function' => function($rowData) use ($context)
{
return timeformat($rowData['ban_time'], empty($context['ban_time_format']) ? true : $context['ban_time_format']);
},
),
'sort' => array(

Operation #3
Find: [Select]
'function' => create_function('$rowData', '
global $txt;

// This ban never expires...whahaha.
if ($rowData[\'expire_time\'] === null)
return $txt[\'never\'];

// This ban has already expired.
elseif ($rowData[\'expire_time\'] < time())
return sprintf(\'<span style="color: red">%1$s</span>\', $txt[\'ban_expired\']);

// Still need to wait a few days for this ban to expire.
else
return sprintf(\'%1$d&nbsp;%2$s\', ceil(($rowData[\'expire_time\'] - time()) / (60 * 60 * 24)), $txt[\'ban_days\']);
'),
),
'sort' => array(
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
// This ban never expires...whahaha.
if ($rowData['expire_time'] === null)
return $txt['never'];

// This ban has already expired.
elseif ($rowData['expire_time'] < time())
return sprintf('<span style="color: red">%1$s</span>', $txt['ban_expired']);

// Still need to wait a few days for this ban to expire.
else
return sprintf('%1$d&nbsp;%2$s', ceil(($rowData['expire_time'] - time()) / (60 * 60 * 24)), $txt['ban_days']);
},
),
'sort' => array(

Operation #4
Find: [Select]
'function' => create_function('$rowData', '
return range2ip(array(
$rowData[\'ip_low1\'],
$rowData[\'ip_low2\'],
$rowData[\'ip_low3\'],
$rowData[\'ip_low4\']
), array(
$rowData[\'ip_high1\'],
$rowData[\'ip_high2\'],
$rowData[\'ip_high3\'],
$rowData[\'ip_high4\']
));
'),
);
$listOptions['columns']['banned_entity']['sort'] = array(
Replace With: [Select]
'function' => function($rowData)
{
return range2ip(array(
$rowData['ip_low1'],
$rowData['ip_low2'],
$rowData['ip_low3'],
$rowData['ip_low4']
), array(
$rowData['ip_high1'],
$rowData['ip_high2'],
$rowData['ip_high3'],
$rowData['ip_high4']
));
},
);
$listOptions['columns']['banned_entity']['sort'] = array(

Operation #5
Find: [Select]
'function' => create_function('$rowData', '
global $smcFunc;
return strtr($smcFunc[\'htmlspecialchars\']($rowData[\'hostname\']), array(\'%\' => \'*\'));
'),
);
$listOptions['columns']['banned_entity']['sort'] = array(
Replace With: [Select]
'function' => function($rowData) use ($smcFunc)
{
return strtr($smcFunc['htmlspecialchars']($rowData['hostname']), array('%' => '*'));
},
);
$listOptions['columns']['banned_entity']['sort'] = array(

Operation #6
Find: [Select]
'function' => create_function('$rowData', '
global $smcFunc;
return strtr($smcFunc[\'htmlspecialchars\']($rowData[\'email_address\']), array(\'%\' => \'*\'));
'),
);
$listOptions['columns']['banned_entity']['sort'] = array(
Replace With: [Select]
'function' => function($rowData) use ($smcFunc)
{
return strtr($smcFunc['htmlspecialchars']($rowData['email_address']), array('%' => '*'));
},
);
$listOptions['columns']['banned_entity']['sort'] = array(

Operation #7
Find: [Select]
'function' => create_function('$rowData', '
return timeformat($rowData[\'log_time\']);
'),
),
'sort' => array(
Replace With: [Select]
'function' => function($rowData)
{
return timeformat($rowData['log_time']);
},
),
'sort' => array(

./Sources/ManageCalendar.php

Operation #1
Find: [Select]
* @version 2.0
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'function' => create_function('$rowData', '
global $txt;

// Recurring every year or just a single year?
$year = $rowData[\'year\'] == \'0004\' ? sprintf(\'(%1$s)\', $txt[\'every_year\']) : $rowData[\'year\'];

// Construct the date.
return sprintf(\'%1$d %2$s %3$s\', $rowData[\'day\'], $txt[\'months\'][(int) $rowData[\'month\']], $year);
'),
'class' => 'windowbg',
),
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
// Recurring every year or just a single year?
$year = $rowData['year'] == '0004' ? sprintf('(%1$s)', $txt['every_year']) : $rowData['year'];

// Construct the date.
return sprintf('%1$d %2$s %3$s', $rowData['day'], $txt['months'][(int) $rowData['month']], $year);
},
'class' => 'windowbg',
),

./Sources/ManageErrors.php

Operation #1
Find: [Select]
* @version 2.0.4
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
if ($search_message == $filter['value']['sql'])
$search_message = $smcFunc['db_escape_wildcard_string']($row['message']);
$show_message = strtr(strtr(preg_replace('~&lt;span class=&quot;remove&quot;&gt;(.+?)&lt;/span&gt;~', '$1', $row['message']), array("\r" => '', '<br />' => "\n", '<' => '&lt;', '>' => '&gt;', '"' => '&quot;')), array("\n" => '<br />'));
Replace With: [Select]
if (isset($filter) && $search_message == $filter['value']['sql'])
$search_message = $smcFunc['db_escape_wildcard_string']($row['message']);
$show_message = strtr(strtr(preg_replace('~&lt;span class=&quot;remove&quot;&gt;(.+?)&lt;/span&gt;~', '$1', $row['message']), array("\r" => '', '<br />' => "\n", '<' => '&lt;', '>' => '&gt;', '"' => '&quot;')), array("\n" => '<br />'));

./Sources/ManageMail.php

Operation #1
Find: [Select]
* @version 2.0
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'function' => create_function('$rowData', '
global $smcFunc;
return $smcFunc[\'strlen\']($rowData[\'subject\']) > 50 ? sprintf(\'%1$s...\', htmlspecialchars($smcFunc[\'substr\']($rowData[\'subject\'], 0, 47))) : htmlspecialchars($rowData[\'subject\']);
'),
'class' => 'smalltext',
),
Replace With: [Select]
'function' => function($rowData) use ($smcFunc)
{
return $smcFunc['strlen']($rowData['subject']) > 50 ? sprintf('%1$s...', $smcFunc['htmlspecialchars']($smcFunc['substr']($rowData['subject'], 0, 47))) : $smcFunc['htmlspecialchars']($rowData['subject']);
},
'class' => 'smalltext',
),

Operation #3
Find: [Select]
'function' => create_function('$rowData', '
global $txt;

// We probably have a text label with your priority.
$txtKey = sprintf(\'mq_mpriority_%1$s\', $rowData[\'priority\']);

// But if not, revert to priority 0.
return isset($txt[$txtKey]) ? $txt[$txtKey] : $txt[\'mq_mpriority_1\'];
'),
'class' => 'smalltext',
),
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
// We probably have a text label with your priority.
$txtKey = sprintf('mq_mpriority_%1$s', $rowData['priority']);

// But if not, revert to priority 0.
return isset($txt[$txtKey]) ? $txt[$txtKey] : $txt['mq_mpriority_1'];
},
'class' => 'smalltext',
),

Operation #4
Find: [Select]
'function' => create_function('$rowData', '
return time_since(time() - $rowData[\'time_sent\']);
'),
'class' => 'smalltext',
),
Replace With: [Select]
'function' => function($rowData)
{
return time_since(time() - $rowData['time_sent']);
},
'class' => 'smalltext',
),

Operation #5
Find: [Select]
'function' => create_function('$rowData', '
return \'<input type="checkbox" name="delete[]" value="\' . $rowData[\'id_mail\'] . \'" class="input_check" />\';
'),
'class' => 'smalltext',
),
Replace With: [Select]
'function' => function($rowData)
{
return '<input type="checkbox" name="delete[]" value="' . $rowData['id_mail'] . '">';
},
'class' => 'smalltext',
),

./Sources/ManageMembergroups.php

Operation #1
Find: [Select]
* @version 2.0.7
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'function' => create_function('$rowData', '
global $scripturl;

// Since the moderator group has no explicit members, no link is needed.
if ($rowData[\'id_group\'] == 3)
$group_name = $rowData[\'group_name\'];
else
{
$color_style = empty($rowData[\'online_color\']) ? \'\' : sprintf(\' style="color: %1$s;"\', $rowData[\'online_color\']);
$group_name = sprintf(\'<a href="%1$s?action=admin;area=membergroups;sa=members;group=%2$d"%3$s>%4$s</a>\', $scripturl, $rowData[\'id_group\'], $color_style, $rowData[\'group_name\']);
}

// Add a help option for moderator and administrator.
if ($rowData[\'id_group\'] == 1)
$group_name .= sprintf(\' (<a href="%1$s?action=helpadmin;help=membergroup_administrator" onclick="return reqWin(this.href);">?</a>)\', $scripturl);
elseif ($rowData[\'id_group\'] == 3)
$group_name .= sprintf(\' (<a href="%1$s?action=helpadmin;help=membergroup_moderator" onclick="return reqWin(this.href);">?</a>)\', $scripturl);

return $group_name;
'),
),
'sort' => array(
Replace With: [Select]
'function' => function($rowData) use ($scripturl)
{
// Since the moderator group has no explicit members, no link is needed.
if ($rowData['id_group'] == 3)
$group_name = $rowData['group_name'];
else
{
$color_style = empty($rowData['online_color']) ? '' : sprintf(' style="color: %1$s;"', $rowData['online_color']);
$group_name = sprintf('<a href="%1$s?action=admin;area=membergroups;sa=members;group=%2$d"%3$s>%4$s</a>', $scripturl, $rowData['id_group'], $color_style, $rowData['group_name']);
}

// Add a help option for moderator and administrator.
if ($rowData['id_group'] == 1)
$group_name .= sprintf(' (<a href="%1$s?action=helpadmin;help=membergroup_administrator" onclick="return reqWin(this.href);">?</a>)', $scripturl);
elseif ($rowData['id_group'] == 3)
$group_name .= sprintf(' (<a href="%1$s?action=helpadmin;help=membergroup_moderator" onclick="return reqWin(this.href);">?</a>)', $scripturl);

return $group_name;
},
),
'sort' => array(

Operation #3
Find: [Select]
'function' => create_function('$rowData', '
global $settings;

$stars = explode(\'#\', $rowData[\'stars\']);

// In case no stars are setup, return with nothing
if (empty($stars[0]) || empty($stars[1]))
return \'\';

// Otherwise repeat the image a given number of times.
else
{
$image = sprintf(\'<img src="%1$s/%2$s" alt="*" />\', $settings[\'images_url\'], $stars[1]);
return str_repeat($image, $stars[0]);
}
'),

),
'sort' => array(
Replace With: [Select]
'function' => function($rowData) use ($settings)
{
$stars = explode('#', $rowData['stars']);

// In case no stars are setup, return with nothing
if (empty($stars[0]) || empty($stars[1]))
return '';

// Otherwise repeat the image a given number of times.
else
{
$image = sprintf('<img src="%1$s/%2$s" alt="*" />', $settings['images_url'], $stars[1]);
return str_repeat($image, $stars[0]);
}
},
),
'sort' => array(

Operation #4
Find: [Select]
'function' => create_function('$rowData', '
global $txt;

// No explicit members for the moderator group.
return $rowData[\'id_group\'] == 3 ? $txt[\'membergroups_guests_na\'] : $rowData[\'num_members\'];
'),
'style' => 'text-align: center',
),
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
// No explicit members for the moderator group.
return $rowData['id_group'] == 3 ? $txt['membergroups_guests_na'] : $rowData['num_members'];
},
'style' => 'text-align: center',
),

Operation #5
Find: [Select]
'function' => create_function('$rowData', '
global $scripturl;

$colorStyle = empty($rowData[\'online_color\']) ? \'\' : sprintf(\' style="color: %1$s;"\', $rowData[\'online_color\']);
return sprintf(\'<a href="%1$s?action=moderate;area=viewgroups;sa=members;group=%2$d"%3$s>%4$s</a>\', $scripturl, $rowData[\'id_group\'], $colorStyle, $rowData[\'group_name\']);
'),
),
'sort' => array(
Replace With: [Select]
'function' => function($rowData) use ($scripturl)
{
$colorStyle = empty($rowData['online_color']) ? '' : sprintf(' style="color: %1$s;"', $rowData['online_color']);
return sprintf('<a href="%1$s?action=moderate;area=viewgroups;sa=members;group=%2$d"%3$s>%4$s</a>', $scripturl, $rowData['id_group'], $colorStyle, $rowData['group_name']);
},
),
'sort' => array(

Operation #6
Find: [Select]
'function' => create_function('$rowData', '
global $settings;

$stars = explode(\'#\', $rowData[\'stars\']);

if (empty($stars[0]) || empty($stars[1]))
return \'\';
else
{
$star_image = sprintf(\'<img src="%1$s/%2$s" alt="*" />\', $settings[\'images_url\'], $stars[1]);
return str_repeat($star_image, $stars[0]);
}
'),
),
'sort' => array(
Replace With: [Select]
'function' => function($rowData) use ($settings)
{
$stars = explode('#', $rowData['stars']);

if (empty($stars[0]) || empty($stars[1]))
return '';
else
{
$star_image = sprintf('<img src="%1$s/%2$s" alt="*" />', $settings['images_url'], $stars[1]);
return str_repeat($star_image, $stars[0]);
}
},
),
'sort' => array(

./Sources/ManageMembers.php

Operation #1
Find: [Select]
* @version 2.0.15
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'function' => create_function('$rowData', '
global $txt;

// Calculate number of days since last online.
if (empty($rowData[\'last_login\']))
$difference = $txt[\'never\'];
else
{
$num_days_difference = jeffsdatediff($rowData[\'last_login\']);

// Today.
if (empty($num_days_difference))
$difference = $txt[\'viewmembers_today\'];

// Yesterday.
elseif ($num_days_difference == 1)
$difference = sprintf(\'1 %1$s\', $txt[\'viewmembers_day_ago\']);

// X days ago.
else
$difference = sprintf(\'%1$d %2$s\', $num_days_difference, $txt[\'viewmembers_days_ago\']);
}

// Show it in italics if they\'re not activated...
if ($rowData[\'is_activated\'] % 10 != 1)
$difference = sprintf(\'<em title="%1$s">%2$s</em>\', $txt[\'not_activated\'], $difference);

return $difference;
'),
),
'sort' => array(
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
// Calculate number of days since last online.
if (empty($rowData['last_login']))
$difference = $txt['never'];
else
{
$num_days_difference = jeffsdatediff($rowData['last_login']);

// Today.
if (empty($num_days_difference))
$difference = $txt['viewmembers_today'];

// Yesterday.
elseif ($num_days_difference == 1)
$difference = sprintf('1 %1$s', $txt['viewmembers_day_ago']);

// X days ago.
else
$difference = sprintf('%1$d %2$s', $num_days_difference, $txt['viewmembers_days_ago']);
}

// Show it in italics if they're not activated...
if ($rowData['is_activated'] % 10 != 1)
$difference = sprintf('<em title="%1$s">%2$s</em>', $txt['not_activated'], $difference);

return $difference;
},
),
'sort' => array(

Operation #3
Find: [Select]
'function' => create_function('$rowData', '
global $user_info;

return \'<input type="checkbox" name="delete[]" value="\' . $rowData[\'id_member\'] . \'" class="input_check" \' . ($rowData[\'id_member\'] == $user_info[\'id\'] || $rowData[\'id_group\'] == 1 || in_array(1, explode(\',\', $rowData[\'additional_groups\'])) ? \'disabled="disabled"\' : \'\') . \' />\';
'),
'class' => 'windowbg',
'style' => 'text-align: center',
Replace With: [Select]
'function' => function($rowData) use ($user_info)
{
return '<input type="checkbox" name="delete[]" value="' . $rowData['id_member'] . '" class="input_check" ' . ($rowData['id_member'] == $user_info['id'] || $rowData['id_group'] == 1 || in_array(1, explode(',', $rowData['additional_groups'])) ? 'disabled="disabled"' : '') . ' />';
},
'class' => 'windowbg',
'style' => 'text-align: center',

Operation #4
Find: [Select]
'function' => create_function('$rowData', '
global $modSettings;

return host_from_ip($rowData[\'member_ip\']);
'),
'class' => 'smalltext',
),
Replace With: [Select]
'function' => function($rowData)
{
return host_from_ip($rowData['member_ip']);
},
'class' => 'smalltext',
),

Operation #5
Find: [Select]
'function' => create_function('$rowData', '
return timeformat($rowData[\'date_registered\']);
'),
),
'sort' => array(
Replace With: [Select]
'function' => function($rowData)
{
return timeformat($rowData['date_registered']);
},
),
'sort' => array(

Operation #6
Find: [Select]
'function' => create_function('$rowData', '
global $scripturl, $txt;

$member_links = array();
foreach ($rowData[\'duplicate_members\'] as $member)
{
if ($member[\'id\'])
$member_links[] = \'<a href="\' . $scripturl . \'?action=profile;u=\' . $member[\'id\'] . \'" \' . (!empty($member[\'is_banned\']) ? \'style="color: red;"\' : \'\') . \'>\' . $member[\'name\'] . \'</a>\';
else
$member_links[] = $member[\'name\'] . \' (\' . $txt[\'guest\'] . \')\';
}
return implode (\', \', $member_links);
'),
'class' => 'smalltext',
),
Replace With: [Select]
'function' => function($rowData) use ($scripturl, $txt)
{
$member_links = array();
foreach ($rowData['duplicate_members'] as $member)
{
if ($member['id'])
$member_links[] = '<a href="' . $scripturl . '?action=profile;u=' . $member['id'] . '" ' . (!empty($member['is_banned']) ? 'style="color: red;"' : '') . '>' . $member['name'] . '</a>';
else
$member_links[] = $member['name'] . ' (' . $txt['guest'] . ')';
}
return implode (', ', $member_links);
},
'class' => 'smalltext',
),

./Sources/ManagePaid.php

Operation #1
Find: [Select]
* @version 2.0.12
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'function' => create_function('', '
global $context;
return $context[\'subscriptions\'];
'),
),
'get_count' => array(
'function' => create_function('', '
global $context;
return count($context[\'subscriptions\']);
'),
),
'no_items_label' => $txt['paid_none_yet'],
Replace With: [Select]
'function' => function() use ($context)
{
return $context['subscriptions'];
},
),
'get_count' => array(
'function' => function() use ($context)
{
return count($context['subscriptions']);
},
),
'no_items_label' => $txt['paid_none_yet'],

Operation #3
Find: [Select]
'function' => create_function('$rowData', '
global $scripturl;

return sprintf(\'<a href="%1$s?action=admin;area=paidsubscribe;sa=viewsub;sid=%2$s">%3$s</a>\', $scripturl, $rowData[\'id\'], $rowData[\'name\']);
'),
),
),
Replace With: [Select]
'function' => function($rowData) use ($scripturl)
{
return sprintf('<a href="%1$s?action=admin;area=paidsubscribe;sa=viewsub;sid=%2$s">%3$s</a>', $scripturl, $rowData['id'], $rowData['name']);
},
),
),

Operation #4
Find: [Select]
'function' => create_function('$rowData', '
global $context, $txt;

return $rowData[\'flexible\'] ? \'<em>\' . $txt[\'flexible\'] . \'</em>\' : $rowData[\'cost\'] . \' / \' . $rowData[\'length\'];
'),
),
),
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
return $rowData['flexible'] ? '<em>' . $txt['flexible'] . '</em>' : $rowData['cost'] . ' / ' . $rowData['length'];
},
),
),

Operation #5
Find: [Select]
'function' => create_function('$rowData', '
global $context, $txt;

return \'<span style="color: \' . ($rowData[\'active\'] ? \'green\' : \'red\') . \'">\' . ($rowData[\'active\'] ? $txt[\'yes\'] : $txt[\'no\']) . \'</span>\';
'),
'style' => 'text-align: center;',
),
),
'modify' => array(
'data' => array(
'function' => create_function('$rowData', '
global $context, $txt, $scripturl;

return \'<a href="\' . $scripturl . \'?action=admin;area=paidsubscribe;sa=modify;sid=\' . $rowData[\'id\'] . \'">\' . $txt[\'modify\'] . \'</a>\';
'),
'style' => 'text-align: center;',
),
),
'delete' => array(
'data' => array(
'function' => create_function('$rowData', '
global $context, $txt, $scripturl;

return \'<a href="\' . $scripturl . \'?action=admin;area=paidsubscribe;sa=modify;delete;sid=\' . $rowData[\'id\'] . \'">\' . $txt[\'delete\'] . \'</a>\';
'),
'style' => 'text-align: center;',
),
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
return '<span style="color: ' . ($rowData['active'] ? 'green' : 'red') . '">' . ($rowData['active'] ? $txt['yes'] : $txt['no']) . '</span>';
},
'style' => 'text-align: center;',
),
),
'modify' => array(
'data' => array(
'function' => function($rowData) use ($txt, $scripturl)
{
return '<a href="' . $scripturl . '?action=admin;area=paidsubscribe;sa=modify;sid=' . $rowData['id'] . '">' . $txt['modify'] . '</a>';
},
'style' => 'text-align: center;',
),
),
'delete' => array(
'data' => array(
'function' => function($rowData) use ($scripturl, $txt)
{
return '<a href="' . $scripturl . '?action=admin;area=paidsubscribe;sa=modify;delete;sid=' . $rowData['id'] . '">' . $txt['delete'] . '</a>';
},
'style' => 'text-align: center;',
),

Operation #6
Find: [Select]
'function' => create_function('$rowData', '
global $context, $txt, $scripturl;

return $rowData[\'id_member\'] == 0 ? $txt[\'guest\'] : \'<a href="\' . $scripturl . \'?action=profile;u=\' . $rowData[\'id_member\'] . \'">\' . $rowData[\'name\'] . \'</a>\';
'),
),
'sort' => array(
Replace With: [Select]
'function' => function($rowData) use ($context, $txt, $scripturl)
{
return $rowData['id_member'] == 0 ? $txt['guest'] : '<a href="' . $scripturl . '?action=profile;u=' . $rowData['id_member'] . '">' . $rowData['name'] . '</a>';
},
),
'sort' => array(

Operation #7
Find: [Select]
'function' => create_function('$rowData', '
global $context, $txt, $scripturl;

return \'<a href="\' . $scripturl . \'?action=admin;area=paidsubscribe;sa=modifyuser;lid=\' . $rowData[\'id\'] . \'">\' . $txt[\'modify\'] . \'</a>\';
'),
'style' => 'text-align: center;',
),
Replace With: [Select]
'function' => function($rowData) use ($txt, $scripturl)
{
return '<a href="' . $scripturl . '?action=admin;area=paidsubscribe;sa=modifyuser;lid=' . $rowData['id'] . '">' . $txt['modify'] . '</a>';
},
'style' => 'text-align: center;',
),

Operation #8
Find: [Select]
'function' => create_function('$rowData', '
global $context, $txt, $scripturl;

return \'<input type="checkbox" name="delsub[\' . $rowData[\'id\'] . \']" class="input_check" />\';
'),
'style' => 'text-align: center;',
),
Replace With: [Select]
'function' => function($rowData)
{
return '<input type="checkbox" name="delsub[' . $rowData['id'] . ']" class="input_check" />';
},
'style' => 'text-align: center;',
),

./Sources/ManageRegistration.php

Operation #1
Find: [Select]
* @version 2.0.16
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
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' : ''),
'',
Replace With: [Select]
array('check', 'requirePolicyAgreement', 'text_label' => $txt['admin_privacy_policy'], 'value' => !empty($modSettings['force_gdpr']) ? 1 : $modSettings['requirePolicyAgreement'], 'disabled' => !empty($modSettings['force_gdpr'])),
array('warning', empty($policy) ? 'error_no_privacy_policy' : ''),
'',

./Sources/ManageScheduledTasks.php

Operation #1
Find: [Select]
* @version 2.0
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'function' => create_function('$rowData', '
return timeformat($rowData[\'time_run\'], true);
'),
),
'sort' => array(
Replace With: [Select]
'function' => function($rowData)
{
return timeformat($rowData['time_run'], true);
},
),
'sort' => array(

./Sources/ManageSearchEngines.php

Operation #1
Find: [Select]
* @version 2.0
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'function' => create_function('$rowData', '
global $scripturl;

return sprintf(\'<a href="%1$s?action=admin;area=sengines;sa=editspiders;sid=%2$d">%3$s</a>\', $scripturl, $rowData[\'id_spider\'], htmlspecialchars($rowData[\'spider_name\']));
'),
),
'sort' => array(
Replace With: [Select]
'function' => function($rowData) use ($scripturl)
{
return sprintf('<a href="%1$s?action=admin;area=sengines;sa=editspiders;sid=%2$d">%3$s</a>', $scripturl, $rowData['id_spider'], htmlspecialchars($rowData['spider_name']));
},
),
'sort' => array(

Operation #3
Find: [Select]
'function' => create_function('$rowData', '
global $context, $txt;

return isset($context[\'spider_last_seen\'][$rowData[\'id_spider\']]) ? timeformat($context[\'spider_last_seen\'][$rowData[\'id_spider\']]) : $txt[\'spider_last_never\'];
'),
),
),
Replace With: [Select]
'function' => function($rowData) use ($context, $txt)
{
return isset($context['spider_last_seen'][$rowData['id_spider']]) ? timeformat($context['spider_last_seen'][$rowData['id_spider']]) : $txt['spider_last_never'];
},
),
),

Operation #4
Find: [Select]
'function' => create_function('$rowData', '
return timeformat($rowData[\'log_time\']);
'),
),
'sort' => array(
Replace With: [Select]
'function' => function($rowData)
{
return timeformat($rowData['log_time']);
},
),
'sort' => array(

./Sources/ManageServer.php

Operation #1
Find: [Select]
* @version 2.0.16
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
array('cookie_no_auth_secret', $txt['cookie_no_auth_secret'], 'db', 'check', false, 'cookie_no_auth_secret', 'disabled' => empty($modSettings['integrate_verify_user'])),
'',
// Sessions
Replace With: [Select]
array('cookie_no_auth_secret', $txt['cookie_no_auth_secret'], 'db', 'check', false, 'cookie_no_auth_secret'),
'',
// Sessions

Operation #3
Find: [Select]
// 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;

saveSettings($config_vars);

Replace With: [Select]
saveSettings($config_vars);


Operation #4
Find: [Select]
'function' => create_function('', '
global $context;
return $context[\'files\'][\'lang\'];
'),
),
'columns' => array(
Replace With: [Select]
'function' => function() use ($context)
{
return $context['files']['lang'];
},
),
'columns' => array(

Operation #5
Find: [Select]
'function' => create_function('$rowData', '
global $context, $txt;

return \'<strong>\' . $rowData[\'name\'] . \'</strong><br /><span class="smalltext">\' . $txt[\'languages_download_dest\'] . \': \' . $rowData[\'destination\'] . \'</span>\' . ($rowData[\'version_compare\'] == \'older\' ? \'<br />\' . $txt[\'languages_download_older\'] : \'\');
'),
),
),
Replace With: [Select]
'function' => function($rowData) use ($context, $txt)
{
return '<strong>' . $rowData['name'] . '</strong><br /><span class="smalltext">' . $txt['languages_download_dest'] . ': ' . $rowData['destination'] . '</span>' . ($rowData['version_compare'] == 'older' ? '<br />' . $txt['languages_download_older'] : '');
},
),
),

Operation #6
Find: [Select]
'function' => create_function('$rowData', '
global $txt;

return \'<span style="color: \' . ($rowData[\'writable\'] ? \'green\' : \'red\') . \';">\' . ($rowData[\'writable\'] ? $txt[\'yes\'] : $txt[\'no\']) . \'</span>\';
'),
'style' => 'text-align: center',
),
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
return '<span style="color: ' . ($rowData['writable'] ? 'green' : 'red') . ';">' . ($rowData['writable'] ? $txt['yes'] : $txt['no']) . '</span>';
},
'style' => 'text-align: center',
),

Operation #7
Find: [Select]
'function' => create_function('$rowData', '
global $txt;

return \'<span style="color: \' . ($rowData[\'version_compare\'] == \'older\' ? \'red\' : ($rowData[\'version_compare\'] == \'same\' ? \'orange\' : \'green\')) . \';">\' . $rowData[\'version\'] . \'</span>\';
'),
),
),
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
return '<span style="color: ' . ($rowData['version_compare'] == 'older' ? 'red' : ($rowData['version_compare'] == 'same' ? 'orange' : 'green')) . ';">' . $rowData['version'] . '</span>';
},
),
),

Operation #8
Find: [Select]
'function' => create_function('$rowData', '
global $txt;

return $rowData[\'exists\'] ? ($rowData[\'exists\'] == \'same\' ? $txt[\'languages_download_exists_same\'] : $txt[\'languages_download_exists_different\']) : $txt[\'no\'];
'),
),
),
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
return $rowData['exists'] ? ($rowData['exists'] == 'same' ? $txt['languages_download_exists_same'] : $txt['languages_download_exists_different']) : $txt['no'];
},
),
),

Operation #9
Find: [Select]
'function' => create_function('$rowData', '
return \'<input type="checkbox" name="copy_file[]" value="\' . $rowData[\'generaldest\'] . \'" \' . ($rowData[\'default_copy\'] ? \'checked="checked"\' : \'\') . \' class="input_check" />\';
'),
'style' => 'text-align: center; width: 4%;',
),
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
return '<input type="checkbox" name="copy_file[]" value="' . $rowData['generaldest'] . '" ' . ($rowData['default_copy'] ? 'checked="checked"' : '') . ' class="input_check" />';
},
'style' => 'text-align: center; width: 4%;',
),

Operation #10
Find: [Select]
'function' => create_function('$rowData', '
return \'<input type="radio" name="def_language" value="\' . $rowData[\'id\'] . \'" \' . ($rowData[\'default\'] ? \'checked="checked"\' : \'\') . \' onclick="highlightSelected(\\\'list_language_list_\' . $rowData[\'id\'] . \'\\\');" class="input_radio" />\';
'),
'style' => 'text-align: center; width: 8%;',
),
Replace With: [Select]
'function' => function($rowData)
{
return '<input type="radio" name="def_language" value="' . $rowData['id'] . '" ' . ($rowData['default'] ? 'checked="checked"' : '') . ' onclick="highlightSelected(\'list_language_list_' . $rowData['id'] . '\');" class="input_radio" />';
},
'style' => 'text-align: center; width: 8%;',
),

Operation #11
Find: [Select]
'function' => create_function('$rowData', '
global $scripturl, $context;

return sprintf(\'<a href="%1$s?action=admin;area=languages;sa=editlang;lid=%2$s">%3$s</a>\', $scripturl, $rowData[\'id\'], $rowData[\'name\']);
'),
),
),
Replace With: [Select]
'function' => function($rowData) use ($scripturl, $context)
{
return sprintf('<a href="%1$s?action=admin;area=languages;sa=editlang;lid=%2$s">%3$s</a>', $scripturl, $rowData['id'], $rowData['name']);
},
),
),

Operation #12
Find: [Select]
if ($string{$i} == '\\')
{
// Toggle the escape.
Replace With: [Select]
if ($string[$i] == '\\')
{
// Toggle the escape.

Operation #13
Find: [Select]
elseif (($string{$i} == 'n' || $string{$i} == 't') && $in_string == 2 && $is_escape)
{
// Put the escape back...
$new_string .= $string{$i} == 'n' ? "\n" : "\t";
$is_escape = false;
continue;
}
// Have we got a single quote?
elseif ($string{$i} == '\'')
{
// Already in a parsed string, or escaped in a linear string, means we print it - otherwise something special.
Replace With: [Select]
elseif (($string[$i] == 'n' || $string[$i] == 't') && $in_string == 2 && $is_escape)
{
// Put the escape back...
$new_string .= $string[$i] == 'n' ? "\n" : "\t";
$is_escape = false;
continue;
}
// Have we got a single quote?
elseif ($string[$i] == '\'')
{
// Already in a parsed string, or escaped in a linear string, means we print it - otherwise something special.

Operation #14
Find: [Select]
elseif ($string{$i} == '"')
{
// Already in a single quote string, or escaped in a parsed string, means we print it - otherwise something special.
Replace With: [Select]
elseif ($string[$i] == '"')
{
// Already in a single quote string, or escaped in a parsed string, means we print it - otherwise something special.

Operation #15
Find: [Select]
elseif ($in_string == 0 && (empty($string{$i}) || $string{$i} == '.'))
continue;
// Start of a variable?
elseif ($in_string == 0 && $string{$i} == '$')
{
// Find the whole of it!
Replace With: [Select]
elseif ($in_string == 0 && (empty($string[$i]) || $string[$i] == '.'))
continue;
// Start of a variable?
elseif ($in_string == 0 && $string[$i] == '$')
{
// Find the whole of it!

Operation #16
Find: [Select]
$new_string .= $string{$i};
// If anything was escaped it ain't any longer!
$is_escape = false;
Replace With: [Select]
$new_string .= $string[$i];
// If anything was escaped it ain't any longer!
$is_escape = false;

Operation #17
Find: [Select]
if ($string{$i} == "\n" || $string{$i} == "\t")
{
// Are we in a string? Is it the right type?
if ($in_string == 1)
{
// Change type!
$new_string .= '\' . "\\' . ($string{$i} == "\n" ? 'n' : 't');
$in_string = 2;
}
elseif ($in_string == 2)
$new_string .= '\\' . ($string{$i} == "\n" ? 'n' : 't');
// Otherwise start one off - joining if required.
else
$new_string .= ($new_string ? ' . ' : '') . '"\\' . ($string{$i} == "\n" ? 'n' : 't');

continue;
Replace With: [Select]
if ($string[$i] == "\n" || $string[$i] == "\t")
{
// Are we in a string? Is it the right type?
if ($in_string == 1)
{
// Change type!
$new_string .= '\' . "\\' . ($string[$i] == "\n" ? 'n' : 't');
$in_string = 2;
}
elseif ($in_string == 2)
$new_string .= '\\' . ($string[$i] == "\n" ? 'n' : 't');
// Otherwise start one off - joining if required.
else
$new_string .= ($new_string ? ' . ' : '') . '"\\' . ($string[$i] == "\n" ? 'n' : 't');

continue;

Operation #18
Find: [Select]
if ($string{$i} == '{' && $string{$i + 1} == '%' && $string{$i + 2} == '$')
{
// Grab the variable.
Replace With: [Select]
if ($string[$i] == '{' && $string[$i + 1] == '%' && $string[$i + 2] == '$')
{
// Grab the variable.

Operation #19
Find: [Select]
elseif ($string{$i} == '<')
{
// Probably HTML?
if ($string{$i + 1} != ' ')
$in_html = true;
// Assume we need an entity...
Replace With: [Select]
elseif ($string[$i] == '<')
{
// Probably HTML?
if ($string[$i + 1] != ' ')
$in_html = true;
// Assume we need an entity...

Operation #20
Find: [Select]
elseif ($string{$i} == '>')
{
// Will it be HTML?
Replace With: [Select]
elseif ($string[$i] == '>')
{
// Will it be HTML?

Operation #21
Find: [Select]
if ($string{$i} == '\\')
$new_string .= '\\';
// The infamous double quote?
elseif ($string{$i} == '"')
{
// If we're in HTML we leave it as a quote - otherwise we entity it.
Replace With: [Select]
if ($string[$i] == '\\')
$new_string .= '\\';
// The infamous double quote?
elseif ($string[$i] == '"')
{
// If we're in HTML we leave it as a quote - otherwise we entity it.

Operation #22
Find: [Select]
elseif ($string{$i} == '\'')
{
// Must be in a string so escape it.
$new_string .= '\\';
}

// Finally add the character to the string!
$new_string .= $string{$i};
}
Replace With: [Select]
elseif ($string[$i] == '\'')
{
// Must be in a string so escape it.
$new_string .= '\\';
}

// Finally add the character to the string!
$new_string .= $string[$i];
}

./Sources/ManageSettings.php

Operation #1
Find: [Select]
* @version 2.0.16
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'save_callback' => create_function('$value', '
global $smcFunc;
if (!$value)
{
$smcFunc[\'db_query\'](\'\', \'
UPDATE {db_prefix}custom_fields
SET active = 0\');
}
'),
'setting_callback' => create_function('$value', '
if (!$value)
return array(
\'disabled_profile_fields\' => \'\',
\'registration_fields\' => \'\',
\'displayFields\' => \'\',
);
else
return array();
'),
),
// k = karma.
Replace With: [Select]
'save_callback' => function($value)
{
global $smcFunc;
if (!$value)
{
$smcFunc['db_query']('', '
UPDATE {db_prefix}custom_fields
SET active = 0');
}
},
'setting_callback' => function($value)
{
if (!$value)
return array(
'disabled_profile_fields' => '',
'registration_fields' => '',
'displayFields' => '',
);
else
return array();
},
),
// k = karma.

Operation #3
Find: [Select]
'setting_callback' => create_function('$value', '
global $sourcedir;

// Cant use warning post moderation if disabled!
if (!$value)
{
require_once($sourcedir . \'/PostModeration.php\');
approveAllData();

return array(\'warning_moderate\' => 0);
}
else
return array();
'),
),
// ps = Paid Subscriptions.
Replace With: [Select]
'setting_callback' => function($value)
{
global $sourcedir;

// Cant use warning post moderation if disabled!
if (!$value)
{
require_once($sourcedir . '/PostModeration.php');
approveAllData();

return array('warning_moderate' => 0);
}
else
return array();
},
),
// ps = Paid Subscriptions.

Operation #4
Find: [Select]
'setting_callback' => create_function('$value', '
global $smcFunc, $sourcedir;

// Set the correct disabled value for scheduled task.
$smcFunc[\'db_query\'](\'\', \'
UPDATE {db_prefix}scheduled_tasks
SET disabled = {int:disabled}
WHERE task = {string:task}\',
array(
\'disabled\' => $value ? 0 : 1,
\'task\' => \'paid_subscriptions\',
)
);

// Should we calculate next trigger?
if ($value)
{
require_once($sourcedir . \'/ScheduledTasks.php\');
CalculateNextTrigger(\'paid_subscriptions\');
}
'),
),
// rg = report generator.
Replace With: [Select]
'setting_callback' => function($value)
{
global $smcFunc, $sourcedir;

// Set the correct disabled value for scheduled task.
$smcFunc['db_query']('', '
UPDATE {db_prefix}scheduled_tasks
SET disabled = {int:disabled}
WHERE task = {string:task}',
array(
'disabled' => $value ? 0 : 1,
'task' => 'paid_subscriptions',
)
);

// Should we calculate next trigger?
if ($value)
{
require_once($sourcedir . '/ScheduledTasks.php');
CalculateNextTrigger('paid_subscriptions');
}
},
),
// rg = report generator.

Operation #5
Find: [Select]
'setting_callback' => create_function('$value', '
global $modSettings;
list ($modSettings[\'warning_enable\'], $modSettings[\'user_limit\'], $modSettings[\'warning_decrement\']) = explode(\',\', $modSettings[\'warning_settings\']);
$warning_settings = ($value ? 1 : 0) . \',\' . $modSettings[\'user_limit\'] . \',\' . $modSettings[\'warning_decrement\'];
if (!$value)
{
$returnSettings = array(
\'warning_watch\' => 0,
\'warning_moderate\' => 0,
\'warning_mute\' => 0,
);
}
elseif (empty($modSettings[\'warning_enable\']) && $value)
{
$returnSettings = array(
\'warning_watch\' => 10,
\'warning_moderate\' => 35,
\'warning_mute\' => 60,
);
}
else
$returnSettings = array();

$returnSettings[\'warning_settings\'] = $warning_settings;
return $returnSettings;
'),
),
// Search engines
Replace With: [Select]
'setting_callback' => function($value)
{
global $modSettings;
list ($modSettings['warning_enable'], $modSettings['user_limit'], $modSettings['warning_decrement']) = explode(',', $modSettings['warning_settings']);
$warning_settings = ($value ? 1 : 0) . ',' . $modSettings['user_limit'] . ',' . $modSettings['warning_decrement'];
if (!$value)
{
$returnSettings = array(
'warning_watch' => 0,
'warning_moderate' => 0,
'warning_mute' => 0,
);
}
elseif (empty($modSettings['warning_enable']) && $value)
{
$returnSettings = array(
'warning_watch' => 10,
'warning_moderate' => 35,
'warning_mute' => 60,
);
}
else
$returnSettings = array();

$returnSettings['warning_settings'] = $warning_settings;
return $returnSettings;
},
),
// Search engines

Operation #6
Find: [Select]
'setting_callback' => create_function('$value', '
// Turn off the spider group if disabling.
if (!$value)
return array(\'spider_group\' => 0, \'show_spider_online\' => 0);
'),
'on_save' => create_function('', '
global $sourcedir, $modSettings;
require_once($sourcedir . \'/ManageSearchEngines.php\');
recacheSpiderNames();
'),
),
// Quick setting to toggle into GDPR compliance
Replace With: [Select]
'setting_callback' => function($value)
{
// Turn off the spider group if disabling.
if (!$value)
return array('spider_group' => 0, 'show_spider_online' => 0);
},
'on_save' => function()
{
global $sourcedir, $modSettings;
require_once($sourcedir . '/ManageSearchEngines.php');
recacheSpiderNames();
},
),
// Quick setting to toggle into GDPR compliance

Operation #7
Find: [Select]
'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\']);
'),
),
);
Replace With: [Select]
'setting_callback' => 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' => 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']);
},
),
);

Operation #8
Find: [Select]
'function' => create_function('$rowData', '
$isChecked = $rowData[\'disabled\'] ? \'\' : \' checked="checked"\';
$onClickHandler = $rowData[\'can_show_register\'] ? sprintf(\'onclick="document.getElementById(\\\'reg_%1$s\\\').disabled = !this.checked;"\', $rowData[\'id\']) : \'\';
return sprintf(\'<input type="checkbox" name="active[]" id="active_%1$s" value="%1$s" class="input_check"%2$s%3$s />\', $rowData[\'id\'], $isChecked, $onClickHandler);
'),
'style' => 'width: 20%; text-align: center;',
),
Replace With: [Select]
'function' => function($rowData)
{
$isChecked = $rowData['disabled'] ? '' : ' checked';
$onClickHandler = $rowData['can_show_register'] ? sprintf(' onclick="document.getElementById(\'reg_%1$s\').disabled = !this.checked;"', $rowData['id']) : '';
return sprintf('<input type="checkbox" name="active[]" id="active_%1$s" value="%1$s" %2$s%3$s>', $rowData['id'], $isChecked, $onClickHandler);
},
'style' => 'width: 20%; text-align: center;',
),

Operation #9
Find: [Select]
'function' => create_function('$rowData', '
$isChecked = $rowData[\'on_register\'] && !$rowData[\'disabled\'] ? \' checked="checked"\' : \'\';
$isDisabled = $rowData[\'can_show_register\'] ? \'\' : \' disabled="disabled"\';
return sprintf(\'<input type="checkbox" name="reg[]" id="reg_%1$s" value="%1$s" class="input_check"%2$s%3$s />\', $rowData[\'id\'], $isChecked, $isDisabled);
'),
'style' => 'width: 20%; text-align: center;',
),
Replace With: [Select]
'function' => function($rowData)
{
$isChecked = $rowData['on_register'] && !$rowData['disabled'] ? ' checked' : '';
$isDisabled = $rowData['can_show_register'] ? '' : ' disabled';
return sprintf('<input type="checkbox" name="reg[]" id="reg_%1$s" value="%1$s" %2$s%3$s>', $rowData['id'], $isChecked, $isDisabled);
},
'style' => 'width: 20%; text-align: center;',
),

Operation #10
Find: [Select]
'function' => create_function('$rowData', '
global $scripturl;

return sprintf(\'<a href="%1$s?action=admin;area=featuresettings;sa=profileedit;fid=%2$d">%3$s</a><div class="smalltext">%4$s</div>\', $scripturl, $rowData[\'id_field\'], $rowData[\'field_name\'], $rowData[\'field_desc\']);
'),
'style' => 'width: 62%;',
),
Replace With: [Select]
'function' => function($rowData) use ($scripturl)
{
return sprintf('<a href="%1$s?action=admin;area=featuresettings;sa=profileedit;fid=%2$d">%3$s</a><div class="smalltext">%4$s</div>', $scripturl, $rowData['id_field'], $rowData['field_name'], $rowData['field_desc']);
},
'style' => 'width: 62%;',
),

Operation #11
Find: [Select]
'function' => create_function('$rowData', '
global $txt;

$textKey = sprintf(\'custom_profile_type_%1$s\', $rowData[\'field_type\']);
return isset($txt[$textKey]) ? $txt[$textKey] : $textKey;
'),
'style' => 'width: 15%;',
),
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
$textKey = sprintf('custom_profile_type_%1$s', $rowData['field_type']);
return isset($txt[$textKey]) ? $txt[$textKey] : $textKey;
},
'style' => 'width: 15%;',
),

Operation #12
Find: [Select]
'function' => create_function('$rowData', '
global $txt;

return $rowData[\'active\'] ? $txt[\'yes\'] : $txt[\'no\'];
'),
'style' => 'width: 8%; text-align: center;',
),
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
return $rowData['active'] ? $txt['yes'] : $txt['no'];
},
'style' => 'width: 8%; text-align: center;',
),

Operation #13
Find: [Select]
'function' => create_function('$rowData', '
global $txt;

return $txt[\'custom_profile_placement_\' . (empty($rowData[\'placement\']) ? \'standard\' : ($rowData[\'placement\'] == 1 ? \'withicons\' : \'abovesignature\'))];
'),
'style' => 'width: 8%; text-align: center;',
),
Replace With: [Select]
'function' => function($rowData)
{
global $txt, $context;

return $txt['custom_profile_placement_' . (empty($rowData['placement']) ? 'standard' : ($rowData['placement'] == 1 ? 'withicons' : 'abovesignature'))];
},
'style' => 'width: 8%; text-align: center;',
),

./Sources/ManageSmileys.php

Operation #1
Find: [Select]
* @version 2.0
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'function' => create_function('$rowData', '
return $rowData[\'selected\'] ? \'<strong>*</strong>\' : \'\';
'),
'style' => 'text-align: center;',
),
Replace With: [Select]
'function' => function($rowData)
{
return $rowData['selected'] ? '<strong>*</strong>' : '';
},
'style' => 'text-align: center;',
),

Operation #3
Find: [Select]
'function' => create_function('$rowData', '
return $rowData[\'id\'] == 0 ? \'\' : sprintf(\'<input type="checkbox" name="smiley_set[%1$d]" class="input_check" />\', $rowData[\'id\']);
'),
'style' => 'text-align: center',
),
Replace With: [Select]
'function' => function($rowData)
{
return $rowData['id'] == 0 ? '' : sprintf('<input type="checkbox" name="smiley_set[%1$d]" class="input_check" />', $rowData['id']);
},
'style' => 'text-align: center',
),

Operation #4
Find: [Select]
'function' => create_function('$rowData', '
global $txt;

if (empty($rowData[\'hidden\']))
return $txt[\'smileys_location_form\'];
elseif ($rowData[\'hidden\'] == 1)
return $txt[\'smileys_location_hidden\'];
else
return $txt[\'smileys_location_popup\'];
'),
'class' => 'windowbg',
),
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
if (empty($rowData['hidden']))
return $txt['smileys_location_form'];
elseif ($rowData['hidden'] == 1)
return $txt['smileys_location_hidden'];
else
return $txt['smileys_location_popup'];
},
'class' => 'windowbg',
),

Operation #5
Find: [Select]
'function' => create_function('$rowData', empty($modSettings['smileys_dir']) || !is_dir($modSettings['smileys_dir']) ? '
return htmlspecialchars($rowData[\'description\']);
' : '
global $context, $txt, $modSettings;

// Check if there are smileys missing in some sets.
$missing_sets = array();
foreach ($context[\'smiley_sets\'] as $smiley_set)
if (!file_exists(sprintf(\'%1$s/%2$s/%3$s\', $modSettings[\'smileys_dir\'], $smiley_set[\'path\'], $rowData[\'filename\'])))
$missing_sets[] = $smiley_set[\'path\'];

$description = htmlspecialchars($rowData[\'description\']);

if (!empty($missing_sets))
$description .= sprintf(\'<br /><span class="smalltext"><strong>%1$s:</strong> %2$s</span>\', $txt[\'smileys_not_found_in_set\'], implode(\', \', $missing_sets));

return $description;
'),
'class' => 'windowbg',
),
Replace With: [Select]
'function' => function($rowData) use ($modSettings, $context, $txt)
{
if (empty($modSettings['smileys_dir']) || !is_dir($modSettings['smileys_dir']))
return htmlspecialchars($rowData['description']);

// Check if there are smileys missing in some sets.
$missing_sets = array();
foreach ($context['smiley_sets'] as $smiley_set)
if (!file_exists(sprintf('%1$s/%2$s/%3$s', $modSettings['smileys_dir'], $smiley_set['path'], $rowData['filename'])))
$missing_sets[] = $smiley_set['path'];

$description = htmlspecialchars($rowData['description']);

if (!empty($missing_sets))
$description .= sprintf('<br /><span class="smalltext"><strong>%1$s:</strong> %2$s</span>', $txt['smileys_not_found_in_set'], implode(', ', $missing_sets));

return $description;
},
'class' => 'windowbg',
),

Operation #6
Find: [Select]
'function' => create_function('$rowData', '
global $settings;

$images_url = $settings[file_exists(sprintf(\'%1$s/images/post/%2$s.gif\', $settings[\'theme_dir\'], $rowData[\'filename\'])) ? \'actual_images_url\' : \'default_images_url\'];
return sprintf(\'<img src="%1$s/post/%2$s.gif" alt="%3$s" />\', $images_url, $rowData[\'filename\'], htmlspecialchars($rowData[\'title\']));
'),
),
'style' => 'text-align: center;',
Replace With: [Select]
'function' => function($rowData) use ($settings)
{
$images_url = $settings[file_exists(sprintf('%1$s/images/post/%2$s.gif', $settings['theme_dir'], $rowData['filename'])) ? 'actual_images_url' : 'default_images_url'];
return sprintf('<img src="%1$s/post/%2$s.gif" alt="%3$s" />', $images_url, $rowData['filename'], htmlspecialchars($rowData['title']));
},
),
'style' => 'text-align: center;',

Operation #7
Find: [Select]
'function' => create_function('$rowData', '
global $txt;

return empty($rowData[\'board_name\']) ? $txt[\'icons_edit_icons_all_boards\'] : $rowData[\'board_name\'];
'),
),
),
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
return empty($rowData['board_name']) ? $txt['icons_edit_icons_all_boards'] : $rowData['board_name'];
},
),
),

./Sources/Memberlist.php

Operation #1
Find: [Select]
* @version 2.0.12
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
if (!get_magic_quotes_gpc())
{
// Escape things just in case...
Replace With: [Select]
if (!(version_compare(PHP_VERSION, '7.4.0') == -1 && function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc() != 0))
{
// Escape things just in case...

./Sources/ModerationCenter.php

Operation #1
Find: [Select]
* @version 2.0.12
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'function' => create_function('$member', '
global $scripturl;

return allowedTo(\'issue_warning\') ? \'<a href="\' . $scripturl . \'?action=profile;area=issuewarning;u=\' . $member[\'id\'] . \'">\' . $member[\'warning\'] . \'%</a>\' : $member[\'warning\'] . \'%\';
'),
),
'sort' => array(
Replace With: [Select]
'function' => function($member) use ($scripturl)
{
return allowedTo('issue_warning') ? '<a href="' . $scripturl . '?action=profile;area=issuewarning;u=' . $member['id'] . '">' . $member['warning'] . '%</a>' : $member['warning'] . '%';
},
),
'sort' => array(

Operation #3
Find: [Select]
'function' => create_function('$member', '
global $scripturl;

if ($member[\'last_post_id\'])
return \'<a href="\' . $scripturl . \'?msg=\' . $member[\'last_post_id\'] . \'">\' . $member[\'last_post\'] . \'</a>\';
else
return $member[\'last_post\'];
'),
),
),
Replace With: [Select]
'function' => function($member) use ($scripturl)
{
if ($member['last_post_id'])
return '<a href="' . $scripturl . '?msg=' . $member['last_post_id'] . '">' . $member['last_post'] . '</a>';
else
return $member['last_post'];
},
),
),

Operation #4
Find: [Select]
'function' => create_function('$post', '
return template_user_watch_post_callback($post);
'),
),
),
Replace With: [Select]
'function' => function($post)
{
return template_user_watch_post_callback($post);
},
),
),

Operation #5
Find: [Select]
'function' => create_function('$warning', '
global $scripturl, $settings, $txt;

$output = \'
<div class="floatleft">
\' . $warning[\'reason\'] . \'
</div>\';

if (!empty($warning[\'id_notice\']))
$output .= \'
<div class="floatright">
<a href="\' . $scripturl . \'?action=moderate;area=notice;nid=\' . $warning[\'id_notice\'] . \'" onclick="window.open(this.href, \\\'\\\', \\\'scrollbars=yes,resizable=yes,width=400,height=250\\\');return false;" target="_blank" class="new_win" title="\' . $txt[\'profile_warning_previous_notice\'] . \'"><img src="\' . $settings[\'default_images_url\'] . \'/filter.gif" alt="\' . $txt[\'profile_warning_previous_notice\'] . \'" /></a>
</div>\';

return $output;
'),
),
),
Replace With: [Select]
'function' => function($rowData) use ($scripturl, $txt, $settings)
{
$output = '
<div class="floatleft">
' . $rowData['reason'] . '
</div>';

if (!empty($rowData['id_notice']))
$output .= '
&nbsp;<a href="' . $scripturl . '?action=moderate;area=notice;nid=' . $rowData['id_notice'] . '" onclick="window.open(this.href, \'\', \'scrollbars=yes,resizable=yes,width=400,height=250\');return false;" target="_blank" rel="noopener" class="new_win" title="' . $txt['profile_warning_previous_notice'] . '"><img src="' . $settings['default_images_url'] . '/filter.gif" alt="' . $txt['profile_warning_previous_notice'] . '" /></a>';
return $output;
},
),
),

Operation #6
Find: [Select]
'function' => create_function('$rowData', '
global $context, $txt, $scripturl;

return \'<input type="checkbox" name="deltpl[]" value="\' . $rowData[\'id_comment\'] . \'" class="input_check" />\';
'),
'style' => 'text-align: center;',
),
Replace With: [Select]
'function' => function($rowData)
{
return '<input type="checkbox" name="deltpl[]" value="' . $rowData['id_comment'] . '">';
},
'style' => 'text-align: center;',
),

./Sources/Modlog.php

Operation #1
Find: [Select]
* @version 2.0.16
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
AND log_time < {int:twenty_four_hours_wait}
AND action NOT IN ({array_string:uneditable})',
array(
'twenty_four_hours_wait' => time() - $context['hoursdisable'] * 3600,
Replace With: [Select]
AND log_time < {int:twenty_four_hours_wait}' . (!empty($context['uneditable_actions']) ? '
AND action NOT IN ({array_string:uneditable})' : ''),
array(
'twenty_four_hours_wait' => time() - $context['hoursdisable'] * 3600,

Operation #3
Find: [Select]
AND log_time < {int:twenty_four_hours_wait}
AND action NOT IN ({array_string:uneditable})',
array(
'twenty_four_hours_wait' => time() - $context['hoursdisable'] * 3600,
Replace With: [Select]
AND log_time < {int:twenty_four_hours_wait}' . (!empty($context['uneditable_actions']) ? '
AND action NOT IN ({array_string:uneditable})' : ''),
array(
'twenty_four_hours_wait' => time() - $context['hoursdisable'] * 3600,

Operation #4
Find: [Select]
'function' => create_function('$entry', '
return \'<input type="checkbox" class="input_check" name="delete[]" value="\' . $entry[\'id\'] . \'"\' . ($entry[\'editable\'] ? \'\' : \' disabled="disabled"\') . \' />\';
'),
'style' => 'text-align: center;',
),
Replace With: [Select]
'function' => function($entry)
{
return '<input type="checkbox" class="input_check" name="delete[]" value="' . $entry['id'] . '"' . ($entry['editable'] ? '' : ' disabled="disabled"') . ' />';
},
'style' => 'text-align: center;',
),

Operation #5
Find: [Select]
// Do some formatting of the action string.
$callback = pregReplaceCurry('list_getModLogEntriesCallback', 3);
Replace With: [Select]
// Do some formatting of the action string.

Operation #6
Find: [Select]
$entries[$k]['action_text'] = preg_replace_callback('~\{([A-Za-z\d_]+)\}~i', $callback($entries, $k), $entries[$k]['action_text']);

Replace With: [Select]
$entries[$k]['action_text'] = preg_replace_callback('~\{([A-Za-z\d_]+)\}~i',
function($matches) use ($entries, $k)
{
return isset($entries[$k]['extra'][$matches[1]]) ? $entries[$k]['extra'][$matches[1]] : '';
}, $entries[$k]['action_text']);

Operation #7
Find: [Select]
// Mog Log Replacment Callback.
function list_getModLogEntriesCallback($entries, $key, $matches)
{
return isset($entries[$key]['extra'][$matches[1]]) ? $entries[$key]['extra'][$matches[1]] : '';
}

?>
Replace With: [Select]
?>

./Sources/News.php

Operation #1
Find: [Select]
* @version 2.0.17
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
if (empty($modSettings['xmlnews_enable']))
obExit(false);
Replace With: [Select]
if (empty($modSettings['xmlnews_enable']) && ($_GET['sa'] !== 'profile' || $_GET['u'] !== $user_info['id']))
obExit(false);

Operation #3
Find: [Select]
'email' => in_array(showEmailAddress(!empty($profile['hide_email']), $profile['id']), array('yes', 'yes_permission_override')) ? $profile['email'] : null,
'uri' => !empty($profile['website']) ? $profile['website']['url'] : ''
),
Replace With: [Select]
'email' => $user_info['id'] == $profile['id'] || in_array($profile['show_email'], array('yes', 'yes_permission_override')) ? $profile['email'] : null,
'uri' => !empty($profile['website']) ? $profile['website']['url'] : ''
),

Operation #4
Find: [Select]
if (in_array($profile['show_email'], array('yes', 'yes_permission_override')))
$data['email'] = $profile['email'];
Replace With: [Select]
if ($user_info['id'] == $profile['id'] || in_array($profile['show_email'], array('yes', 'yes_permission_override')))
$data['email'] = $profile['email'];

./Sources/Packages.php

Operation #1
Find: [Select]
* @version 2.0.12
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'action' => $smcFunc['htmlspecialchars'](strtr($mod_action['filename'], array($boarddir => '.'))),
'description' => $failed ? $txt['package_action_failure'] : $txt['package_action_success'],
'failed' => $failed,
Replace With: [Select]
'action' => $smcFunc['htmlspecialchars'](strtr($mod_action['filename'], array(strtr($boarddir, '\\', '/') => '.'))),
'description' => $failed ? $txt['package_action_failure'] : $txt['package_action_success'],
'failed' => $failed,

Operation #3
Find: [Select]
'action' => $smcFunc['htmlspecialchars'](strtr($mod_action['filename'], array($boarddir => '.'))),
'description' => $failed ? $txt['package_action_failure'] : $txt['package_action_success'],
'failed' => $failed,
Replace With: [Select]
'action' => $smcFunc['htmlspecialchars'](strtr($mod_action['filename'], array(strtr($boarddir, '\\', '/') => '.'))),
'description' => $failed ? $txt['package_action_failure'] : $txt['package_action_success'],
'failed' => $failed,

./Sources/Post.php

Operation #1
Find: [Select]
* @version 2.0.16
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
{
require_once($sourcedir . '/Notify.php');
$token = createUnsubscribeToken($row['id_member'], $row['email_address'], 'announcements');

$replacements['UNSUBSCRIBELINK'] .= ';u=' . $row['id_member'] . ';token=' . $token;
}

$emaildata = loadEmailTemplate('new_announcement', $replacements, $cur_language);
Replace With: [Select]
$replacements['UNSUBSCRIBELINK'] .= ';u={UNSUBSCRIBE_ID};token={UNSUBSCRIBE_TOKEN}';

$emaildata = loadEmailTemplate('new_announcement', $replacements, $cur_language);

Operation #3
Find: [Select]
sendmail($mail['recipients'], $mail['subject'], $mail['body'], null, null, false, 5);

$context['percentage_done'] = round(100 * $context['start'] / $modSettings['latestMember'], 1);
Replace With: [Select]
{
if (!empty($modSettings['notify_tokens']))
{
foreach ($mail['recipients'] as $member_id => $member_email)
{
require_once($sourcedir . '/Notify.php');
$token = createUnsubscribeToken($member_id, $member_email, 'announcements');

$body = str_replace(array('{UNSUBSCRIBE_ID}', '{UNSUBSCRIBE_TOKEN}'), array($member_id, $token), $mail['body']);

sendmail($member_email, $mail['subject'], $body, null, null, false, 5);
}
}
else
sendmail($mail['recipients'], $mail['subject'], $mail['body'], null, null, false, 5);
}

$context['percentage_done'] = round(100 * $context['start'] / $modSettings['latestMember'], 1);

./Sources/Profile-Modify.php

Operation #1
Find: [Select]
* @version 2.0.16
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'input_validate' => create_function('&$value', '
$value = strtr($value, \' \', \'+\');
return true;
'),
),
'avatar_choice' => array(
Replace With: [Select]
'input_validate' => function(&$value)
{
$value = strtr($value, ' ', '+');
return true;
},
),
'avatar_choice' => array(

Operation #3
Find: [Select]
'preload' => create_function('', '
global $cur_profile, $context;

// Split up the birthdate....
list ($uyear, $umonth, $uday) = explode(\'-\', empty($cur_profile[\'birthdate\']) || $cur_profile[\'birthdate\'] == \'0001-01-01\' ? \'0000-00-00\' : $cur_profile[\'birthdate\']);
$context[\'member\'][\'birth_date\'] = array(
\'year\' => $uyear == \'0004\' ? \'0000\' : $uyear,
\'month\' => $umonth,
\'day\' => $uday,
);

return true;
'),
'input_validate' => create_function('&$value', '
global $profile_vars, $cur_profile;

if (isset($_POST[\'bday2\'], $_POST[\'bday3\']) && $value > 0 && $_POST[\'bday2\'] > 0)
{
// Set to blank?
if ((int) $_POST[\'bday3\'] == 1 && (int) $_POST[\'bday2\'] == 1 && (int) $value == 1)
$value = \'0001-01-01\';
else
$value = checkdate($value, $_POST[\'bday2\'], $_POST[\'bday3\'] < 4 ? 4 : $_POST[\'bday3\']) ? sprintf(\'%04d-%02d-%02d\', $_POST[\'bday3\'] < 4 ? 4 : $_POST[\'bday3\'], $_POST[\'bday1\'], $_POST[\'bday2\']) : \'0001-01-01\';
}
else
$value = \'0001-01-01\';

$profile_vars[\'birthdate\'] = $value;
$cur_profile[\'birthdate\'] = $value;
return false;
'),
),
// Setting the birthdate the old style way?
'birthdate' => array(
'type' => 'hidden',
'permission' => 'profile_extra',
'input_validate' => create_function('&$value', '
global $cur_profile;
// !!! Should we check for this year and tell them they made a mistake :P? (based on coppa at least?)
if (preg_match(\'/(\d{4})[\-\., ](\d{2})[\-\., ](\d{2})/\', $value, $dates) === 1)
{
$value = checkdate($dates[2], $dates[3], $dates[1] < 4 ? 4 : $dates[1]) ? sprintf(\'%04d-%02d-%02d\', $dates[1] < 4 ? 4 : $dates[1], $dates[2], $dates[3]) : \'0001-01-01\';
return true;
}
else
{
$value = empty($cur_profile[\'birthdate\']) ? \'0001-01-01\' : $cur_profile[\'birthdate\'];
return false;
}
'),
),
'date_registered' => array(
Replace With: [Select]
'preload' => function() use ($cur_profile, &$context)
{
// Split up the birthdate....
list ($uyear, $umonth, $uday) = explode('-', empty($cur_profile['birthdate']) || $cur_profile['birthdate'] === '1004-01-01' ? '--' : $cur_profile['birthdate']);
$context['member']['birth_date'] = array(
'year' => $uyear,
'month' => $umonth,
'day' => $uday,
);

return true;
},
'input_validate' => function(&$value) use (&$cur_profile, &$profile_vars)
{
if (isset($_POST['bday2'], $_POST['bday3']) && $value > 0 && $_POST['bday2'] > 0)
{
// Set to blank?
if ((int) $_POST['bday3'] == 1 && (int) $_POST['bday2'] == 1 && (int) $value == 1)
$value = '1004-01-01';
else
$value = checkdate($value, $_POST['bday2'], $_POST['bday3'] < 1004 ? 1004 : $_POST['bday3']) ? sprintf('%04d-%02d-%02d', $_POST['bday3'] < 1004 ? 1004 : $_POST['bday3'], $_POST['bday1'], $_POST['bday2']) : '1004-01-01';
}
else
$value = '1004-01-01';

$profile_vars['birthdate'] = $value;
$cur_profile['birthdate'] = $value;
return false;
},
),
// Setting the birthdate the old style way?
'birthdate' => array(
'type' => 'hidden',
'permission' => 'profile_extra',
'input_validate' => function(&$value) use ($cur_profile)
{
// @todo Should we check for this year and tell them they made a mistake :P? (based on coppa at least?)
if (preg_match('/(\d{4})[\-\., ](\d{2})[\-\., ](\d{2})/', $value, $dates) === 1)
{
$value = checkdate($dates[2], $dates[3], $dates[1] < 4 ? 4 : $dates[1]) ? sprintf('%04d-%02d-%02d', $dates[1] < 4 ? 4 : $dates[1], $dates[2], $dates[3]) : '1004-01-01';
return true;
}
else
{
$value = empty($cur_profile['birthdate']) ? '1004-01-01' : $cur_profile['birthdate'];
return false;
}
},
),
'date_registered' => array(

Operation #4
Find: [Select]
'input_validate' => create_function('&$value', '
global $txt, $user_info, $modSettings, $cur_profile, $context;

// Bad date! Go try again - please?
if (($value = strtotime($value)) === -1)
{
$value = $cur_profile[\'date_registered\'];
return $txt[\'invalid_registration\'] . \' \' . strftime(\'%d %b %Y \' . (strpos($user_info[\'time_format\'], \'%H\') !== false ? \'%I:%M:%S %p\' : \'%H:%M:%S\'), forum_time(false));
}
// As long as it doesn\'t equal "N/A"...
elseif ($value != $txt[\'not_applicable\'] && $value != strtotime(strftime(\'%Y-%m-%d\', $cur_profile[\'date_registered\'] + ($user_info[\'time_offset\'] + $modSettings[\'time_offset\']) * 3600)))
$value = $value - ($user_info[\'time_offset\'] + $modSettings[\'time_offset\']) * 3600;
else
$value = $cur_profile[\'date_registered\'];

return true;
'),
),
'email_address' => array(
Replace With: [Select]
'input_validate' => function(&$value) use ($txt, $user_info, $modSettings, $cur_profile, $context)
{
// Bad date! Go try again - please?
if (($value = strtotime($value)) === false)
{
$value = $cur_profile['date_registered'];
return $txt['invalid_registration'] . ' ' . strftime('%d %b %Y ' . (strpos($user_info['time_format'], '%H') !== false ? '%I:%M:%S %p' : '%H:%M:%S'), forum_time(false));
}

// As long as it doesn't equal "N/A"...
elseif ($value != $txt['not_applicable'] && $value != strtotime(strftime('%Y-%m-%d', $cur_profile['date_registered'] + ($user_info['time_offset'] + $modSettings['time_offset']) * 3600)))
$value = $value - ($user_info['time_offset'] + $modSettings['time_offset']) * 3600;

else
$value = $cur_profile['date_registered'];

return true;
},
),
'email_address' => array(

Operation #5
Find: [Select]
'input_validate' => create_function('&$value', '
global $context, $old_profile, $context, $profile_vars, $sourcedir, $modSettings;

if (strtolower($value) == strtolower($old_profile[\'email_address\']))
return false;

$isValid = profileValidateEmail($value, $context[\'id_member\']);

// Do they need to revalidate? If so schedule the function!
if ($isValid === true && !empty($modSettings[\'send_validation_onChange\']) && !allowedTo(\'moderate_forum\'))
{
require_once($sourcedir . \'/Subs-Members.php\');
$profile_vars[\'validation_code\'] = generateValidationCode();
$profile_vars[\'is_activated\'] = 2;
$context[\'profile_execute_on_save\'][] = \'profileSendActivation\';
unset($context[\'profile_execute_on_save\'][\'reload_user\']);
}

return $isValid;
'),
),
'gender' => array(
Replace With: [Select]
'input_validate' => function(&$value)
{
global $context, $old_profile, $profile_vars, $sourcedir, $modSettings;

if (strtolower($value) == strtolower($old_profile['email_address']))
return false;

$isValid = profileValidateEmail($value, $context['id_member']);

// Do they need to revalidate? If so schedule the function!
if ($isValid === true && !empty($modSettings['send_validation_onChange']) && !allowedTo('moderate_forum'))
{
require_once($sourcedir . '/Subs-Members.php');
$profile_vars['validation_code'] = generateValidationCode();
$profile_vars['is_activated'] = 2;
$context['profile_execute_on_save'][] = 'profileSendActivation';
unset($context['profile_execute_on_save']['reload_user']);
}

return $isValid;
},
),
'gender' => array(

Operation #6
Find: [Select]
'input_validate' => create_function('&$value', '
$value = $value == 0 ? 1 : 0;

return true;
'),
),
'icq' => array(
Replace With: [Select]
'input_validate' => function(&$value)
{
$value = $value == 0 ? 1 : 0;

return true;
},
),
'icq' => array(

Operation #7
Find: [Select]
'input_validate' => create_function('&$value', '
if (empty($value))
$value = \'\';
else
$value = (int) $value;
return true;
'),
),
// Selecting group membership is a complicated one so we treat it separate!
Replace With: [Select]
'input_validate' => function(&$value)
{
if (empty($value))
$value = '';
else
$value = (int) $value;
return true;
},
),
// Selecting group membership is a complicated one so we treat it separate!

Operation #8
Find: [Select]
'preload' => create_function('', '
global $smcFunc, $context, $cur_profile, $txt;

$request = $smcFunc[\'db_query\'](\'\', \'
SELECT value
FROM {db_prefix}themes
WHERE id_theme = {int:id_theme}
AND variable = {string:variable}
LIMIT 1\', array(
\'id_theme\' => $cur_profile[\'id_theme\'],
\'variable\' => \'name\',
)
);
list ($name) = $smcFunc[\'db_fetch_row\']($request);
$smcFunc[\'db_free_result\']($request);

$context[\'member\'][\'theme\'] = array(
\'id\' => $cur_profile[\'id_theme\'],
\'name\' => empty($cur_profile[\'id_theme\']) ? $txt[\'theme_forum_default\'] : $name
);
return true;
'),
'input_validate' => create_function('&$value', '
$value = (int) $value;
return true;
'),
),
'karma_good' => array(
'type' => 'callback',
'callback_func' => 'karma_modify',
'permission' => 'admin_forum',
// Set karma_bad too!
'input_validate' => create_function('&$value', '
global $profile_vars, $cur_profile;

$value = (int) $value;
if (isset($_POST[\'karma_bad\']))
{
$profile_vars[\'karma_bad\'] = $_POST[\'karma_bad\'] != \'\' ? (int) $_POST[\'karma_bad\'] : 0;
$cur_profile[\'karma_bad\'] = $_POST[\'karma_bad\'] != \'\' ? (int) $_POST[\'karma_bad\'] : 0;
}
return true;
'),
'preload' => create_function('', '
global $context, $cur_profile;

$context[\'member\'][\'karma\'][\'good\'] = $cur_profile[\'karma_good\'];
$context[\'member\'][\'karma\'][\'bad\'] = $cur_profile[\'karma_bad\'];

return true;
'),
'enabled' => !empty($modSettings['karmaMode']),
),
Replace With: [Select]
'preload' => function() use ($smcFunc, &$context, $cur_profile, $txt)
{
$request = $smcFunc['db_query']('', '
SELECT value
FROM {db_prefix}themes
WHERE id_theme = {int:id_theme}
AND variable = {string:variable}
LIMIT 1', array(
'id_theme' => $cur_profile['id_theme'],
'variable' => 'name',
)
);
list ($name) = $smcFunc['db_fetch_row']($request);
$smcFunc['db_free_result']($request);

$context['member']['theme'] = array(
'id' => $cur_profile['id_theme'],
'name' => empty($cur_profile['id_theme']) ? $txt['theme_forum_default'] : $name
);
return true;
},
'input_validate' => function(&$value)
{
$value = (int) $value;
return true;
},
),
'karma_good' => array(
'type' => 'callback',
'callback_func' => 'karma_modify',
'permission' => 'admin_forum',
// Set karma_bad too!
'input_validate' => function(&$value)
{
global $profile_vars, $cur_profile;

$value = (int) $value;
if (isset($_POST['karma_bad']))
{
$profile_vars['karma_bad'] = $_POST['karma_bad'] != '' ? (int) $_POST['karma_bad'] : 0;
$cur_profile['karma_bad'] = $_POST['karma_bad'] != '' ? (int) $_POST['karma_bad'] : 0;
}
return true;
},
'preload' => function()
{
global $context, $cur_profile;

$context['member']['karma']['good'] = $cur_profile['karma_good'];
$context['member']['karma']['bad'] = $cur_profile['karma_bad'];

return true;
},
'enabled' => !empty($modSettings['karmaMode']),
),

Operation #9
Find: [Select]
'input_validate' => create_function('&$value', '
global $context, $cur_profile;

// Load the languages.
profileLoadLanguages();

if (isset($context[\'profile_languages\'][$value]))
{
if ($context[\'user\'][\'is_owner\'] && empty($context[\'password_auth_failed\']))
$_SESSION[\'language\'] = $value;
return true;
}
else
{
$value = $cur_profile[\'lngfile\'];
return false;
}
'),
),
'location' => array(
Replace With: [Select]
'input_validate' => function(&$value) use (&$context, $cur_profile)
{
// Load the languages.
profileLoadLanguages();

if (isset($context['profile_languages'][$value]))
{
if ($context['user']['is_owner'] && empty($context['password_auth_failed']))
$_SESSION['language'] = $value;
return true;
}
else
{
$value = $cur_profile['lngfile'];
return false;
}
},
),
'location' => array(

Operation #10
Find: [Select]
'input_validate' => create_function('&$value', '
global $sourcedir, $context, $user_info, $cur_profile;

if (allowedTo(\'admin_forum\'))
{
// We\'ll need this...
require_once($sourcedir . \'/Subs-Auth.php\');

// Maybe they are trying to change their password as well?
$resetPassword = true;
if (isset($_POST[\'passwrd1\']) && $_POST[\'passwrd1\'] != \'\' && isset($_POST[\'passwrd2\']) && $_POST[\'passwrd1\'] == $_POST[\'passwrd2\'] && validatePassword($_POST[\'passwrd1\'], $value, array($cur_profile[\'real_name\'], $user_info[\'username\'], $user_info[\'name\'], $user_info[\'email\'])) == null)
$resetPassword = false;

// Do the reset... this will send them an email too.
if ($resetPassword)
resetPassword($context[\'id_member\'], $value);
elseif ($value !== null)
{
validateUsername($context[\'id_member\'], trim(preg_replace(\'~[\t\n\r \x0B\0\' . ($context[\'utf8\'] ? ($context[\'server\'][\'complex_preg_chars\'] ? \'\x{A0}\x{AD}\x{2000}-\x{200F}\x{201F}\x{202F}\x{3000}\x{FEFF}\' : "\xC2\xA0\xC2\xAD\xE2\x80\x80-\xE2\x80\x8F\xE2\x80\x9F\xE2\x80\xAF\xE2\x80\x9F\xE3\x80\x80\xEF\xBB\xBF") : \'\x00-\x08\x0B\x0C\x0E-\x19\xA0\') . \']+~\' . ($context[\'utf8\'] ? \'u\' : \'\'), \' \', $value)));
updateMemberData($context[\'id_member\'], array(\'member_name\' => $value));
}
}
return false;
'),
),
'msn' => array(
Replace With: [Select]
'input_validate' => function(&$value)
{
global $sourcedir, $context, $user_info, $cur_profile;

if (allowedTo('admin_forum'))
{
// We\'ll need this...
require_once($sourcedir . '/Subs-Auth.php');

// Maybe they are trying to change their password as well?
$resetPassword = true;
if (isset($_POST['passwrd1']) && $_POST['passwrd1'] != '' && isset($_POST['passwrd2']) && $_POST['passwrd1'] == $_POST['passwrd2'] && validatePassword($_POST['passwrd1'], $value, array($cur_profile['real_name'], $user_info['username'], $user_info['name'], $user_info['email'])) == null)
$resetPassword = false;

// Do the reset... this will send them an email too.
if ($resetPassword)
resetPassword($context['id_member'], $value);
elseif ($value !== null)
{
validateUsername($context['id_member'], trim(preg_replace('~[\t\n\r \x0B\0' . ($context['utf8'] ? ($context['server']['complex_preg_chars'] ? '\x{A0}\x{AD}\x{2000}-\x{200F}\x{201F}\x{202F}\x{3000}\x{FEFF}' : "\xC2\xA0\xC2\xAD\xE2\x80\x80-\xE2\x80\x8F\xE2\x80\x9F\xE2\x80\xAF\xE2\x80\x9F\xE3\x80\x80\xEF\xBB\xBF") : '\x00-\x08\x0B\x0C\x0E-\x19\xA0') . ']+~' . ($context['utf8'] ? 'u' : ''), ' ', $value)));
updateMemberData($context['id_member'], array('member_name' => $value));
}
}
return false;
},
),
'msn' => array(

Operation #11
Find: [Select]
'input_validate' => create_function('&$value', '
global $cur_profile;
// Make sure the msn one is an email address, not something like \'none\' :P.
if ($value != \'\' && preg_match(\'~^[0-9A-Za-z=_+\-/][0-9A-Za-z=_\\\'+\-/\.]*@[\w\-]+(\.[\w\-]+)*(\.[\w]{2,6})$~\', $value) == 0)
{
$value = $cur_profile[\'msn\'];
return false;
}
return true;
'),
),
'passwrd1' => array(
Replace With: [Select]
'input_validate' => function(&$value)
{
global $cur_profile;
// Make sure the msn one is an email address, not something like \'none\' :P.
if ($value != '' && preg_match('~^[0-9A-Za-z=_+\-/][0-9A-Za-z=_\\\'+\-/\.]*@[\w\-]+(\.[\w\-]+)*(\.[\w]{2,6})$~', $value) == 0)
{
$value = $cur_profile['msn'];
return false;
}
return true;
},
),
'passwrd1' => array(

Operation #12
Find: [Select]
'input_validate' => create_function('&$value', '
global $sourcedir, $user_info, $smcFunc, $cur_profile;

// If we didn\'t try it then ignore it!
if ($value == \'\')
return false;

// Do the two entries for the password even match?
if (!isset($_POST[\'passwrd2\']) || $value != $_POST[\'passwrd2\'])
return \'bad_new_password\';

// Let\'s get the validation function into play...
require_once($sourcedir . \'/Subs-Auth.php\');
$passwordErrors = validatePassword($value, $cur_profile[\'member_name\'], array($cur_profile[\'real_name\'], $user_info[\'username\'], $user_info[\'name\'], $user_info[\'email\']));

// Were there errors?
if ($passwordErrors != null)
return \'password_\' . $passwordErrors;

// Set up the new password variable... ready for storage.
$value = sha1(strtolower($cur_profile[\'member_name\']) . un_htmlspecialchars($value));
return true;
'),
),
'passwrd2' => array(
Replace With: [Select]
'input_validate' => function(&$value)
{
global $sourcedir, $user_info, $smcFunc, $cur_profile;

// If we didn\'t try it then ignore it!
if ($value == '')
return false;

// Do the two entries for the password even match?
if (!isset($_POST['passwrd2']) || $value != $_POST['passwrd2'])
return 'bad_new_password';

// Let\'s get the validation function into play...
require_once($sourcedir . '/Subs-Auth.php');
$passwordErrors = validatePassword($value, $cur_profile['member_name'], array($cur_profile['real_name'], $user_info['username'], $user_info['name'], $user_info['email']));

// Were there errors?
if ($passwordErrors != null)
return 'password_' . $passwordErrors;

// Set up the new password variable... ready for storage.
$value = sha1(strtolower($cur_profile['member_name']) . un_htmlspecialchars($value));
return true;
},
),
'passwrd2' => array(

Operation #13
Find: [Select]
'preload' => create_function('', '
global $context, $cur_profile;

$context[\'display_mode\'] = $cur_profile[\'pm_prefs\'] & 3;
$context[\'send_email\'] = $cur_profile[\'pm_email_notify\'];
$context[\'receive_from\'] = !empty($cur_profile[\'pm_receive_from\']) ? $cur_profile[\'pm_receive_from\'] : 0;

return true;
'),
'input_validate' => create_function('&$value', '
global $cur_profile, $profile_vars;

// Simple validate and apply the two "sub settings"
$value = max(min($value, 2), 0);

$cur_profile[\'pm_email_notify\'] = $profile_vars[\'pm_email_notify\'] = max(min((int) $_POST[\'pm_email_notify\'], 2), 0);
$cur_profile[\'pm_receive_from\'] = $profile_vars[\'pm_receive_from\'] = max(min((int) $_POST[\'pm_receive_from\'], 4), 0);

return true;
'),
),
'posts' => array(
Replace With: [Select]
'preload' => function()
{
global $context, $cur_profile;

$context['display_mode'] = $cur_profile['pm_prefs'] & 3;
$context['send_email'] = $cur_profile['pm_email_notify'];
$context['receive_from'] = !empty($cur_profile['pm_receive_from']) ? $cur_profile['pm_receive_from'] : 0;

return true;
},
'input_validate' => function(&$value)
{
global $cur_profile, $profile_vars;

// Simple validate and apply the two "sub settings"
$value = max(min($value, 2), 0);

$cur_profile['pm_email_notify'] = $profile_vars['pm_email_notify'] = max(min((int) $_POST['pm_email_notify'], 2), 0);
$cur_profile['pm_receive_from'] = $profile_vars['pm_receive_from'] = max(min((int) $_POST['pm_receive_from'], 4), 0);

return true;
},
),
'posts' => array(

Operation #14
Find: [Select]
'input_validate' => create_function('&$value', '
$value = $value != \'\' ? strtr($value, array(\',\' => \'\', \'.\' => \'\', \' \' => \'\')) : 0;
return true;
'),
),
'real_name' => array(
Replace With: [Select]
'input_validate' => function(&$value)
{
$value = $value != '' ? strtr($value, array(',' => '', '.' => '', ' ' => '')) : 0;
return true;
},
),
'real_name' => array(

Operation #15
Find: [Select]
'input_validate' => create_function('&$value', '
global $context, $smcFunc, $sourcedir, $cur_profile;

$value = trim(preg_replace(\'~[\t\n\r \x0B\0\' . ($context[\'utf8\'] ? ($context[\'server\'][\'complex_preg_chars\'] ? \'\x{A0}\x{AD}\x{2000}-\x{200F}\x{201F}\x{202F}\x{3000}\x{FEFF}\' : "\xC2\xA0\xC2\xAD\xE2\x80\x80-\xE2\x80\x8F\xE2\x80\x9F\xE2\x80\xAF\xE2\x80\x9F\xE3\x80\x80\xEF\xBB\xBF") : \'\x00-\x08\x0B\x0C\x0E-\x19\xA0\') . \']+~\' . ($context[\'utf8\'] ? \'u\' : \'\'), \' \', $value));

if (trim($value) == \'\')
return \'no_name\';
elseif ($smcFunc[\'strlen\']($value) > 60)
return \'name_too_long\';
elseif ($cur_profile[\'real_name\'] != $value)
{
require_once($sourcedir . \'/Subs-Members.php\');
if (isReservedName($value, $context[\'id_member\']))
return \'name_taken\';
}
return true;
'),
),
'secret_question' => array(
Replace With: [Select]
'input_validate' => function(&$value)
{
global $context, $smcFunc, $sourcedir, $cur_profile;

$value = trim(preg_replace('~[\t\n\r \x0B\0' . ($context['utf8'] ? ($context['server']['complex_preg_chars'] ? '\x{A0}\x{AD}\x{2000}-\x{200F}\x{201F}\x{202F}\x{3000}\x{FEFF}' : "\xC2\xA0\xC2\xAD\xE2\x80\x80-\xE2\x80\x8F\xE2\x80\x9F\xE2\x80\xAF\xE2\x80\x9F\xE3\x80\x80\xEF\xBB\xBF") : '\x00-\x08\x0B\x0C\x0E-\x19\xA0') . ']+~' . ($context['utf8'] ? 'u' : ''), ' ', $value));

if (trim($value) == '')
return 'no_name';
elseif ($smcFunc['strlen']($value) > 60)
return 'name_too_long';
elseif ($cur_profile['real_name'] != $value)
{
require_once($sourcedir . '/Subs-Members.php');
if (isReservedName($value, $context['id_member']))
return 'name_taken';
}
return true;
},
),
'secret_question' => array(

Operation #16
Find: [Select]
'input_validate' => create_function('&$value', '
$value = $value != \'\' ? md5($value) : \'\';
return true;
'),
),
'signature' => array(
Replace With: [Select]
'input_validate' => function(&$value)
{
$value = $value != '' ? md5($value) : '';
return true;
},
),
'signature' => array(

Operation #17
Find: [Select]
'preload' => create_function('', '
global $modSettings, $context, $txt, $cur_profile;

$context[\'member\'][\'smiley_set\'][\'id\'] = empty($cur_profile[\'smiley_set\']) ? \'\' : $cur_profile[\'smiley_set\'];
$context[\'smiley_sets\'] = explode(\',\', \'none,,\' . $modSettings[\'smiley_sets_known\']);
$set_names = explode("\n", $txt[\'smileys_none\'] . "\n" . $txt[\'smileys_forum_board_default\'] . "\n" . $modSettings[\'smiley_sets_names\']);
foreach ($context[\'smiley_sets\'] as $i => $set)
{
$context[\'smiley_sets\'][$i] = array(
\'id\' => htmlspecialchars($set),
\'name\' => htmlspecialchars($set_names[$i]),
\'selected\' => $set == $context[\'member\'][\'smiley_set\'][\'id\']
);

if ($context[\'smiley_sets\'][$i][\'selected\'])
$context[\'member\'][\'smiley_set\'][\'name\'] = $set_names[$i];
}
return true;
'),
'input_validate' => create_function('&$value', '
global $modSettings;

$smiley_sets = explode(\',\', $modSettings[\'smiley_sets_known\']);
if (!in_array($value, $smiley_sets) && $value != \'none\')
$value = \'\';
return true;
'),
),
// Pretty much a dummy entry - it populates all the theme settings.
Replace With: [Select]
'preload' => function()
{
global $modSettings, $context, $txt, $cur_profile;

$context['member']['smiley_set']['id'] = empty($cur_profile['smiley_set']) ? '' : $cur_profile['smiley_set'];
$context['smiley_sets'] = explode(',', 'none,,' . $modSettings['smiley_sets_known']);
$set_names = explode("\n", $txt['smileys_none'] . "\n" . $txt['smileys_forum_board_default'] . "\n" . $modSettings['smiley_sets_names']);
foreach ($context['smiley_sets'] as $i => $set)
{
$context['smiley_sets'][$i] = array(
'id' => htmlspecialchars($set),
'name' => htmlspecialchars($set_names[$i]),
'selected' => $set == $context['member']['smiley_set']['id']
);

if ($context['smiley_sets'][$i]['selected'])
$context['member']['smiley_set']['name'] = $set_names[$i];
}
return true;
},
'input_validate' => function(&$value)
{
global $modSettings;

$smiley_sets = explode(',', $modSettings['smiley_sets_known']);
if (!in_array($value, $smiley_sets) && $value != 'none')
$value = '';
return true;
},
),
// Pretty much a dummy entry - it populates all the theme settings.

Operation #18
Find: [Select]
'preload' => create_function('', '
loadLanguage(\'Settings\');
return true;
'),
),
'time_format' => array(
'type' => 'callback',
'callback_func' => 'timeformat_modify',
'permission' => 'profile_extra',
'preload' => create_function('', '
global $context, $user_info, $txt, $cur_profile, $modSettings;

$context[\'easy_timeformats\'] = array(
array(\'format\' => \'\', \'title\' => $txt[\'timeformat_default\']),
array(\'format\' => \'%B %d, %Y, %I:%M:%S %p\', \'title\' => $txt[\'timeformat_easy1\']),
array(\'format\' => \'%B %d, %Y, %H:%M:%S\', \'title\' => $txt[\'timeformat_easy2\']),
array(\'format\' => \'%Y-%m-%d, %H:%M:%S\', \'title\' => $txt[\'timeformat_easy3\']),
array(\'format\' => \'%d %B %Y, %H:%M:%S\', \'title\' => $txt[\'timeformat_easy4\']),
array(\'format\' => \'%d-%m-%Y, %H:%M:%S\', \'title\' => $txt[\'timeformat_easy5\'])
);

$context[\'member\'][\'time_format\'] = $cur_profile[\'time_format\'];
$context[\'current_forum_time\'] = timeformat(time() - $user_info[\'time_offset\'] * 3600, false);
$context[\'current_forum_time_js\'] = strftime(\'%Y,\' . ((int) strftime(\'%m\', time() + $modSettings[\'time_offset\'] * 3600) - 1) . \',%d,%H,%M,%S\', time() + $modSettings[\'time_offset\'] * 3600);
$context[\'current_forum_time_hour\'] = (int) strftime(\'%H\', forum_time(false));
return true;
'),
),
'time_offset' => array(
'type' => 'callback',
'callback_func' => 'timeoffset_modify',
'permission' => 'profile_extra',
'preload' => create_function('', '
global $context, $cur_profile;
$context[\'member\'][\'time_offset\'] = $cur_profile[\'time_offset\'];
return true;
'),
'input_validate' => create_function('&$value', '
// Validate the time_offset...
$value = (float) strtr($value, \',\', \'.\');

if ($value < -23.5 || $value > 23.5)
return \'bad_offset\';

return true;
'),
),
'usertitle' => array(
Replace With: [Select]
'preload' => function()
{
loadLanguage('Settings');
return true;
},
),
'time_format' => array(
'type' => 'callback',
'callback_func' => 'timeformat_modify',
'permission' => 'profile_extra',
'preload' => function() use (&$context, $user_info, $txt, $cur_profile, $modSettings)
{
$context['easy_timeformats'] = array(
array('format' => '', 'title' => $txt['timeformat_default']),
array('format' => '%B %d, %Y, %I:%M:%S %p', 'title' => $txt['timeformat_easy1']),
array('format' => '%B %d, %Y, %H:%M:%S', 'title' => $txt['timeformat_easy2']),
array('format' => '%Y-%m-%d, %H:%M:%S', 'title' => $txt['timeformat_easy3']),
array('format' => '%d %B %Y, %H:%M:%S', 'title' => $txt['timeformat_easy4']),
array('format' => '%d-%m-%Y, %H:%M:%S', 'title' => $txt['timeformat_easy5'])
);

$context['member']['time_format'] = $cur_profile['time_format'];
$context['current_forum_time'] = timeformat(time() - $user_info['time_offset'] * 3600, false);
$context['current_forum_time_js'] = strftime('%Y,' . ((int) strftime('%m', time() + $modSettings['time_offset'] * 3600) - 1) . ',%d,%H,%M,%S', time() + $modSettings['time_offset'] * 3600);
$context['current_forum_time_hour'] = (int) strftime('%H', forum_time(false));
return true;
},
),
'time_offset' => array(
'type' => 'callback',
'callback_func' => 'timeoffset_modify',
'permission' => 'profile_extra',
'preload' => function()
{
global $context, $cur_profile;
$context['member']['time_offset'] = $cur_profile['time_offset'];
return true;
},
'input_validate' => function(&$value)
{
// Validate the time_offset...
$value = (float) strtr($value, ',', '.');

if ($value < -23.5 || $value > 23.5)
return 'bad_offset';

return true;
},
),
'usertitle' => array(

Operation #19
Find: [Select]
'input_validate' => create_function('&$value', '

if (strlen(trim($value)) > 0 && strpos($value, \'://\') === false)
$value = \'http://\' . $value;
if (strlen($value) < 8 || (substr($value, 0, 7) !== \'http://\' && substr($value, 0, 8) !== \'https://\'))
$value = \'\';
return true;
'),
'link_with' => 'website',
),
Replace With: [Select]
'input_validate' => function(&$value)
{
if (strlen(trim($value)) > 0 && strpos($value, '://') === false)
$value = 'http://' . $value;
if (strlen($value) < 8 || (substr($value, 0, 7) !== 'http://' && substr($value, 0, 8) !== 'https://'))
$value = '';
return true;
},
'link_with' => 'website',
),

Operation #20
Find: [Select]
'function' => create_function('$board', '
global $settings, $txt;

$link = $board[\'link\'];

if ($board[\'new\'])
$link .= \' <a href="\' . $board[\'href\'] . \'"><img src="\' . $settings[\'lang_images_url\'] . \'/new.gif" alt="\' . $txt[\'new\'] . \'" /></a>\';

return $link;
'),
),
'sort' => array(
Replace With: [Select]
'function' => function($board) use ($settings, $txt)
{
$link = $board['link'];

if ($board['new'])
$link .= ' <a href="' . $board['href'] . '"><img src="' . $settings['lang_images_url'] . '/new.gif" alt="' . $txt['new'] . '" /></a>';

return $link;
},
),
'sort' => array(

Operation #21
Find: [Select]
'function' => create_function('$topic', '
global $settings, $txt;

$link = $topic[\'link\'];

if ($topic[\'new\'])
$link .= \' <a href="\' . $topic[\'new_href\'] . \'"><img src="\' . $settings[\'lang_images_url\'] . \'/new.gif" alt="\' . $txt[\'new\'] . \'" /></a>\';

$link .= \'<br /><span class="smalltext"><em>\' . $txt[\'in\'] . \' \' . $topic[\'board_link\'] . \'</em></span>\';

return $link;
'),
),
'sort' => array(
Replace With: [Select]
'function' => function($topic) use ($settings, $txt)
{
$link = $topic['link'];

if ($topic['new'])
$link .= ' <a href="' . $topic['new_href'] . '"><img src="' . $settings['lang_images_url'] . '/new.gif" alt="' . $txt['new'] . '" /></a>';

$link .= '<br /><span class="smalltext"><em>' . $txt['in'] . ' ' . $topic['board_link'] . '</em></span>';

return $link;
},
),
'sort' => array(

./Sources/Profile-View.php

Operation #1
Find: [Select]
* @version 2.0.14
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'afrinic' => array(
'name' => $txt['whois_afrinic'],
'url' => 'http://www.afrinic.net/cgi-bin/whois?searchtext=' . $context['ip'],
'range' => array(41, 154, 196),
),
'apnic' => array(
'name' => $txt['whois_apnic'],
'url' => 'http://wq.apnic.net/apnic-bin/whois.pl?searchtext=' . $context['ip'],
'range' => array(58, 59, 60, 61, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
125, 126, 133, 150, 153, 163, 171, 202, 203, 210, 211, 218, 219, 220, 221, 222),
),
'arin' => array(
'name' => $txt['whois_arin'],
'url' => 'http://whois.arin.net/rest/ip/' . $context['ip'],
'range' => array(7, 24, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 96, 97, 98, 99,
128, 129, 130, 131, 132, 134, 135, 136, 137, 138, 139, 140, 142, 143, 144, 146, 147, 148, 149,
Replace With: [Select]
'apnic' => array(
'name' => $txt['whois_apnic'],
'url' => 'https://wq.apnic.net/apnic-bin/whois.pl?searchtext=' . $context['ip'],
'range' => array(58, 59, 60, 61, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
125, 126, 133, 150, 153, 163, 171, 202, 203, 210, 211, 218, 219, 220, 221, 222),
),
'arin' => array(
'name' => $txt['whois_arin'],
'url' => 'https://whois.arin.net/rest/ip/' . $context['ip'],
'range' => array(7, 24, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 96, 97, 98, 99,
128, 129, 130, 131, 132, 134, 135, 136, 137, 138, 139, 140, 142, 143, 144, 146, 147, 148, 149,

Operation #3
Find: [Select]
'url' => 'http://lacnic.net/cgi-bin/lacnic/whois?query=' . $context['ip'],
'range' => array(186, 187, 189, 190, 191, 200, 201),
),
Replace With: [Select]
'url' => 'https://lacnic.net/cgi-bin/lacnic/whois?query=' . $context['ip'],
'range' => array(186, 187, 189, 190, 191, 200, 201),
),

./Sources/QueryString.php

Operation #1
Find: [Select]
* @version 2.0.16
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
if (function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc() != 0 && empty($modSettings['integrate_magic_quotes']))
$_GET = $removeMagicQuoteFunction($_GET);
}
elseif (strpos(@ini_get('arg_separator.input'), ';') !== false)
{
if (function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc() != 0 && empty($modSettings['integrate_magic_quotes']))
$_GET = $removeMagicQuoteFunction($_GET);
Replace With: [Select]
if (version_compare(PHP_VERSION, '7.4.0') == -1 && function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc() != 0 && empty($modSettings['integrate_magic_quotes']))
$_GET = $removeMagicQuoteFunction($_GET);
}
elseif (strpos(@ini_get('arg_separator.input'), ';') !== false)
{
if (version_compare(PHP_VERSION, '7.4.0') == -1 && function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc() != 0 && empty($modSettings['integrate_magic_quotes']))
$_GET = $removeMagicQuoteFunction($_GET);

Operation #3
Find: [Select]
if (function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc() != 0)
{
$_ENV = $removeMagicQuoteFunction($_ENV);
Replace With: [Select]
if (version_compare(PHP_VERSION, '7.4.0') == -1 && function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc() != 0)
{
$_ENV = $removeMagicQuoteFunction($_ENV);

./Sources/Register.php

Operation #1
Find: [Select]
* @version 2.0.16
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
call_integration_hook('integrate_activate', array($row['member_name']));
Replace With: [Select]
call_integration_hook('integrate_activate', array($regOptions['username']));

Operation #3
Find: [Select]
if ($_REQUEST['letter'] > 0 && $_REQUEST['letter'] <= strlen($code) && !showLetterImage(strtolower($code{$_REQUEST['letter'] - 1})))
{
header('Content-Type: image/gif');
Replace With: [Select]
if ($_REQUEST['letter'] > 0 && $_REQUEST['letter'] <= strlen($code) && !showLetterImage(strtolower($code[$_REQUEST['letter'] - 1])))
{
header('Content-Type: image/gif');

./Sources/RepairBoards.php

Operation #1
Find: [Select]
* @version 2.0
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
'fix_processing' => create_function('$row', '
global $smcFunc, $salvageBoardID;

// Only if we don\'t have a reasonable idea of where to put it.
if ($row[\'id_board\'] == 0)
{
createSalvageArea();
$row[\'id_board\'] = (int) $salvageBoardID;
}

// Make sure that no topics claim the first/last message as theirs.
$smcFunc[\'db_query\'](\'\', \'
UPDATE {db_prefix}topics
SET id_first_msg = 0
WHERE id_first_msg = {int:id_first_msg}\',
array(
\'id_first_msg\' => $row[\'myid_first_msg\'],
)
);
$smcFunc[\'db_query\'](\'\', \'
UPDATE {db_prefix}topics
SET id_last_msg = 0
WHERE id_last_msg = {int:id_last_msg}\',
array(
\'id_last_msg\' => $row[\'myid_last_msg\'],
)
);

$memberStartedID = (int) getMsgMemberID($row[\'myid_first_msg\']);
$memberUpdatedID = (int) getMsgMemberID($row[\'myid_last_msg\']);

$smcFunc[\'db_insert\'](\'\',
\'{db_prefix}topics\',
array(
\'id_board\' => \'int\',
\'id_member_started\' => \'int\',
\'id_member_updated\' => \'int\',
\'id_first_msg\' => \'int\',
\'id_last_msg\' => \'int\',
\'num_replies\' => \'int\'
),
array(
$row[\'id_board\'],
$memberStartedID,
$memberUpdatedID,
$row[\'myid_first_msg\'],
$row[\'myid_last_msg\'],
$row[\'my_num_replies\']
),
array(\'id_topic\')
);

$newTopicID = $smcFunc[\'db_insert_id\']("{db_prefix}topics", \'id_topic\');

$smcFunc[\'db_query\'](\'\', "
UPDATE {db_prefix}messages
SET id_topic = $newTopicID, id_board = $row[id_board]
WHERE id_topic = $row[id_topic]",
array(
)
);
'),
'force_fix' => array('stats_topics'),
'messages' => array('repair_missing_topics', 'id_msg', 'id_topic'),
Replace With: [Select]
'fix_processing' => function($row) use ($smcFunc)
{
global $salvageBoardID;

// Only if we don't have a reasonable idea of where to put it.
if ($row['id_board'] == 0)
{
createSalvageArea();
$row['id_board'] = (int) $salvageBoardID;
}

// Make sure that no topics claim the first/last message as theirs.
$smcFunc['db_query']('', '
UPDATE {db_prefix}topics
SET id_first_msg = 0
WHERE id_first_msg = {int:id_first_msg}',
array(
'id_first_msg' => $row['myid_first_msg'],
)
);
$smcFunc['db_query']('', '
UPDATE {db_prefix}topics
SET id_last_msg = 0
WHERE id_last_msg = {int:id_last_msg}',
array(
'id_last_msg' => $row['myid_last_msg'],
)
);

$memberStartedID = (int) getMsgMemberID($row['myid_first_msg']);
$memberUpdatedID = (int) getMsgMemberID($row['myid_last_msg']);

$smcFunc['db_insert']('',
'{db_prefix}topics',
array(
'id_board' => 'int',
'id_member_started' => 'int',
'id_member_updated' => 'int',
'id_first_msg' => 'int',
'id_last_msg' => 'int',
'num_replies' => 'int'
),
array(
$row['id_board'],
$memberStartedID,
$memberUpdatedID,
$row['myid_first_msg'],
$row['myid_last_msg'],
$row['my_num_replies']
),
array('id_topic'),
1
);

$newTopicID = $smcFunc['db_insert_id']('{db_prefix}topics', 'id_topic');

$smcFunc['db_query']('', '
UPDATE {db_prefix}messages
SET id_topic = {int:newTopicID}, id_board = {int:board_id}
WHERE id_topic = {int:topic_id}',
array(
'board_id' => $row['id_board'],
'topic_id' => $row['id_topic'],
'newTopicID' => $newTopicID,
)
);
},
'force_fix' => array('stats_topics'),
'messages' => array('repair_missing_topics', 'id_msg', 'id_topic'),

Operation #3
Find: [Select]
'process' => create_function('$topics', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
DELETE FROM {db_prefix}topics
WHERE id_topic IN ({array_int:topics})",
array(
\'topics\' => $topics
)
);
$smcFunc[\'db_query\'](\'\', "
DELETE FROM {db_prefix}log_topics
WHERE id_topic IN ({array_int:topics})",
array(
\'topics\' => $topics
)
);
'),
),
'messages' => array('repair_missing_messages', 'id_topic'),
Replace With: [Select]
'process' => function($topics) use ($smcFunc)
{
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}topics
WHERE id_topic IN ({array_int:topics})',
array(
'topics' => $topics,
)
);
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_topics
WHERE id_topic IN ({array_int:topics})',
array(
'topics' => $topics,
)
);
},
),
'messages' => array('repair_missing_messages', 'id_topic'),

Operation #4
Find: [Select]
'fix_processing' => create_function('$row', '
global $smcFunc, $salvageBoardID, $txt;

// Only if we don\'t have a reasonable idea of where to put it.
if ($row[\'id_board\'] == 0)
{
createSalvageArea();
$row[\'id_board\'] = (int) $salvageBoardID;
}

$row[\'poster_name\'] = !empty($row[\'poster_name\']) ? $row[\'poster_name\'] : $txt[\'guest\'];

$smcFunc[\'db_insert\'](\'\',
\'{db_prefix}messages\',
array(
\'id_board\' => \'int\',
\'id_topic\' => \'int\',
\'poster_time\' => \'int\',
\'id_member\' => \'int\',
\'subject\' => \'string-255\',
\'poster_name\' => \'string-255\',
\'poster_email\' => \'string-255\',
\'poster_ip\' => \'string-16\',
\'smileys_enabled\' => \'int\',
\'body\' => \'string-65534\',
\'icon\' => \'string-16\',
\'approved\' => \'int\',
),
array(
$row[\'id_board\'],
0,
time(),
$row[\'id_member\'],
$txt[\'salvaged_poll_topic_name\'],
$row[\'poster_name\'],
\'\',
\'127.0.0.1\',
1,
$txt[\'salvaged_poll_message_body\'],
\'xx\',
1,
),
array(\'id_topic\')
);

$newMessageID = $smcFunc[\'db_insert_id\']("{db_prefix}messages", \'id_msg\');

$smcFunc[\'db_insert\'](\'\',
\'{db_prefix}topics\',
array(
\'id_board\' => \'int\',
\'id_poll\' => \'int\',
\'id_member_started\' => \'int\',
\'id_member_updated\' => \'int\',
\'id_first_msg\' => \'int\',
\'id_last_msg\' => \'int\',
\'num_replies\' => \'int\',
),
array(
$row[\'id_board\'],
$row[\'id_poll\'],
$row[\'id_member\'],
$row[\'id_member\'],
$newMessageID,
$newMessageID,
0,
),
array(\'id_topic\')
);

$newTopicID = $smcFunc[\'db_insert_id\']("{db_prefix}topics", \'id_topic\');

$smcFunc[\'db_query\'](\'\', "
UPDATE {db_prefix}messages
SET id_topic = $newTopicID, id_board = $row[id_board]
WHERE id_msg = $newMessageID",
array(
)
);

updateStats(\'subject\', $newTopicID, $txt[\'salvaged_poll_topic_name\']);

'),
'force_fix' => array('stats_topics'),
'messages' => array('repair_polls_missing_topics', 'id_poll', 'id_topic'),
Replace With: [Select]
'fix_processing' => function($row) use ($smcFunc)
{
global $txt, $salvageBoardID;

// Only if we don't have a reasonable idea of where to put it.
if ($row['id_board'] == 0)
{
createSalvageArea();
$row['id_board'] = (int) $salvageBoardID;
}

$row['poster_name'] = !empty($row['poster_name']) ? $row['poster_name'] : $txt['guest'];

$smcFunc['db_insert']('',
'{db_prefix}messages',
array(
'id_board' => 'int',
'id_topic' => 'int',
'poster_time' => 'int',
'id_member' => 'int',
'subject' => 'string-255',
'poster_name' => 'string-255',
'poster_email' => 'string-255',
'poster_ip' => 'inet',
'smileys_enabled' => 'int',
'body' => 'string-65534',
'icon' => 'string-16',
'approved' => 'int',
),
array(
$row['id_board'],
0,
time(),
$row['id_member'],
$txt['salvaged_poll_topic_name'],
$row['poster_name'],
'',
'127.0.0.1',
1,
$txt['salvaged_poll_message_body'],
'xx',
1,
),
array('id_msg'),
1
);

$newMessageID = $smcFunc['db_insert_id']('{db_prefix}messages', 'id_msg');

$smcFunc['db_insert']('',
'{db_prefix}topics',
array(
'id_board' => 'int',
'id_poll' => 'int',
'id_member_started' => 'int',
'id_member_updated' => 'int',
'id_first_msg' => 'int',
'id_last_msg' => 'int',
'num_replies' => 'int',
),
array(
$row['id_board'],
$row['id_poll'],
$row['id_member'],
$row['id_member'],
$newMessageID,
$newMessageID,
0,
),
array('id_topic'),
1
);

$newTopicID = $smcFunc['db_insert_id']('{db_prefix}topics', 'id_topic');

$smcFunc['db_query']('', '
UPDATE {db_prefix}messages
SET id_topic = {int:newTopicID}, id_board = {int:id_board}
WHERE id_msg = {int:newMessageID}',
array(
'id_board' => $row['id_board'],
'newTopicID' => $newTopicID,
'newMessageID' => $newMessageID,
)
);

updateStats('subject', $newTopicID, $txt['salvaged_poll_topic_name']);
},
'force_fix' => array('stats_topics'),
'messages' => array('repair_polls_missing_topics', 'id_poll', 'id_topic'),

Operation #5
Find: [Select]
'fix_processing' => create_function('$row', '
global $smcFunc;
$row[\'firstmsg_approved\'] = (int) $row[\'firstmsg_approved\'];
$row[\'myid_first_msg\'] = (int) $row[\'myid_first_msg\'];
$row[\'myid_last_msg\'] = (int) $row[\'myid_last_msg\'];

// Not really a problem?
if ($row[\'myid_first_msg\'] == $row[\'myid_first_msg\'] && $row[\'myid_first_msg\'] == $row[\'myid_first_msg\'] && $row[\'approved\'] == $row[\'firstmsg_approved\'])
return false;

$memberStartedID = (int) getMsgMemberID($row[\'myid_first_msg\']);
$memberUpdatedID = (int) getMsgMemberID($row[\'myid_last_msg\']);

$smcFunc[\'db_query\'](\'\', "
UPDATE {db_prefix}topics
SET id_first_msg = $row[myid_first_msg],
id_member_started = $memberStartedID, id_last_msg = $row[myid_last_msg],
id_member_updated = $memberUpdatedID, approved = $row[firstmsg_approved]
WHERE id_topic = $row[id_topic]",
array(
)
);
'),
'message_function' => create_function('$row', '
global $txt, $context;

// A pretend error?
if ($row[\'myid_first_msg\'] == $row[\'myid_first_msg\'] && $row[\'myid_first_msg\'] == $row[\'myid_first_msg\'] && $row[\'approved\'] == $row[\'firstmsg_approved\'])
return false;

if ($row[\'id_first_msg\'] != $row[\'myid_first_msg\'])
$context[\'repair_errors\'][] = sprintf($txt[\'repair_stats_topics_1\'], $row[\'id_topic\'], $row[\'id_first_msg\']);
if ($row[\'id_last_msg\'] != $row[\'myid_last_msg\'])
$context[\'repair_errors\'][] = sprintf($txt[\'repair_stats_topics_2\'], $row[\'id_topic\'], $row[\'id_last_msg\']);
if ($row[\'approved\'] != $row[\'firstmsg_approved\'])
$context[\'repair_errors\'][] = sprintf($txt[\'repair_stats_topics_5\'], $row[\'id_topic\']);

return true;
'),
),
// Find topics with incorrect num_replies.
Replace With: [Select]
'fix_processing' => function($row) use ($smcFunc)
{
$row['firstmsg_approved'] = (int) $row['firstmsg_approved'];
$row['myid_first_msg'] = (int) $row['myid_first_msg'];
$row['myid_last_msg'] = (int) $row['myid_last_msg'];

// Not really a problem?
if ($row['id_first_msg'] == $row['myid_first_msg'] && $row['id_first_msg'] == $row['myid_first_msg'] && $row['approved'] == $row['firstmsg_approved'])
return false;

$memberStartedID = (int) getMsgMemberID($row['myid_first_msg']);
$memberUpdatedID = (int) getMsgMemberID($row['myid_last_msg']);

$smcFunc['db_query']('', '
UPDATE {db_prefix}topics
SET id_first_msg = {int:myid_first_msg},
id_member_started = {int:memberStartedID}, id_last_msg = {int:myid_last_msg},
id_member_updated = {int:memberUpdatedID}, approved = {int:firstmsg_approved}
WHERE id_topic = {int:topic_id}',
array(
'myid_first_msg' => $row['myid_first_msg'],
'memberStartedID' => $memberStartedID,
'myid_last_msg' => $row['myid_last_msg'],
'memberUpdatedID' => $memberUpdatedID,
'firstmsg_approved' => $row['firstmsg_approved'],
'topic_id' => $row['id_topic'],
)
);
},
'message_function' => function($row)
{
global $txt, $context;

// A pretend error?
if ($row['id_first_msg'] == $row['myid_first_msg'] && $row['id_last_msg'] == $row['myid_last_msg'] && $row['approved'] == $row['firstmsg_approved'])
return false;

if ($row['id_first_msg'] != $row['myid_first_msg'])
$context['repair_errors'][] = sprintf($txt['repair_stats_topics_1'], $row['id_topic'], $row['id_first_msg']);
if ($row['id_last_msg'] != $row['myid_last_msg'])
$context['repair_errors'][] = sprintf($txt['repair_stats_topics_2'], $row['id_topic'], $row['id_last_msg']);
if ($row['approved'] != $row['firstmsg_approved'])
$context['repair_errors'][] = sprintf($txt['repair_stats_topics_5'], $row['id_topic']);

return true;
},
),
// Find topics with incorrect num_replies.

Operation #6
Find: [Select]
'fix_processing' => create_function('$row', '
global $smcFunc;
$row[\'my_num_replies\'] = (int) $row[\'my_num_replies\'];

// Not really a problem?
if ($row[\'my_num_replies\'] == $row[\'num_replies\'])
return false;

$smcFunc[\'db_query\'](\'\', "
UPDATE {db_prefix}topics
SET num_replies = $row[my_num_replies]
WHERE id_topic = $row[id_topic]",
array(
)
);
'),
'message_function' => create_function('$row', '
global $txt, $context;

// Just joking?
if ($row[\'my_num_replies\'] == $row[\'num_replies\'])
return false;

if ($row[\'num_replies\'] != $row[\'my_num_replies\'])
$context[\'repair_errors\'][] = sprintf($txt[\'repair_stats_topics_3\'], $row[\'id_topic\'], $row[\'num_replies\']);

return true;
'),
),
// Find topics with incorrect unapproved_posts.
Replace With: [Select]
'fix_processing' => function($row)
{
global $smcFunc;
$row['my_num_replies'] = (int) $row['my_num_replies'];

// Not really a problem?
if ($row['my_num_replies'] == $row['num_replies'])
return false;

$smcFunc['db_query']('', '
UPDATE {db_prefix}topics
SET num_replies = {int:my_num_replies}
WHERE id_topic = {int:topic_id}',
array(
'my_num_replies' => $row['my_num_replies'],
'topic_id' => $row['id_topic'],
)
);
},
'message_function' => function($row)
{
global $txt, $context;

// Just joking?
if ($row['my_num_replies'] == $row['num_replies'])
return false;

if ($row['num_replies'] != $row['my_num_replies'])
$context['repair_errors'][] = sprintf($txt['repair_stats_topics_3'], $row['id_topic'], $row['num_replies']);

return true;
},
),
// Find topics with incorrect unapproved_posts.

Operation #7
Find: [Select]
'fix_processing' => create_function('$row', '
global $smcFunc;
$row[\'my_unapproved_posts\'] = (int) $row[\'my_unapproved_posts\'];

$smcFunc[\'db_query\'](\'\', "
UPDATE {db_prefix}topics
SET unapproved_posts = $row[my_unapproved_posts]
WHERE id_topic = $row[id_topic]",
array(
)
);
'),
'messages' => array('repair_stats_topics_4', 'id_topic', 'unapproved_posts'),
),
Replace With: [Select]
'fix_processing' => function($row)
{
global $smcFunc;
$row['my_unapproved_posts'] = (int) $row['my_unapproved_posts'];

$smcFunc['db_query']('', '
UPDATE {db_prefix}topics
SET unapproved_posts = {int:my_unapproved_posts}
WHERE id_topic = {int:topic_id}',
array(
'my_unapproved_posts' => $row['my_unapproved_posts'],
'topic_id' => $row['id_topic'],
)
);
},
'messages' => array('repair_stats_topics_4', 'id_topic', 'unapproved_posts'),
),

Operation #8
Find: [Select]
'fix_processing' => create_function('$row', '
global $smcFunc, $salvageCatID;
createSalvageArea();

$row[\'my_num_topics\'] = (int) $row[\'my_num_topics\'];
$row[\'my_num_posts\'] = (int) $row[\'my_num_posts\'];

$smcFunc[\'db_insert\'](\'\',
\'{db_prefix}boards\',
array(\'id_cat\' => \'int\', \'name\' => \'string\', \'description\' => \'string\', \'num_topics\' => \'int\', \'num_posts\' => \'int\', \'member_groups\' => \'string\'),
array($salvageCatID, \'Salvaged board\', \'\', $row[\'my_num_topics\'], $row[\'my_num_posts\'], \'1\'),
array(\'id_board\')
);
$newBoardID = $smcFunc[\'db_insert_id\'](\'{db_prefix}boards\', \'id_board\');

$smcFunc[\'db_query\'](\'\', "
UPDATE {db_prefix}topics
SET id_board = $newBoardID
WHERE id_board = $row[id_board]",
array(
)
);
$smcFunc[\'db_query\'](\'\', "
UPDATE {db_prefix}messages
SET id_board = $newBoardID
WHERE id_board = $row[id_board]",
array(
)
);
'),
'messages' => array('repair_missing_boards', 'id_topic', 'id_board'),
),
Replace With: [Select]
'fix_processing' => function($row)
{
global $smcFunc, $salvageCatID, $txt;
createSalvageArea();

$row['my_num_topics'] = (int) $row['my_num_topics'];
$row['my_num_posts'] = (int) $row['my_num_posts'];

$smcFunc['db_insert']('',
'{db_prefix}boards',
array('id_cat' => 'int', 'name' => 'string', 'description' => 'string', 'num_topics' => 'int', 'num_posts' => 'int', 'member_groups' => 'string'),
array($salvageCatID, $txt['salvaged_board_name'], $txt['salvaged_board_description'], $row['my_num_topics'], $row['my_num_posts'], '1'),
array('id_board'),
1
);

$newBoardID = $smcFunc['db_insert_id']('{db_prefix}boards', 'id_board');

$smcFunc['db_query']('', '
UPDATE {db_prefix}topics
SET id_board = {int:newBoardID}
WHERE id_board = {int:board_id}',
array(
'newBoardID' => $newBoardID,
'board_id' => $row['id_board'],
)
);
$smcFunc['db_query']('', '
UPDATE {db_prefix}messages
SET id_board = {int:newBoardID}
WHERE id_board = {int:board_id}',
array(
'newBoardID' => $newBoardID,
'board_id' => $row['id_board'],
)
);
},
'messages' => array('repair_missing_boards', 'id_topic', 'id_board'),
),

Operation #9
Find: [Select]
'process' => create_function('$cats', '
global $smcFunc, $salvageCatID;
createSalvageArea();
$smcFunc[\'db_query\'](\'\', "
UPDATE {db_prefix}boards
SET id_cat = $salvageCatID
WHERE id_cat IN ({array_int:categories})",
array(
\'categories\' => $cats
)
);
'),
),
'messages' => array('repair_missing_categories', 'id_board', 'id_cat'),
Replace With: [Select]
'process' => function($cats)
{
global $smcFunc, $salvageCatID;
createSalvageArea();
$smcFunc['db_query']('', '
UPDATE {db_prefix}boards
SET id_cat = {int:salvageCatID}
WHERE id_cat IN ({array_int:categories})',
array(
'salvageCatID' => $salvageCatID,
'categories' => $cats,
)
);
},
),
'messages' => array('repair_missing_categories', 'id_board', 'id_cat'),

Operation #10
Find: [Select]
'process' => create_function('$msgs', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
UPDATE {db_prefix}messages
SET id_member = 0
WHERE id_msg IN ({array_int:msgs})",
array(
\'msgs\' => $msgs
)
);
'),
),
'messages' => array('repair_missing_posters', 'id_msg', 'id_member'),
Replace With: [Select]
'process' => function($msgs)
{
global $smcFunc;
$smcFunc['db_query']('', '
UPDATE {db_prefix}messages
SET id_member = {int:guest_id}
WHERE id_msg IN ({array_int:msgs})',
array(
'msgs' => $msgs,
'guest_id' => 0,
)
);
},
),
'messages' => array('repair_missing_posters', 'id_msg', 'id_member'),

Operation #11
Find: [Select]
'process' => create_function('$parents', '
global $smcFunc, $salvageBoardID, $salvageCatID;
createSalvageArea();
$smcFunc[\'db_query\'](\'\', "
UPDATE {db_prefix}boards
SET id_parent = $salvageBoardID, id_cat = $salvageCatID, child_level = 1
WHERE id_parent IN ({array_int:parents})",
array(
\'parents\' => $parents
)
);
'),
),
'messages' => array('repair_missing_parents', 'id_board', 'id_parent'),
Replace With: [Select]
'process' => function($parents)
{
global $smcFunc, $salvageBoardID, $salvageCatID;

createSalvageArea();
(int) $salvageBoardID;

$smcFunc['db_query']('', '
UPDATE {db_prefix}boards
SET id_parent = {int:salvageBoardID}, id_cat = {int:salvageCatID}, child_level = 1
WHERE id_parent IN ({array_int:parents})',
array(
'salvageBoardID' => $salvageBoardID,
'salvageCatID' => $salvageCatID,
'parents' => $parents,
)
);
},
),
'messages' => array('repair_missing_parents', 'id_board', 'id_parent'),

Operation #12
Find: [Select]
'process' => create_function('$polls', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
UPDATE {db_prefix}topics
SET id_poll = 0
WHERE id_poll IN ({array_int:polls})",
array(
\'polls\' => $polls
)
);
'),
),
'messages' => array('repair_missing_polls', 'id_topic', 'id_poll'),
Replace With: [Select]
'process' => function($polls)
{
global $smcFunc;
$smcFunc['db_query']('', '
UPDATE {db_prefix}topics
SET id_poll = 0
WHERE id_poll IN ({array_int:polls})',
array(
'polls' => $polls,
)
);
},
),
'messages' => array('repair_missing_polls', 'id_topic', 'id_poll'),

Operation #13
Find: [Select]
'process' => create_function('$events', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', \'
UPDATE {db_prefix}calendar
SET id_topic = 0, id_board = 0
WHERE id_topic IN ({array_int:events})\',
array(
\'events\' => $events
)
);
'),
),
'messages' => array('repair_missing_calendar_topics', 'id_event', 'id_topic'),
Replace With: [Select]
'process' => function($events)
{
global $smcFunc;
$smcFunc['db_query']('', '
UPDATE {db_prefix}calendar
SET id_topic = 0, id_board = 0
WHERE id_topic IN ({array_int:events})',
array(
'events' => $events,
)
);
},
),
'messages' => array('repair_missing_calendar_topics', 'id_event', 'id_topic'),

Operation #14
Find: [Select]
'process' => create_function('$topics', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
DELETE FROM {db_prefix}log_topics
WHERE id_topic IN ({array_int:topics})",
array(
\'topics\' => $topics
)
);
'),
),
'messages' => array('repair_missing_log_topics', 'id_topic'),
Replace With: [Select]
'process' => function($topics)
{
global $smcFunc;
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_topics
WHERE id_topic IN ({array_int:topics})',
array(
'topics' => $topics,
)
);
},
),
'messages' => array('repair_missing_log_topics', 'id_topic'),

Operation #15
Find: [Select]
'process' => create_function('$members', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
DELETE FROM {db_prefix}log_topics
WHERE id_member IN ({array_int:members})",
array(
\'members\' => $members
)
);
'),
),
'messages' => array('repair_missing_log_topics_members', 'id_member'),
Replace With: [Select]
'process' => function($members)
{
global $smcFunc;
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_topics
WHERE id_member IN ({array_int:members})',
array(
'members' => $members,
)
);
},
),
'messages' => array('repair_missing_log_topics_members', 'id_member'),

Operation #16
Find: [Select]
'process' => create_function('$boards', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
DELETE FROM {db_prefix}log_boards
WHERE id_board IN ({array_int:boards})",
array(
\'boards\' => $boards
)
);
'),
),
'messages' => array('repair_missing_log_boards', 'id_board'),
Replace With: [Select]
'process' => function($boards)
{
global $smcFunc;
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_boards
WHERE id_board IN ({array_int:boards})',
array(
'boards' => $boards,
)
);
},
),
'messages' => array('repair_missing_log_boards', 'id_board'),

Operation #17
Find: [Select]
'process' => create_function('$members', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
DELETE FROM {db_prefix}log_boards
WHERE id_member IN ({array_int:members})",
array(
\'members\' => $members
)
);
'),
),
'messages' => array('repair_missing_log_boards_members', 'id_member'),
Replace With: [Select]
'process' => function($members) use ($smcFunc)
{
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_boards
WHERE id_member IN ({array_int:members})',
array(
'members' => $members,
)
);
},
),
'messages' => array('repair_missing_log_boards_members', 'id_member'),

Operation #18
Find: [Select]
'process' => create_function('$boards', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
DELETE FROM {db_prefix}log_mark_read
WHERE id_board IN ({array_int:boards})",
array(
\'boards\' => $boards
)
);
'),
),
'messages' => array('repair_missing_log_mark_read', 'id_board'),
Replace With: [Select]
'process' => function($boards) use ($smcFunc)
{
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_mark_read
WHERE id_board IN ({array_int:boards})',
array(
'boards' => $boards,
)
);
},
),
'messages' => array('repair_missing_log_mark_read', 'id_board'),

Operation #19
Find: [Select]
'process' => create_function('$members', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
DELETE FROM {db_prefix}log_mark_read
WHERE id_member IN ({array_int:members})",
array(
\'members\' => $members
)
);
'),
),
'messages' => array('repair_missing_log_mark_read_members', 'id_member'),
Replace With: [Select]
'process' => function($members) use ($smcFunc)
{
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_mark_read
WHERE id_member IN ({array_int:members})',
array(
'members' => $members,
)
);
},
),
'messages' => array('repair_missing_log_mark_read_members', 'id_member'),

Operation #20
Find: [Select]
'process' => create_function('$pms', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
DELETE FROM {db_prefix}pm_recipients
WHERE id_pm IN ({array_int:pms})",
array(
\'pms\' => $pms
)
);
'),
),
'messages' => array('repair_missing_pms', 'id_pm'),
Replace With: [Select]
'process' => function($pms) use ($smcFunc)
{
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}pm_recipients
WHERE id_pm IN ({array_int:pms})',
array(
'pms' => $pms,
)
);
},
),
'messages' => array('repair_missing_pms', 'id_pm'),

Operation #21
Find: [Select]
'process' => create_function('$members', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
DELETE FROM {db_prefix}pm_recipients
WHERE id_member IN ({array_int:members})",
array(
\'members\' => $members
)
);
'),
),
'messages' => array('repair_missing_recipients', 'id_member'),
Replace With: [Select]
'process' => function($members)
{
global $smcFunc;
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}pm_recipients
WHERE id_member IN ({array_int:members})',
array(
'members' => $members,
)
);
},
),
'messages' => array('repair_missing_recipients', 'id_member'),

Operation #22
Find: [Select]
'process' => create_function('$guestMessages', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
UPDATE {db_prefix}personal_messages
SET id_member_from = 0
WHERE id_pm IN ({array_int:guestMessages})",
array(
\'guestMessages\' => $guestMessages
));
'),
),
'messages' => array('repair_missing_senders', 'id_pm', 'id_member_from'),
Replace With: [Select]
'process' => function($guestMessages)
{
global $smcFunc;
$smcFunc['db_query']('', '
UPDATE {db_prefix}personal_messages
SET id_member_from = 0
WHERE id_pm IN ({array_int:guestMessages})',
array(
'guestMessages' => $guestMessages,
)
);
},
),
'messages' => array('repair_missing_senders', 'id_pm', 'id_member_from'),

Operation #23
Find: [Select]
'process' => create_function('$members', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
DELETE FROM {db_prefix}log_notify
WHERE id_member IN ({array_int:members})",
array(
\'members\' => $members
)
);
'),
),
'messages' => array('repair_missing_notify_members', 'id_member'),
Replace With: [Select]
'process' => function($members) use ($smcFunc)
{
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_notify
WHERE id_member IN ({array_int:members})',
array(
'members' => $members,
)
);
},
),
'messages' => array('repair_missing_notify_members', 'id_member'),

Operation #24
Find: [Select]
'fix_full_processing' => create_function('$result', '
global $smcFunc;

$inserts = array();
while ($row = $smcFunc[\'db_fetch_assoc\']($result))
{
foreach (text2words($row[\'subject\']) as $word)
$inserts[] = array($word, $row[\'id_topic\']);
if (count($inserts) > 500)
{
$smcFunc[\'db_insert\'](\'ignore\',
"{db_prefix}log_search_subjects",
array(\'word\' => \'string\', \'id_topic\' => \'int\'),
$inserts,
array(\'word\', \'id_topic\')
);
$inserts = array();
}

}

if (!empty($inserts))
$smcFunc[\'db_insert\'](\'ignore\',
"{db_prefix}log_search_subjects",
array(\'word\' => \'string\', \'id_topic\' => \'int\'),
$inserts,
array(\'word\', \'id_topic\')
);
'),
'message_function' => create_function('$row', '
global $txt, $context;

if (count(text2words($row[\'subject\'])) != 0)
{
$context[\'repair_errors\'][] = sprintf($txt[\'repair_missing_cached_subject\'], $row[\'id_topic\']);
return true;
}

return false;
'),
),
'missing_topic_for_cache' => array(
Replace With: [Select]
'fix_full_processing' => function($result)
{
global $smcFunc;

$inserts = array();
while ($row = $smcFunc['db_fetch_assoc']($result))
{
foreach (text2words($row['subject']) as $word)
$inserts[] = array($word, $row['id_topic']);
if (count($inserts) > 500)
{
$smcFunc['db_insert']('ignore',
'{db_prefix}log_search_subjects',
array('word' => 'string', 'id_topic' => 'int'),
$inserts,
array('word', 'id_topic')
);
$inserts = array();
}
}

if (!empty($inserts))
$smcFunc['db_insert']('ignore',
'{db_prefix}log_search_subjects',
array('word' => 'string', 'id_topic' => 'int'),
$inserts,
array('word', 'id_topic')
);
},
'message_function' => function($row)
{
global $txt, $context;

if (count(text2words($row['subject'])) != 0)
{
$context['repair_errors'][] = sprintf($txt['repair_missing_cached_subject'], $row['id_topic']);
return true;
}

return false;
},
),
'missing_topic_for_cache' => array(

Operation #25
Find: [Select]
'process' => create_function('$deleteTopics', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
DELETE FROM {db_prefix}log_search_subjects
WHERE id_topic IN ({array_int:deleteTopics})",
array(
\'deleteTopics\' => $deleteTopics
)
);
'),
),
'messages' => array('repair_missing_topic_for_cache', 'word'),
Replace With: [Select]
'process' => function($deleteTopics)
{
global $smcFunc;
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_search_subjects
WHERE id_topic IN ({array_int:deleteTopics})',
array(
'deleteTopics' => $deleteTopics,
)
);
},
),
'messages' => array('repair_missing_topic_for_cache', 'word'),

Operation #26
Find: [Select]
'process' => create_function('$members', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
DELETE FROM {db_prefix}log_polls
WHERE id_member IN ({array_int:members})",
array(
\'members\' => $members
)
);
'),
),
'messages' => array('repair_missing_log_poll_member', 'id_poll', 'id_member'),
Replace With: [Select]
'process' => function($members)
{
global $smcFunc;
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_polls
WHERE id_member IN ({array_int:members})',
array(
'members' => $members,
)
);
},
),
'messages' => array('repair_missing_log_poll_member', 'id_poll', 'id_member'),

Operation #27
Find: [Select]
'process' => create_function('$polls', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
DELETE FROM {db_prefix}log_polls
WHERE id_poll IN ({array_int:polls})",
array(
\'polls\' => $polls
)
);
'),
),
'messages' => array('repair_missing_log_poll_vote', 'id_member', 'id_poll'),
Replace With: [Select]
'process' => function($polls)
{
global $smcFunc;
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_polls
WHERE id_poll IN ({array_int:polls})',
array(
'polls' => $polls,
)
);
},
),
'messages' => array('repair_missing_log_poll_vote', 'id_member', 'id_poll'),

Operation #28
Find: [Select]
'process' => create_function('$reports', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
DELETE FROM {db_prefix}log_reported
WHERE id_report IN ({array_int:reports})",
array(
\'reports\' => $reports
)
);
'),
),
'messages' => array('repair_report_missing_comments', 'id_report', 'subject'),
Replace With: [Select]
'process' => function($reports)
{
global $smcFunc;
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_reported
WHERE id_report IN ({array_int:reports})',
array(
'reports' => $reports,
)
);
},
),
'messages' => array('repair_report_missing_comments', 'id_report', 'subject'),

Operation #29
Find: [Select]
'process' => create_function('$reports', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
DELETE FROM {db_prefix}log_reported_comments
WHERE id_report IN ({array_int:reports})",
array(
\'reports\' => $reports
)
);
'),
),
'messages' => array('repair_comments_missing_report', 'id_report', 'membername'),
Replace With: [Select]
'process' => function($reports)
{
global $smcFunc;
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_reported_comments
WHERE id_report IN ({array_int:reports})',
array(
'reports' => $reports,
)
);
},
),
'messages' => array('repair_comments_missing_report', 'id_report', 'membername'),

Operation #30
Find: [Select]
'process' => create_function('$members', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', "
DELETE FROM {db_prefix}log_group_requests
WHERE id_member IN ({array_int:members})",
array(
\'members\' => $members
)
);
'),
),
'messages' => array('repair_group_request_missing_member', 'id_member'),
Replace With: [Select]
'process' => function($members)
{
global $smcFunc;
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_group_requests
WHERE id_member IN ({array_int:members})',
array(
'members' => $members,
)
);
},
),
'messages' => array('repair_group_request_missing_member', 'id_member'),

Operation #31
Find: [Select]
'process' => create_function('$groups', '
global $smcFunc;
$smcFunc[\'db_query\'](\'\', \'
DELETE FROM {db_prefix}log_group_requests
WHERE id_group IN ({array_int:groups})\',
array(
\'groups\' => $groups
)
);
'),
),
'messages' => array('repair_group_request_missing_group', 'id_group'),
Replace With: [Select]
'process' => function($groups)
{
global $smcFunc;
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_group_requests
WHERE id_group IN ({array_int:groups})',
array(
'groups' => $groups,
)
);
},
),
'messages' => array('repair_group_request_missing_group', 'id_group'),

Operation #32
Find: [Select]
$db_cache = '';

$context['total_steps'] = count($errorTests);
Replace With: [Select]
$db_cache = array();

$context['total_steps'] = count($errorTests);

Operation #33
Find: [Select]
$db_cache = '';

// Are we done yet?
Replace With: [Select]
$db_cache = array();

// Are we done yet?

./Sources/ScheduledTasks.php

Operation #1
Find: [Select]
* @version 2.0.16
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
if (filemtime($cachedir . '/images/' . $file) < time() - (5 * 86400))
unlink($cachedir . '/images/' . $file);
}
Replace With: [Select]
if (is_file($cachedir . '/images/' . $file) && !in_array($file, array('index.php', '.htaccess')) && time() - filemtime($cachedir . '/images/' . $file) > 5 * 86400)
unlink($cachedir . '/images/' . $file);
}

./Sources/Subs-Admin.php

Operation #1
Find: [Select]
* @version 2.0.16
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
// Blank out the file - done to fix a oddity with some servers.
$fp = @fopen($boarddir . '/Settings.php', 'w');

// Is it even writable, though?
if ($fp)
{
fclose($fp);

$fp = fopen($boarddir . '/Settings.php', 'r+');
foreach ($settingsArray as $line)
fwrite($fp, strtr($line, "\r", ''));
fclose($fp);
}
Replace With: [Select]
$fp = @fopen($boarddir . '/Settings.php', 'c');

// Is it even writable, though?
if ($fp)
{
flock($fp, LOCK_EX);
ftruncate($fp, 0);
rewind($fp);
foreach ($settingsArray as $line)
fwrite($fp, strtr($line, "\r", ''));
flock($fp, LOCK_UN);
fclose($fp);
}

Operation #3
Find: [Select]
if ($fp = @fopen($file, 'w'))
{
// Reset the file buffer.
set_file_buffer($fp, 0);

// Update the file.
$t = flock($fp, LOCK_EX);
$bytes = fwrite($fp, $data);
flock($fp, LOCK_UN);
Replace With: [Select]
if ($fp = @fopen($file, 'c'))
{
// Reset the file buffer.
set_file_buffer($fp, 0);

// Update the file.
$t = flock($fp, LOCK_EX);
ftruncate($fp, 0);
rewind($fp);
$bytes = fwrite($fp, $data);
flock($fp, LOCK_UN);

./Sources/Subs-Auth.php

Operation #1
Find: [Select]
* @version 2.0.16
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
// 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());
Replace With: [Select]
// Ensure the cookie can't be forged.
// Note: $cookie_no_auth_secret is a fallback that will be removed in future versions!
if ($password !== '' && empty($cookie_no_auth_secret))
$password = hash_hmac('sha1', $password, get_auth_secret());

Operation #3
Find: [Select]
$fixchar = create_function('$n', '
if ($n < 128)
return chr($n);
Replace With: [Select]
$fixchar = function($n)
{
if ($n < 128)
return chr($n);

Operation #4
Find: [Select]
return chr(240 | $n >> 18) . chr(128 | $n >> 12 & 63) . chr(128 | $n >> 6 & 63) . chr(128 | $n & 63);');

$row['real_name'] = preg_replace_callback('~&#(\d+);~', 'fixchar__callback', $row['real_name']);
Replace With: [Select]
return chr(240 | $n >> 18) . chr(128 | $n >> 12 & 63) . chr(128 | $n >> 6 & 63) . chr(128 | $n & 63);
};

$row['real_name'] = preg_replace_callback('~&#(\d+);~', 'fixchar__callback', $row['real_name']);

./Sources/Subs-Compat.php

Operation #1
Find: [Select]
* @version 2.0
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
$blks[$i >> 2] |= ord($str{$i}) << (24 - ($i % 4) * 8);

$blks[$i >> 2] |= 0x80 << (24 - ($i % 4) * 8);
Replace With: [Select]
$blks[$i >> 2] |= ord($str[$i]) << (24 - ($i % 4) * 8);

$blks[$i >> 2] |= 0x80 << (24 - ($i % 4) * 8);

./Sources/Subs-Editor.php

Operation #1
Find: [Select]
* @version 2.0.11
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
if ($text{$i} == '=')
{
if ($tag_state == 0)
Replace With: [Select]
if ($text[$i] == '=')
{
if ($tag_state == 0)

Operation #3
Find: [Select]
elseif ($text{$i} == ' ')
{
if ($tag_state == 2)
Replace With: [Select]
elseif ($text[$i] == ' ')
{
if ($tag_state == 2)

Operation #4
Find: [Select]
elseif ($text{$i} == '"')
{
// Must be either going into or out of a string.
Replace With: [Select]
elseif ($text[$i] == '"')
{
// Must be either going into or out of a string.

Operation #5
Find: [Select]
$key .= $text{$i};
else
$value .= $text{$i};
}
}
Replace With: [Select]
$key .= $text[$i];
else
$value .= $text[$i];
}
}

./Sources/Subs-Graphics.php

Operation #1
Find: [Select]
* @version 2.0.16
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
// Paranoid check. Some like it that way.
if (preg_match('~(iframe|\\<\\?|\\<%|html|eval|body|script\W|[CF]WS[\x01-\x0C])~i', $prev_chunk . $cur_chunk) === 1)
{
fclose($fp);
Replace With: [Select]
// Paranoid check. Use this if you have reason to distrust your host's security config.
// Will result in MANY false positives, and is not suitable for photography sites.
if (preg_match('~(iframe|\\<\\?|\\<%|html|eval|body|script\W|(?-i)[CFZ]WS[\x01-\x0E])~i', $prev_chunk . $cur_chunk) === 1)
{
fclose($fp);

Operation #3
Find: [Select]
// Check for potential infection
if (preg_match('~(iframe|(?<!cellTextIs)html|eval|body|script\W|[CF]WS[\x01-\x0C])~i', $prev_chunk . $cur_chunk) === 1)
{
fclose($fp);
Replace With: [Select]
// Check for potential infection - focus on clues for inline php & flash.
// Will result in significantly fewer false positives than the paranoid check.
if (preg_match('~(\\<\\?php\s|(?-i)[CFZ]WS[\x01-\x0E])~i', $prev_chunk . $cur_chunk) === 1)
{
fclose($fp);

Operation #4
Find: [Select]
$b = ord($palettedata{$j++});
$g = ord($palettedata{$j++});
$r = ord($palettedata{$j++});

$palette[$n++] = imagecolorallocate($dst_img, $r, $g, $b);
Replace With: [Select]
$b = ord($palettedata[$j++]);
$g = ord($palettedata[$j++]);
$r = ord($palettedata[$j++]);

$palette[$n++] = imagecolorallocate($dst_img, $r, $g, $b);

Operation #5
Find: [Select]
$b = ord($scan_line{$j++});
$g = ord($scan_line{$j++});
$r = ord($scan_line{$j++});
$j++;
Replace With: [Select]
$b = ord($scan_line[$j++]);
$g = ord($scan_line[$j++]);
$r = ord($scan_line[$j++]);
$j++;

Operation #6
Find: [Select]
$b = ord($scan_line{$j++});
$g = ord($scan_line{$j++});
$r = ord($scan_line{$j++});

$color = imagecolorexact($dst_img, $r, $g, $b);
Replace With: [Select]
$b = ord($scan_line[$j++]);
$g = ord($scan_line[$j++]);
$r = ord($scan_line[$j++]);

$color = imagecolorexact($dst_img, $r, $g, $b);

Operation #7
Find: [Select]
$b1 = ord($scan_line{$j++});
$b2 = ord($scan_line{$j++});

$word = $b2 * 256 + $b1;
Replace With: [Select]
$b1 = ord($scan_line[$j++]);
$b2 = ord($scan_line[$j++]);

$word = $b2 * 256 + $b1;

Operation #8
Find: [Select]
imagesetpixel($dst_img, $x, $y, $palette[ord($scan_line{$j++})]);
}
elseif ($info['bits'] == 4)
{
$x = 0;
for ($j = 0; $j < $scan_line_size; $x++)
{
$byte = ord($scan_line{$j++});

imagesetpixel($dst_img, $x, $y, $palette[(int) ($byte / 16)]);
Replace With: [Select]
imagesetpixel($dst_img, $x, $y, $palette[ord($scan_line[$j++])]);
}
elseif ($info['bits'] == 4)
{
$x = 0;
for ($j = 0; $j < $scan_line_size; $x++)
{
$byte = ord($scan_line[$j++]);

imagesetpixel($dst_img, $x, $y, $palette[(int) ($byte / 16)]);

Operation #9
Find: [Select]
'id' => $code{$i},
'font' => array_rand($font_list),
);
Replace With: [Select]
'id' => $code[$i],
'font' => array_rand($font_list),
);

./Sources/Subs-Members.php

Operation #1
Find: [Select]
* @version 2.0.16
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
// Log their acceptance of the agreement and privacy policy, for future reference.
foreach (array('agreement_accepted', 'policy_accepted') as $key)
Replace With: [Select]
// Since they're not a user yet, user_info is incomplete, which breaks logging.
// Fill in enough gaps for logging to be successful.
if (empty($user_info['id']))
$user_info['id'] = $memberID;
if (empty($user_info['username']))
$user_info['username'] = $regOptions['username'];

// Log their acceptance of the agreement and privacy policy, for future reference.
foreach (array('agreement_accepted', 'policy_accepted') as $key)

Operation #3
Find: [Select]
$replaceEntities = create_function('$string', '
$num = substr($string, 0, 1) === \'x\' ? hexdec(substr($string, 1)) : (int) $string;
if ($num === 0x202E || $num === 0x202D) return \'\'; if (in_array($num, array(0x22, 0x26, 0x27, 0x3C, 0x3E))) return \'&#\' . $num . \';\';' .
(empty($context['utf8']) ? 'return $num < 0x20 ? \'\' : ($num < 0x80 ? chr($num) : \'&#\' . $string . \';\');' : '
return $num < 0x20 || $num > 0x10FFFF || ($num >= 0xD800 && $num <= 0xDFFF) ? \'\' : ($num < 0x80 ? chr($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))));')
);

$name = preg_replace_callback('~(&#(\d{1,7}|x[0-9a-fA-F]{1,6});)~', 'replaceEntities__callback', $name);
Replace With: [Select]
$replaceEntities = function($string) use ($context)
{
$num = substr($string, 0, 1) === 'x' ? hexdec(substr($string, 1)) : (int) $string;
if ($num === 0x202E || $num === 0x202D)
return '';
if (in_array($num, array(0x22, 0x26, 0x27, 0x3C, 0x3E)))
return '&#' . $num . ';';
if (empty($context['utf8']))
return $num < 0x20 ? '' : ($num < 0x80 ? chr($num) : '&#' . $string . ';');
return $num < 0x20 || $num > 0x10FFFF || ($num >= 0xD800 && $num <= 0xDFFF) ? '' : ($num < 0x80 ? chr($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))));
};

$name = preg_replace_callback('~(&#(\d{1,7}|x[0-9a-fA-F]{1,6});)~', 'replaceEntities__callback', $name);

./Sources/Subs-Package.php

Operation #1
Find: [Select]
* @version 2.0.17
*/
Replace With: [Select]
* @version 2.0.18
*/

Operation #2
Find: [Select]
while ($flags & 8 && $data{$offset++} != "\0")
continue;
while ($flags & 4 && $data{$offset++} != "\0")
continue;
}
Replace With: [Select]
while ($flags & 8 && $data[$offset++] != "\0")
continue;
while ($flags & 4 && $data[$offset++] != "\0")
continue;
}

Operation #3
Find: [Select]
$checksum += ord($header{$i});
for ($i = 156; $i < 512; $i++)
$checksum += ord($header{$i});

if ($current['checksum'] != $checksum)
Replace With: [Select]
$checksum += ord($header[$i]);
for ($i = 156; $i < 512; $i++)
$checksum += ord($header[$i]);

if ($current['checksum'] != $checksum)

Operation #4
Find: [Select]
'function' => create_function('$rowData', '
global $txt;

$formatTxt = $rowData[\'result\'] == \'\' || $rowData[\'result\'] == \'skipped\' ? $txt[\'package_restore_permissions_pre_change\'] : $txt[\'package_restore_permissions_post_change\'];
return sprintf($formatTxt, $rowData[\'cur_perms\'], $rowData[\'new_perms\'], $rowData[\'writable_message\']);
'),
'class' => 'smalltext',
),
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
$formatTxt = $rowData['result'] == '' || $rowData['result'] == 'skipped' ? $txt['package_restore_permissions_pre_change'] : $txt['package_restore_permissions_post_change'];
return sprintf($formatTxt, $rowData['cur_perms'], $rowData['new_perms'], $rowData['writable_message']);
},
'class' => 'smalltext',
),

Operation #5
Find: [Select]
'function' => create_function('$rowData', '
global $txt;

return $txt[\'package_restore_permissions_action_\' . $rowData[\'result\']];
'),
'class' => 'smalltext',
),
Replace With: [Select]
'function' => function($rowData) use ($txt)
{
return $txt['package_restore_permissions_action_' . $rowData['result']];
},
'class' => 'smalltext',
),

Operation #6
Find: [Select]
// First, we need to build the list of all the files likely to get changed.
foreach ($files as $file)
{
// What is the filename we're currently on?
$filename = parse_path(trim($file->fetch('@name')));

// Now, we need to work out whether this is even a template file...
foreach ($theme_paths as $id => $theme)
Replace With: [Select]
// Translate everything to unix dir separators for comparisons during parsing
foreach ($theme_paths as $id => $theme)
$theme_paths[$id]['theme_dir'] = strtr($theme_paths[$id]['theme_dir'], '\\', '/');

// First, we need to build the list of all the files likely to get changed.
foreach ($files as $file)
{
// What is the filename we're currently on?
$filename = parse_path(trim($file->fetch('@name')));

// Xlate it to unix style for comparisons...
$filename = strtr($filename, '\\', '/');

// Now, we need to work out whether this is even a template file...
foreach ($theme_paths as $id => $theme)

Operation #7
Find: [Select]
// Sometimes though, we have some additional files for other themes, if we have add them to the mix.
<