Example #1
0
 /**
  * AJAX method to fetch manuals for a specified product and version
  *
  * @param $ver string The string representation of the version to retrieve 
  * 					  manuals for.
  * @returns string JSON representation of the manuals
  */
 public static function ajaxFetchManuals($product, $ver)
 {
     PonyDocsProductVersion::LoadVersionsForProduct($product);
     PonyDocsProductVersion::SetSelectedVersion($product, $ver);
     $manuals = PonyDocsProductManual::LoadManualsForProduct($product, TRUE);
     $result = array();
     foreach ($manuals as $manual) {
         if (!$manual->isStatic()) {
             $result[] = array("shortname" => $manual->getShortName(), "longname" => $manual->getLongName());
         }
     }
     $result = json_encode($result);
     return $result;
 }
 /**
  * Hook function which
  * - Sets the version correctly when editing a topic
  * - Redirects to the first topic in a manual if the user requested a bare manual URL
  * - Redirect to the landing page when there are no available versions
  */
 public function onArticleFromTitleQuickLookup(&$title, &$article)
 {
     global $wgScriptPath;
     if (preg_match('/&action=edit/', $_SERVER['PATH_INFO'])) {
         // Check referrer and see if we're coming from a doc page.
         // If so, we're editing it, so we should force the version
         // to be from the referrer.
         if (preg_match('/^' . str_replace("/", "\\/", $wgScriptPath) . '\\/' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . '\\/(\\w+)\\/((latest|[\\w\\.]*)\\/)?(\\w+)\\/?/i', $_SERVER['HTTP_REFERER'], $match)) {
             $targetProduct = $match[1];
             $targetVersion = $match[3];
             if ($targetVersion == "latest") {
                 PonyDocsProductVersion::SetSelectedVersion($targetProduct, PonyDocsProductVersion::GetLatestReleasedVersion($targetProduct)->getVersionName());
             } else {
                 PonyDocsProductVersion::SetSelectedVersion($targetProduct, $targetVersion);
             }
         }
     }
     // Match a URL like /Documentation/PRODUCT
     if (preg_match('/^' . str_replace("/", "\\/", $wgScriptPath) . '\\/' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . '\\/([' . PONYDOCS_PRODUCT_LEGALCHARS . ']+)$/i', $_SERVER['PATH_INFO'], $match)) {
         $targetProduct = $match[1];
         $version = PonyDocsProductVersion::GetVersions($targetProduct, TRUE);
         //check for product not found
         if (empty($version)) {
             PonyDocsExtension::redirectToLandingPage();
             return true;
         }
     }
     // Matches a URL like /Documentation/PRODUCT/VERSION/MANUAL
     // TODO: Should match PONYDOCS_PRODUCTMANUAL_LEGALCHARS instead of \w at the end
     if (preg_match('/^' . str_replace("/", "\\/", $wgScriptPath) . '\\/' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . '\\/([' . PONYDOCS_PRODUCT_LEGALCHARS . ']+)\\/([' . PONYDOCS_PRODUCTVERSION_LEGALCHARS . ']+)\\/(\\w+)\\/?$/i', $_SERVER['PATH_INFO'], $match)) {
         $targetProduct = $match[1];
         $targetVersion = $match[2];
         $targetManual = $match[3];
         $p = PonyDocsProduct::GetProductByShortName($targetProduct);
         if (!$p instanceof PonyDocsProduct) {
             $wgHooks['BeforePageDisplay'][] = "PonyDocsExtension::handle404";
             return false;
         }
         // User wants to find first topic in a requested manual.
         // Load up versions
         PonyDocsProductVersion::LoadVersionsForProduct($targetProduct);
         // Determine version
         if ($targetVersion == '') {
             // No version specified, use the user's selected version
             $ver = PonyDocsProductVersion::GetVersionByName($targetProduct, PonyDocsProductVersion::GetSelectedVersion($targetProduct));
         } else {
             if (strtolower($targetVersion) == "latest") {
                 // User wants the latest version.
                 $ver = PonyDocsProductVersion::GetLatestReleasedVersion($targetProduct);
             } else {
                 // Okay, they want to get a version by a specific name
                 $ver = PonyDocsProductVersion::GetVersionByName($targetProduct, $targetVersion);
             }
         }
         if (!$ver) {
             if (PONYDOCS_DEBUG) {
                 error_log("DEBUG [" . __METHOD__ . ":" . __LINE__ . "] redirecting to {$wgScriptPath}/" . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME);
             }
             header('Location: ' . $wgScriptPath . '/' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME);
             die;
         }
         // Okay, the version is valid, let's set the user's version.
         PonyDocsProductVersion::SetSelectedVersion($targetProduct, $ver->getVersionName());
         PonyDocsProductManual::LoadManualsForProduct($targetProduct);
         $manual = PonyDocsProductManual::GetManualByShortName($targetProduct, $targetManual);
         if (!$manual) {
             // Rewrite to Main documentation
             if (PONYDOCS_DEBUG) {
                 error_log("DEBUG [" . __METHOD__ . ":" . __LINE__ . "] redirecting to {$wgScriptPath}/" . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME);
             }
             header('Location: ' . $wgScriptPath . '/' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME);
             die;
         } elseif (!$manual->isStatic()) {
             // Get the TOC out of here! heehee
             $toc = new PonyDocsTOC($manual, $ver, $p);
             list($toc, $prev, $next, $start) = $toc->loadContent();
             //Added empty check for WEB-10038
             if (empty($toc)) {
                 PonyDocsExtension::redirectToLandingPage();
                 return FALSE;
             }
             foreach ($toc as $entry) {
                 if (isset($entry['link']) && $entry['link'] != "") {
                     // We found the first article in the manual with a link.
                     // Redirect to it.
                     if (PONYDOCS_DEBUG) {
                         error_log("DEBUG [" . __METHOD__ . ":" . __LINE__ . "] redirecting to " . $entry['link']);
                     }
                     header("Location: " . $entry['link']);
                     die;
                 }
             }
             //Replace die with a warning log and redirect
             error_log("WARNING [" . __METHOD__ . ":" . __LINE__ . "] redirecting to " . PonyDocsExtension::getDefaultUrl());
             PonyDocsExtension::redirectToLandingPage();
             return FALSE;
         }
     }
     return TRUE;
 }
