annotate forum/Sources/RepairBoards.php @ 76:e3e11437ecea website

Add forum code
author Chris Cannam
date Sun, 07 Jul 2013 11:25:48 +0200
parents
children
rev   line source
Chris@76 1 <?php
Chris@76 2
Chris@76 3 /**
Chris@76 4 * Simple Machines Forum (SMF)
Chris@76 5 *
Chris@76 6 * @package SMF
Chris@76 7 * @author Simple Machines http://www.simplemachines.org
Chris@76 8 * @copyright 2011 Simple Machines
Chris@76 9 * @license http://www.simplemachines.org/about/smf/license.php BSD
Chris@76 10 *
Chris@76 11 * @version 2.0
Chris@76 12 */
Chris@76 13
Chris@76 14 if (!defined('SMF'))
Chris@76 15 die('Hacking attempt...');
Chris@76 16
Chris@76 17 /* This is here for the "repair any errors" feature in the admin center. It
Chris@76 18 uses just two simple functions:
Chris@76 19
Chris@76 20 void RepairBoards()
Chris@76 21 - finds or repairs errors in the database to fix possible problems.
Chris@76 22 - requires the admin_forum permission.
Chris@76 23 - uses the raw_data sub template.
Chris@76 24 - calls createSalvageArea() to create a new board, if necesary.
Chris@76 25 - accessed by ?action=admin;area=repairboards.
Chris@76 26
Chris@76 27 void pauseRepairProcess(array to_fix, string current_step_desc, int max_substep = none, force = false)
Chris@76 28 - show the not_done template to avoid CGI timeouts and similar.
Chris@76 29 - called when 3 or more seconds have passed while searching for errors.
Chris@76 30 - if max_substep is set, $_GET['substep'] / $max_substep is the percent
Chris@76 31 done this step is.
Chris@76 32
Chris@76 33 array findForumErrors()
Chris@76 34 - checks for errors in steps, until 5 seconds have passed.
Chris@76 35 - keeps track of the errors it did find, so that the actual repair
Chris@76 36 won't have to recheck everything.
Chris@76 37 - returns the array of errors found.
Chris@76 38
Chris@76 39 void createSalvageArea()
Chris@76 40 - creates a salvage board/category if one doesn't already exist.
Chris@76 41 - uses the forum's default language, and checks based on that name.
Chris@76 42 */
Chris@76 43
Chris@76 44 function RepairBoards()
Chris@76 45 {
Chris@76 46 global $txt, $scripturl, $db_connection, $context, $sourcedir;
Chris@76 47 global $salvageCatID, $salvageBoardID, $smcFunc, $errorTests;
Chris@76 48
Chris@76 49 isAllowedTo('admin_forum');
Chris@76 50
Chris@76 51 // Try secure more memory.
Chris@76 52 @ini_set('memory_limit', '128M');
Chris@76 53
Chris@76 54 // Print out the top of the webpage.
Chris@76 55 $context['page_title'] = $txt['admin_repair'];
Chris@76 56 $context['sub_template'] = 'repair_boards';
Chris@76 57 $context[$context['admin_menu_name']]['current_subsection'] = 'general';
Chris@76 58
Chris@76 59 // Load the language file.
Chris@76 60 loadLanguage('ManageMaintenance');
Chris@76 61
Chris@76 62 // Make sure the tabs stay nice.
Chris@76 63 $context[$context['admin_menu_name']]['tab_data'] = array(
Chris@76 64 'title' => $txt['maintain_title'],
Chris@76 65 'help' => '',
Chris@76 66 'description' => $txt['maintain_info'],
Chris@76 67 'tabs' => array(),
Chris@76 68 );
Chris@76 69
Chris@76 70 // Start displaying errors without fixing them.
Chris@76 71 if (isset($_GET['fixErrors']))
Chris@76 72 checkSession('get');
Chris@76 73
Chris@76 74 // Will want this.
Chris@76 75 loadForumTests();
Chris@76 76
Chris@76 77 // Giant if/else. The first displays the forum errors if a variable is not set and asks
Chris@76 78 // if you would like to continue, the other fixes the errors.
Chris@76 79 if (!isset($_GET['fixErrors']))
Chris@76 80 {
Chris@76 81 $context['error_search'] = true;
Chris@76 82 $context['repair_errors'] = array();
Chris@76 83 $context['to_fix'] = findForumErrors();
Chris@76 84
Chris@76 85 if (!empty($context['to_fix']))
Chris@76 86 {
Chris@76 87 $_SESSION['repairboards_to_fix'] = $context['to_fix'];
Chris@76 88 $_SESSION['repairboards_to_fix2'] = null;
Chris@76 89
Chris@76 90 if (empty($context['repair_errors']))
Chris@76 91 $context['repair_errors'][] = '???';
Chris@76 92 }
Chris@76 93 }
Chris@76 94 else
Chris@76 95 {
Chris@76 96 $context['error_search'] = false;
Chris@76 97 $context['to_fix'] = isset($_SESSION['repairboards_to_fix']) ? $_SESSION['repairboards_to_fix'] : array();
Chris@76 98
Chris@76 99 require_once($sourcedir . '/Subs-Boards.php');
Chris@76 100
Chris@76 101 // Get the MySQL version for future reference.
Chris@76 102 $mysql_version = $smcFunc['db_server_info']($db_connection);
Chris@76 103
Chris@76 104 // Actually do the fix.
Chris@76 105 findForumErrors(true);
Chris@76 106
Chris@76 107 // Note that we've changed everything possible ;)
Chris@76 108 updateSettings(array(
Chris@76 109 'settings_updated' => time(),
Chris@76 110 ));
Chris@76 111 updateStats('message');
Chris@76 112 updateStats('topic');
Chris@76 113 updateSettings(array(
Chris@76 114 'calendar_updated' => time(),
Chris@76 115 ));
Chris@76 116
Chris@76 117 if (!empty($salvageBoardID))
Chris@76 118 {
Chris@76 119 $context['redirect_to_recount'] = true;
Chris@76 120 }
Chris@76 121
Chris@76 122 $_SESSION['repairboards_to_fix'] = null;
Chris@76 123 $_SESSION['repairboards_to_fix2'] = null;
Chris@76 124 }
Chris@76 125 }
Chris@76 126
Chris@76 127 function pauseRepairProcess($to_fix, $current_step_description, $max_substep = 0, $force = false)
Chris@76 128 {
Chris@76 129 global $context, $txt, $time_start, $db_temp_cache, $db_cache;
Chris@76 130
Chris@76 131 // More time, I need more time!
Chris@76 132 @set_time_limit(600);
Chris@76 133 if (function_exists('apache_reset_timeout'))
Chris@76 134 @apache_reset_timeout();
Chris@76 135
Chris@76 136 // Errr, wait. How much time has this taken already?
Chris@76 137 if (!$force && time() - array_sum(explode(' ', $time_start)) < 3)
Chris@76 138 return;
Chris@76 139
Chris@76 140 // Restore the query cache if interested.
Chris@76 141 if (!empty($db_temp_cache))
Chris@76 142 $db_cache = $db_temp_cache;
Chris@76 143
Chris@76 144 $context['continue_get_data'] = '?action=admin;area=repairboards' . (isset($_GET['fixErrors']) ? ';fixErrors' : '') . ';step=' . $_GET['step'] . ';substep=' . $_GET['substep'] . ';' . $context['session_var'] . '=' . $context['session_id'];
Chris@76 145 $context['page_title'] = $txt['not_done_title'];
Chris@76 146 $context['continue_post_data'] = '';
Chris@76 147 $context['continue_countdown'] = '2';
Chris@76 148 $context['sub_template'] = 'not_done';
Chris@76 149
Chris@76 150 // Change these two if more steps are added!
Chris@76 151 if (empty($max_substep))
Chris@76 152 $context['continue_percent'] = round(($_GET['step'] * 100) / $context['total_steps']);
Chris@76 153 else
Chris@76 154 $context['continue_percent'] = round((($_GET['step'] + ($_GET['substep'] / $max_substep)) * 100) / $context['total_steps']);
Chris@76 155
Chris@76 156 // Never more than 100%!
Chris@76 157 $context['continue_percent'] = min($context['continue_percent'], 100);
Chris@76 158
Chris@76 159 // What about substeps?
Chris@76 160 $context['substep_enabled'] = $max_substep != 0;
Chris@76 161 $context['substep_title'] = sprintf($txt['repair_currently_' . (isset($_GET['fixErrors']) ? 'fixing' : 'checking')], (isset($txt['repair_operation_' . $current_step_description]) ? $txt['repair_operation_' . $current_step_description] : $current_step_description));
Chris@76 162 $context['substep_continue_percent'] = $max_substep == 0 ? 0 : round(($_GET['substep'] * 100) / $max_substep, 1);
Chris@76 163
Chris@76 164 $_SESSION['repairboards_to_fix'] = $to_fix;
Chris@76 165 $_SESSION['repairboards_to_fix2'] = $context['repair_errors'];
Chris@76 166
Chris@76 167 obExit();
Chris@76 168 }
Chris@76 169
Chris@76 170 // Load up all the tests we might want to do ;)
Chris@76 171 function loadForumTests()
Chris@76 172 {
Chris@76 173 global $smcFunc, $errorTests;
Chris@76 174
Chris@76 175 /* Here this array is defined like so:
Chris@76 176 string check_query: Query to be executed when testing if errors exist.
Chris@76 177 string check_type: Defines how it knows if a problem was found. If set to count looks for the first variable from check_query
Chris@76 178 being > 0. Anything else it looks for some results. If not set assumes you want results.
Chris@76 179 string fix_it_query: When doing fixes if an error was detected this query is executed to "fix" it.
Chris@76 180 string fix_query: The query to execute to get data when doing a fix. If not set check_query is used again.
Chris@76 181 array fix_collect: This array is used if the fix is basically gathering all broken ids and then doing something with it.
Chris@76 182 - string index: The value returned from the main query and passed to the processing function.
Chris@76 183 - process: A function passed an array of ids to execute the fix on.
Chris@76 184 function fix_processing:
Chris@76 185 Function called for each row returned from fix_query to execute whatever fixes are required.
Chris@76 186 function fix_full_processing:
Chris@76 187 As above but does the while loop and everything itself - except the freeing.
Chris@76 188 array force_fix: If this is set then the error types included within this array will also be assumed broken.
Chris@76 189 Note: At the moment only processes these if they occur after the primary error in the array.
Chris@76 190 */
Chris@76 191
Chris@76 192 // This great array contains all of our error checks, fixes, etc etc etc.
Chris@76 193 $errorTests = array(
Chris@76 194 // Make a last-ditch-effort check to get rid of topics with zeros..
Chris@76 195 'zero_topics' => array(
Chris@76 196 'check_query' => '
Chris@76 197 SELECT COUNT(*)
Chris@76 198 FROM {db_prefix}topics
Chris@76 199 WHERE id_topic = 0',
Chris@76 200 'check_type' => 'count',
Chris@76 201 'fix_it_query' => '
Chris@76 202 UPDATE {db_prefix}topics
Chris@76 203 SET id_topic = NULL
Chris@76 204 WHERE id_topic = 0',
Chris@76 205 'message' => 'repair_zero_ids',
Chris@76 206 ),
Chris@76 207 // ... and same with messages.
Chris@76 208 'zero_messages' => array(
Chris@76 209 'check_query' => '
Chris@76 210 SELECT COUNT(*)
Chris@76 211 FROM {db_prefix}messages
Chris@76 212 WHERE id_msg = 0',
Chris@76 213 'check_type' => 'count',
Chris@76 214 'fix_it_query' => '
Chris@76 215 UPDATE {db_prefix}messages
Chris@76 216 SET id_msg = NULL
Chris@76 217 WHERE id_msg = 0',
Chris@76 218 'message' => 'repair_zero_ids',
Chris@76 219 ),
Chris@76 220 // Find messages that don't have existing topics.
Chris@76 221 'missing_topics' => array(
Chris@76 222 'substeps' => array(
Chris@76 223 'step_size' => 1000,
Chris@76 224 'step_max' => '
Chris@76 225 SELECT MAX(id_topic)
Chris@76 226 FROM {db_prefix}messages'
Chris@76 227 ),
Chris@76 228 'check_query' => '
Chris@76 229 SELECT m.id_topic, m.id_msg
Chris@76 230 FROM {db_prefix}messages AS m
Chris@76 231 LEFT JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
Chris@76 232 WHERE m.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 233 AND t.id_topic IS NULL
Chris@76 234 ORDER BY m.id_topic, m.id_msg',
Chris@76 235 'fix_query' => '
Chris@76 236 SELECT
Chris@76 237 m.id_board, m.id_topic, MIN(m.id_msg) AS myid_first_msg, MAX(m.id_msg) AS myid_last_msg,
Chris@76 238 COUNT(*) - 1 AS my_num_replies
Chris@76 239 FROM {db_prefix}messages AS m
Chris@76 240 LEFT JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
Chris@76 241 WHERE t.id_topic IS NULL
Chris@76 242 GROUP BY m.id_topic, m.id_board',
Chris@76 243 'fix_processing' => create_function('$row', '
Chris@76 244 global $smcFunc, $salvageBoardID;
Chris@76 245
Chris@76 246 // Only if we don\'t have a reasonable idea of where to put it.
Chris@76 247 if ($row[\'id_board\'] == 0)
Chris@76 248 {
Chris@76 249 createSalvageArea();
Chris@76 250 $row[\'id_board\'] = (int) $salvageBoardID;
Chris@76 251 }
Chris@76 252
Chris@76 253 // Make sure that no topics claim the first/last message as theirs.
Chris@76 254 $smcFunc[\'db_query\'](\'\', \'
Chris@76 255 UPDATE {db_prefix}topics
Chris@76 256 SET id_first_msg = 0
Chris@76 257 WHERE id_first_msg = {int:id_first_msg}\',
Chris@76 258 array(
Chris@76 259 \'id_first_msg\' => $row[\'myid_first_msg\'],
Chris@76 260 )
Chris@76 261 );
Chris@76 262 $smcFunc[\'db_query\'](\'\', \'
Chris@76 263 UPDATE {db_prefix}topics
Chris@76 264 SET id_last_msg = 0
Chris@76 265 WHERE id_last_msg = {int:id_last_msg}\',
Chris@76 266 array(
Chris@76 267 \'id_last_msg\' => $row[\'myid_last_msg\'],
Chris@76 268 )
Chris@76 269 );
Chris@76 270
Chris@76 271 $memberStartedID = (int) getMsgMemberID($row[\'myid_first_msg\']);
Chris@76 272 $memberUpdatedID = (int) getMsgMemberID($row[\'myid_last_msg\']);
Chris@76 273
Chris@76 274 $smcFunc[\'db_insert\'](\'\',
Chris@76 275 \'{db_prefix}topics\',
Chris@76 276 array(
Chris@76 277 \'id_board\' => \'int\',
Chris@76 278 \'id_member_started\' => \'int\',
Chris@76 279 \'id_member_updated\' => \'int\',
Chris@76 280 \'id_first_msg\' => \'int\',
Chris@76 281 \'id_last_msg\' => \'int\',
Chris@76 282 \'num_replies\' => \'int\'
Chris@76 283 ),
Chris@76 284 array(
Chris@76 285 $row[\'id_board\'],
Chris@76 286 $memberStartedID,
Chris@76 287 $memberUpdatedID,
Chris@76 288 $row[\'myid_first_msg\'],
Chris@76 289 $row[\'myid_last_msg\'],
Chris@76 290 $row[\'my_num_replies\']
Chris@76 291 ),
Chris@76 292 array(\'id_topic\')
Chris@76 293 );
Chris@76 294
Chris@76 295 $newTopicID = $smcFunc[\'db_insert_id\']("{db_prefix}topics", \'id_topic\');
Chris@76 296
Chris@76 297 $smcFunc[\'db_query\'](\'\', "
Chris@76 298 UPDATE {db_prefix}messages
Chris@76 299 SET id_topic = $newTopicID, id_board = $row[id_board]
Chris@76 300 WHERE id_topic = $row[id_topic]",
Chris@76 301 array(
Chris@76 302 )
Chris@76 303 );
Chris@76 304 '),
Chris@76 305 'force_fix' => array('stats_topics'),
Chris@76 306 'messages' => array('repair_missing_topics', 'id_msg', 'id_topic'),
Chris@76 307 ),
Chris@76 308 // Find topics with no messages.
Chris@76 309 'missing_messages' => array(
Chris@76 310 'substeps' => array(
Chris@76 311 'step_size' => 1000,
Chris@76 312 'step_max' => '
Chris@76 313 SELECT MAX(id_topic)
Chris@76 314 FROM {db_prefix}topics'
Chris@76 315 ),
Chris@76 316 'check_query' => '
Chris@76 317 SELECT t.id_topic, COUNT(m.id_msg) AS num_msg
Chris@76 318 FROM {db_prefix}topics AS t
Chris@76 319 LEFT JOIN {db_prefix}messages AS m ON (m.id_topic = t.id_topic)
Chris@76 320 WHERE t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 321 GROUP BY t.id_topic
Chris@76 322 HAVING COUNT(m.id_msg) = 0',
Chris@76 323 // Remove all topics that have zero messages in the messages table.
Chris@76 324 'fix_collect' => array(
Chris@76 325 'index' => 'id_topic',
Chris@76 326 'process' => create_function('$topics', '
Chris@76 327 global $smcFunc;
Chris@76 328 $smcFunc[\'db_query\'](\'\', "
Chris@76 329 DELETE FROM {db_prefix}topics
Chris@76 330 WHERE id_topic IN ({array_int:topics})",
Chris@76 331 array(
Chris@76 332 \'topics\' => $topics
Chris@76 333 )
Chris@76 334 );
Chris@76 335 $smcFunc[\'db_query\'](\'\', "
Chris@76 336 DELETE FROM {db_prefix}log_topics
Chris@76 337 WHERE id_topic IN ({array_int:topics})",
Chris@76 338 array(
Chris@76 339 \'topics\' => $topics
Chris@76 340 )
Chris@76 341 );
Chris@76 342 '),
Chris@76 343 ),
Chris@76 344 'messages' => array('repair_missing_messages', 'id_topic'),
Chris@76 345 ),
Chris@76 346 'polls_missing_topics' => array(
Chris@76 347 'substeps' => array(
Chris@76 348 'step_size' => 500,
Chris@76 349 'step_max' => '
Chris@76 350 SELECT MAX(id_poll)
Chris@76 351 FROM {db_prefix}polls'
Chris@76 352 ),
Chris@76 353 'check_query' => '
Chris@76 354 SELECT p.id_poll, p.id_member, p.poster_name, t.id_board
Chris@76 355 FROM {db_prefix}polls AS p
Chris@76 356 LEFT JOIN {db_prefix}topics AS t ON (t.id_poll = p.id_poll)
Chris@76 357 WHERE p.id_poll BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 358 AND t.id_poll IS NULL',
Chris@76 359 'fix_processing' => create_function('$row', '
Chris@76 360 global $smcFunc, $salvageBoardID, $txt;
Chris@76 361
Chris@76 362 // Only if we don\'t have a reasonable idea of where to put it.
Chris@76 363 if ($row[\'id_board\'] == 0)
Chris@76 364 {
Chris@76 365 createSalvageArea();
Chris@76 366 $row[\'id_board\'] = (int) $salvageBoardID;
Chris@76 367 }
Chris@76 368
Chris@76 369 $row[\'poster_name\'] = !empty($row[\'poster_name\']) ? $row[\'poster_name\'] : $txt[\'guest\'];
Chris@76 370
Chris@76 371 $smcFunc[\'db_insert\'](\'\',
Chris@76 372 \'{db_prefix}messages\',
Chris@76 373 array(
Chris@76 374 \'id_board\' => \'int\',
Chris@76 375 \'id_topic\' => \'int\',
Chris@76 376 \'poster_time\' => \'int\',
Chris@76 377 \'id_member\' => \'int\',
Chris@76 378 \'subject\' => \'string-255\',
Chris@76 379 \'poster_name\' => \'string-255\',
Chris@76 380 \'poster_email\' => \'string-255\',
Chris@76 381 \'poster_ip\' => \'string-16\',
Chris@76 382 \'smileys_enabled\' => \'int\',
Chris@76 383 \'body\' => \'string-65534\',
Chris@76 384 \'icon\' => \'string-16\',
Chris@76 385 \'approved\' => \'int\',
Chris@76 386 ),
Chris@76 387 array(
Chris@76 388 $row[\'id_board\'],
Chris@76 389 0,
Chris@76 390 time(),
Chris@76 391 $row[\'id_member\'],
Chris@76 392 $txt[\'salvaged_poll_topic_name\'],
Chris@76 393 $row[\'poster_name\'],
Chris@76 394 \'\',
Chris@76 395 \'127.0.0.1\',
Chris@76 396 1,
Chris@76 397 $txt[\'salvaged_poll_message_body\'],
Chris@76 398 \'xx\',
Chris@76 399 1,
Chris@76 400 ),
Chris@76 401 array(\'id_topic\')
Chris@76 402 );
Chris@76 403
Chris@76 404 $newMessageID = $smcFunc[\'db_insert_id\']("{db_prefix}messages", \'id_msg\');
Chris@76 405
Chris@76 406 $smcFunc[\'db_insert\'](\'\',
Chris@76 407 \'{db_prefix}topics\',
Chris@76 408 array(
Chris@76 409 \'id_board\' => \'int\',
Chris@76 410 \'id_poll\' => \'int\',
Chris@76 411 \'id_member_started\' => \'int\',
Chris@76 412 \'id_member_updated\' => \'int\',
Chris@76 413 \'id_first_msg\' => \'int\',
Chris@76 414 \'id_last_msg\' => \'int\',
Chris@76 415 \'num_replies\' => \'int\',
Chris@76 416 ),
Chris@76 417 array(
Chris@76 418 $row[\'id_board\'],
Chris@76 419 $row[\'id_poll\'],
Chris@76 420 $row[\'id_member\'],
Chris@76 421 $row[\'id_member\'],
Chris@76 422 $newMessageID,
Chris@76 423 $newMessageID,
Chris@76 424 0,
Chris@76 425 ),
Chris@76 426 array(\'id_topic\')
Chris@76 427 );
Chris@76 428
Chris@76 429 $newTopicID = $smcFunc[\'db_insert_id\']("{db_prefix}topics", \'id_topic\');
Chris@76 430
Chris@76 431 $smcFunc[\'db_query\'](\'\', "
Chris@76 432 UPDATE {db_prefix}messages
Chris@76 433 SET id_topic = $newTopicID, id_board = $row[id_board]
Chris@76 434 WHERE id_msg = $newMessageID",
Chris@76 435 array(
Chris@76 436 )
Chris@76 437 );
Chris@76 438
Chris@76 439 updateStats(\'subject\', $newTopicID, $txt[\'salvaged_poll_topic_name\']);
Chris@76 440
Chris@76 441 '),
Chris@76 442 'force_fix' => array('stats_topics'),
Chris@76 443 'messages' => array('repair_polls_missing_topics', 'id_poll', 'id_topic'),
Chris@76 444 ),
Chris@76 445 'stats_topics' => array(
Chris@76 446 'substeps' => array(
Chris@76 447 'step_size' => 200,
Chris@76 448 'step_max' => '
Chris@76 449 SELECT MAX(id_topic)
Chris@76 450 FROM {db_prefix}topics'
Chris@76 451 ),
Chris@76 452 'check_query' => '
Chris@76 453 SELECT
Chris@76 454 t.id_topic, t.id_first_msg, t.id_last_msg,
Chris@76 455 CASE WHEN MIN(ma.id_msg) > 0 THEN
Chris@76 456 CASE WHEN MIN(mu.id_msg) > 0 THEN
Chris@76 457 CASE WHEN MIN(mu.id_msg) < MIN(ma.id_msg) THEN MIN(mu.id_msg) ELSE MIN(ma.id_msg) END ELSE
Chris@76 458 MIN(ma.id_msg) END ELSE
Chris@76 459 MIN(mu.id_msg) END AS myid_first_msg,
Chris@76 460 CASE WHEN MAX(ma.id_msg) > 0 THEN MAX(ma.id_msg) ELSE MIN(mu.id_msg) END AS myid_last_msg,
Chris@76 461 t.approved, mf.approved, mf.approved AS firstmsg_approved
Chris@76 462 FROM {db_prefix}topics AS t
Chris@76 463 LEFT JOIN {db_prefix}messages AS ma ON (ma.id_topic = t.id_topic AND ma.approved = 1)
Chris@76 464 LEFT JOIN {db_prefix}messages AS mu ON (mu.id_topic = t.id_topic AND mu.approved = 0)
Chris@76 465 LEFT JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)
Chris@76 466 WHERE t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 467 GROUP BY t.id_topic, t.id_first_msg, t.id_last_msg, t.approved, mf.approved
Chris@76 468 ORDER BY t.id_topic',
Chris@76 469 'fix_processing' => create_function('$row', '
Chris@76 470 global $smcFunc;
Chris@76 471 $row[\'firstmsg_approved\'] = (int) $row[\'firstmsg_approved\'];
Chris@76 472 $row[\'myid_first_msg\'] = (int) $row[\'myid_first_msg\'];
Chris@76 473 $row[\'myid_last_msg\'] = (int) $row[\'myid_last_msg\'];
Chris@76 474
Chris@76 475 // Not really a problem?
Chris@76 476 if ($row[\'myid_first_msg\'] == $row[\'myid_first_msg\'] && $row[\'myid_first_msg\'] == $row[\'myid_first_msg\'] && $row[\'approved\'] == $row[\'firstmsg_approved\'])
Chris@76 477 return false;
Chris@76 478
Chris@76 479 $memberStartedID = (int) getMsgMemberID($row[\'myid_first_msg\']);
Chris@76 480 $memberUpdatedID = (int) getMsgMemberID($row[\'myid_last_msg\']);
Chris@76 481
Chris@76 482 $smcFunc[\'db_query\'](\'\', "
Chris@76 483 UPDATE {db_prefix}topics
Chris@76 484 SET id_first_msg = $row[myid_first_msg],
Chris@76 485 id_member_started = $memberStartedID, id_last_msg = $row[myid_last_msg],
Chris@76 486 id_member_updated = $memberUpdatedID, approved = $row[firstmsg_approved]
Chris@76 487 WHERE id_topic = $row[id_topic]",
Chris@76 488 array(
Chris@76 489 )
Chris@76 490 );
Chris@76 491 '),
Chris@76 492 'message_function' => create_function('$row', '
Chris@76 493 global $txt, $context;
Chris@76 494
Chris@76 495 // A pretend error?
Chris@76 496 if ($row[\'myid_first_msg\'] == $row[\'myid_first_msg\'] && $row[\'myid_first_msg\'] == $row[\'myid_first_msg\'] && $row[\'approved\'] == $row[\'firstmsg_approved\'])
Chris@76 497 return false;
Chris@76 498
Chris@76 499 if ($row[\'id_first_msg\'] != $row[\'myid_first_msg\'])
Chris@76 500 $context[\'repair_errors\'][] = sprintf($txt[\'repair_stats_topics_1\'], $row[\'id_topic\'], $row[\'id_first_msg\']);
Chris@76 501 if ($row[\'id_last_msg\'] != $row[\'myid_last_msg\'])
Chris@76 502 $context[\'repair_errors\'][] = sprintf($txt[\'repair_stats_topics_2\'], $row[\'id_topic\'], $row[\'id_last_msg\']);
Chris@76 503 if ($row[\'approved\'] != $row[\'firstmsg_approved\'])
Chris@76 504 $context[\'repair_errors\'][] = sprintf($txt[\'repair_stats_topics_5\'], $row[\'id_topic\']);
Chris@76 505
Chris@76 506 return true;
Chris@76 507 '),
Chris@76 508 ),
Chris@76 509 // Find topics with incorrect num_replies.
Chris@76 510 'stats_topics2' => array(
Chris@76 511 'substeps' => array(
Chris@76 512 'step_size' => 300,
Chris@76 513 'step_max' => '
Chris@76 514 SELECT MAX(id_topic)
Chris@76 515 FROM {db_prefix}topics'
Chris@76 516 ),
Chris@76 517 'check_query' => '
Chris@76 518 SELECT
Chris@76 519 t.id_topic, t.num_replies, mf.approved,
Chris@76 520 CASE WHEN COUNT(ma.id_msg) > 0 THEN CASE WHEN mf.approved > 0 THEN COUNT(ma.id_msg) - 1 ELSE COUNT(ma.id_msg) END ELSE 0 END AS my_num_replies
Chris@76 521 FROM {db_prefix}topics AS t
Chris@76 522 LEFT JOIN {db_prefix}messages AS ma ON (ma.id_topic = t.id_topic AND ma.approved = 1)
Chris@76 523 LEFT JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)
Chris@76 524 WHERE t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 525 GROUP BY t.id_topic, t.num_replies, mf.approved
Chris@76 526 ORDER BY t.id_topic',
Chris@76 527 'fix_processing' => create_function('$row', '
Chris@76 528 global $smcFunc;
Chris@76 529 $row[\'my_num_replies\'] = (int) $row[\'my_num_replies\'];
Chris@76 530
Chris@76 531 // Not really a problem?
Chris@76 532 if ($row[\'my_num_replies\'] == $row[\'num_replies\'])
Chris@76 533 return false;
Chris@76 534
Chris@76 535 $smcFunc[\'db_query\'](\'\', "
Chris@76 536 UPDATE {db_prefix}topics
Chris@76 537 SET num_replies = $row[my_num_replies]
Chris@76 538 WHERE id_topic = $row[id_topic]",
Chris@76 539 array(
Chris@76 540 )
Chris@76 541 );
Chris@76 542 '),
Chris@76 543 'message_function' => create_function('$row', '
Chris@76 544 global $txt, $context;
Chris@76 545
Chris@76 546 // Just joking?
Chris@76 547 if ($row[\'my_num_replies\'] == $row[\'num_replies\'])
Chris@76 548 return false;
Chris@76 549
Chris@76 550 if ($row[\'num_replies\'] != $row[\'my_num_replies\'])
Chris@76 551 $context[\'repair_errors\'][] = sprintf($txt[\'repair_stats_topics_3\'], $row[\'id_topic\'], $row[\'num_replies\']);
Chris@76 552
Chris@76 553 return true;
Chris@76 554 '),
Chris@76 555 ),
Chris@76 556 // Find topics with incorrect unapproved_posts.
Chris@76 557 'stats_topics3' => array(
Chris@76 558 'substeps' => array(
Chris@76 559 'step_size' => 1000,
Chris@76 560 'step_max' => '
Chris@76 561 SELECT MAX(id_topic)
Chris@76 562 FROM {db_prefix}topics'
Chris@76 563 ),
Chris@76 564 'check_query' => '
Chris@76 565 SELECT
Chris@76 566 t.id_topic, t.unapproved_posts, COUNT(mu.id_msg) AS my_unapproved_posts
Chris@76 567 FROM {db_prefix}topics AS t
Chris@76 568 LEFT JOIN {db_prefix}messages AS mu ON (mu.id_topic = t.id_topic AND mu.approved = 0)
Chris@76 569 WHERE t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 570 GROUP BY t.id_topic, t.unapproved_posts
Chris@76 571 HAVING unapproved_posts != COUNT(mu.id_msg)
Chris@76 572 ORDER BY t.id_topic',
Chris@76 573 'fix_processing' => create_function('$row', '
Chris@76 574 global $smcFunc;
Chris@76 575 $row[\'my_unapproved_posts\'] = (int) $row[\'my_unapproved_posts\'];
Chris@76 576
Chris@76 577 $smcFunc[\'db_query\'](\'\', "
Chris@76 578 UPDATE {db_prefix}topics
Chris@76 579 SET unapproved_posts = $row[my_unapproved_posts]
Chris@76 580 WHERE id_topic = $row[id_topic]",
Chris@76 581 array(
Chris@76 582 )
Chris@76 583 );
Chris@76 584 '),
Chris@76 585 'messages' => array('repair_stats_topics_4', 'id_topic', 'unapproved_posts'),
Chris@76 586 ),
Chris@76 587 // Find topics with nonexistent boards.
Chris@76 588 'missing_boards' => array(
Chris@76 589 'substeps' => array(
Chris@76 590 'step_size' => 1000,
Chris@76 591 'step_max' => '
Chris@76 592 SELECT MAX(id_topic)
Chris@76 593 FROM {db_prefix}topics'
Chris@76 594 ),
Chris@76 595 'check_query' => '
Chris@76 596 SELECT t.id_topic, t.id_board
Chris@76 597 FROM {db_prefix}topics AS t
Chris@76 598 LEFT JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
Chris@76 599 WHERE b.id_board IS NULL
Chris@76 600 AND t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 601 ORDER BY t.id_board, t.id_topic',
Chris@76 602 'fix_query' => '
Chris@76 603 SELECT t.id_board, COUNT(*) AS my_num_topics, COUNT(m.id_msg) AS my_num_posts
Chris@76 604 FROM {db_prefix}topics AS t
Chris@76 605 LEFT JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
Chris@76 606 LEFT JOIN {db_prefix}messages AS m ON (m.id_topic = t.id_topic)
Chris@76 607 WHERE b.id_board IS NULL
Chris@76 608 AND t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 609 GROUP BY t.id_board',
Chris@76 610 'fix_processing' => create_function('$row', '
Chris@76 611 global $smcFunc, $salvageCatID;
Chris@76 612 createSalvageArea();
Chris@76 613
Chris@76 614 $row[\'my_num_topics\'] = (int) $row[\'my_num_topics\'];
Chris@76 615 $row[\'my_num_posts\'] = (int) $row[\'my_num_posts\'];
Chris@76 616
Chris@76 617 $smcFunc[\'db_insert\'](\'\',
Chris@76 618 \'{db_prefix}boards\',
Chris@76 619 array(\'id_cat\' => \'int\', \'name\' => \'string\', \'description\' => \'string\', \'num_topics\' => \'int\', \'num_posts\' => \'int\', \'member_groups\' => \'string\'),
Chris@76 620 array($salvageCatID, \'Salvaged board\', \'\', $row[\'my_num_topics\'], $row[\'my_num_posts\'], \'1\'),
Chris@76 621 array(\'id_board\')
Chris@76 622 );
Chris@76 623 $newBoardID = $smcFunc[\'db_insert_id\'](\'{db_prefix}boards\', \'id_board\');
Chris@76 624
Chris@76 625 $smcFunc[\'db_query\'](\'\', "
Chris@76 626 UPDATE {db_prefix}topics
Chris@76 627 SET id_board = $newBoardID
Chris@76 628 WHERE id_board = $row[id_board]",
Chris@76 629 array(
Chris@76 630 )
Chris@76 631 );
Chris@76 632 $smcFunc[\'db_query\'](\'\', "
Chris@76 633 UPDATE {db_prefix}messages
Chris@76 634 SET id_board = $newBoardID
Chris@76 635 WHERE id_board = $row[id_board]",
Chris@76 636 array(
Chris@76 637 )
Chris@76 638 );
Chris@76 639 '),
Chris@76 640 'messages' => array('repair_missing_boards', 'id_topic', 'id_board'),
Chris@76 641 ),
Chris@76 642 // Find boards with nonexistent categories.
Chris@76 643 'missing_categories' => array(
Chris@76 644 'check_query' => '
Chris@76 645 SELECT b.id_board, b.id_cat
Chris@76 646 FROM {db_prefix}boards AS b
Chris@76 647 LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)
Chris@76 648 WHERE c.id_cat IS NULL
Chris@76 649 ORDER BY b.id_cat, b.id_board',
Chris@76 650 'fix_collect' => array(
Chris@76 651 'index' => 'id_cat',
Chris@76 652 'process' => create_function('$cats', '
Chris@76 653 global $smcFunc, $salvageCatID;
Chris@76 654 createSalvageArea();
Chris@76 655 $smcFunc[\'db_query\'](\'\', "
Chris@76 656 UPDATE {db_prefix}boards
Chris@76 657 SET id_cat = $salvageCatID
Chris@76 658 WHERE id_cat IN ({array_int:categories})",
Chris@76 659 array(
Chris@76 660 \'categories\' => $cats
Chris@76 661 )
Chris@76 662 );
Chris@76 663 '),
Chris@76 664 ),
Chris@76 665 'messages' => array('repair_missing_categories', 'id_board', 'id_cat'),
Chris@76 666 ),
Chris@76 667 // Find messages with nonexistent members.
Chris@76 668 'missing_posters' => array(
Chris@76 669 'substeps' => array(
Chris@76 670 'step_size' => 2000,
Chris@76 671 'step_max' => '
Chris@76 672 SELECT MAX(id_msg)
Chris@76 673 FROM {db_prefix}messages'
Chris@76 674 ),
Chris@76 675 'check_query' => '
Chris@76 676 SELECT m.id_msg, m.id_member
Chris@76 677 FROM {db_prefix}messages AS m
Chris@76 678 LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
Chris@76 679 WHERE mem.id_member IS NULL
Chris@76 680 AND m.id_member != 0
Chris@76 681 AND m.id_msg BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 682 ORDER BY m.id_msg',
Chris@76 683 // Last step-make sure all non-guest posters still exist.
Chris@76 684 'fix_collect' => array(
Chris@76 685 'index' => 'id_msg',
Chris@76 686 'process' => create_function('$msgs', '
Chris@76 687 global $smcFunc;
Chris@76 688 $smcFunc[\'db_query\'](\'\', "
Chris@76 689 UPDATE {db_prefix}messages
Chris@76 690 SET id_member = 0
Chris@76 691 WHERE id_msg IN ({array_int:msgs})",
Chris@76 692 array(
Chris@76 693 \'msgs\' => $msgs
Chris@76 694 )
Chris@76 695 );
Chris@76 696 '),
Chris@76 697 ),
Chris@76 698 'messages' => array('repair_missing_posters', 'id_msg', 'id_member'),
Chris@76 699 ),
Chris@76 700 // Find boards with nonexistent parents.
Chris@76 701 'missing_parents' => array(
Chris@76 702 'check_query' => '
Chris@76 703 SELECT b.id_board, b.id_parent
Chris@76 704 FROM {db_prefix}boards AS b
Chris@76 705 LEFT JOIN {db_prefix}boards AS p ON (p.id_board = b.id_parent)
Chris@76 706 WHERE b.id_parent != 0
Chris@76 707 AND (p.id_board IS NULL OR p.id_board = b.id_board)
Chris@76 708 ORDER BY b.id_parent, b.id_board',
Chris@76 709 'fix_collect' => array(
Chris@76 710 'index' => 'id_parent',
Chris@76 711 'process' => create_function('$parents', '
Chris@76 712 global $smcFunc, $salvageBoardID, $salvageCatID;
Chris@76 713 createSalvageArea();
Chris@76 714 $smcFunc[\'db_query\'](\'\', "
Chris@76 715 UPDATE {db_prefix}boards
Chris@76 716 SET id_parent = $salvageBoardID, id_cat = $salvageCatID, child_level = 1
Chris@76 717 WHERE id_parent IN ({array_int:parents})",
Chris@76 718 array(
Chris@76 719 \'parents\' => $parents
Chris@76 720 )
Chris@76 721 );
Chris@76 722 '),
Chris@76 723 ),
Chris@76 724 'messages' => array('repair_missing_parents', 'id_board', 'id_parent'),
Chris@76 725 ),
Chris@76 726 'missing_polls' => array(
Chris@76 727 'substeps' => array(
Chris@76 728 'step_size' => 500,
Chris@76 729 'step_max' => '
Chris@76 730 SELECT MAX(id_poll)
Chris@76 731 FROM {db_prefix}topics'
Chris@76 732 ),
Chris@76 733 'check_query' => '
Chris@76 734 SELECT t.id_poll, t.id_topic
Chris@76 735 FROM {db_prefix}topics AS t
Chris@76 736 LEFT JOIN {db_prefix}polls AS p ON (p.id_poll = t.id_poll)
Chris@76 737 WHERE t.id_poll != 0
Chris@76 738 AND t.id_poll BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 739 AND p.id_poll IS NULL',
Chris@76 740 'fix_collect' => array(
Chris@76 741 'index' => 'id_poll',
Chris@76 742 'process' => create_function('$polls', '
Chris@76 743 global $smcFunc;
Chris@76 744 $smcFunc[\'db_query\'](\'\', "
Chris@76 745 UPDATE {db_prefix}topics
Chris@76 746 SET id_poll = 0
Chris@76 747 WHERE id_poll IN ({array_int:polls})",
Chris@76 748 array(
Chris@76 749 \'polls\' => $polls
Chris@76 750 )
Chris@76 751 );
Chris@76 752 '),
Chris@76 753 ),
Chris@76 754 'messages' => array('repair_missing_polls', 'id_topic', 'id_poll'),
Chris@76 755 ),
Chris@76 756 'missing_calendar_topics' => array(
Chris@76 757 'substeps' => array(
Chris@76 758 'step_size' => 1000,
Chris@76 759 'step_max' => '
Chris@76 760 SELECT MAX(id_topic)
Chris@76 761 FROM {db_prefix}calendar'
Chris@76 762 ),
Chris@76 763 'check_query' => '
Chris@76 764 SELECT cal.id_topic, cal.id_event
Chris@76 765 FROM {db_prefix}calendar AS cal
Chris@76 766 LEFT JOIN {db_prefix}topics AS t ON (t.id_topic = cal.id_topic)
Chris@76 767 WHERE cal.id_topic != 0
Chris@76 768 AND cal.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 769 AND t.id_topic IS NULL
Chris@76 770 ORDER BY cal.id_topic',
Chris@76 771 'fix_collect' => array(
Chris@76 772 'index' => 'id_topic',
Chris@76 773 'process' => create_function('$events', '
Chris@76 774 global $smcFunc;
Chris@76 775 $smcFunc[\'db_query\'](\'\', \'
Chris@76 776 UPDATE {db_prefix}calendar
Chris@76 777 SET id_topic = 0, id_board = 0
Chris@76 778 WHERE id_topic IN ({array_int:events})\',
Chris@76 779 array(
Chris@76 780 \'events\' => $events
Chris@76 781 )
Chris@76 782 );
Chris@76 783 '),
Chris@76 784 ),
Chris@76 785 'messages' => array('repair_missing_calendar_topics', 'id_event', 'id_topic'),
Chris@76 786 ),
Chris@76 787 'missing_log_topics' => array(
Chris@76 788 'substeps' => array(
Chris@76 789 'step_size' => 150,
Chris@76 790 'step_max' => '
Chris@76 791 SELECT MAX(id_member)
Chris@76 792 FROM {db_prefix}log_topics'
Chris@76 793 ),
Chris@76 794 'check_query' => '
Chris@76 795 SELECT lt.id_topic
Chris@76 796 FROM {db_prefix}log_topics AS lt
Chris@76 797 LEFT JOIN {db_prefix}topics AS t ON (t.id_topic = lt.id_topic)
Chris@76 798 WHERE t.id_topic IS NULL
Chris@76 799 AND lt.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}',
Chris@76 800 'fix_collect' => array(
Chris@76 801 'index' => 'id_topic',
Chris@76 802 'process' => create_function('$topics', '
Chris@76 803 global $smcFunc;
Chris@76 804 $smcFunc[\'db_query\'](\'\', "
Chris@76 805 DELETE FROM {db_prefix}log_topics
Chris@76 806 WHERE id_topic IN ({array_int:topics})",
Chris@76 807 array(
Chris@76 808 \'topics\' => $topics
Chris@76 809 )
Chris@76 810 );
Chris@76 811 '),
Chris@76 812 ),
Chris@76 813 'messages' => array('repair_missing_log_topics', 'id_topic'),
Chris@76 814 ),
Chris@76 815 'missing_log_topics_members' => array(
Chris@76 816 'substeps' => array(
Chris@76 817 'step_size' => 150,
Chris@76 818 'step_max' => '
Chris@76 819 SELECT MAX(id_member)
Chris@76 820 FROM {db_prefix}log_topics'
Chris@76 821 ),
Chris@76 822 'check_query' => '
Chris@76 823 SELECT lt.id_member
Chris@76 824 FROM {db_prefix}log_topics AS lt
Chris@76 825 LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lt.id_member)
Chris@76 826 WHERE mem.id_member IS NULL
Chris@76 827 AND lt.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 828 GROUP BY lt.id_member',
Chris@76 829 'fix_collect' => array(
Chris@76 830 'index' => 'id_member',
Chris@76 831 'process' => create_function('$members', '
Chris@76 832 global $smcFunc;
Chris@76 833 $smcFunc[\'db_query\'](\'\', "
Chris@76 834 DELETE FROM {db_prefix}log_topics
Chris@76 835 WHERE id_member IN ({array_int:members})",
Chris@76 836 array(
Chris@76 837 \'members\' => $members
Chris@76 838 )
Chris@76 839 );
Chris@76 840 '),
Chris@76 841 ),
Chris@76 842 'messages' => array('repair_missing_log_topics_members', 'id_member'),
Chris@76 843 ),
Chris@76 844 'missing_log_boards' => array(
Chris@76 845 'substeps' => array(
Chris@76 846 'step_size' => 500,
Chris@76 847 'step_max' => '
Chris@76 848 SELECT MAX(id_member)
Chris@76 849 FROM {db_prefix}log_boards'
Chris@76 850 ),
Chris@76 851 'check_query' => '
Chris@76 852 SELECT lb.id_board
Chris@76 853 FROM {db_prefix}log_boards AS lb
Chris@76 854 LEFT JOIN {db_prefix}boards AS b ON (b.id_board = lb.id_board)
Chris@76 855 WHERE b.id_board IS NULL
Chris@76 856 AND lb.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 857 GROUP BY lb.id_board',
Chris@76 858 'fix_collect' => array(
Chris@76 859 'index' => 'id_board',
Chris@76 860 'process' => create_function('$boards', '
Chris@76 861 global $smcFunc;
Chris@76 862 $smcFunc[\'db_query\'](\'\', "
Chris@76 863 DELETE FROM {db_prefix}log_boards
Chris@76 864 WHERE id_board IN ({array_int:boards})",
Chris@76 865 array(
Chris@76 866 \'boards\' => $boards
Chris@76 867 )
Chris@76 868 );
Chris@76 869 '),
Chris@76 870 ),
Chris@76 871 'messages' => array('repair_missing_log_boards', 'id_board'),
Chris@76 872 ),
Chris@76 873 'missing_log_boards_members' => array(
Chris@76 874 'substeps' => array(
Chris@76 875 'step_size' => 500,
Chris@76 876 'step_max' => '
Chris@76 877 SELECT MAX(id_member)
Chris@76 878 FROM {db_prefix}log_boards'
Chris@76 879 ),
Chris@76 880 'check_query' => '
Chris@76 881 SELECT lb.id_member
Chris@76 882 FROM {db_prefix}log_boards AS lb
Chris@76 883 LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lb.id_member)
Chris@76 884 WHERE mem.id_member IS NULL
Chris@76 885 AND lb.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 886 GROUP BY lb.id_member',
Chris@76 887 'fix_collect' => array(
Chris@76 888 'index' => 'id_member',
Chris@76 889 'process' => create_function('$members', '
Chris@76 890 global $smcFunc;
Chris@76 891 $smcFunc[\'db_query\'](\'\', "
Chris@76 892 DELETE FROM {db_prefix}log_boards
Chris@76 893 WHERE id_member IN ({array_int:members})",
Chris@76 894 array(
Chris@76 895 \'members\' => $members
Chris@76 896 )
Chris@76 897 );
Chris@76 898 '),
Chris@76 899 ),
Chris@76 900 'messages' => array('repair_missing_log_boards_members', 'id_member'),
Chris@76 901 ),
Chris@76 902 'missing_log_mark_read' => array(
Chris@76 903 'substeps' => array(
Chris@76 904 'step_size' => 500,
Chris@76 905 'step_max' => '
Chris@76 906 SELECT MAX(id_member)
Chris@76 907 FROM {db_prefix}log_mark_read'
Chris@76 908 ),
Chris@76 909 'check_query' => '
Chris@76 910 SELECT lmr.id_board
Chris@76 911 FROM {db_prefix}log_mark_read AS lmr
Chris@76 912 LEFT JOIN {db_prefix}boards AS b ON (b.id_board = lmr.id_board)
Chris@76 913 WHERE b.id_board IS NULL
Chris@76 914 AND lmr.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 915 GROUP BY lmr.id_board',
Chris@76 916 'fix_collect' => array(
Chris@76 917 'index' => 'id_board',
Chris@76 918 'process' => create_function('$boards', '
Chris@76 919 global $smcFunc;
Chris@76 920 $smcFunc[\'db_query\'](\'\', "
Chris@76 921 DELETE FROM {db_prefix}log_mark_read
Chris@76 922 WHERE id_board IN ({array_int:boards})",
Chris@76 923 array(
Chris@76 924 \'boards\' => $boards
Chris@76 925 )
Chris@76 926 );
Chris@76 927 '),
Chris@76 928 ),
Chris@76 929 'messages' => array('repair_missing_log_mark_read', 'id_board'),
Chris@76 930 ),
Chris@76 931 'missing_log_mark_read_members' => array(
Chris@76 932 'substeps' => array(
Chris@76 933 'step_size' => 500,
Chris@76 934 'step_max' => '
Chris@76 935 SELECT MAX(id_member)
Chris@76 936 FROM {db_prefix}log_mark_read'
Chris@76 937 ),
Chris@76 938 'check_query' => '
Chris@76 939 SELECT lmr.id_member
Chris@76 940 FROM {db_prefix}log_mark_read AS lmr
Chris@76 941 LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lmr.id_member)
Chris@76 942 WHERE mem.id_member IS NULL
Chris@76 943 AND lmr.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 944 GROUP BY lmr.id_member',
Chris@76 945 'fix_collect' => array(
Chris@76 946 'index' => 'id_member',
Chris@76 947 'process' => create_function('$members', '
Chris@76 948 global $smcFunc;
Chris@76 949 $smcFunc[\'db_query\'](\'\', "
Chris@76 950 DELETE FROM {db_prefix}log_mark_read
Chris@76 951 WHERE id_member IN ({array_int:members})",
Chris@76 952 array(
Chris@76 953 \'members\' => $members
Chris@76 954 )
Chris@76 955 );
Chris@76 956 '),
Chris@76 957 ),
Chris@76 958 'messages' => array('repair_missing_log_mark_read_members', 'id_member'),
Chris@76 959 ),
Chris@76 960 'missing_pms' => array(
Chris@76 961 'substeps' => array(
Chris@76 962 'step_size' => 500,
Chris@76 963 'step_max' => '
Chris@76 964 SELECT MAX(id_pm)
Chris@76 965 FROM {db_prefix}pm_recipients'
Chris@76 966 ),
Chris@76 967 'check_query' => '
Chris@76 968 SELECT pmr.id_pm
Chris@76 969 FROM {db_prefix}pm_recipients AS pmr
Chris@76 970 LEFT JOIN {db_prefix}personal_messages AS pm ON (pm.id_pm = pmr.id_pm)
Chris@76 971 WHERE pm.id_pm IS NULL
Chris@76 972 AND pmr.id_pm BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 973 GROUP BY pmr.id_pm',
Chris@76 974 'fix_collect' => array(
Chris@76 975 'index' => 'id_pm',
Chris@76 976 'process' => create_function('$pms', '
Chris@76 977 global $smcFunc;
Chris@76 978 $smcFunc[\'db_query\'](\'\', "
Chris@76 979 DELETE FROM {db_prefix}pm_recipients
Chris@76 980 WHERE id_pm IN ({array_int:pms})",
Chris@76 981 array(
Chris@76 982 \'pms\' => $pms
Chris@76 983 )
Chris@76 984 );
Chris@76 985 '),
Chris@76 986 ),
Chris@76 987 'messages' => array('repair_missing_pms', 'id_pm'),
Chris@76 988 ),
Chris@76 989 'missing_recipients' => array(
Chris@76 990 'substeps' => array(
Chris@76 991 'step_size' => 500,
Chris@76 992 'step_max' => '
Chris@76 993 SELECT MAX(id_member)
Chris@76 994 FROM {db_prefix}pm_recipients'
Chris@76 995 ),
Chris@76 996 'check_query' => '
Chris@76 997 SELECT pmr.id_member
Chris@76 998 FROM {db_prefix}pm_recipients AS pmr
Chris@76 999 LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = pmr.id_member)
Chris@76 1000 WHERE pmr.id_member != 0
Chris@76 1001 AND pmr.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 1002 AND mem.id_member IS NULL
Chris@76 1003 GROUP BY pmr.id_member',
Chris@76 1004 'fix_collect' => array(
Chris@76 1005 'index' => 'id_member',
Chris@76 1006 'process' => create_function('$members', '
Chris@76 1007 global $smcFunc;
Chris@76 1008 $smcFunc[\'db_query\'](\'\', "
Chris@76 1009 DELETE FROM {db_prefix}pm_recipients
Chris@76 1010 WHERE id_member IN ({array_int:members})",
Chris@76 1011 array(
Chris@76 1012 \'members\' => $members
Chris@76 1013 )
Chris@76 1014 );
Chris@76 1015 '),
Chris@76 1016 ),
Chris@76 1017 'messages' => array('repair_missing_recipients', 'id_member'),
Chris@76 1018 ),
Chris@76 1019 'missing_senders' => array(
Chris@76 1020 'substeps' => array(
Chris@76 1021 'step_size' => 500,
Chris@76 1022 'step_max' => '
Chris@76 1023 SELECT MAX(id_pm)
Chris@76 1024 FROM {db_prefix}personal_messages'
Chris@76 1025 ),
Chris@76 1026 'check_query' => '
Chris@76 1027 SELECT pm.id_pm, pm.id_member_from
Chris@76 1028 FROM {db_prefix}personal_messages AS pm
Chris@76 1029 LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = pm.id_member_from)
Chris@76 1030 WHERE pm.id_member_from != 0
Chris@76 1031 AND pm.id_pm BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 1032 AND mem.id_member IS NULL',
Chris@76 1033 'fix_collect' => array(
Chris@76 1034 'index' => 'id_pm',
Chris@76 1035 'process' => create_function('$guestMessages', '
Chris@76 1036 global $smcFunc;
Chris@76 1037 $smcFunc[\'db_query\'](\'\', "
Chris@76 1038 UPDATE {db_prefix}personal_messages
Chris@76 1039 SET id_member_from = 0
Chris@76 1040 WHERE id_pm IN ({array_int:guestMessages})",
Chris@76 1041 array(
Chris@76 1042 \'guestMessages\' => $guestMessages
Chris@76 1043 ));
Chris@76 1044 '),
Chris@76 1045 ),
Chris@76 1046 'messages' => array('repair_missing_senders', 'id_pm', 'id_member_from'),
Chris@76 1047 ),
Chris@76 1048 'missing_notify_members' => array(
Chris@76 1049 'substeps' => array(
Chris@76 1050 'step_size' => 500,
Chris@76 1051 'step_max' => '
Chris@76 1052 SELECT MAX(id_member)
Chris@76 1053 FROM {db_prefix}log_notify'
Chris@76 1054 ),
Chris@76 1055 'check_query' => '
Chris@76 1056 SELECT ln.id_member
Chris@76 1057 FROM {db_prefix}log_notify AS ln
Chris@76 1058 LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = ln.id_member)
Chris@76 1059 WHERE ln.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 1060 AND mem.id_member IS NULL
Chris@76 1061 GROUP BY ln.id_member',
Chris@76 1062 'fix_collect' => array(
Chris@76 1063 'index' => 'id_member',
Chris@76 1064 'process' => create_function('$members', '
Chris@76 1065 global $smcFunc;
Chris@76 1066 $smcFunc[\'db_query\'](\'\', "
Chris@76 1067 DELETE FROM {db_prefix}log_notify
Chris@76 1068 WHERE id_member IN ({array_int:members})",
Chris@76 1069 array(
Chris@76 1070 \'members\' => $members
Chris@76 1071 )
Chris@76 1072 );
Chris@76 1073 '),
Chris@76 1074 ),
Chris@76 1075 'messages' => array('repair_missing_notify_members', 'id_member'),
Chris@76 1076 ),
Chris@76 1077 'missing_cached_subject' => array(
Chris@76 1078 'substeps' => array(
Chris@76 1079 'step_size' => 100,
Chris@76 1080 'step_max' => '
Chris@76 1081 SELECT MAX(id_topic)
Chris@76 1082 FROM {db_prefix}topics'
Chris@76 1083 ),
Chris@76 1084 'check_query' => '
Chris@76 1085 SELECT t.id_topic, fm.subject
Chris@76 1086 FROM {db_prefix}topics AS t
Chris@76 1087 INNER JOIN {db_prefix}messages AS fm ON (fm.id_msg = t.id_first_msg)
Chris@76 1088 LEFT JOIN {db_prefix}log_search_subjects AS lss ON (lss.id_topic = t.id_topic)
Chris@76 1089 WHERE t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 1090 AND lss.id_topic IS NULL',
Chris@76 1091 'fix_full_processing' => create_function('$result', '
Chris@76 1092 global $smcFunc;
Chris@76 1093
Chris@76 1094 $inserts = array();
Chris@76 1095 while ($row = $smcFunc[\'db_fetch_assoc\']($result))
Chris@76 1096 {
Chris@76 1097 foreach (text2words($row[\'subject\']) as $word)
Chris@76 1098 $inserts[] = array($word, $row[\'id_topic\']);
Chris@76 1099 if (count($inserts) > 500)
Chris@76 1100 {
Chris@76 1101 $smcFunc[\'db_insert\'](\'ignore\',
Chris@76 1102 "{db_prefix}log_search_subjects",
Chris@76 1103 array(\'word\' => \'string\', \'id_topic\' => \'int\'),
Chris@76 1104 $inserts,
Chris@76 1105 array(\'word\', \'id_topic\')
Chris@76 1106 );
Chris@76 1107 $inserts = array();
Chris@76 1108 }
Chris@76 1109
Chris@76 1110 }
Chris@76 1111
Chris@76 1112 if (!empty($inserts))
Chris@76 1113 $smcFunc[\'db_insert\'](\'ignore\',
Chris@76 1114 "{db_prefix}log_search_subjects",
Chris@76 1115 array(\'word\' => \'string\', \'id_topic\' => \'int\'),
Chris@76 1116 $inserts,
Chris@76 1117 array(\'word\', \'id_topic\')
Chris@76 1118 );
Chris@76 1119 '),
Chris@76 1120 'message_function' => create_function('$row', '
Chris@76 1121 global $txt, $context;
Chris@76 1122
Chris@76 1123 if (count(text2words($row[\'subject\'])) != 0)
Chris@76 1124 {
Chris@76 1125 $context[\'repair_errors\'][] = sprintf($txt[\'repair_missing_cached_subject\'], $row[\'id_topic\']);
Chris@76 1126 return true;
Chris@76 1127 }
Chris@76 1128
Chris@76 1129 return false;
Chris@76 1130 '),
Chris@76 1131 ),
Chris@76 1132 'missing_topic_for_cache' => array(
Chris@76 1133 'substeps' => array(
Chris@76 1134 'step_size' => 50,
Chris@76 1135 'step_max' => '
Chris@76 1136 SELECT MAX(id_topic)
Chris@76 1137 FROM {db_prefix}log_search_subjects'
Chris@76 1138 ),
Chris@76 1139 'check_query' => '
Chris@76 1140 SELECT lss.id_topic, lss.word
Chris@76 1141 FROM {db_prefix}log_search_subjects AS lss
Chris@76 1142 LEFT JOIN {db_prefix}topics AS t ON (t.id_topic = lss.id_topic)
Chris@76 1143 WHERE lss.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 1144 AND t.id_topic IS NULL',
Chris@76 1145 'fix_collect' => array(
Chris@76 1146 'index' => 'id_topic',
Chris@76 1147 'process' => create_function('$deleteTopics', '
Chris@76 1148 global $smcFunc;
Chris@76 1149 $smcFunc[\'db_query\'](\'\', "
Chris@76 1150 DELETE FROM {db_prefix}log_search_subjects
Chris@76 1151 WHERE id_topic IN ({array_int:deleteTopics})",
Chris@76 1152 array(
Chris@76 1153 \'deleteTopics\' => $deleteTopics
Chris@76 1154 )
Chris@76 1155 );
Chris@76 1156 '),
Chris@76 1157 ),
Chris@76 1158 'messages' => array('repair_missing_topic_for_cache', 'word'),
Chris@76 1159 ),
Chris@76 1160 'missing_member_vote' => array(
Chris@76 1161 'substeps' => array(
Chris@76 1162 'step_size' => 500,
Chris@76 1163 'step_max' => '
Chris@76 1164 SELECT MAX(id_member)
Chris@76 1165 FROM {db_prefix}log_polls'
Chris@76 1166 ),
Chris@76 1167 'check_query' => '
Chris@76 1168 SELECT lp.id_poll, lp.id_member
Chris@76 1169 FROM {db_prefix}log_polls AS lp
Chris@76 1170 LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lp.id_member)
Chris@76 1171 WHERE lp.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 1172 AND lp.id_member > 0
Chris@76 1173 AND mem.id_member IS NULL',
Chris@76 1174 'fix_collect' => array(
Chris@76 1175 'index' => 'id_member',
Chris@76 1176 'process' => create_function('$members', '
Chris@76 1177 global $smcFunc;
Chris@76 1178 $smcFunc[\'db_query\'](\'\', "
Chris@76 1179 DELETE FROM {db_prefix}log_polls
Chris@76 1180 WHERE id_member IN ({array_int:members})",
Chris@76 1181 array(
Chris@76 1182 \'members\' => $members
Chris@76 1183 )
Chris@76 1184 );
Chris@76 1185 '),
Chris@76 1186 ),
Chris@76 1187 'messages' => array('repair_missing_log_poll_member', 'id_poll', 'id_member'),
Chris@76 1188 ),
Chris@76 1189 'missing_log_poll_vote' => array(
Chris@76 1190 'substeps' => array(
Chris@76 1191 'step_size' => 500,
Chris@76 1192 'step_max' => '
Chris@76 1193 SELECT MAX(id_poll)
Chris@76 1194 FROM {db_prefix}log_polls'
Chris@76 1195 ),
Chris@76 1196 'check_query' => '
Chris@76 1197 SELECT lp.id_poll, lp.id_member
Chris@76 1198 FROM {db_prefix}log_polls AS lp
Chris@76 1199 LEFT JOIN {db_prefix}polls AS p ON (p.id_poll = lp.id_poll)
Chris@76 1200 WHERE lp.id_poll BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 1201 AND p.id_poll IS NULL',
Chris@76 1202 'fix_collect' => array(
Chris@76 1203 'index' => 'id_poll',
Chris@76 1204 'process' => create_function('$polls', '
Chris@76 1205 global $smcFunc;
Chris@76 1206 $smcFunc[\'db_query\'](\'\', "
Chris@76 1207 DELETE FROM {db_prefix}log_polls
Chris@76 1208 WHERE id_poll IN ({array_int:polls})",
Chris@76 1209 array(
Chris@76 1210 \'polls\' => $polls
Chris@76 1211 )
Chris@76 1212 );
Chris@76 1213 '),
Chris@76 1214 ),
Chris@76 1215 'messages' => array('repair_missing_log_poll_vote', 'id_member', 'id_poll'),
Chris@76 1216 ),
Chris@76 1217 'report_missing_comments' => array(
Chris@76 1218 'substeps' => array(
Chris@76 1219 'step_size' => 500,
Chris@76 1220 'step_max' => '
Chris@76 1221 SELECT MAX(id_report)
Chris@76 1222 FROM {db_prefix}log_reported'
Chris@76 1223 ),
Chris@76 1224 'check_query' => '
Chris@76 1225 SELECT lr.id_report, lr.subject
Chris@76 1226 FROM {db_prefix}log_reported AS lr
Chris@76 1227 LEFT JOIN {db_prefix}log_reported_comments AS lrc ON (lrc.id_report = lr.id_report)
Chris@76 1228 WHERE lr.id_report BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 1229 AND lrc.id_report IS NULL',
Chris@76 1230 'fix_collect' => array(
Chris@76 1231 'index' => 'id_report',
Chris@76 1232 'process' => create_function('$reports', '
Chris@76 1233 global $smcFunc;
Chris@76 1234 $smcFunc[\'db_query\'](\'\', "
Chris@76 1235 DELETE FROM {db_prefix}log_reported
Chris@76 1236 WHERE id_report IN ({array_int:reports})",
Chris@76 1237 array(
Chris@76 1238 \'reports\' => $reports
Chris@76 1239 )
Chris@76 1240 );
Chris@76 1241 '),
Chris@76 1242 ),
Chris@76 1243 'messages' => array('repair_report_missing_comments', 'id_report', 'subject'),
Chris@76 1244 ),
Chris@76 1245 'comments_missing_report' => array(
Chris@76 1246 'substeps' => array(
Chris@76 1247 'step_size' => 200,
Chris@76 1248 'step_max' => '
Chris@76 1249 SELECT MAX(id_report)
Chris@76 1250 FROM {db_prefix}log_reported_comments'
Chris@76 1251 ),
Chris@76 1252 'check_query' => '
Chris@76 1253 SELECT lrc.id_report, lrc.membername
Chris@76 1254 FROM {db_prefix}log_reported_comments AS lrc
Chris@76 1255 LEFT JOIN {db_prefix}log_reported AS lr ON (lr.id_report = lrc.id_report)
Chris@76 1256 WHERE lrc.id_report BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 1257 AND lr.id_report IS NULL',
Chris@76 1258 'fix_collect' => array(
Chris@76 1259 'index' => 'id_report',
Chris@76 1260 'process' => create_function('$reports', '
Chris@76 1261 global $smcFunc;
Chris@76 1262 $smcFunc[\'db_query\'](\'\', "
Chris@76 1263 DELETE FROM {db_prefix}log_reported_comments
Chris@76 1264 WHERE id_report IN ({array_int:reports})",
Chris@76 1265 array(
Chris@76 1266 \'reports\' => $reports
Chris@76 1267 )
Chris@76 1268 );
Chris@76 1269 '),
Chris@76 1270 ),
Chris@76 1271 'messages' => array('repair_comments_missing_report', 'id_report', 'membername'),
Chris@76 1272 ),
Chris@76 1273 'group_request_missing_member' => array(
Chris@76 1274 'substeps' => array(
Chris@76 1275 'step_size' => 200,
Chris@76 1276 'step_max' => '
Chris@76 1277 SELECT MAX(id_member)
Chris@76 1278 FROM {db_prefix}log_group_requests'
Chris@76 1279 ),
Chris@76 1280 'check_query' => '
Chris@76 1281 SELECT lgr.id_member
Chris@76 1282 FROM {db_prefix}log_group_requests AS lgr
Chris@76 1283 LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lgr.id_member)
Chris@76 1284 WHERE lgr.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 1285 AND mem.id_member IS NULL
Chris@76 1286 GROUP BY lgr.id_member',
Chris@76 1287 'fix_collect' => array(
Chris@76 1288 'index' => 'id_member',
Chris@76 1289 'process' => create_function('$members', '
Chris@76 1290 global $smcFunc;
Chris@76 1291 $smcFunc[\'db_query\'](\'\', "
Chris@76 1292 DELETE FROM {db_prefix}log_group_requests
Chris@76 1293 WHERE id_member IN ({array_int:members})",
Chris@76 1294 array(
Chris@76 1295 \'members\' => $members
Chris@76 1296 )
Chris@76 1297 );
Chris@76 1298 '),
Chris@76 1299 ),
Chris@76 1300 'messages' => array('repair_group_request_missing_member', 'id_member'),
Chris@76 1301 ),
Chris@76 1302 'group_request_missing_group' => array(
Chris@76 1303 'substeps' => array(
Chris@76 1304 'step_size' => 200,
Chris@76 1305 'step_max' => '
Chris@76 1306 SELECT MAX(id_group)
Chris@76 1307 FROM {db_prefix}log_group_requests'
Chris@76 1308 ),
Chris@76 1309 'check_query' => '
Chris@76 1310 SELECT lgr.id_group
Chris@76 1311 FROM {db_prefix}log_group_requests AS lgr
Chris@76 1312 LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = lgr.id_group)
Chris@76 1313 WHERE lgr.id_group BETWEEN {STEP_LOW} AND {STEP_HIGH}
Chris@76 1314 AND mg.id_group IS NULL
Chris@76 1315 GROUP BY lgr.id_group',
Chris@76 1316 'fix_collect' => array(
Chris@76 1317 'index' => 'id_group',
Chris@76 1318 'process' => create_function('$groups', '
Chris@76 1319 global $smcFunc;
Chris@76 1320 $smcFunc[\'db_query\'](\'\', \'
Chris@76 1321 DELETE FROM {db_prefix}log_group_requests
Chris@76 1322 WHERE id_group IN ({array_int:groups})\',
Chris@76 1323 array(
Chris@76 1324 \'groups\' => $groups
Chris@76 1325 )
Chris@76 1326 );
Chris@76 1327 '),
Chris@76 1328 ),
Chris@76 1329 'messages' => array('repair_group_request_missing_group', 'id_group'),
Chris@76 1330 ),
Chris@76 1331 );
Chris@76 1332 }
Chris@76 1333
Chris@76 1334 function findForumErrors($do_fix = false)
Chris@76 1335 {
Chris@76 1336 global $context, $txt, $smcFunc, $errorTests, $db_cache, $db_temp_cache;
Chris@76 1337
Chris@76 1338 // This may take some time...
Chris@76 1339 @set_time_limit(600);
Chris@76 1340
Chris@76 1341 $to_fix = !empty($_SESSION['repairboards_to_fix']) ? $_SESSION['repairboards_to_fix'] : array();
Chris@76 1342 $context['repair_errors'] = isset($_SESSION['repairboards_to_fix2']) ? $_SESSION['repairboards_to_fix2'] : array();
Chris@76 1343
Chris@76 1344 $_GET['step'] = empty($_GET['step']) ? 0 : (int) $_GET['step'];
Chris@76 1345 $_GET['substep'] = empty($_GET['substep']) ? 0 : (int) $_GET['substep'];
Chris@76 1346
Chris@76 1347 // Don't allow the cache to get too full.
Chris@76 1348 $db_temp_cache = $db_cache;
Chris@76 1349 $db_cache = '';
Chris@76 1350
Chris@76 1351 $context['total_steps'] = count($errorTests);
Chris@76 1352
Chris@76 1353 // For all the defined error types do the necessary tests.
Chris@76 1354 $current_step = -1;
Chris@76 1355 $total_queries = 0;
Chris@76 1356 foreach ($errorTests as $error_type => $test)
Chris@76 1357 {
Chris@76 1358 $current_step++;
Chris@76 1359
Chris@76 1360 // Already done this?
Chris@76 1361 if ($_GET['step'] > $current_step)
Chris@76 1362 continue;
Chris@76 1363
Chris@76 1364 // If we're fixing it but it ain't broke why try?
Chris@76 1365 if ($do_fix && !in_array($error_type, $to_fix))
Chris@76 1366 {
Chris@76 1367 $_GET['step']++;
Chris@76 1368 continue;
Chris@76 1369 }
Chris@76 1370
Chris@76 1371 // Has it got substeps?
Chris@76 1372 if (isset($test['substeps']))
Chris@76 1373 {
Chris@76 1374 $step_size = isset($test['substeps']['step_size']) ? $test['substeps']['step_size'] : 100;
Chris@76 1375 $request = $smcFunc['db_query']('',
Chris@76 1376 $test['substeps']['step_max'],
Chris@76 1377 array(
Chris@76 1378 )
Chris@76 1379 );
Chris@76 1380 list ($step_max) = $smcFunc['db_fetch_row']($request);
Chris@76 1381
Chris@76 1382 $total_queries++;
Chris@76 1383 $smcFunc['db_free_result']($request);
Chris@76 1384 }
Chris@76 1385
Chris@76 1386 // We in theory keep doing this... the substeps.
Chris@76 1387 $done = false;
Chris@76 1388 while (!$done)
Chris@76 1389 {
Chris@76 1390 // Make sure there's at least one ID to test.
Chris@76 1391 if (isset($test['substeps']) && empty($step_max))
Chris@76 1392 break;
Chris@76 1393
Chris@76 1394 // What is the testing query (Changes if we are testing or fixing)
Chris@76 1395 if (!$do_fix)
Chris@76 1396 $test_query = 'check_query';
Chris@76 1397 else
Chris@76 1398 $test_query = isset($test['fix_query']) ? 'fix_query' : 'check_query';
Chris@76 1399
Chris@76 1400 // Do the test...
Chris@76 1401 $request = $smcFunc['db_query']('',
Chris@76 1402 isset($test['substeps']) ? strtr($test[$test_query], array('{STEP_LOW}' => $_GET['substep'], '{STEP_HIGH}' => $_GET['substep'] + $step_size - 1)) : $test[$test_query],
Chris@76 1403 array(
Chris@76 1404 )
Chris@76 1405 );
Chris@76 1406 $needs_fix = false;
Chris@76 1407
Chris@76 1408 // Does it need a fix?
Chris@76 1409 if (!empty($test['check_type']) && $test['check_type'] == 'count')
Chris@76 1410 list ($needs_fix) = $smcFunc['db_fetch_row']($request);
Chris@76 1411 else
Chris@76 1412 $needs_fix = $smcFunc['db_num_rows']($request);
Chris@76 1413
Chris@76 1414 $total_queries++;
Chris@76 1415
Chris@76 1416 if ($needs_fix)
Chris@76 1417 {
Chris@76 1418 // What about a message to the user?
Chris@76 1419 if (!$do_fix)
Chris@76 1420 {
Chris@76 1421 // Assume need to fix.
Chris@76 1422 $found_errors = true;
Chris@76 1423
Chris@76 1424 if (isset($test['message']))
Chris@76 1425 $context['repair_errors'][] = $txt[$test['message']];
Chris@76 1426
Chris@76 1427 // One per row!
Chris@76 1428 elseif (isset($test['messages']))
Chris@76 1429 {
Chris@76 1430 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 1431 {
Chris@76 1432 $variables = $test['messages'];
Chris@76 1433 foreach ($variables as $k => $v)
Chris@76 1434 {
Chris@76 1435 if ($k == 0 && isset($txt[$v]))
Chris@76 1436 $variables[$k] = $txt[$v];
Chris@76 1437 elseif ($k > 0 && isset($row[$v]))
Chris@76 1438 $variables[$k] = $row[$v];
Chris@76 1439 }
Chris@76 1440 $context['repair_errors'][] = call_user_func_array('sprintf', $variables);
Chris@76 1441 }
Chris@76 1442 }
Chris@76 1443
Chris@76 1444 // A function to process?
Chris@76 1445 elseif (isset($test['message_function']))
Chris@76 1446 {
Chris@76 1447 // Find out if there are actually errors.
Chris@76 1448 $found_errors = false;
Chris@76 1449 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 1450 $found_errors |= $test['message_function']($row);
Chris@76 1451 }
Chris@76 1452
Chris@76 1453 // Actually have something to fix?
Chris@76 1454 if ($found_errors)
Chris@76 1455 $to_fix[] = $error_type;
Chris@76 1456 }
Chris@76 1457
Chris@76 1458 // We want to fix, we need to fix - so work out what exactly to do!
Chris@76 1459 else
Chris@76 1460 {
Chris@76 1461 // Are we simply getting a collection of ids?
Chris@76 1462 if (isset($test['fix_collect']))
Chris@76 1463 {
Chris@76 1464 $ids = array();
Chris@76 1465 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 1466 $ids[] = $row[$test['fix_collect']['index']];
Chris@76 1467 if (!empty($ids))
Chris@76 1468 {
Chris@76 1469 // Fix it!
Chris@76 1470 $test['fix_collect']['process']($ids);
Chris@76 1471 }
Chris@76 1472 }
Chris@76 1473
Chris@76 1474 // Simply executing a fix it query?
Chris@76 1475 elseif (isset($test['fix_it_query']))
Chris@76 1476 $smcFunc['db_query']('',
Chris@76 1477 $test['fix_it_query'],
Chris@76 1478 array(
Chris@76 1479 )
Chris@76 1480 );
Chris@76 1481
Chris@76 1482 // Do we have some processing to do?
Chris@76 1483 elseif (isset($test['fix_processing']))
Chris@76 1484 {
Chris@76 1485 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 1486 $test['fix_processing']($row);
Chris@76 1487 }
Chris@76 1488
Chris@76 1489 // What about the full set of processing?
Chris@76 1490 elseif (isset($test['fix_full_processing']))
Chris@76 1491 $test['fix_full_processing']($request);
Chris@76 1492
Chris@76 1493 // Do we have other things we need to fix as a result?
Chris@76 1494 if (!empty($test['force_fix']))
Chris@76 1495 {
Chris@76 1496 foreach ($test['force_fix'] as $item)
Chris@76 1497 if (!in_array($item, $to_fix))
Chris@76 1498 $to_fix[] = $item;
Chris@76 1499 }
Chris@76 1500 }
Chris@76 1501 }
Chris@76 1502
Chris@76 1503 // Free the result.
Chris@76 1504 $smcFunc['db_free_result']($request);
Chris@76 1505 // Keep memory down.
Chris@76 1506 $db_cache = '';
Chris@76 1507
Chris@76 1508 // Are we done yet?
Chris@76 1509 if (isset($test['substeps']))
Chris@76 1510 {
Chris@76 1511 $_GET['substep'] += $step_size;
Chris@76 1512 // Not done?
Chris@76 1513 if ($_GET['substep'] <= $step_max)
Chris@76 1514 {
Chris@76 1515 pauseRepairProcess($to_fix, $error_type, $step_max);
Chris@76 1516 }
Chris@76 1517 else
Chris@76 1518 $done = true;
Chris@76 1519 }
Chris@76 1520 else
Chris@76 1521 $done = true;
Chris@76 1522
Chris@76 1523 // Don't allow more than 1000 queries at a time.
Chris@76 1524 if ($total_queries >= 1000)
Chris@76 1525 pauseRepairProcess($to_fix, $error_type, $step_max, true);
Chris@76 1526 }
Chris@76 1527
Chris@76 1528 // Keep going.
Chris@76 1529 $_GET['step']++;
Chris@76 1530 $_GET['substep'] = 0;
Chris@76 1531
Chris@76 1532 $to_fix = array_unique($to_fix);
Chris@76 1533
Chris@76 1534 // If we're doing fixes and this needed a fix and we're all done then don't do it again.
Chris@76 1535 if ($do_fix)
Chris@76 1536 {
Chris@76 1537 $key = array_search($error_type, $to_fix);
Chris@76 1538 if ($key !== false && isset($to_fix[$key]))
Chris@76 1539 unset($to_fix[$key]);
Chris@76 1540 }
Chris@76 1541
Chris@76 1542 // Are we done?
Chris@76 1543 pauseRepairProcess($to_fix, $error_type);
Chris@76 1544 }
Chris@76 1545
Chris@76 1546 // Restore the cache.
Chris@76 1547 $db_cache = $db_temp_cache;
Chris@76 1548
Chris@76 1549 return $to_fix;
Chris@76 1550 }
Chris@76 1551
Chris@76 1552 // Create a salvage area for repair purposes.
Chris@76 1553 function createSalvageArea()
Chris@76 1554 {
Chris@76 1555 global $txt, $language, $salvageBoardID, $salvageCatID, $smcFunc;
Chris@76 1556 static $createOnce = false;
Chris@76 1557
Chris@76 1558 // Have we already created it?
Chris@76 1559 if ($createOnce)
Chris@76 1560 return;
Chris@76 1561 else
Chris@76 1562 $createOnce = true;
Chris@76 1563
Chris@76 1564 // Back to the forum's default language.
Chris@76 1565 loadLanguage('Admin', $language);
Chris@76 1566
Chris@76 1567 // Check to see if a 'Salvage Category' exists, if not => insert one.
Chris@76 1568 $result = $smcFunc['db_query']('', '
Chris@76 1569 SELECT id_cat
Chris@76 1570 FROM {db_prefix}categories
Chris@76 1571 WHERE name = {string:cat_name}
Chris@76 1572 LIMIT 1',
Chris@76 1573 array(
Chris@76 1574 'cat_name' => $txt['salvaged_category_name'],
Chris@76 1575 )
Chris@76 1576 );
Chris@76 1577 if ($smcFunc['db_num_rows']($result) != 0)
Chris@76 1578 list ($salvageCatID) = $smcFunc['db_fetch_row']($result);
Chris@76 1579 $smcFunc['db_free_result']($result);
Chris@76 1580
Chris@76 1581 if (empty($salveageCatID))
Chris@76 1582 {
Chris@76 1583 $smcFunc['db_insert']('',
Chris@76 1584 '{db_prefix}categories',
Chris@76 1585 array('name' => 'string-255', 'cat_order' => 'int'),
Chris@76 1586 array($txt['salvaged_category_name'], -1),
Chris@76 1587 array('id_cat')
Chris@76 1588 );
Chris@76 1589
Chris@76 1590 if ($smcFunc['db_affected_rows']() <= 0)
Chris@76 1591 {
Chris@76 1592 loadLanguage('Admin');
Chris@76 1593 fatal_lang_error('salvaged_category_error', false);
Chris@76 1594 }
Chris@76 1595
Chris@76 1596 $salvageCatID = $smcFunc['db_insert_id']('{db_prefix}categories', 'id_cat');
Chris@76 1597 }
Chris@76 1598
Chris@76 1599 // Check to see if a 'Salvage Board' exists, if not => insert one.
Chris@76 1600 $result = $smcFunc['db_query']('', '
Chris@76 1601 SELECT id_board
Chris@76 1602 FROM {db_prefix}boards
Chris@76 1603 WHERE id_cat = {int:id_cat}
Chris@76 1604 AND name = {string:board_name}
Chris@76 1605 LIMIT 1',
Chris@76 1606 array(
Chris@76 1607 'id_cat' => $salvageCatID,
Chris@76 1608 'board_name' => $txt['salvaged_board_name'],
Chris@76 1609 )
Chris@76 1610 );
Chris@76 1611 if ($smcFunc['db_num_rows']($result) != 0)
Chris@76 1612 list ($salvageBoardID) = $smcFunc['db_fetch_row']($result);
Chris@76 1613 $smcFunc['db_free_result']($result);
Chris@76 1614
Chris@76 1615 if (empty($salvageBoardID))
Chris@76 1616 {
Chris@76 1617 $smcFunc['db_insert']('',
Chris@76 1618 '{db_prefix}boards',
Chris@76 1619 array('name' => 'string-255', 'description' => 'string-255', 'id_cat' => 'int', 'member_groups' => 'string', 'board_order' => 'int', 'redirect' => 'string'),
Chris@76 1620 array($txt['salvaged_board_name'], $txt['salvaged_board_description'], $salvageCatID, '1', -1, ''),
Chris@76 1621 array('id_board')
Chris@76 1622 );
Chris@76 1623
Chris@76 1624 if ($smcFunc['db_affected_rows']() <= 0)
Chris@76 1625 {
Chris@76 1626 loadLanguage('Admin');
Chris@76 1627 fatal_lang_error('salvaged_board_error', false);
Chris@76 1628 }
Chris@76 1629
Chris@76 1630 $salvageBoardID = $smcFunc['db_insert_id']('{db_prefix}boards', 'id_board');
Chris@76 1631 }
Chris@76 1632
Chris@76 1633 $smcFunc['db_query']('alter_table_boards', '
Chris@76 1634 ALTER TABLE {db_prefix}boards
Chris@76 1635 ORDER BY board_order',
Chris@76 1636 array(
Chris@76 1637 )
Chris@76 1638 );
Chris@76 1639
Chris@76 1640 // Restore the user's language.
Chris@76 1641 loadLanguage('Admin');
Chris@76 1642 }
Chris@76 1643
Chris@76 1644 ?>