/** * When an article is fully saved, we want to update the doclinks for that * article in our doclinks table. Only if it's in the documentation * namepsace, however. * * @param WikiPage $article * @param User $user * @param string $text * @param string $summary * @param boolean $minor * @param boolean $watch * @param $sectionanchor * @param integer $flags * @param Revision $revision * @param Status $status * @param integer $baseRevId * * @deprecated Replace with PageContentSaveComplete hook * */ public static function onArticleSaveComplete(&$article, &$user, $text, $summary, $minoredit, $watchthis, $sectionanchor, &$flags, $revision, &$status, $baseRevId) { $title = $article->getTitle(); $realArticle = Article::newFromWikiPage($article, RequestContext::getMain()); // Update doc links PonyDocsExtension::updateOrDeleteDocLinks("update", $realArticle, $text); if (!preg_match('/^' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':/i', $title->__toString(), $matches)) { return TRUE; } // Okay, article is in doc namespace // Now we need to remove any pdf books for this topic. // Since the person is editing the article, it's safe to say that the // version and manual can be fetched from the classes and not do any // manipulation on the article itself. $productName = PonyDocsProduct::GetSelectedProduct(); $product = PonyDocsProduct::GetProductByShortName($productName); $version = PonyDocsProductVersion::GetSelectedVersion($productName); $manual = PonyDocsProductManual::GetCurrentManual($productName, $title); if ($manual != null) { // Then we are in the documentation namespace, but we're not part of // manual. // Clear any PDF for this manual PonyDocsPdfBook::removeCachedFile($productName, $manual->getShortName(), $version); } // Clear all TOC cache entries for each version. // Dangerous. Only set the flag if you know that you should be skipping this processing. // Currently used for branch/inherit. if ($manual && !PonyDocsExtension::isSpeedProcessingEnabled()) { // Clear any TOC cache entries this article may be related to. $topic = new PonyDocsTopic($realArticle); $manVersionList = $topic->getProductVersions(); foreach ($manVersionList as $version) { PonyDocsTOC::clearTOCCache($manual, $version, $product); PonyDocsProductVersion::clearNAVCache($version); } } PonyDocsExtension::clearArticleCategoryCache($realArticle); // if this is product versions or manuals page, clear navigation cache if (preg_match(PONYDOCS_PRODUCTVERSION_TITLE_REGEX, $title->__toString(), $matches) || preg_match(PONYDOCS_PRODUCTMANUAL_TITLE_REGEX, $title->__toString(), $matches)) { // reload to get updated version list PonyDocsProductVersion::LoadVersionsForProduct($productName, true); $prodVersionList = PonyDocsProductVersion::GetVersions($productName); foreach ($prodVersionList as $version) { PonyDocsProductVersion::clearNAVCache($version); } } return true; }
/** * Called when an unknown action occurs on url. We are only interested in pdfbook action. */ function onUnknownAction($action, $article) { global $wgOut, $wgUser, $wgTitle, $wgParser, $wgRequest; global $wgServer, $wgArticlePath, $wgScriptPath, $wgUploadPath, $wgUploadDirectory, $wgScript, $wgStylePath; // We don't do any processing unless it's pdfbook if ($action != 'pdfbook') { return true; } // Get the title and make sure we're in Documentation namespace $title = $article->getTitle(); if ($title->getNamespace() != NS_PONYDOCS) { return true; } // Grab parser options for the logged in user. $opt = ParserOptions::newFromUser($wgUser); // Log the export $msg = $wgUser->getUserPage()->getPrefixedText() . ' exported as a PonyDocs PDF Book'; $log = new LogPage('ponydocspdfbook', false); $log->addEntry('book', $wgTitle, $msg); // Initialise PDF variables $layout = '--firstpage p1'; $x_margin = '1.25in'; $y_margin = '1in'; $font = 'Arial'; $size = '12'; $linkcol = '4d9bb3'; $levels = '2'; $exclude = array(); $width = '1024'; $width = "--browserwidth 1024"; // Determine articles to gather $articles = array(); $pieces = explode(":", $wgTitle->__toString()); // Try and get rid of the TOC portion of the title if (strpos($pieces[2], "TOC") && count($pieces) == 3) { $pieces[2] = substr($pieces[2], 0, strpos($pieces[2], "TOC")); } else { if (count($pieces) != 5) { // something is wrong, let's get out of here $defaultRedirect = PonyDocsExtension::getDefaultUrl(); if (PONYDOCS_DEBUG) { error_log("DEBUG [" . __METHOD__ . ":" . __LINE__ . "] redirecting to {$defaultRedirect}"); } header("Location: " . $defaultRedirect); exit; } } $productName = $pieces[1]; $ponydocs = PonyDocsWiki::getInstance($productName); $pProduct = PonyDocsProduct::GetProductByShortName($productName); if ($pProduct === NULL) { // product wasn't valid wfProfileOut(__METHOD__); $wgOut->setStatusCode(404); return FALSE; } $productLongName = $pProduct->getLongName(); if (PonyDocsProductManual::isManual($productName, $pieces[2])) { $pManual = PonyDocsProductManual::GetManualByShortName($productName, $pieces[2]); } $versionText = PonyDocsProductVersion::GetSelectedVersion($productName); if (!empty($pManual)) { // We should always have a pManual, if we're printing from a TOC $v = PonyDocsProductVersion::GetVersionByName($productName, $versionText); // We have our version and our manual Check to see if a file already exists for this combination $pdfFileName = "{$wgUploadDirectory}/ponydocspdf-" . $productName . "-" . $versionText . "-" . $pManual->getShortName() . "-book.pdf"; // Check first to see if this PDF has already been created and is up to date. If so, serve it to the user and stop // execution. if (file_exists($pdfFileName)) { error_log("INFO [PonyDocsPdfBook::onUnknownAction] " . php_uname('n') . ": cache serve username=\"" . $wgUser->getName() . "\" product=\"" . $productName . "\" version=\"" . $versionText . "\" " . " manual=\"" . $pManual->getShortName() . "\""); PonyDocsPdfBook::servePdf($pdfFileName, $productName, $versionText, $pManual->getShortName()); // No more processing return false; } } else { error_log("ERROR [PonyDocsPdfBook::onUnknownAction] " . php_uname('n') . ": User attempted to print a pdfbook from a non TOC page with path:" . $wgTitle->__toString()); } $html = self::getManualHTML($pProduct, $pManual, $v); // HTMLDOC does not care for utf8. $html = utf8_decode("{$html}\n"); // Write the HTML to a tmp file $file = "{$wgUploadDirectory}/" . uniqid('ponydocs-pdf-book'); $fh = fopen($file, 'w+'); fwrite($fh, $html); fclose($fh); // Okay, create the title page $titlepagefile = "{$wgUploadDirectory}/" . uniqid('ponydocs-pdf-book-title'); $fh = fopen($titlepagefile, 'w+'); $coverPageHTML = self::getCoverPageHTML($pProduct, $pManual, $v); fwrite($fh, $coverPageHTML); fclose($fh); $format = 'manual'; /* @todo Modify so single topics can be printed in pdf */ $footer = $format == 'single' ? '...' : '.1.'; $toc = $format == 'single' ? '' : " --toclevels {$levels}"; // Send the file to the client via htmldoc converter $wgOut->disable(); $cmd = " --left {$x_margin} --right {$x_margin} --top {$y_margin} --bottom {$y_margin}"; $cmd .= " --header ... --footer {$footer} --tocfooter .i. --quiet --jpeg --color"; $cmd .= " --bodyfont {$font} --fontsize {$size} --linkstyle plain --linkcolor {$linkcol}"; $cmd .= "{$toc} --format pdf14 {$layout} {$width} --titlefile {$titlepagefile} --size letter"; $cmd = "htmldoc -t pdf --book --charset iso-8859-1 --no-numbered {$cmd} {$file} > {$pdfFileName}"; putenv("HTMLDOC_NOCGI=1"); $output = array(); $returnVar = 1; exec($cmd, $output, $returnVar); if ($returnVar != 0) { // 0 is success error_log("INFO [PonyDocsPdfBook::onUnknownAction] " . php_uname('n') . ": Failed to run htmldoc (" . $returnVar . ") Output is as follows: " . implode("-", $output)); print "Failed to create PDF. Our team is looking into it."; } // Delete the htmlfile and title file from the filesystem. @unlink($file); if (file_exists($file)) { error_log("ERROR [PonyDocsPdfBook::onUnknownAction] " . php_uname('n') . ": Failed to delete temp file {$file}"); } @unlink($titlepagefile); if (file_exists($titlepagefile)) { error_log("ERROR [PonyDocsPdfBook::onUnknownAction] " . php_uname('n') . ": Failed to delete temp file {$titlepagefile}"); } // Okay, let's add an entry to the error log to dictate someone requested a pdf error_log("INFO [PonyDocsPdfBook::onUnknownAction] " . php_uname('n') . ": fresh serve username=\"" . $wgUser->getName() . "\" version=\"{$versionText}\" " . " manual=\"" . $pManual->getLongName() . "\""); PonyDocsPdfBook::servePdf($pdfFileName, $productName, $versionText, $pManual->getLongName()); // No more processing return false; }