Example #3
0
/**
 * Our primary setup function simply handles URL rewrites for aliasing (per spec) and calls our PonyDocsWiki singleton instance
 * to ensure it runs the data retrieval functions for versions and manuals and the like. 
 */
function efPonyDocsSetup()
{
    global $wgPonyDocs, $wgScriptPath, $wgArticlePath;
    // force mediawiki to start session for anonymous traffic
    if (session_id() == '') {
        wfSetupSession();
        if (PONYDOCS_DEBUG) {
            error_log("DEBUG [" . __METHOD__ . "] started session");
        }
    }
    // Set selected product from URL
    if (preg_match('/^' . str_replace("/", "\\/", $wgScriptPath) . '\\/((index.php\\?title=)|)' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . '[\\/|:]{1}([' . PONYDOCS_PRODUCT_LEGALCHARS . ']+)[\\/|:]?/i', $_SERVER['PATH_INFO'], $match)) {
        PonyDocsProduct::SetSelectedProduct($match[3]);
    }
    // Set selected version from URL
    // - every time from /-separated title URLs
    // - only when no selected version already set from :-separated title
    $currentVersion = PonyDocsProductVersion::GetSelectedVersion(PonyDocsProduct::GetSelectedProduct(), FALSE);
    if (preg_match('/^' . str_replace("/", "\\/", $wgScriptPath) . '\\/((index.php\\?title=)|)' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . '\\/([' . PONYDOCS_PRODUCT_LEGALCHARS . ']+)\\/([' . PONYDOCS_PRODUCTVERSION_LEGALCHARS . ']+)/i', $_SERVER['PATH_INFO'], $match) || preg_match('/^' . str_replace("/", "\\/", $wgScriptPath) . '\\/((index.php\\?title=)|)' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . '\\/([' . PONYDOCS_PRODUCT_LEGALCHARS . ']+)\\/[' . PONYDOCS_PRODUCTMANUAL_LEGALCHARS . ']+TOC([' . PONYDOCS_PRODUCTVERSION_LEGALCHARS . ']+)/i', $_SERVER['PATH_INFO'], $match) || !isset($currentVersion) && preg_match('/^' . str_replace("/", "\\/", $wgScriptPath) . '\\/((index.php\\?title=)|)' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':([' . PONYDOCS_PRODUCT_LEGALCHARS . ']+):[' . PONYDOCS_PRODUCTMANUAL_LEGALCHARS . ']+TOC([' . PONYDOCS_PRODUCTVERSION_LEGALCHARS . ']+)/i', $_SERVER['PATH_INFO'], $match) || !isset($currentVersion) && preg_match('/^' . str_replace("/", "\\/", $wgScriptPath) . '\\/((index.php\\?title=)|)' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':([' . PONYDOCS_PRODUCT_LEGALCHARS . ']+):[' . PONYDOCS_PRODUCTMANUAL_LEGALCHARS . ']+:[^:]+:([' . PONYDOCS_PRODUCTVERSION_LEGALCHARS . ']+)/i', $_SERVER['PATH_INFO'], $match)) {
        $result = PonyDocsProductVersion::SetSelectedVersion($match[3], $match[4]);
        if (is_null($result)) {
            // this version isn't available to this user; go away
            $defaultRedirect = PonyDocsExtension::getDefaultUrl();
            if (PONYDOCS_DEBUG) {
                error_log("DEBUG [" . __METHOD__ . ":" . __LINE__ . "] redirecting to {$defaultRedirect}");
            }
            header("Location: " . $defaultRedirect);
            exit;
        }
    }
    PonyDocsWiki::getInstance(PonyDocsProduct::GetSelectedProduct());
}
Example #4
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;
 }
