12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670 |
- <?php
- /**
- * This is here for the "repair any errors" feature in the admin center.
- *
- * Simple Machines Forum (SMF)
- *
- * @package SMF
- * @author Simple Machines http://www.simplemachines.org
- * @copyright 2013 Simple Machines and individual contributors
- * @license http://www.simplemachines.org/about/smf/license.php BSD
- *
- * @version 2.1 Alpha 1
- */
- if (!defined('SMF'))
- die('No direct access...');
- /**
- * Finds or repairs errors in the database to fix possible problems.
- * Requires the admin_forum permission.
- * Calls createSalvageArea() to create a new board, if necesary.
- * Accessed by ?action=admin;area=repairboards.
- *
- * @uses raw_data sub-template.
- */
- function RepairBoards()
- {
- global $txt, $context, $sourcedir, $salvageBoardID;
- isAllowedTo('admin_forum');
- // Try secure more memory.
- setMemoryLimit('128M');
- // Print out the top of the webpage.
- $context['page_title'] = $txt['admin_repair'];
- $context['sub_template'] = 'repair_boards';
- $context[$context['admin_menu_name']]['current_subsection'] = 'general';
- // Load the language file.
- loadLanguage('ManageMaintenance');
- // Make sure the tabs stay nice.
- $context[$context['admin_menu_name']]['tab_data'] = array(
- 'title' => $txt['maintain_title'],
- 'help' => '',
- 'description' => $txt['maintain_info'],
- 'tabs' => array(),
- );
- // Start displaying errors without fixing them.
- if (isset($_GET['fixErrors']))
- checkSession('get');
- // Will want this.
- loadForumTests();
- // Giant if/else. The first displays the forum errors if a variable is not set and asks
- // if you would like to continue, the other fixes the errors.
- if (!isset($_GET['fixErrors']))
- {
- $context['error_search'] = true;
- $context['repair_errors'] = array();
- $context['to_fix'] = findForumErrors();
- if (!empty($context['to_fix']))
- {
- $_SESSION['repairboards_to_fix'] = $context['to_fix'];
- $_SESSION['repairboards_to_fix2'] = null;
- if (empty($context['repair_errors']))
- $context['repair_errors'][] = '???';
- }
- }
- else
- {
- $context['error_search'] = false;
- $context['to_fix'] = isset($_SESSION['repairboards_to_fix']) ? $_SESSION['repairboards_to_fix'] : array();
- require_once($sourcedir . '/Subs-Boards.php');
- // Actually do the fix.
- findForumErrors(true);
- // Note that we've changed everything possible ;)
- updateSettings(array(
- 'settings_updated' => time(),
- ));
- updateStats('message');
- updateStats('topic');
- updateSettings(array(
- 'calendar_updated' => time(),
- ));
- if (!empty($salvageBoardID))
- {
- $context['redirect_to_recount'] = true;
- }
- $_SESSION['repairboards_to_fix'] = null;
- $_SESSION['repairboards_to_fix2'] = null;
- }
- }
- /**
- * Show the not_done template to avoid CGI timeouts and similar.
- * Called when 3 or more seconds have passed while searching for errors.
- * If max_substep is set, $_GET['substep'] / $max_substep is the percent
- * done this step is.
- *
- * @param array $to_fix
- * @param string $current_step_description
- * @param int $max_substep = none
- * @param force $force = false
- */
- function pauseRepairProcess($to_fix, $current_step_description, $max_substep = 0, $force = false)
- {
- global $context, $txt, $time_start, $db_temp_cache, $db_cache;
- // More time, I need more time!
- @set_time_limit(600);
- if (function_exists('apache_reset_timeout'))
- @apache_reset_timeout();
- // Errr, wait. How much time has this taken already?
- if (!$force && time() - array_sum(explode(' ', $time_start)) < 3)
- return;
- // Restore the query cache if interested.
- if (!empty($db_temp_cache))
- $db_cache = $db_temp_cache;
- $context['continue_get_data'] = '?action=admin;area=repairboards' . (isset($_GET['fixErrors']) ? ';fixErrors' : '') . ';step=' . $_GET['step'] . ';substep=' . $_GET['substep'] . ';' . $context['session_var'] . '=' . $context['session_id'];
- $context['page_title'] = $txt['not_done_title'];
- $context['continue_post_data'] = '';
- $context['continue_countdown'] = '2';
- $context['sub_template'] = 'not_done';
- // Change these two if more steps are added!
- if (empty($max_substep))
- $context['continue_percent'] = round(($_GET['step'] * 100) / $context['total_steps']);
- else
- $context['continue_percent'] = round((($_GET['step'] + ($_GET['substep'] / $max_substep)) * 100) / $context['total_steps']);
- // Never more than 100%!
- $context['continue_percent'] = min($context['continue_percent'], 100);
- // What about substeps?
- $context['substep_enabled'] = $max_substep != 0;
- $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));
- $context['substep_continue_percent'] = $max_substep == 0 ? 0 : round(($_GET['substep'] * 100) / $max_substep, 1);
- $_SESSION['repairboards_to_fix'] = $to_fix;
- $_SESSION['repairboards_to_fix2'] = $context['repair_errors'];
- obExit();
- }
- /**
- * Load up all the tests we might want to do ;)
- */
- function loadForumTests()
- {
- global $errorTests;
- /* Here this array is defined like so:
- string check_query: Query to be executed when testing if errors exist.
- string check_type: Defines how it knows if a problem was found. If set to count looks for the first variable from check_query
- being > 0. Anything else it looks for some results. If not set assumes you want results.
- string fix_it_query: When doing fixes if an error was detected this query is executed to "fix" it.
- string fix_query: The query to execute to get data when doing a fix. If not set check_query is used again.
- array fix_collect: This array is used if the fix is basically gathering all broken ids and then doing something with it.
- - string index: The value returned from the main query and passed to the processing function.
- - process: A function passed an array of ids to execute the fix on.
- function fix_processing:
- Function called for each row returned from fix_query to execute whatever fixes are required.
- function fix_full_processing:
- As above but does the while loop and everything itself - except the freeing.
- array force_fix: If this is set then the error types included within this array will also be assumed broken.
- Note: At the moment only processes these if they occur after the primary error in the array.
- */
- // This great array contains all of our error checks, fixes, etc etc etc.
- $errorTests = array(
- // Make a last-ditch-effort check to get rid of topics with zeros..
- 'zero_topics' => array(
- 'check_query' => '
- SELECT COUNT(*)
- FROM {db_prefix}topics
- WHERE id_topic = 0',
- 'check_type' => 'count',
- 'fix_it_query' => '
- UPDATE {db_prefix}topics
- SET id_topic = NULL
- WHERE id_topic = 0',
- 'message' => 'repair_zero_ids',
- ),
- // ... and same with messages.
- 'zero_messages' => array(
- 'check_query' => '
- SELECT COUNT(*)
- FROM {db_prefix}messages
- WHERE id_msg = 0',
- 'check_type' => 'count',
- 'fix_it_query' => '
- UPDATE {db_prefix}messages
- SET id_msg = NULL
- WHERE id_msg = 0',
- 'message' => 'repair_zero_ids',
- ),
- // Find messages that don't have existing topics.
- 'missing_topics' => array(
- 'substeps' => array(
- 'step_size' => 1000,
- 'step_max' => '
- SELECT MAX(id_topic)
- FROM {db_prefix}messages'
- ),
- 'check_query' => '
- SELECT m.id_topic, m.id_msg
- FROM {db_prefix}messages AS m
- LEFT JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
- WHERE m.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
- AND t.id_topic IS NULL
- ORDER BY m.id_topic, m.id_msg',
- 'fix_query' => '
- SELECT
- m.id_board, m.id_topic, MIN(m.id_msg) AS myid_first_msg, MAX(m.id_msg) AS myid_last_msg,
- COUNT(*) - 1 AS my_num_replies
- FROM {db_prefix}messages AS m
- LEFT JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
- WHERE t.id_topic IS NULL
- GROUP BY m.id_topic, m.id_board',
- '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 = {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'),
- ),
- // Find topics with no messages.
- 'missing_messages' => array(
- 'substeps' => array(
- 'step_size' => 1000,
- 'step_max' => '
- SELECT MAX(id_topic)
- FROM {db_prefix}topics'
- ),
- 'check_query' => '
- SELECT t.id_topic, COUNT(m.id_msg) AS num_msg
- FROM {db_prefix}topics AS t
- LEFT JOIN {db_prefix}messages AS m ON (m.id_topic = t.id_topic)
- WHERE t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
- GROUP BY t.id_topic
- HAVING COUNT(m.id_msg) = 0',
- // Remove all topics that have zero messages in the messages table.
- 'fix_collect' => array(
- 'index' => 'id_topic',
- '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'),
- ),
- 'polls_missing_topics' => array(
- 'substeps' => array(
- 'step_size' => 500,
- 'step_max' => '
- SELECT MAX(id_poll)
- FROM {db_prefix}polls'
- ),
- 'check_query' => '
- SELECT p.id_poll, p.id_member, p.poster_name, t.id_board
- FROM {db_prefix}polls AS p
- LEFT JOIN {db_prefix}topics AS t ON (t.id_poll = p.id_poll)
- WHERE p.id_poll BETWEEN {STEP_LOW} AND {STEP_HIGH}
- AND t.id_poll IS NULL',
- '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 = {int:newTopicID}, id_board = {int:id_board}
- WHERE id_msg = $newMessageID\',
- array(
- \'id_board\' => $row[\'id_board\'],
- \'newTopicID\' => $newTopicID,
- )
- );
- updateStats(\'subject\', $newTopicID, $txt[\'salvaged_poll_topic_name\']);
- '),
- 'force_fix' => array('stats_topics'),
- 'messages' => array('repair_polls_missing_topics', 'id_poll', 'id_topic'),
- ),
- 'stats_topics' => array(
- 'substeps' => array(
- 'step_size' => 200,
- 'step_max' => '
- SELECT MAX(id_topic)
- FROM {db_prefix}topics'
- ),
- 'check_query' => '
- SELECT
- t.id_topic, t.id_first_msg, t.id_last_msg,
- CASE WHEN MIN(ma.id_msg) > 0 THEN
- CASE WHEN MIN(mu.id_msg) > 0 THEN
- CASE WHEN MIN(mu.id_msg) < MIN(ma.id_msg) THEN MIN(mu.id_msg) ELSE MIN(ma.id_msg) END ELSE
- MIN(ma.id_msg) END ELSE
- MIN(mu.id_msg) END AS myid_first_msg,
- CASE WHEN MAX(ma.id_msg) > 0 THEN MAX(ma.id_msg) ELSE MIN(mu.id_msg) END AS myid_last_msg,
- t.approved, mf.approved, mf.approved AS firstmsg_approved
- FROM {db_prefix}topics AS t
- LEFT JOIN {db_prefix}messages AS ma ON (ma.id_topic = t.id_topic AND ma.approved = 1)
- LEFT JOIN {db_prefix}messages AS mu ON (mu.id_topic = t.id_topic AND mu.approved = 0)
- LEFT JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)
- WHERE t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
- GROUP BY t.id_topic, t.id_first_msg, t.id_last_msg, t.approved, mf.approved
- ORDER BY t.id_topic',
- '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 = {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' => 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.
- 'stats_topics2' => array(
- 'substeps' => array(
- 'step_size' => 300,
- 'step_max' => '
- SELECT MAX(id_topic)
- FROM {db_prefix}topics'
- ),
- 'check_query' => '
- SELECT
- t.id_topic, t.num_replies, mf.approved,
- 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
- FROM {db_prefix}topics AS t
- LEFT JOIN {db_prefix}messages AS ma ON (ma.id_topic = t.id_topic AND ma.approved = 1)
- LEFT JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)
- WHERE t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
- GROUP BY t.id_topic, t.num_replies, mf.approved
- ORDER BY t.id_topic',
- '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 = {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' => 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.
- 'stats_topics3' => array(
- 'substeps' => array(
- 'step_size' => 1000,
- 'step_max' => '
- SELECT MAX(id_topic)
- FROM {db_prefix}topics'
- ),
- 'check_query' => '
- SELECT
- t.id_topic, t.unapproved_posts, COUNT(mu.id_msg) AS my_unapproved_posts
- FROM {db_prefix}topics AS t
- LEFT JOIN {db_prefix}messages AS mu ON (mu.id_topic = t.id_topic AND mu.approved = 0)
- WHERE t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
- GROUP BY t.id_topic, t.unapproved_posts
- HAVING unapproved_posts != COUNT(mu.id_msg)
- ORDER BY t.id_topic',
- '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 = {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'),
- ),
- // Find topics with nonexistent boards.
- 'missing_boards' => array(
- 'substeps' => array(
- 'step_size' => 1000,
- 'step_max' => '
- SELECT MAX(id_topic)
- FROM {db_prefix}topics'
- ),
- 'check_query' => '
- SELECT t.id_topic, t.id_board
- FROM {db_prefix}topics AS t
- LEFT JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
- WHERE b.id_board IS NULL
- AND t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
- ORDER BY t.id_board, t.id_topic',
- 'fix_query' => '
- SELECT t.id_board, COUNT(*) AS my_num_topics, COUNT(m.id_msg) AS my_num_posts
- FROM {db_prefix}topics AS t
- LEFT JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
- LEFT JOIN {db_prefix}messages AS m ON (m.id_topic = t.id_topic)
- WHERE b.id_board IS NULL
- AND t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
- GROUP BY t.id_board',
- '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 = {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'),
- ),
- // Find boards with nonexistent categories.
- 'missing_categories' => array(
- 'check_query' => '
- SELECT b.id_board, b.id_cat
- FROM {db_prefix}boards AS b
- LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)
- WHERE c.id_cat IS NULL
- ORDER BY b.id_cat, b.id_board',
- 'fix_collect' => array(
- 'index' => 'id_cat',
- 'process' => create_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'),
- ),
- // Find messages with nonexistent members.
- 'missing_posters' => array(
- 'substeps' => array(
- 'step_size' => 2000,
- 'step_max' => '
- SELECT MAX(id_msg)
- FROM {db_prefix}messages'
- ),
- 'check_query' => '
- SELECT m.id_msg, m.id_member
- FROM {db_prefix}messages AS m
- LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
- WHERE mem.id_member IS NULL
- AND m.id_member != 0
- AND m.id_msg BETWEEN {STEP_LOW} AND {STEP_HIGH}
- ORDER BY m.id_msg',
- // Last step-make sure all non-guest posters still exist.
- 'fix_collect' => array(
- 'index' => 'id_msg',
- 'process' => create_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'),
- ),
- // Find boards with nonexistent parents.
- 'missing_parents' => array(
- 'check_query' => '
- SELECT b.id_board, b.id_parent
- FROM {db_prefix}boards AS b
- LEFT JOIN {db_prefix}boards AS p ON (p.id_board = b.id_parent)
- WHERE b.id_parent != 0
- AND (p.id_board IS NULL OR p.id_board = b.id_board)
- ORDER BY b.id_parent, b.id_board',
- 'fix_collect' => array(
- 'index' => 'id_parent',
- 'process' => create_function('$parents', '
- global $smcFunc, $salvageBoardID, $salvageCatID;
- createSalvageArea();
- $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'),
- ),
- 'missing_polls' => array(
- 'substeps' => array(
- 'step_size' => 500,
- 'step_max' => '
- SELECT MAX(id_poll)
- FROM {db_prefix}topics'
- ),
- 'check_query' => '
- SELECT t.id_poll, t.id_topic
- FROM {db_prefix}topics AS t
- LEFT JOIN {db_prefix}polls AS p ON (p.id_poll = t.id_poll)
- WHERE t.id_poll != 0
- AND t.id_poll BETWEEN {STEP_LOW} AND {STEP_HIGH}
- AND p.id_poll IS NULL',
- 'fix_collect' => array(
- 'index' => 'id_poll',
- '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'),
- ),
- 'missing_calendar_topics' => array(
- 'substeps' => array(
- 'step_size' => 1000,
- 'step_max' => '
- SELECT MAX(id_topic)
- FROM {db_prefix}calendar'
- ),
- 'check_query' => '
- SELECT cal.id_topic, cal.id_event
- FROM {db_prefix}calendar AS cal
- LEFT JOIN {db_prefix}topics AS t ON (t.id_topic = cal.id_topic)
- WHERE cal.id_topic != 0
- AND cal.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
- AND t.id_topic IS NULL
- ORDER BY cal.id_topic',
- 'fix_collect' => array(
- 'index' => 'id_topic',
- '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'),
- ),
- 'missing_log_topics' => array(
- 'substeps' => array(
- 'step_size' => 150,
- 'step_max' => '
- SELECT MAX(id_member)
- FROM {db_prefix}log_topics'
- ),
- 'check_query' => '
- SELECT lt.id_topic
- FROM {db_prefix}log_topics AS lt
- LEFT JOIN {db_prefix}topics AS t ON (t.id_topic = lt.id_topic)
- WHERE t.id_topic IS NULL
- AND lt.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}',
- 'fix_collect' => array(
- 'index' => 'id_topic',
- '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'),
- ),
- 'missing_log_topics_members' => array(
- 'substeps' => array(
- 'step_size' => 150,
- 'step_max' => '
- SELECT MAX(id_member)
- FROM {db_prefix}log_topics'
- ),
- 'check_query' => '
- SELECT lt.id_member
- FROM {db_prefix}log_topics AS lt
- LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lt.id_member)
- WHERE mem.id_member IS NULL
- AND lt.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
- GROUP BY lt.id_member',
- 'fix_collect' => array(
- 'index' => 'id_member',
- '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'),
- ),
- 'missing_log_boards' => array(
- 'substeps' => array(
- 'step_size' => 500,
- 'step_max' => '
- SELECT MAX(id_member)
- FROM {db_prefix}log_boards'
- ),
- 'check_query' => '
- SELECT lb.id_board
- FROM {db_prefix}log_boards AS lb
- LEFT JOIN {db_prefix}boards AS b ON (b.id_board = lb.id_board)
- WHERE b.id_board IS NULL
- AND lb.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
- GROUP BY lb.id_board',
- 'fix_collect' => array(
- 'index' => 'id_board',
- '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'),
- ),
- 'missing_log_boards_members' => array(
- 'substeps' => array(
- 'step_size' => 500,
- 'step_max' => '
- SELECT MAX(id_member)
- FROM {db_prefix}log_boards'
- ),
- 'check_query' => '
- SELECT lb.id_member
- FROM {db_prefix}log_boards AS lb
- LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lb.id_member)
- WHERE mem.id_member IS NULL
- AND lb.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
- GROUP BY lb.id_member',
- 'fix_collect' => array(
- 'index' => 'id_member',
- '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'),
- ),
- 'missing_log_mark_read' => array(
- 'substeps' => array(
- 'step_size' => 500,
- 'step_max' => '
- SELECT MAX(id_member)
- FROM {db_prefix}log_mark_read'
- ),
- 'check_query' => '
- SELECT lmr.id_board
- FROM {db_prefix}log_mark_read AS lmr
- LEFT JOIN {db_prefix}boards AS b ON (b.id_board = lmr.id_board)
- WHERE b.id_board IS NULL
- AND lmr.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
- GROUP BY lmr.id_board',
- 'fix_collect' => array(
- 'index' => 'id_board',
- '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'),
- ),
- 'missing_log_mark_read_members' => array(
- 'substeps' => array(
- 'step_size' => 500,
- 'step_max' => '
- SELECT MAX(id_member)
- FROM {db_prefix}log_mark_read'
- ),
- 'check_query' => '
- SELECT lmr.id_member
- FROM {db_prefix}log_mark_read AS lmr
- LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lmr.id_member)
- WHERE mem.id_member IS NULL
- AND lmr.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
- GROUP BY lmr.id_member',
- 'fix_collect' => array(
- 'index' => 'id_member',
- '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'),
- ),
- 'missing_pms' => array(
- 'substeps' => array(
- 'step_size' => 500,
- 'step_max' => '
- SELECT MAX(id_pm)
- FROM {db_prefix}pm_recipients'
- ),
- 'check_query' => '
- SELECT pmr.id_pm
- FROM {db_prefix}pm_recipients AS pmr
- LEFT JOIN {db_prefix}personal_messages AS pm ON (pm.id_pm = pmr.id_pm)
- WHERE pm.id_pm IS NULL
- AND pmr.id_pm BETWEEN {STEP_LOW} AND {STEP_HIGH}
- GROUP BY pmr.id_pm',
- 'fix_collect' => array(
- 'index' => 'id_pm',
- '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'),
- ),
- 'missing_recipients' => array(
- 'substeps' => array(
- 'step_size' => 500,
- 'step_max' => '
- SELECT MAX(id_member)
- FROM {db_prefix}pm_recipients'
- ),
- 'check_query' => '
- SELECT pmr.id_member
- FROM {db_prefix}pm_recipients AS pmr
- LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = pmr.id_member)
- WHERE pmr.id_member != 0
- AND pmr.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
- AND mem.id_member IS NULL
- GROUP BY pmr.id_member',
- 'fix_collect' => array(
- 'index' => 'id_member',
- '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'),
- ),
- 'missing_senders' => array(
- 'substeps' => array(
- 'step_size' => 500,
- 'step_max' => '
- SELECT MAX(id_pm)
- FROM {db_prefix}personal_messages'
- ),
- 'check_query' => '
- SELECT pm.id_pm, pm.id_member_from
- FROM {db_prefix}personal_messages AS pm
- LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = pm.id_member_from)
- WHERE pm.id_member_from != 0
- AND pm.id_pm BETWEEN {STEP_LOW} AND {STEP_HIGH}
- AND mem.id_member IS NULL',
- 'fix_collect' => array(
- 'index' => 'id_pm',
- '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'),
- ),
- 'missing_notify_members' => array(
- 'substeps' => array(
- 'step_size' => 500,
- 'step_max' => '
- SELECT MAX(id_member)
- FROM {db_prefix}log_notify'
- ),
- 'check_query' => '
- SELECT ln.id_member
- FROM {db_prefix}log_notify AS ln
- LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = ln.id_member)
- WHERE ln.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
- AND mem.id_member IS NULL
- GROUP BY ln.id_member',
- 'fix_collect' => array(
- 'index' => 'id_member',
- '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'),
- ),
- 'missing_cached_subject' => array(
- 'substeps' => array(
- 'step_size' => 100,
- 'step_max' => '
- SELECT MAX(id_topic)
- FROM {db_prefix}topics'
- ),
- 'check_query' => '
- SELECT t.id_topic, fm.subject
- FROM {db_prefix}topics AS t
- INNER JOIN {db_prefix}messages AS fm ON (fm.id_msg = t.id_first_msg)
- LEFT JOIN {db_prefix}log_search_subjects AS lss ON (lss.id_topic = t.id_topic)
- WHERE t.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
- AND lss.id_topic IS NULL',
- '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(
- 'substeps' => array(
- 'step_size' => 50,
- 'step_max' => '
- SELECT MAX(id_topic)
- FROM {db_prefix}log_search_subjects'
- ),
- 'check_query' => '
- SELECT lss.id_topic, lss.word
- FROM {db_prefix}log_search_subjects AS lss
- LEFT JOIN {db_prefix}topics AS t ON (t.id_topic = lss.id_topic)
- WHERE lss.id_topic BETWEEN {STEP_LOW} AND {STEP_HIGH}
- AND t.id_topic IS NULL',
- 'fix_collect' => array(
- 'index' => 'id_topic',
- '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'),
- ),
- 'missing_member_vote' => array(
- 'substeps' => array(
- 'step_size' => 500,
- 'step_max' => '
- SELECT MAX(id_member)
- FROM {db_prefix}log_polls'
- ),
- 'check_query' => '
- SELECT lp.id_poll, lp.id_member
- FROM {db_prefix}log_polls AS lp
- LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lp.id_member)
- WHERE lp.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
- AND lp.id_member > 0
- AND mem.id_member IS NULL',
- 'fix_collect' => array(
- 'index' => 'id_member',
- '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'),
- ),
- 'missing_log_poll_vote' => array(
- 'substeps' => array(
- 'step_size' => 500,
- 'step_max' => '
- SELECT MAX(id_poll)
- FROM {db_prefix}log_polls'
- ),
- 'check_query' => '
- SELECT lp.id_poll, lp.id_member
- FROM {db_prefix}log_polls AS lp
- LEFT JOIN {db_prefix}polls AS p ON (p.id_poll = lp.id_poll)
- WHERE lp.id_poll BETWEEN {STEP_LOW} AND {STEP_HIGH}
- AND p.id_poll IS NULL',
- 'fix_collect' => array(
- 'index' => 'id_poll',
- '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'),
- ),
- 'report_missing_comments' => array(
- 'substeps' => array(
- 'step_size' => 500,
- 'step_max' => '
- SELECT MAX(id_report)
- FROM {db_prefix}log_reported'
- ),
- 'check_query' => '
- SELECT lr.id_report, lr.subject
- FROM {db_prefix}log_reported AS lr
- LEFT JOIN {db_prefix}log_reported_comments AS lrc ON (lrc.id_report = lr.id_report)
- WHERE lr.id_report BETWEEN {STEP_LOW} AND {STEP_HIGH}
- AND lrc.id_report IS NULL',
- 'fix_collect' => array(
- 'index' => 'id_report',
- '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'),
- ),
- 'comments_missing_report' => array(
- 'substeps' => array(
- 'step_size' => 200,
- 'step_max' => '
- SELECT MAX(id_report)
- FROM {db_prefix}log_reported_comments'
- ),
- 'check_query' => '
- SELECT lrc.id_report, lrc.membername
- FROM {db_prefix}log_reported_comments AS lrc
- LEFT JOIN {db_prefix}log_reported AS lr ON (lr.id_report = lrc.id_report)
- WHERE lrc.id_report BETWEEN {STEP_LOW} AND {STEP_HIGH}
- AND lr.id_report IS NULL',
- 'fix_collect' => array(
- 'index' => 'id_report',
- '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'),
- ),
- 'group_request_missing_member' => array(
- 'substeps' => array(
- 'step_size' => 200,
- 'step_max' => '
- SELECT MAX(id_member)
- FROM {db_prefix}log_group_requests'
- ),
- 'check_query' => '
- SELECT lgr.id_member
- FROM {db_prefix}log_group_requests AS lgr
- LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lgr.id_member)
- WHERE lgr.id_member BETWEEN {STEP_LOW} AND {STEP_HIGH}
- AND mem.id_member IS NULL
- GROUP BY lgr.id_member',
- 'fix_collect' => array(
- 'index' => 'id_member',
- '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'),
- ),
- 'group_request_missing_group' => array(
- 'substeps' => array(
- 'step_size' => 200,
- 'step_max' => '
- SELECT MAX(id_group)
- FROM {db_prefix}log_group_requests'
- ),
- 'check_query' => '
- SELECT lgr.id_group
- FROM {db_prefix}log_group_requests AS lgr
- LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = lgr.id_group)
- WHERE lgr.id_group BETWEEN {STEP_LOW} AND {STEP_HIGH}
- AND mg.id_group IS NULL
- GROUP BY lgr.id_group',
- 'fix_collect' => array(
- 'index' => 'id_group',
- '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'),
- ),
- );
- }
- /**
- * Checks for errors in steps, until 5 seconds have passed.
- * It keeps track of the errors it did find, so that the actual repair
- * won't have to recheck everything.
- *
- * @param $do_fix
- * @return array, the errors found.
- */
- function findForumErrors($do_fix = false)
- {
- global $context, $txt, $smcFunc, $errorTests, $db_cache, $db_temp_cache;
- // This may take some time...
- @set_time_limit(600);
- $to_fix = !empty($_SESSION['repairboards_to_fix']) ? $_SESSION['repairboards_to_fix'] : array();
- $context['repair_errors'] = isset($_SESSION['repairboards_to_fix2']) ? $_SESSION['repairboards_to_fix2'] : array();
- $_GET['step'] = empty($_GET['step']) ? 0 : (int) $_GET['step'];
- $_GET['substep'] = empty($_GET['substep']) ? 0 : (int) $_GET['substep'];
- // Don't allow the cache to get too full.
- $db_temp_cache = $db_cache;
- $db_cache = '';
- $context['total_steps'] = count($errorTests);
- // For all the defined error types do the necessary tests.
- $current_step = -1;
- $total_queries = 0;
- foreach ($errorTests as $error_type => $test)
- {
- $current_step++;
- // Already done this?
- if ($_GET['step'] > $current_step)
- continue;
- // If we're fixing it but it ain't broke why try?
- if ($do_fix && !in_array($error_type, $to_fix))
- {
- $_GET['step']++;
- continue;
- }
- // Has it got substeps?
- if (isset($test['substeps']))
- {
- $step_size = isset($test['substeps']['step_size']) ? $test['substeps']['step_size'] : 100;
- $request = $smcFunc['db_query']('',
- $test['substeps']['step_max'],
- array(
- )
- );
- list ($step_max) = $smcFunc['db_fetch_row']($request);
- $total_queries++;
- $smcFunc['db_free_result']($request);
- }
- // We in theory keep doing this... the substeps.
- $done = false;
- while (!$done)
- {
- // Make sure there's at least one ID to test.
- if (isset($test['substeps']) && empty($step_max))
- break;
- // What is the testing query (Changes if we are testing or fixing)
- if (!$do_fix)
- $test_query = 'check_query';
- else
- $test_query = isset($test['fix_query']) ? 'fix_query' : 'check_query';
- // Do the test...
- $request = $smcFunc['db_query']('',
- isset($test['substeps']) ? strtr($test[$test_query], array('{STEP_LOW}' => $_GET['substep'], '{STEP_HIGH}' => $_GET['substep'] + $step_size - 1)) : $test[$test_query],
- array(
- )
- );
- $needs_fix = false;
- // Does it need a fix?
- if (!empty($test['check_type']) && $test['check_type'] == 'count')
- list ($needs_fix) = $smcFunc['db_fetch_row']($request);
- else
- $needs_fix = $smcFunc['db_num_rows']($request);
- $total_queries++;
- if ($needs_fix)
- {
- // What about a message to the user?
- if (!$do_fix)
- {
- // Assume need to fix.
- $found_errors = true;
- if (isset($test['message']))
- $context['repair_errors'][] = $txt[$test['message']];
- // One per row!
- elseif (isset($test['messages']))
- {
- while ($row = $smcFunc['db_fetch_assoc']($request))
- {
- $variables = $test['messages'];
- foreach ($variables as $k => $v)
- {
- if ($k == 0 && isset($txt[$v]))
- $variables[$k] = $txt[$v];
- elseif ($k > 0 && isset($row[$v]))
- $variables[$k] = $row[$v];
- }
- $context['repair_errors'][] = call_user_func_array('sprintf', $variables);
- }
- }
- // A function to process?
- elseif (isset($test['message_function']))
- {
- // Find out if there are actually errors.
- $found_errors = false;
- while ($row = $smcFunc['db_fetch_assoc']($request))
- $found_errors |= $test['message_function']($row);
- }
- // Actually have something to fix?
- if ($found_errors)
- $to_fix[] = $error_type;
- }
- // We want to fix, we need to fix - so work out what exactly to do!
- else
- {
- // Are we simply getting a collection of ids?
- if (isset($test['fix_collect']))
- {
- $ids = array();
- while ($row = $smcFunc['db_fetch_assoc']($request))
- $ids[] = $row[$test['fix_collect']['index']];
- if (!empty($ids))
- {
- // Fix it!
- $test['fix_collect']['process']($ids);
- }
- }
- // Simply executing a fix it query?
- elseif (isset($test['fix_it_query']))
- $smcFunc['db_query']('',
- $test['fix_it_query'],
- array(
- )
- );
- // Do we have some processing to do?
- elseif (isset($test['fix_processing']))
- {
- while ($row = $smcFunc['db_fetch_assoc']($request))
- $test['fix_processing']($row);
- }
- // What about the full set of processing?
- elseif (isset($test['fix_full_processing']))
- $test['fix_full_processing']($request);
- // Do we have other things we need to fix as a result?
- if (!empty($test['force_fix']))
- {
- foreach ($test['force_fix'] as $item)
- if (!in_array($item, $to_fix))
- $to_fix[] = $item;
- }
- }
- }
- // Free the result.
- $smcFunc['db_free_result']($request);
- // Keep memory down.
- $db_cache = '';
- // Are we done yet?
- if (isset($test['substeps']))
- {
- $_GET['substep'] += $step_size;
- // Not done?
- if ($_GET['substep'] <= $step_max)
- {
- pauseRepairProcess($to_fix, $error_type, $step_max);
- }
- else
- $done = true;
- }
- else
- $done = true;
- // Don't allow more than 1000 queries at a time.
- if ($total_queries >= 1000)
- pauseRepairProcess($to_fix, $error_type, $step_max, true);
- }
- // Keep going.
- $_GET['step']++;
- $_GET['substep'] = 0;
- $to_fix = array_unique($to_fix);
- // If we're doing fixes and this needed a fix and we're all done then don't do it again.
- if ($do_fix)
- {
- $key = array_search($error_type, $to_fix);
- if ($key !== false && isset($to_fix[$key]))
- unset($to_fix[$key]);
- }
- // Are we done?
- pauseRepairProcess($to_fix, $error_type);
- }
- // Restore the cache.
- $db_cache = $db_temp_cache;
- return $to_fix;
- }
- /**
- * Create a salvage area for repair purposes, if one doesn't already exist.
- * Uses the forum's default language, and checks based on that name.
- */
- function createSalvageArea()
- {
- global $txt, $language, $salvageBoardID, $salvageCatID, $smcFunc;
- static $createOnce = false;
- // Have we already created it?
- if ($createOnce)
- return;
- else
- $createOnce = true;
- // Back to the forum's default language.
- loadLanguage('Admin', $language);
- // Check to see if a 'Salvage Category' exists, if not => insert one.
- $result = $smcFunc['db_query']('', '
- SELECT id_cat
- FROM {db_prefix}categories
- WHERE name = {string:cat_name}
- LIMIT 1',
- array(
- 'cat_name' => $txt['salvaged_category_name'],
- )
- );
- if ($smcFunc['db_num_rows']($result) != 0)
- list ($salvageCatID) = $smcFunc['db_fetch_row']($result);
- $smcFunc['db_free_result']($result);
- if (empty($salvageCatID))
- {
- $smcFunc['db_insert']('',
- '{db_prefix}categories',
- array('name' => 'string-255', 'cat_order' => 'int'),
- array($txt['salvaged_category_name'], -1),
- array('id_cat')
- );
- if ($smcFunc['db_affected_rows']() <= 0)
- {
- loadLanguage('Admin');
- fatal_lang_error('salvaged_category_error', false);
- }
- $salvageCatID = $smcFunc['db_insert_id']('{db_prefix}categories', 'id_cat');
- }
- // Check to see if a 'Salvage Board' exists, if not => insert one.
- $result = $smcFunc['db_query']('', '
- SELECT id_board
- FROM {db_prefix}boards
- WHERE id_cat = {int:id_cat}
- AND name = {string:board_name}
- LIMIT 1',
- array(
- 'id_cat' => $salvageCatID,
- 'board_name' => $txt['salvaged_board_name'],
- )
- );
- if ($smcFunc['db_num_rows']($result) != 0)
- list ($salvageBoardID) = $smcFunc['db_fetch_row']($result);
- $smcFunc['db_free_result']($result);
- if (empty($salvageBoardID))
- {
- $smcFunc['db_insert']('',
- '{db_prefix}boards',
- array('name' => 'string-255', 'description' => 'string-255', 'id_cat' => 'int', 'member_groups' => 'string', 'board_order' => 'int', 'redirect' => 'string'),
- array($txt['salvaged_board_name'], $txt['salvaged_board_description'], $salvageCatID, '1', -1, ''),
- array('id_board')
- );
- if ($smcFunc['db_affected_rows']() <= 0)
- {
- loadLanguage('Admin');
- fatal_lang_error('salvaged_board_error', false);
- }
- $salvageBoardID = $smcFunc['db_insert_id']('{db_prefix}boards', 'id_board');
- }
- $smcFunc['db_query']('alter_table_boards', '
- ALTER TABLE {db_prefix}boards
- ORDER BY board_order',
- array(
- )
- );
- // Restore the user's language.
- loadLanguage('Admin');
- }
- ?>
|