PageRenderTime 46ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/qa-include/app/recalc.php

http://github.com/q2a/question2answer
PHP | 809 lines | 544 code | 176 blank | 89 comment | 68 complexity | 25ca7f79a3f150147a1e33150e83d681 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /*
  3. Question2Answer by Gideon Greenspan and contributors
  4. http://www.question2answer.org/
  5. Description: Managing database recalculations (clean-up operations) and status messages
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. More about this license: http://www.question2answer.org/license.php
  15. */
  16. /*
  17. A full list of redundant (non-normal) information in the database that can be recalculated:
  18. Recalculated in doreindexcontent:
  19. ================================
  20. ^titlewords (all): index of words in titles of posts
  21. ^contentwords (all): index of words in content of posts
  22. ^tagwords (all): index of words in tags of posts (a tag can contain multiple words)
  23. ^posttags (all): index tags of posts
  24. ^words (all): list of words used for indexes
  25. ^options (title=cache_*): cached values for various things (e.g. counting questions)
  26. Recalculated in dorecountposts:
  27. ==============================
  28. ^posts (upvotes, downvotes, netvotes, hotness, acount, amaxvotes, flagcount): number of votes, hotness, answers, answer votes, flags
  29. Recalculated in dorecalcpoints:
  30. ===============================
  31. ^userpoints (all except bonus): points calculation for all users
  32. ^options (title=cache_userpointscount):
  33. Recalculated in dorecalccategories:
  34. ===================================
  35. ^posts (categoryid): assign to answers and comments based on their antecedent question
  36. ^posts (catidpath1, catidpath2, catidpath3): hierarchical path to category ids (requires QA_CATEGORY_DEPTH=4)
  37. ^categories (qcount): number of (visible) questions in each category
  38. ^categories (backpath): full (backwards) path of slugs to that category
  39. Recalculated in dorebuildupdates:
  40. =================================
  41. ^sharedevents (all): per-entity event streams (see big comment in /qa-include/db/favorites.php)
  42. ^userevents (all): per-subscriber event streams
  43. [but these are not entirely redundant since they can contain historical information no longer in ^posts]
  44. */
  45. if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
  46. header('Location: ../../');
  47. exit;
  48. }
  49. if (defined('QA_DEBUG_PERFORMANCE') && QA_DEBUG_PERFORMANCE) {
  50. trigger_error('Included file ' . basename(__FILE__) . ' is deprecated');
  51. }
  52. require_once QA_INCLUDE_DIR . 'db/recalc.php';
  53. require_once QA_INCLUDE_DIR . 'db/post-create.php';
  54. require_once QA_INCLUDE_DIR . 'db/points.php';
  55. require_once QA_INCLUDE_DIR . 'db/selects.php';
  56. require_once QA_INCLUDE_DIR . 'db/admin.php';
  57. require_once QA_INCLUDE_DIR . 'db/users.php';
  58. require_once QA_INCLUDE_DIR . 'app/options.php';
  59. require_once QA_INCLUDE_DIR . 'app/post-create.php';
  60. require_once QA_INCLUDE_DIR . 'app/post-update.php';
  61. /**
  62. * Advance the recalculation operation represented by $state by a single step.
  63. * $state can also be the name of a recalculation operation on its own.
  64. * @param string $state
  65. * @return bool
  66. */
  67. function qa_recalc_perform_step(&$state)
  68. {
  69. $continue = false;
  70. @list($operation, $length, $next, $done) = explode("\t", $state);
  71. switch ($operation) {
  72. case 'doreindexcontent':
  73. qa_recalc_transition($state, 'doreindexcontent_pagereindex');
  74. break;
  75. case 'doreindexcontent_pagereindex':
  76. $pages = qa_db_pages_get_for_reindexing($next, 10);
  77. if (count($pages)) {
  78. require_once QA_INCLUDE_DIR . 'app/format.php';
  79. $lastpageid = max(array_keys($pages));
  80. foreach ($pages as $pageid => $page) {
  81. if (!($page['flags'] & QA_PAGE_FLAGS_EXTERNAL)) {
  82. $searchmodules = qa_load_modules_with('search', 'unindex_page');
  83. foreach ($searchmodules as $searchmodule) {
  84. $searchmodule->unindex_page($pageid);
  85. }
  86. $searchmodules = qa_load_modules_with('search', 'index_page');
  87. if (count($searchmodules)) {
  88. $indextext = qa_viewer_text($page['content'], 'html');
  89. foreach ($searchmodules as $searchmodule)
  90. $searchmodule->index_page($pageid, $page['tags'], $page['heading'], $page['content'], 'html', $indextext);
  91. }
  92. }
  93. }
  94. $next = 1 + $lastpageid;
  95. $done += count($pages);
  96. $continue = true;
  97. } else {
  98. qa_recalc_transition($state, 'doreindexcontent_postcount');
  99. }
  100. break;
  101. case 'doreindexcontent_postcount':
  102. qa_db_qcount_update();
  103. qa_db_acount_update();
  104. qa_db_ccount_update();
  105. qa_recalc_transition($state, 'doreindexcontent_postreindex');
  106. break;
  107. case 'doreindexcontent_postreindex':
  108. $posts = qa_db_posts_get_for_reindexing($next, 10);
  109. if (count($posts)) {
  110. require_once QA_INCLUDE_DIR . 'app/format.php';
  111. $lastpostid = max(array_keys($posts));
  112. qa_db_prepare_for_reindexing($next, $lastpostid);
  113. qa_suspend_update_counts();
  114. foreach ($posts as $postid => $post) {
  115. qa_post_unindex($postid);
  116. qa_post_index($postid, $post['type'], $post['questionid'], $post['parentid'], $post['title'], $post['content'],
  117. $post['format'], qa_viewer_text($post['content'], $post['format']), $post['tags'], $post['categoryid']);
  118. }
  119. $next = 1 + $lastpostid;
  120. $done += count($posts);
  121. $continue = true;
  122. } else {
  123. qa_db_truncate_indexes($next);
  124. qa_recalc_transition($state, 'doreindexposts_wordcount');
  125. }
  126. break;
  127. case 'doreindexposts_wordcount':
  128. $wordids = qa_db_words_prepare_for_recounting($next, 1000);
  129. if (count($wordids)) {
  130. $lastwordid = max($wordids);
  131. qa_db_words_recount($next, $lastwordid);
  132. $next = 1 + $lastwordid;
  133. $done += count($wordids);
  134. $continue = true;
  135. } else {
  136. qa_db_tagcount_update(); // this is quick so just do it here
  137. qa_recalc_transition($state, 'doreindexposts_complete');
  138. }
  139. break;
  140. case 'dorecountposts':
  141. qa_recalc_transition($state, 'dorecountposts_postcount');
  142. break;
  143. case 'dorecountposts_postcount':
  144. qa_db_qcount_update();
  145. qa_db_acount_update();
  146. qa_db_ccount_update();
  147. qa_db_unaqcount_update();
  148. qa_db_unselqcount_update();
  149. qa_recalc_transition($state, 'dorecountposts_votecount');
  150. break;
  151. case 'dorecountposts_votecount':
  152. $postids = qa_db_posts_get_for_recounting($next, 1000);
  153. if (count($postids)) {
  154. $lastpostid = max($postids);
  155. qa_db_posts_votes_recount($next, $lastpostid);
  156. $next = 1 + $lastpostid;
  157. $done += count($postids);
  158. $continue = true;
  159. } else {
  160. qa_recalc_transition($state, 'dorecountposts_acount');
  161. }
  162. break;
  163. case 'dorecountposts_acount':
  164. $postids = qa_db_posts_get_for_recounting($next, 1000);
  165. if (count($postids)) {
  166. $lastpostid = max($postids);
  167. qa_db_posts_answers_recount($next, $lastpostid);
  168. $next = 1 + $lastpostid;
  169. $done += count($postids);
  170. $continue = true;
  171. } else {
  172. qa_db_unupaqcount_update();
  173. qa_recalc_transition($state, 'dorecountposts_complete');
  174. }
  175. break;
  176. case 'dorecalcpoints':
  177. qa_recalc_transition($state, 'dorecalcpoints_usercount');
  178. break;
  179. case 'dorecalcpoints_usercount':
  180. qa_db_userpointscount_update(); // for progress update - not necessarily accurate
  181. qa_db_uapprovecount_update(); // needs to be somewhere and this is the most appropriate place
  182. qa_recalc_transition($state, 'dorecalcpoints_recalc');
  183. break;
  184. case 'dorecalcpoints_recalc':
  185. $recalccount = 10;
  186. $userids = qa_db_users_get_for_recalc_points($next, $recalccount + 1); // get one extra so we know where to start from next
  187. $gotcount = count($userids);
  188. $recalccount = min($recalccount, $gotcount); // can't recalc more than we got
  189. if ($recalccount > 0) {
  190. $lastuserid = $userids[$recalccount - 1];
  191. qa_db_users_recalc_points($next, $lastuserid);
  192. $done += $recalccount;
  193. } else {
  194. $lastuserid = $next; // for truncation
  195. }
  196. if ($gotcount > $recalccount) { // more left to do
  197. $next = $userids[$recalccount]; // start next round at first one not recalculated
  198. $continue = true;
  199. } else {
  200. qa_db_truncate_userpoints($lastuserid);
  201. qa_db_userpointscount_update(); // quick so just do it here
  202. qa_recalc_transition($state, 'dorecalcpoints_complete');
  203. }
  204. break;
  205. case 'dorefillevents':
  206. qa_recalc_transition($state, 'dorefillevents_qcount');
  207. break;
  208. case 'dorefillevents_qcount':
  209. qa_db_qcount_update();
  210. qa_recalc_transition($state, 'dorefillevents_refill');
  211. break;
  212. case 'dorefillevents_refill':
  213. $questionids = qa_db_qs_get_for_event_refilling($next, 1);
  214. if (count($questionids)) {
  215. require_once QA_INCLUDE_DIR . 'app/events.php';
  216. require_once QA_INCLUDE_DIR . 'app/updates.php';
  217. require_once QA_INCLUDE_DIR . 'util/sort.php';
  218. $lastquestionid = max($questionids);
  219. foreach ($questionids as $questionid) {
  220. // Retrieve all posts relating to this question
  221. list($question, $childposts, $achildposts) = qa_db_select_with_pending(
  222. qa_db_full_post_selectspec(null, $questionid),
  223. qa_db_full_child_posts_selectspec(null, $questionid),
  224. qa_db_full_a_child_posts_selectspec(null, $questionid)
  225. );
  226. // Merge all posts while preserving keys as postids
  227. $posts = array($questionid => $question);
  228. foreach ($childposts as $postid => $post) {
  229. $posts[$postid] = $post;
  230. }
  231. foreach ($achildposts as $postid => $post) {
  232. $posts[$postid] = $post;
  233. }
  234. // Creation and editing of each post
  235. foreach ($posts as $postid => $post) {
  236. $followonq = ($post['basetype'] == 'Q') && ($postid != $questionid);
  237. if ($followonq) {
  238. $updatetype = QA_UPDATE_FOLLOWS;
  239. } elseif ($post['basetype'] == 'C' && @$posts[$post['parentid']]['basetype'] == 'Q') {
  240. $updatetype = QA_UPDATE_C_FOR_Q;
  241. } elseif ($post['basetype'] == 'C' && @$posts[$post['parentid']]['basetype'] == 'A') {
  242. $updatetype = QA_UPDATE_C_FOR_A;
  243. } else {
  244. $updatetype = null;
  245. }
  246. qa_create_event_for_q_user($questionid, $postid, $updatetype, $post['userid'], @$posts[$post['parentid']]['userid'], $post['created']);
  247. if (isset($post['updated']) && !$followonq) {
  248. qa_create_event_for_q_user($questionid, $postid, $post['updatetype'], $post['lastuserid'], $post['userid'], $post['updated']);
  249. }
  250. }
  251. // Tags and categories of question
  252. qa_create_event_for_tags($question['tags'], $questionid, null, $question['userid'], $question['created']);
  253. qa_create_event_for_category($question['categoryid'], $questionid, null, $question['userid'], $question['created']);
  254. // Collect comment threads
  255. $parentidcomments = array();
  256. foreach ($posts as $postid => $post) {
  257. if ($post['basetype'] == 'C') {
  258. $parentidcomments[$post['parentid']][$postid] = $post;
  259. }
  260. }
  261. // For each comment thread, notify all previous comment authors of each comment in the thread (could get slow)
  262. foreach ($parentidcomments as $parentid => $comments) {
  263. $keyuserids = array();
  264. qa_sort_by($comments, 'created');
  265. foreach ($comments as $comment) {
  266. foreach ($keyuserids as $keyuserid => $dummy) {
  267. if ($keyuserid != $comment['userid'] && $keyuserid != @$posts[$parentid]['userid']) {
  268. qa_db_event_create_not_entity($keyuserid, $questionid, $comment['postid'], QA_UPDATE_FOLLOWS, $comment['userid'], $comment['created']);
  269. }
  270. }
  271. if (isset($comment['userid'])) {
  272. $keyuserids[$comment['userid']] = true;
  273. }
  274. }
  275. }
  276. }
  277. $next = 1 + $lastquestionid;
  278. $done += count($questionids);
  279. $continue = true;
  280. } else {
  281. qa_recalc_transition($state, 'dorefillevents_complete');
  282. }
  283. break;
  284. case 'dorecalccategories':
  285. qa_recalc_transition($state, 'dorecalccategories_postcount');
  286. break;
  287. case 'dorecalccategories_postcount':
  288. qa_db_acount_update();
  289. qa_db_ccount_update();
  290. qa_recalc_transition($state, 'dorecalccategories_postupdate');
  291. break;
  292. case 'dorecalccategories_postupdate':
  293. $postids = qa_db_posts_get_for_recategorizing($next, 100);
  294. if (count($postids)) {
  295. $lastpostid = max($postids);
  296. qa_db_posts_recalc_categoryid($next, $lastpostid);
  297. qa_db_posts_calc_category_path($next, $lastpostid);
  298. $next = 1 + $lastpostid;
  299. $done += count($postids);
  300. $continue = true;
  301. } else {
  302. qa_recalc_transition($state, 'dorecalccategories_recount');
  303. }
  304. break;
  305. case 'dorecalccategories_recount':
  306. $categoryids = qa_db_categories_get_for_recalcs($next, 10);
  307. if (count($categoryids)) {
  308. $lastcategoryid = max($categoryids);
  309. foreach ($categoryids as $categoryid) {
  310. qa_db_ifcategory_qcount_update($categoryid);
  311. }
  312. $next = 1 + $lastcategoryid;
  313. $done += count($categoryids);
  314. $continue = true;
  315. } else {
  316. qa_recalc_transition($state, 'dorecalccategories_backpaths');
  317. }
  318. break;
  319. case 'dorecalccategories_backpaths':
  320. $categoryids = qa_db_categories_get_for_recalcs($next, 10);
  321. if (count($categoryids)) {
  322. $lastcategoryid = max($categoryids);
  323. qa_db_categories_recalc_backpaths($next, $lastcategoryid);
  324. $next = 1 + $lastcategoryid;
  325. $done += count($categoryids);
  326. $continue = true;
  327. } else {
  328. qa_recalc_transition($state, 'dorecalccategories_complete');
  329. }
  330. break;
  331. case 'dodeletehidden':
  332. qa_recalc_transition($state, 'dodeletehidden_comments');
  333. break;
  334. case 'dodeletehidden_comments':
  335. $posts = qa_db_posts_get_for_deleting('C', $next, 1);
  336. if (count($posts)) {
  337. require_once QA_INCLUDE_DIR . 'app/posts.php';
  338. $postid = $posts[0];
  339. qa_post_delete($postid);
  340. $next = 1 + $postid;
  341. $done++;
  342. $continue = true;
  343. } else {
  344. qa_recalc_transition($state, 'dodeletehidden_answers');
  345. }
  346. break;
  347. case 'dodeletehidden_answers':
  348. $posts = qa_db_posts_get_for_deleting('A', $next, 1);
  349. if (count($posts)) {
  350. require_once QA_INCLUDE_DIR . 'app/posts.php';
  351. $postid = $posts[0];
  352. qa_post_delete($postid);
  353. $next = 1 + $postid;
  354. $done++;
  355. $continue = true;
  356. } else {
  357. qa_recalc_transition($state, 'dodeletehidden_questions');
  358. }
  359. break;
  360. case 'dodeletehidden_questions':
  361. $posts = qa_db_posts_get_for_deleting('Q', $next, 1);
  362. if (count($posts)) {
  363. require_once QA_INCLUDE_DIR . 'app/posts.php';
  364. $postid = $posts[0];
  365. qa_post_delete($postid);
  366. $next = 1 + $postid;
  367. $done++;
  368. $continue = true;
  369. } else {
  370. qa_recalc_transition($state, 'dodeletehidden_complete');
  371. }
  372. break;
  373. case 'doblobstodisk':
  374. qa_recalc_transition($state, 'doblobstodisk_move');
  375. break;
  376. case 'doblobstodisk_move':
  377. $blob = qa_db_get_next_blob_in_db($next);
  378. if (isset($blob)) {
  379. require_once QA_INCLUDE_DIR . 'app/blobs.php';
  380. require_once QA_INCLUDE_DIR . 'db/blobs.php';
  381. if (qa_write_blob_file($blob['blobid'], $blob['content'], $blob['format'])) {
  382. qa_db_blob_set_content($blob['blobid'], null);
  383. }
  384. $next = 1 + $blob['blobid'];
  385. $done++;
  386. $continue = true;
  387. } else {
  388. qa_recalc_transition($state, 'doblobstodisk_complete');
  389. }
  390. break;
  391. case 'doblobstodb':
  392. qa_recalc_transition($state, 'doblobstodb_move');
  393. break;
  394. case 'doblobstodb_move':
  395. $blob = qa_db_get_next_blob_on_disk($next);
  396. if (isset($blob)) {
  397. require_once QA_INCLUDE_DIR . 'app/blobs.php';
  398. require_once QA_INCLUDE_DIR . 'db/blobs.php';
  399. $content = qa_read_blob_file($blob['blobid'], $blob['format']);
  400. qa_db_blob_set_content($blob['blobid'], $content);
  401. qa_delete_blob_file($blob['blobid'], $blob['format']);
  402. $next = 1 + $blob['blobid'];
  403. $done++;
  404. $continue = true;
  405. } else {
  406. qa_recalc_transition($state, 'doblobstodb_complete');
  407. }
  408. break;
  409. case 'docachetrim':
  410. qa_recalc_transition($state, 'docachetrim_process');
  411. break;
  412. case 'docacheclear':
  413. qa_recalc_transition($state, 'docacheclear_process');
  414. break;
  415. case 'docachetrim_process':
  416. case 'docacheclear_process':
  417. $cacheDriver = \Q2A\Storage\CacheFactory::getCacheDriver();
  418. $cacheStats = $cacheDriver->getStats();
  419. $limit = min($cacheStats['files'], 500);
  420. if ($cacheStats['files'] > 0 && $next <= $length) {
  421. $deleted = $cacheDriver->clear($limit, $next, ($operation === 'docachetrim_process'));
  422. $done += $deleted;
  423. $next += $limit - $deleted; // skip files that weren't deleted on next iteration
  424. $continue = true;
  425. } else {
  426. qa_recalc_transition($state, 'docacheclear_complete');
  427. }
  428. break;
  429. default:
  430. $state = '';
  431. break;
  432. }
  433. if ($continue) {
  434. $state = $operation . "\t" . $length . "\t" . $next . "\t" . $done;
  435. }
  436. return $continue && $done < $length;
  437. }
  438. /**
  439. * Change the $state to represent the beginning of a new $operation
  440. * @param string $state
  441. * @param string $operation
  442. */
  443. function qa_recalc_transition(&$state, $operation)
  444. {
  445. $length = qa_recalc_stage_length($operation);
  446. $next = (QA_FINAL_EXTERNAL_USERS && ($operation == 'dorecalcpoints_recalc')) ? '' : 0;
  447. $done = 0;
  448. $state = $operation . "\t" . $length . "\t" . $next . "\t" . $done;
  449. }
  450. /**
  451. * Return how many steps there will be in recalculation $operation
  452. * @param string $operation
  453. * @return int
  454. */
  455. function qa_recalc_stage_length($operation)
  456. {
  457. switch ($operation) {
  458. case 'doreindexcontent_pagereindex':
  459. $length = qa_db_count_pages();
  460. break;
  461. case 'doreindexcontent_postreindex':
  462. $length = qa_opt('cache_qcount') + qa_opt('cache_acount') + qa_opt('cache_ccount');
  463. break;
  464. case 'doreindexposts_wordcount':
  465. $length = qa_db_count_words();
  466. break;
  467. case 'dorecalcpoints_recalc':
  468. $length = qa_opt('cache_userpointscount');
  469. break;
  470. case 'dorecountposts_votecount':
  471. case 'dorecountposts_acount':
  472. case 'dorecalccategories_postupdate':
  473. $length = qa_db_count_posts();
  474. break;
  475. case 'dorefillevents_refill':
  476. $length = qa_opt('cache_qcount') + qa_db_count_posts('Q_HIDDEN');
  477. break;
  478. case 'dorecalccategories_recount':
  479. case 'dorecalccategories_backpaths':
  480. $length = qa_db_count_categories();
  481. break;
  482. case 'dodeletehidden_comments':
  483. $length = count(qa_db_posts_get_for_deleting('C'));
  484. break;
  485. case 'dodeletehidden_answers':
  486. $length = count(qa_db_posts_get_for_deleting('A'));
  487. break;
  488. case 'dodeletehidden_questions':
  489. $length = count(qa_db_posts_get_for_deleting('Q'));
  490. break;
  491. case 'doblobstodisk_move':
  492. $length = qa_db_count_blobs_in_db();
  493. break;
  494. case 'doblobstodb_move':
  495. $length = qa_db_count_blobs_on_disk();
  496. break;
  497. case 'docachetrim_process':
  498. case 'docacheclear_process':
  499. $cacheDriver = \Q2A\Storage\CacheFactory::getCacheDriver();
  500. $cacheStats = $cacheDriver->getStats();
  501. $length = $cacheStats['files'];
  502. break;
  503. default:
  504. $length = 0;
  505. break;
  506. }
  507. return $length;
  508. }
  509. /**
  510. * Return the translated language ID string replacing the progress and total in it.
  511. * @param string $langId Language string ID that contains 2 placeholders (^1 and ^2)
  512. * @param int $progress Amount of processed elements
  513. * @param int $total Total amount of elements
  514. * @return string Returns the language string ID with their placeholders replaced with
  515. * the formatted progress and total numbers
  516. */
  517. function qa_recalc_progress_lang($langId, $progress, $total)
  518. {
  519. return strtr(qa_lang($langId), array(
  520. '^1' => qa_format_number($progress),
  521. '^2' => qa_format_number($total),
  522. ));
  523. }
  524. /**
  525. * Return a string which gives a user-viewable version of $state
  526. * @param string $state
  527. * @return string
  528. */
  529. function qa_recalc_get_message($state)
  530. {
  531. require_once QA_INCLUDE_DIR . 'app/format.php';
  532. @list($operation, $length, $next, $done) = explode("\t", $state);
  533. $done = (int) $done;
  534. $length = (int) $length;
  535. switch ($operation) {
  536. case 'doreindexcontent_postcount':
  537. case 'dorecountposts_postcount':
  538. case 'dorecalccategories_postcount':
  539. case 'dorefillevents_qcount':
  540. $message = qa_lang('admin/recalc_posts_count');
  541. break;
  542. case 'doreindexcontent_pagereindex':
  543. $message = qa_recalc_progress_lang('admin/reindex_pages_reindexed', $done, $length);
  544. break;
  545. case 'doreindexcontent_postreindex':
  546. $message = qa_recalc_progress_lang('admin/reindex_posts_reindexed', $done, $length);
  547. break;
  548. case 'doreindexposts_complete':
  549. $message = qa_lang('admin/reindex_posts_complete');
  550. break;
  551. case 'doreindexposts_wordcount':
  552. $message = qa_recalc_progress_lang('admin/reindex_posts_wordcounted', $done, $length);
  553. break;
  554. case 'dorecountposts_votecount':
  555. $message = qa_recalc_progress_lang('admin/recount_posts_votes_recounted', $done, $length);
  556. break;
  557. case 'dorecountposts_acount':
  558. $message = qa_recalc_progress_lang('admin/recount_posts_as_recounted', $done, $length);
  559. break;
  560. case 'dorecountposts_complete':
  561. $message = qa_lang('admin/recount_posts_complete');
  562. break;
  563. case 'dorecalcpoints_usercount':
  564. $message = qa_lang('admin/recalc_points_usercount');
  565. break;
  566. case 'dorecalcpoints_recalc':
  567. $message = qa_recalc_progress_lang('admin/recalc_points_recalced', $done, $length);
  568. break;
  569. case 'dorecalcpoints_complete':
  570. $message = qa_lang('admin/recalc_points_complete');
  571. break;
  572. case 'dorefillevents_refill':
  573. $message = qa_recalc_progress_lang('admin/refill_events_refilled', $done, $length);
  574. break;
  575. case 'dorefillevents_complete':
  576. $message = qa_lang('admin/refill_events_complete');
  577. break;
  578. case 'dorecalccategories_postupdate':
  579. $message = qa_recalc_progress_lang('admin/recalc_categories_updated', $done, $length);
  580. break;
  581. case 'dorecalccategories_recount':
  582. $message = qa_recalc_progress_lang('admin/recalc_categories_recounting', $done, $length);
  583. break;
  584. case 'dorecalccategories_backpaths':
  585. $message = qa_recalc_progress_lang('admin/recalc_categories_backpaths', $done, $length);
  586. break;
  587. case 'dorecalccategories_complete':
  588. $message = qa_lang('admin/recalc_categories_complete');
  589. break;
  590. case 'dodeletehidden_comments':
  591. $message = qa_recalc_progress_lang('admin/hidden_comments_deleted', $done, $length);
  592. break;
  593. case 'dodeletehidden_answers':
  594. $message = qa_recalc_progress_lang('admin/hidden_answers_deleted', $done, $length);
  595. break;
  596. case 'dodeletehidden_questions':
  597. $message = qa_recalc_progress_lang('admin/hidden_questions_deleted', $done, $length);
  598. break;
  599. case 'dodeletehidden_complete':
  600. $message = qa_lang('admin/delete_hidden_complete');
  601. break;
  602. case 'doblobstodisk_move':
  603. case 'doblobstodb_move':
  604. $message = qa_recalc_progress_lang('admin/blobs_move_moved', $done, $length);
  605. break;
  606. case 'doblobstodisk_complete':
  607. case 'doblobstodb_complete':
  608. $message = qa_lang('admin/blobs_move_complete');
  609. break;
  610. case 'docachetrim_process':
  611. case 'docacheclear_process':
  612. $message = qa_recalc_progress_lang('admin/caching_delete_progress', $done, $length);
  613. break;
  614. case 'docacheclear_complete':
  615. $message = qa_lang('admin/caching_delete_complete');
  616. break;
  617. default:
  618. $message = '';
  619. break;
  620. }
  621. return $message;
  622. }