/** * Processes a rename version request for a single manual * * @param $jobID The unique id for this job (see ajaxFetchJobID) * @param $productName string product short name * @param $manualName string manual short name * @param $sourceVersionName string String representation of the source version * @param $targetVersionName string String representaiton of the target version * @return string Full job log of the process by printing to stdout. */ public static function ajaxProcessManual($jobID, $productName, $manualName, $sourceVersionName, $targetVersionName) { global $wgScriptPath; ob_start(); list($msec, $sec) = explode(' ', microtime()); $startTime = (double) $msec + (double) $sec; $logFields = "action=start status=success product={$productName} manual={$manualName} " . "sourceVersion={$sourceVersionName} targetVersion={$targetVersionName}"; error_log('INFO [' . __METHOD__ . "] [RenameVersion] {$logFields}"); // Validate product and versions $product = PonyDocsProduct::GetProductByShortName($productName); $manual = PonyDocsProductManual::getManualByShortName($productName, $manualName); $sourceVersion = PonyDocsProductVersion::GetVersionByName($productName, $sourceVersionName); $targetVersion = PonyDocsProductVersion::GetVersionByName($productName, $targetVersionName); if (!($product && $manual && $sourceVersion && $targetVersion)) { $result = array('success', false); $result = json_encode($result); return $result; } // TODO: Is this necessary? Haven't we done this already? PonyDocsProductVersion::SetSelectedVersion($productName, $sourceVersionName); print "Beginning process job for manual: {$manualName}<br />"; print "Source version is {$productName}:{$sourceVersionName}<br />"; print "Target version is {$targetVersionName}<br />"; // Get topics // Update log file // TODO: Pull this out into a separate method somewhere $path = PonyDocsExtension::getTempDir() . $jobID; $fp = fopen($path, "w+"); fputs($fp, "Getting Topics for {$manualName}"); fclose($fp); // TODO: This is copied form SpecialBranchInherit::ajaxFetchTopics() and should get DRYed out $manualTopics = array(); $TOC = new PonyDocsTOC($manual, $sourceVersion, $product); list($toc, $prev, $next, $start) = $TOC->loadContent(); // Time to iterate through all the items. $section = ''; foreach ($toc as $tocItem) { if ($tocItem['level'] == 0) { $section = $tocItem['text']; $manualTopics[$manualName]['sections'][$section] = array(); $manualTopics[$manualName]['sections'][$section]['meta'] = array(); $manualTopics[$manualName]['sections'][$section]['topics'] = array(); } // actual topic if ($tocItem['level'] == 1) { $tempEntry = array('title' => $tocItem['title'], 'text' => $tocItem['text'], 'toctitle' => $tocItem['toctitle'], 'conflicts' => PonyDocsBranchInheritEngine::getConflicts($product, $tocItem['title'], $targetVersion)); $manualTopics[$manualName]['sections'][$section]['topics'][] = $tempEntry; } } foreach ($manualTopics as $manualName => $manual) { foreach ($manual['sections'] as $sectionIndex => $section) { if (count($section['topics']) == 0) { unset($manualTopics[$manualName]['sections'][$sectionIndex]); } } } $logFields = "action=topics status=success product={$productName} manual={$manualName} " . "sourceVersion={$sourceVersionName} targetVersion={$targetVersionName}"; error_log('INFO [' . __METHOD__ . "] [RenameVersion] {$logFields}"); // Enable speed processing to avoid any unnecessary processing on topics modified by this tool. // TODO: I'm not 100% sure this is necessary or proper here -RU PonyDocsExtension::setSpeedProcessing(TRUE); // Determine how many topics there are to process so that we can keep track of progress $numOfTopics = 0; $numOfTopicsCompleted = 0; foreach ($manualTopics as $manualName => $manualData) { foreach ($manualData['sections'] as $sectionName => $section) { // The following is a goofy fix for some browsers. // Sometimes the JSON comes along with null values for the first element. // It's just an additional element, so we can drop it. // TODO: Since we're no longer getting this from JSON, this is probably removeable if (empty($section['topics'][0]['text'])) { array_shift($manualTopics[$manualName]['sections'][$sectionName]['topics']); } $numOfTopics += count($manualTopics[$manualName]['sections'][$sectionName]['topics']); } } foreach ($manualTopics as $manualName => $manualData) { // TODO: We already got the manual above, why make another? We could add the manual to $manualTopics somewhere.. $manual = PonyDocsProductManual::GetManualByShortName($productName, $manualName); // First update all the topics print '<div class="normal">Processing topics</div>'; foreach ($manualData['sections'] as $sectionName => $section) { print "<div class=\"normal\">Processing section {$sectionName}</div>"; foreach ($section['topics'] as $topic) { // Update log file $fp = fopen($path, "w+"); fputs($fp, "Renaming topics in manual {$manualName}<br />" . "Completed {$numOfTopicsCompleted} of {$numOfTopics} Total: " . (int) ($numOfTopicsCompleted / $numOfTopics * 100) . '%'); fclose($fp); try { print '<div class="normal">Attempting to update topic ' . $topic['title'] . '...'; PonyDocsRenameVersionEngine::changeVersionOnTopic($topic['title'], $sourceVersion, $targetVersion); $logFields = "action=topic status=success product={$productName} manual={$manualName} " . "title={$topic['title']} sourceVersion={$sourceVersionName} targetVersion={$targetVersionName}"; error_log('INFO [' . __METHOD__ . "] [RenameVersion] {$logFields}"); print 'Complete</div>'; } catch (Exception $e) { $logFields = "action=topic status=failure error={$e->getMessage()} product={$productName} manual={$manualName} " . "title={$topic['title']} sourceVersion={$sourceVersionName} targetVersion={$targetVersionName}"; error_log('WARNING [' . __METHOD__ . "] [RenameVersion] {$logFields}"); print '</div><div class="error">Exception: ' . $e->getMessage() . '</div>'; } $numOfTopicsCompleted++; } } // Now we can update the TOC // Determine if TOC already exists for target version. if (!PonyDocsBranchInheritEngine::TOCExists($product, $manual, $sourceVersion)) { print '<div class="normal">TOC Does not exist for Manual ' . $manual->getShortName() . ' with version ' . $targetVersion->getVersionName() . '</div>'; } else { try { print '<div class="normal">Attempting to update TOC...'; PonyDocsRenameVersionEngine::changeVersionOnTOC($product, $manual, $sourceVersion, $targetVersion); $logFields = "action=TOC status=success product={$productName} manual={$manualName} " . "sourceVersion={$sourceVersionName} targetVersion={$targetVersionName}"; error_log('INFO [' . __METHOD__ . "] [RenameVersion] {$logFields}"); print 'Complete</div>'; } catch (Exception $e) { $logFields = "action=TOC status=failure error={$e->getMessage()} product={$productName} manual={$manualName} " . "sourceVersion={$sourceVersionName} targetVersion={$targetVersionName}"; error_log('WARNING [' . __METHOD__ . "] [RenameVersion] {$logFields}"); print '</div><div class="error">Exception: ' . $e->getMessage() . '</div>'; } } } list($msec, $sec) = explode(' ', microtime()); $endTime = (double) $msec + (double) $sec; print "Done with {$manualName}! Execution Time: " . round($endTime - $startTime, 3) . ' seconds<br />'; //WEB-10792, Clear TOCCACHE for the target version only, each Manual at a time PonyDocsTOC::clearTOCCache($manual, $targetVersion, $product); //Also clear the NAVCache for the target version PonyDocsProductVersion::clearNAVCache($targetVersion); unlink($path); $buffer = ob_get_clean(); return $buffer; }
/** * Processes a branch/inherit job request. * * @param $jobID The unique id for this job (see ajaxFetchJobID) * @param $productName string product short name * @param $sourceVersion string String representation of the source version * @param $targetVersion string String representaiton of the target version * @param $topicActions string JSON array representation of all topics and * their requested actions. * @return string Full job log of the process by printing to stdout. */ public static function ajaxProcessRequest($jobID, $productName, $sourceVersion, $targetVersion, $topicActions) { global $wgScriptPath; ob_start(); $targetVersionName = $targetVersion; $sourceVersionName = $sourceVersion; $topicActions = json_decode($topicActions, true); list($msec, $sec) = explode(' ', microtime()); $startTime = (double) $msec + (double) $sec; $logFields = "action=\"start\" status=\"success\" product=\"" . addslashes($productName) . "\" sourceVersion=\"" . htmlentities($sourceVersionName) . "\" " . "targetVersion=\"" . addslashes($targetVersionName) . "\""; error_log('INFO [' . __METHOD__ . "] [BranchInherit] {$logFields}"); if ($topicActions == false) { print "Failed to read request."; return true; } print "Beginning process job for source version: " . $productName . ':' . $sourceVersion . "<br />"; print "Target version is: " . $targetVersion . "<br />"; // Enable speed processing to avoid any unnecessary processing on // new topics created by this tool. PonyDocsExtension::setSpeedProcessing(true); $product = PonyDocsProduct::GetProductByShortName($productName); $sourceVersion = PonyDocsProductVersion::GetVersionByName($productName, $sourceVersion); $targetVersion = PonyDocsProductVersion::GetVersionByName($productName, $targetVersion); // Determine how many topics there are to process. $numOfTopics = 0; $numOfTopicsCompleted = 0; foreach ($topicActions as $manualIndex => $manualData) { foreach ($manualData['sections'] as $sectionName => $topics) { // The following is a goofy fix for some browsers. Sometimes // the JSON comes along with null values for the first element. // IT's just an additional element, so we can drop it. if (empty($topics[0]['text'])) { array_shift($topicActions[$manualIndex]['sections'][$sectionName]); } $numOfTopics += count($topicActions[$manualIndex]['sections'][$sectionName]); } } $logFields = "action=\"topic\" status=\"success\" product=\"" . addslashes($productName) . "\" numOfTopics={$numOfTopics} " . "sourceVersion=\"" . addslashes($sourceVersionName) . "\" targetVersion=\"" . htmlentities($targetVersionName) . "\""; error_log('INFO [' . __METHOD__ . "] [BranchInherit] {$logFields}"); $lastTopicTarget = null; foreach ($topicActions as $manualName => $manualData) { $manual = PonyDocsProductManual::GetManualByShortName($productName, $manualName); // Determine if TOC already exists for target version. if (!PonyDocsBranchInheritEngine::TOCExists($product, $manual, $targetVersion)) { print "<div class=\"normal\">TOC Does not exist for Manual " . $manual->getShortName() . " for version " . $targetVersion->getVersionName() . "</div>"; // Crl eate the toc or inherit. if ($manualData['tocAction'] != 'default') { // Then they want to force. if ($manualData['tocAction'] == 'forceinherit') { print "<div class=\"normal\">Forcing inheritance of source TOC.</div>"; PonyDocsBranchInheritEngine::addVersionToTOC($product, $manual, $sourceVersion, $targetVersion); print "<div class=\"normal\">Complete</div>"; } else { if ($manualData['tocAction'] == 'forcebranch') { print "<div class=\"normal\">Forcing branch of source TOC.</div>"; PonyDocsBranchInheritEngine::branchTOC($product, $manual, $sourceVersion, $targetVersion); print "<div class=\"normal\">Complete</div>"; } } } else { if ($manualData['tocInherit']) { // We need to get the TOC for source version/manual and add // target version to the category tags. try { print "<div class=\"normal\">Attempting to add target version to existing source version TOC.</div>"; PonyDocsBranchInheritEngine::addVersionToTOC($product, $manual, $sourceVersion, $targetVersion); $logFields = "action=\"TOC\" status=\"success\" product=\"" . addslashes($productName) . "\" manual=\"" . htmlentities($manualName) . "\" " . "sourceVersion=\"" . addslashes($sourceVersionName) . "\" targetVersion=\"" . htmlentities($targetVersionName) . "\""; error_log('INFO [' . __METHOD__ . "] [BranchInherit] {$logFields}"); print "<div class=\"normal\">Complete</div>"; } catch (Exception $e) { $logFields = "action=\"TOC\" status=\"failure\" product=\"" . addslashes($productName) . "\" manual=\"" . htmlentities($manualName) . "\" " . "error=\"" . addslashes($e->getMessage()) . "\" sourceVersion=\"" . htmlentities($sourceVersionName) . "\" " . "targetVersion=\"" . addslashes($targetVersionName) . "\""; error_log('WARNING [' . __METHOD__ . "] [BranchInherit] {$logFields}"); print "<div class=\"error\">Exception: " . $e->getMessage() . "</div>"; } } else { try { print "<div class=\"normal\">Attempting to create TOC for target version.</div>"; $addData = array(); foreach ($manualData['sections'] as $sectionName => $topics) { $addData[$sectionName] = array(); foreach ($topics as $topic) { $addData[$sectionName][] = $topic['toctitle']; } } PonyDocsBranchInheritEngine::createTOC($product, $manual, $targetVersion, $addData); $logFields = "action=\"TOC\" status=\"success\" product=\"" . addslashes($productName) . "\" manual=\"" . htmlentities($manualName) . "\" " . "sourceVersion=\"" . addslashes($sourceVersionName) . "\" targetVersion=\"" . htmlentities($targetVersionName) . "\""; error_log('INFO [' . __METHOD__ . "] [BranchInherit] {$logFields}"); print "<div class=\"normal\">Complete</div>"; } catch (Exception $e) { $logFields = "action=\"TOC\" status=\"failure\" product=\"" . addslashes($productName) . "\" manual=\"" . htmlentities($manualName) . "\" " . "sourceVersion=\"" . addslashes($sourceVersionName) . "\" error=\"" . htmlentities($e->getMessage()) . "\" " . "targetVersion=\"" . addslashes($targetVersionName) . "\""; error_log('WARNING [' . __METHOD__ . "] [BranchInherit] {$logFields}"); print "<div class=\"error\">Exception: " . $e->getMessage() . "</div>"; } } } } else { try { print "<div class=\"normal\">Attempting to update TOC for target version.</div>"; $addData = array(); foreach ($manualData['sections'] as $sectionName => $topics) { $addData[$sectionName] = array(); foreach ($topics as $topic) { if (!isset($topic['action']) || isset($topic['action']) && $topic['action'] != 'ignore') { $addData[$sectionName][] = $topic['toctitle']; } } } PonyDocsBranchInheritEngine::addCollectionToTOC($product, $manual, $targetVersion, $addData); $logFields = "action=\"TOC\" status=\"success\" product=\"" . addslashes($productName) . "\" manual=\"" . htmlentities($manualName) . "\" " . "sourceVersion=\"" . addslashes($sourceVersionName) . "\" targetVersion=\"" . htmlentities($targetVersionName) . "\""; error_log('INFO [' . __METHOD__ . "] [BranchInherit] {$logFields}"); print "<div class=\"normal\">Complete</div>"; } catch (Exception $e) { $logFields = "action=\"TOC\" status=\"failure\" product=\"" . addslashes($productName) . "\" manual=\"" . htmlentities($manualName) . "\" " . "sourceVersion=\"" . addslashes($sourceVersionName) . "\" error=\"" . htmlentities($e->getMessage()) . "\" " . "targetVersion=\"" . addslashes($targetVersionName) . "\""; error_log('WARNING [' . __METHOD__ . "] [BranchInherit] {$logFields}"); print "<div class=\"error\">Exception: " . $e->getMessage() . "</div>"; } } // Okay, now let's go through each of the topics and // branch/inherit. print "Processing topics.\n"; $path = PonyDocsExtension::getTempDir() . $jobID; foreach ($manualData['sections'] as $sectionName => $topics) { print "<div class=\"normal\">Processing section {$sectionName}</div>"; foreach ($topics as $topic) { // Update log file $fp = fopen($path, "w+"); fputs($fp, "Completed " . $numOfTopicsCompleted . " of " . $numOfTopics . " Total: " . (int) ($numOfTopicsCompleted / $numOfTopics * 100) . "%"); fclose($fp); if (isset($topic['action']) && $topic['action'] == "ignore") { print "<div class=\"normal\">Ignoring topic: " . $topic['title'] . "</div>"; $numOfTopicsCompleted++; continue; } else { if (isset($topic['action']) && $topic['action'] == "branchpurge") { try { print "<div class=\"normal\">Attempting to branch topic " . $topic['title'] . " and remove existing topic.</div>"; $lastTopicTarget = PonyDocsBranchInheritEngine::branchTopic($topic['title'], $targetVersion, $sectionName, $topic['text'], TRUE, FALSE); $logFields = "action=\"topic\" status=\"success\" product=\"" . addslashes($productName) . "\" manual=\"" . htmlentities($manualName) . "\" " . "topic=\"" . addslashes($topic['title']) . "\" sourceVersion=\"" . htmlentities($sourceVersionName) . "\" targetVersion=\"" . htmlentities($targetVersionName) . "\""; error_log('INFO [' . __METHOD__ . "] [BranchInherit] {$logFields}"); print "<div class=\"normal\">Complete</div>"; } catch (Exception $e) { $logFields = "action=\"topic\" status=\"failure\" product=\"" . addslashes($productName) . "\" manual=\"" . htmlentities($manualName) . "\" " . "topic=\"" . addslashes($topic['title']) . "\" sourceVersion=\"" . htmlentities($sourceVersionName) . "\" error=\"" . htmlentities($e->getMessage()) . "\" " . "targetVersion=\"" . addslashes($targetVersionName) . "\""; error_log('WARNING [' . __METHOD__ . "] [BranchInherit] {$logFields}"); print "<div class=\"error\">Exception: " . $e->getMessage() . "</div>"; } } else { if (isset($topic['action']) && $topic['action'] == "branch") { try { print "<div class=\"normal\">Attempting to branch topic " . $topic['title'] . "</div>"; $lastTopicTarget = PonyDocsBranchInheritEngine::branchTopic($topic['title'], $targetVersion, $sectionName, $topic['text'], FALSE, TRUE); $logFields = "action=\"topic\" status=\"success\" product=\"" . addslashes($productName) . "\" manual=\"" . htmlentities($manualName) . "\" " . "topic=\"" . addslashes($topic['title']) . "\" sourceVersion=\"" . htmlentities($sourceVersionName) . "\" targetVersion=\"" . htmlentities($targetVersionName) . "\""; error_log('INFO [' . __METHOD__ . "] [BranchInherit] {$logFields}"); print "<div class=\"normal\">Complete</div>"; } catch (Exception $e) { $logFields = "action=\"topic\" status=\"failure\" product=\"" . addslashes($productName) . "\" manual=\"" . htmlentities($manualName) . "\" " . "topic=\"" . addslashes($topic['title']) . "\" sourceVersion=\"" . htmlentities($sourceVersionName) . "\" error=\"" . htmlentities($e->getMessage()) . "\" " . "targetVersion=\"" . addslashes($targetVersionName) . "\""; error_log('WARNING [' . __METHOD__ . "] [BranchInherit] {$logFields}"); print "<div class=\"error\">Exception: " . $e->getMessage() . "</div>"; } } else { if (isset($topic['action']) && $topic['action'] == "branchsplit") { try { print "<div class=\"normal\">Attempting to branch topic " . $topic['title'] . " and split from existing topic.</div>"; $lastTopicTarget = PonyDocsBranchInheritEngine::branchTopic($topic['title'], $targetVersion, $sectionName, $topic['text'], FALSE, TRUE); $logFields = "action=\"topic\" status=\"success\" product=\"" . addslashes($productName) . "\" manual=\"" . htmlentities($manualName) . "\"e " . "topic=\"" . addslashes($topic['title']) . "\" sourceVersion=\"" . htmlentities($sourceVersionName) . "\" " . "targetVersion=\"" . addslashes($targetVersionName) . "\""; error_log('INFO [' . __METHOD__ . "] [BranchInherit] {$logFields}"); print "<div class=\"normal\">Complete</div>"; } catch (Exception $e) { $logFields = "action=\"topic\" status=\"failure\" product=\"" . addslashes($productName) . "\" manual=\"" . htmlentities($manualName) . "\" " . "topic=\"" . addslashes($topic['title']) . "\" sourceVersion=\"" . htmlentities($sourceVersionName) . "\" error=\"" . htmlentities($e->getMessage()) . "\" " . "targetVersion=\"" . addslashes($targetVersionName) . "\""; error_log('WARNING [' . __METHOD__ . "] [BranchInherit] {$logFields}"); print "<div class=\"error\">Exception: " . $e->getMessage() . "</div>"; } } else { if (isset($topic['action']) && $topic['action'] == "inherit") { try { print "<div class=\"normal\">Attempting to inherit topic " . $topic['title'] . "</div>"; $lastTopicTarget = PonyDocsBranchInheritEngine::inheritTopic($topic['title'], $targetVersion, $sectionName, $topic['text'], FALSE); $logFields = "action=\"topic\" status=\"success\" product=\"" . addslashes($productName) . "\" manual=\"" . htmlentities($manualName) . "\" " . "topic=\"" . addslashes($topic['title']) . "\" sourceVersion=\"" . htmlentities($sourceVersionName) . "\" targetVersion=\"" . htmlentities($targetVersionName) . "\""; error_log('INFO [' . __METHOD__ . "] [BranchInherit] {$logFields}"); print "<div class=\"normal\">Complete</div>"; } catch (Exception $e) { $logFields = "action=\"topic\" status=\"failure\" product=\"" . addslashes($productName) . "\" manual=\"" . htmlentities($manualName) . "\" " . "topic=\"" . addslashes($topic['title']) . "\" sourceVersion=\"" . htmlentities($sourceVersionName) . "\" error=\"" . htmlentities($e->getMessage()) . "\" " . "targetVersion=\"" . addslashes($targetVersionName) . "\""; error_log('WARNING [' . __METHOD__ . "] [BranchInherit] {$logFields}"); print "<div class=\"error\">Exception: " . $e->getMessage() . "</div>"; } } else { if (isset($topic['action']) && $topic['action'] == "inheritpurge") { try { print "<div class=\"normal\">Attempting to inherit topic " . $topic['title'] . " and remove existing topic.</div>"; $lastTopicTarget = PonyDocsBranchInheritEngine::inheritTopic($topic['title'], $targetVersion, $sectionName, $topic['text'], TRUE); $logFields = "action=\"topic\" status=\"success\" product=\"" . addslashes($productName) . "\" manual=\"" . htmlentities($manualName) . "\" " . "topic=\"" . addslashes($topic['title']) . "\" sourceVersion=\"" . htmlentities($sourceVersionName) . "\" targetVersion=\"" . htmlentities($targetVersionName) . "\""; error_log('INFO [' . __METHOD__ . "] [BranchInherit] {$logFields}"); print "<div class=\"normal\">Complete</div>"; } catch (Exception $e) { $logFields = "action=\"topic\" status=\"failure\" product=\"" . addslashes($productName) . "\" manual=\"" . htmlentities($manualName) . "\" " . "topic=\"" . addslashes($topic['title']) . "\" sourceVersion=\"" . htmlentities($sourceVersionName) . "\" error=\"" . htmlentities($e->getMessage()) . "\" " . "targetVersion=\"" . addslashes($targetVersionName) . "\""; error_log('WARNING [' . __METHOD__ . "] [BranchInherit] {$logFields}"); print "<div class=\"error\">Exception: " . $e->getMessage() . "</div>"; } } } } } } } $numOfTopicsCompleted++; } } //WEB-10792, Clear TOCCACHE for the target version only, each Manual at a time PonyDocsTOC::clearTOCCache($manual, $targetVersion, $product); //Also clear the NAVCache for the target version PonyDocsProductVersion::clearNAVCache($targetVersion); } list($msec, $sec) = explode(' ', microtime()); $endTime = (double) $msec + (double) $sec; print "All done!\n"; print 'Execution Time: ' . round($endTime - $startTime, 3) . ' seconds'; if ($numOfTopics == 1 && $lastTopicTarget != null) { // We can safely show a link to the topic. print "<br />"; print "Link to new topic: <a href=\"" . $wgScriptPath . "/" . $lastTopicTarget . "\">" . $lastTopicTarget . "</a>"; print "<br />"; } // Okay, let's start the process! unlink($path); $buffer = ob_get_clean(); return $buffer; }