예제 #1
0
 /**
  * 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;
 }
 /**
  * Replace a version on an existing Topic
  *
  * @param $topicTitle string The internal mediawiki title of the article.
  * @param $sourceVersion PonyDocsVersion The source Version
  * @param $targetVersion PonyDocsVersion The target Version
  * @returns boolean
  */
 public static function changeVersionOnTopic($topicTitle, $sourceVersion, $targetVersion)
 {
     global $wgTitle;
     // Clear any hooks so no weirdness gets called after we save the change
     $wgHooks['ArticleSave'] = array();
     if (!preg_match('/^' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':([^:]*):([^:]*):(.*):([^:]*)$/', $topicTitle, $match)) {
         throw new Exception("Invalid Title to Rename Version: {$topicTitle}");
     }
     $productName = $match[1];
     $title = $match[3];
     // Get PonyDocsProduct
     // TODO: Why don't we just pass the product in instead of re-deriving it from something else and then loading it?
     $product = PonyDocsProduct::GetProductByShortName($productName);
     $title = Title::newFromText($topicTitle);
     $wgTitle = $title;
     $article = new Article($title);
     if (!$article->exists()) {
         // No such title exists in the system
         throw new Exception("Invalid Title to Rename Version: {$topicTitle}");
     }
     $content = $article->getContent();
     $oldCategory = '[[Category:V:' . $product->getShortName() . ':' . $sourceVersion->getVersionName() . ']]';
     $newCategory = '[[Category:V:' . $product->getShortName() . ':' . $targetVersion->getVersionName() . ']]';
     $message = '';
     $editTopic = TRUE;
     // Get conflicts.
     $conflicts = PonyDocsBranchInheritEngine::getConflicts($product, $topicTitle, $targetVersion);
     if (!empty($conflicts)) {
         // If there's already a topic with the target version,
         // then we just want to remove the source version from the source topic
         foreach ($conflicts as $conflict) {
             $conflictingArticle = new Article(Title::newFromText($conflict));
             // No big deal.  A conflict no longer exists?  Continue.
             if (!$conflictingArticle->exists()) {
                 continue;
             }
             // Conflict was same as source material. Do nothing with it.
             if ($conflict == $topicTitle) {
                 continue;
                 // Remove source version from source article
             } else {
                 $content = str_replace($oldCategory, '', $content);
                 $message = "Removed version category {$oldCategory} via RenameVersion";
             }
         }
     }
     if (empty($message)) {
         // If the Topic doesn't contain the source version, it may have been branched, or already processed
         if (strpos($content, $oldCategory) === FALSE) {
             $lastColon = strrpos($topicTitle, ':');
             $baseTopic = substr_replace($topicTitle, '', $lastColon);
             $topicTitle = PonyDocsTopic::GetTopicNameFromBaseAndVersion($baseTopic, $productName);
             // We found an instance of this title with the source version! Let's recurse just this once to handle it.
             if ($topicTitle) {
                 $editTopic = FALSE;
                 $title = self::changeVersionOnTopic($topicTitle, $sourceVersion, $targetVersion);
                 // We can't find a topic with the source version, so something is odd. Let's complain
             } else {
                 throw new Exception("Topic {$topicTitle} does not contain source version " . $sourceVersion->getVersionName());
             }
             // If the Topic already has the new version, just remove the old version
         } elseif (strpos($content, $newCategory) !== FALSE) {
             $content = str_replace($oldCategory, '', $content);
             $message = "Removed version category {$oldCategory} via RenameVersion";
             // Otherwise replace old with new
         } else {
             $content = str_replace($oldCategory, $newCategory, $content, $count);
             $message = "Renamed version category {$oldCategory} to {$newCategory} in {$count} locations via RenameVersion";
         }
     }
     // Finally we can edit the topic
     if ($editTopic) {
         // TODO: doEdit returns a status that we should check
         $article->doEdit($content, $message, EDIT_UPDATE);
     }
     return $title;
 }
예제 #3
0
 /**
  * AJAX method to fetch topics for a specified version and manuals
  *
  * @param $productName string product short name
  * @param $sourceVersion string String representation of the source version
  * @param $targetVersion string String representation of the target version
  * @param $manuals string Comma seperated list of manuals to retrieve from
  * @param $forcedTitle string A specific title to pull from and nothing else 
  * 							  (for individual branch/inherit)
  * @returns string JSON representation of all titles requested
  */
 public static function ajaxFetchTopics($productName, $sourceVersion, $targetVersion, $manuals, $forcedTitle = null)
 {
     PonyDocsProduct::LoadProducts(true);
     $product = PonyDocsProduct::GetProductByShortName($productName);
     PonyDocsProductVersion::LoadVersionsForProduct(true, true);
     $sourceVersion = PonyDocsProductVersion::GetVersionByName($productName, $sourceVersion);
     $targetVersion = PonyDocsProductVersion::GetVersionByName($productName, $targetVersion);
     if (!$sourceVersion || !$targetVersion) {
         $result = array("success", false);
         $result = json_encode($result);
         return $result;
     }
     $result = array();
     // Okay, get manual by name.
     $manuals = explode(",", $manuals);
     foreach ($manuals as $manualName) {
         $manual = PonyDocsProductManual::GetManualByShortName($productName, $manualName);
         $result[$manualName] = array();
         $result[$manualName]['meta'] = array();
         // Load up meta.
         $result[$manualName]['meta']['text'] = $manual->getLongName();
         // See if TOC exists for target version.
         $result[$manualName]['meta']['toc_exists'] = PonyDocsBranchInheritEngine::TOCExists($product, $manual, $targetVersion);
         $result[$manualName]['sections'] = array();
         // Got the version and manual, load the TOC.
         $ponyTOC = new PonyDocsTOC($manual, $sourceVersion, $product);
         list($toc, $prev, $next, $start) = $ponyTOC->loadContent();
         // Time to iterate through all the items.
         $section = '';
         foreach ($toc as $tocItem) {
             if ($tocItem['level'] == 0) {
                 $section = $tocItem['text'];
                 $result[$manualName]['sections'][$section] = array();
                 $result[$manualName]['sections'][$section]['meta'] = array();
                 $result[$manualName]['sections'][$section]['topics'] = array();
             }
             if ($tocItem['level'] == 1) {
                 // actual topic
                 if ($forcedTitle == null || $tocItem['title'] == $forcedTitle) {
                     $tempEntry = array('title' => $tocItem['title'], 'text' => $tocItem['text'], 'toctitle' => $tocItem['toctitle'], 'conflicts' => PonyDocsBranchInheritEngine::getConflicts($product, $tocItem['title'], $targetVersion));
                     /**
                      * We want to set to empty, so the UI javascript doesn't 
                      * bork out on this.
                      */
                     if ($tempEntry['conflicts'] == false) {
                         $tempEntry['conflicts'] = '';
                     }
                     $result[$manualName]['sections'][$section]['topics'][] = $tempEntry;
                 }
             }
         }
         foreach ($result as $manualName => $manual) {
             foreach ($manual['sections'] as $sectionIndex => $section) {
                 if (count($section['topics']) == 0) {
                     unset($result[$manualName]['sections'][$sectionIndex]);
                 }
             }
         }
     }
     $result = json_encode($result);
     return $result;
 }