Example #5
0
/**
 * This is called when a version change occurs in the select box.  It should update the version
 * only;  to update the page the Ajax function in JS should then refresh by using history.go(0)
 * or something along those lines, otherwise the content may reflect the old version selection.
 * 
 * @param string $version New version tag to set as current.  Should be some checking.
 * @param string $title The current title that the person resides in, if any.
 * @param boolean $force Force the change, no matter if a doc is in the same version or not
 * @return AjaxResponse
 */
function efPonyDocsAjaxChangeVersion($product, $version, $title, $force = false)
{
    global $wgArticlePath;
    $dbr = wfGetDB(DB_SLAVE);
    PonyDocsProduct::SetSelectedProduct($product);
    PonyDocsProductVersion::SetSelectedVersion($product, $version);
    $response = new AjaxResponse();
    if ($force) {
        // This is coming from the search page.  let's not do any title look up,
        // and instead just pass back the same url.
        $leadingSlash = "/";
        if (substr($title, 0, 1) == "/") {
            $leadingSlash = "";
        }
        $response->addText($leadingSlash . $title);
        // Need to make the url non-relative
        return $response;
    }
    $defaultTitle = PONYDOCS_DOCUMENTATION_NAMESPACE_NAME;
    if (preg_match('/' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':(.*):(.*):(.*):(.*)/i', $title, $match)) {
        $res = $dbr->select('categorylinks', 'cl_from', array("cl_to = 'V:" . $dbr->strencode($product . ":" . $version) . "'", 'cl_type = "page"', "cl_sortkey LIKE '" . $dbr->strencode(strtoupper($product . ':' . $match[2] . ':' . $match[3])) . ":%'"), __METHOD__);
        if ($res->numRows()) {
            $response->addText(str_replace('$1', PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . '/' . $product . '/' . $version . '/' . $match[2] . '/' . $match[3], $wgArticlePath));
            if (PONYDOCS_DEBUG) {
                error_log("DEBUG [" . __METHOD__ . ":" . __LINE__ . "] ajax redirect rule 1");
            }
        } else {
            // same manual/topic doesn't exist for newly selected version, redirect to default
            $response->addText(str_replace('$1', PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . '/' . $product . '/' . $version, $wgArticlePath));
            if (PONYDOCS_DEBUG) {
                error_log("DEBUG [" . __METHOD__ . ":" . __LINE__ . "] ajax redirect rule 2");
            }
        }
    } elseif (preg_match('/' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':(.*):(Manuals|Versions)/i', $title, $match)) {
        // this is a manuals or versions page
        $add_text = str_replace('$1', PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':' . $product . ':' . $match[2], $wgArticlePath);
        /// FIXME we probably need to clear objectcache for this [product]:Manuals page, or even better, do not cache it(?)
        $response->addText($add_text);
        if (PONYDOCS_DEBUG) {
            error_log("DEBUG [" . __METHOD__ . ":" . __LINE__ . "] ajax redirect rule 3");
        }
    } elseif (preg_match('/' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . '\\/(.*)\\/(.*)\\/(.*)\\/(.*)/i', $title, $match)) {
        /**
         * Just swap out the source version tag ($match[2]) with the selected version in the output URL.
         */
        $response->addText(str_replace('$1', PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . '/' . $product . '/' . $version . '/' . $match[3] . '/' . $match[4], $wgArticlePath));
        if (PONYDOCS_DEBUG) {
            error_log("DEBUG [" . __METHOD__ . ":" . __LINE__ . "] ajax redirect rule 4");
        }
    } elseif (preg_match('/' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . '\\/(.*)\\/(.*)\\/(.*)/i', $title, $match)) {
        //Redirection for WEB-10264
        $response->addText(str_replace('$1', PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . '/' . $product . '/' . $version . '/' . $match[3], $wgArticlePath));
        if (PONYDOCS_DEBUG) {
            error_log("DEBUG [" . __METHOD__ . ":" . __LINE__ . "] ajax redirect rule to switch versions on a static manual");
        }
    } else {
        $add_text = str_replace('$1', $defaultTitle . '/' . $product . '/' . $version, $wgArticlePath);
        $response->addText($add_text);
        if (PONYDOCS_DEBUG) {
            error_log("DEBUG [" . __METHOD__ . ":" . __LINE__ . "] ajax redirect rule 5");
        }
    }
    if (PONYDOCS_DEBUG) {
        error_log("DEBUG [" . __METHOD__ . ":" . __LINE__ . "] ajax redirect result " . print_r($response, true));
    }
    return $response;
}