Example #1
0
 /**
  * Return the colon-separated link with actual version (not base version) for the link to SpecialDocumentLinks
  */
 public static function getDocumentLinksArticle()
 {
     global $wgTitle;
     $partialUrl = '';
     $currentVersion = PonyDocsProductVersion::GetSelectedVersion(PonyDocsProduct::GetSelectedProduct(), false);
     $partialUrl = htmlspecialchars($wgTitle->getPartialURL());
     $partialUrlParts = explode(':', $partialUrl);
     if (isset($partialUrlParts[3]) && isset($currentVersion)) {
         $partialUrl = str_replace($partialUrlParts[3], $currentVersion, $partialUrl);
     }
     return $partialUrl;
 }
 /**
  * Used to render a hidden text field which will hold what version we were 
  * in.  This forced the following edit submission to put us back in the 
  * version we were browsing.
  */
 public static function onShowEditFormFields(&$editpage, &$output)
 {
     // Add our form element to the top of the form.
     $product = PonyDocsProduct::GetSelectedProduct();
     $version = PonyDocsProductVersion::GetSelectedVersion($product);
     $output->mBodytext .= "<input type=\"hidden\" name=\"ponydocsversion\" value=\"" . $version . "\" />";
     $output->mBodytext .= "<input type=\"hidden\" name=\"ponydocsproduct\" value=\"" . $product . "\" />";
     return true;
 }
Example #3
0
 /**
  * Called when an unknown action occurs on url.  We are only interested in zipmanual 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 zipmanual
     if ($action != 'zipmanual') {
         return true;
     }
     $zipAllowed = false;
     PonyDocsExtension::onUserCan($wgTitle, $wgUser, 'zipmanual', &$zipAllowed);
     if (!$zipAllowed) {
         error_log("WARNING [" . __METHOD__ . "] User attempted to perform a ZIP Export without permission.");
         $defaultRedirect = PonyDocsExtension::getDefaultUrl();
         header("Location: " . $defaultRedirect);
         exit;
     }
     // 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);
     // Any potential titles to exclude
     $exclude = array();
     // 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);
         $toc = new PonyDocsTOC($pManual, $v, $pProduct);
         list($manualtoc, $tocprev, $tocnext, $tocstart) = $toc->loadContent();
         // We successfully got our table of contents.  It's
         // stored in $manualtoc
         foreach ($manualtoc as $tocEntry) {
             if ($tocEntry['level'] > 0 && strlen($tocEntry['title']) > 0) {
                 $title = Title::newFromText($tocEntry['title']);
                 $articles[$tocEntry['section']][] = array('title' => $title, 'text' => $tocEntry['text']);
             }
         }
     } else {
         error_log("WARNING [" . __METHOD__ . "] " . php_uname('n') . ": User attempted to export ZIP from a non TOC page with path:" . $wgTitle->__toString());
     }
     $html = self::getManualHTML($pProduct, $pManual, $v);
     $coverPageHTML = self::getCoverPageHTML($pProduct, $pManual, $v, false);
     // Make a temporary directory to store our archive contents.
     $tempDirPath = sys_get_temp_dir() . '/ponydocs-zip-export-' . time();
     $success = @mkdir($tempDirPath);
     if (!$success) {
         error_log("FATAL [" . __METHOD__ . "] Failed to create temporary directory " . $tempDirPath . " for Zip Export.");
         throw new Exception('Failed to create temporary directory for Zip Export.');
     }
     // Now, let's fetch all the img elements for both and grab them all in
     // parallel.
     $imgData = array();
     // Initialize our RollingCurl instance
     $rollingCurl = new \RollingCurl\RollingCurl();
     $mh = curl_multi_init();
     $manualDoc = new DOMDocument();
     @$manualDoc->loadHTML($html);
     $coverPageDoc = new DOMDocument();
     @$coverPageDoc->loadHTML($coverPageHTML);
     self::prepareImageRequests($manualDoc, $rollingCurl, $tempDirPath, &$imgData);
     self::prepareImageRequests($coverPageDoc, $rollingCurl, $tempDirPath, &$imgData);
     // Execute the RollingCurl requests
     $rollingCurl->execute();
     // Now update all our image elements in our appropriate DOMDocs.
     foreach ($imgData as $img) {
         // Put the data into it.
         file_put_contents($img['local_path'], $img['request']->getResponseText());
         // Modify element
         $img['element']->setAttribute('src', $img['new_path']);
         // Do curl cleanup
     }
     $html = $manualDoc->saveHTML();
     $coverPageHTML = $coverPageDoc->saveHTML();
     // Write the HTML to a tmp file
     $file = tempnam($tempDirPath, "zipexport-");
     $fh = fopen($file, 'w+');
     fwrite($fh, $html);
     fclose($fh);
     // Okay, write the title page
     $titlepagefile = tempnam($tempDirPath, "zipexport-");
     $fh = fopen($titlepagefile, 'w+');
     fwrite($fh, $coverPageHTML);
     fclose($fh);
     // Disable output of our standard mediawiki output.  We will be outputting a zip file instead.
     $wgOut->disable();
     // Create ZIP Archive which contains a cover and manual html
     $zip = new ZipArchive();
     $tempZipFilePath = tempnam($tempDirPath, "zipexport-");
     $zipFileName = $productName . '-' . $versionText . '-' . $pManual->getShortName() . '.zip';
     $zip->open($tempZipFilePath, ZipArchive::OVERWRITE);
     $zip->addFile($titlepagefile, 'cover.html');
     $zip->addFile($file, 'manual.html');
     // Iterate through all the images
     foreach ($imgData as $img) {
         $zip->addFile($img['local_path'], $img['new_path']);
     }
     $zip->close();
     header("Content-Type: application/zip");
     header("Content-Length: " . filesize($tempZipFilePath));
     header("Content-Disposition: attachment; filename=\"" . $zipFileName . "\"");
     readfile($tempZipFilePath);
     // Now remove all temp files
     self::rrmdir($tempDirPath);
     // Okay, let's add an entry to the error log to dictate someone requested a pdf
     error_log("INFO [" . __METHOD__ . "] " . php_uname('n') . ": zip export serve username=\"" . $wgUser->getName() . "\" version=\"{$versionText}\" " . " manual=\"" . $pManual->getShortName() . "\"");
     // No more processing
     return false;
 }
Example #4
0
/**
 * This is called when {{#manual:short|long}} is found in an article content. It should produce an output
 * set of HTML which provides the name (long) as a link to the most recent (based on version tags) TOC
 * management page for that manual.
 *
 * @param Parser $parser
 * @param string $shortName Short name of the Manual used in links.
 * @param string $longName Long/display name of Manual.
 * @param string $categories The categories for the Manual, in a comma-separated list
 * @return array
 */
function efManualParserFunction_Render(&$parser, $shortName = '', $longName = '', $categories = '')
{
    global $wgArticlePath;
    $valid = TRUE;
    if (!preg_match(PONYDOCS_PRODUCTMANUAL_REGEX, $shortName) || !strlen($shortName) || !strlen($longName)) {
        return $parser->insertStripItem('', $parser->mStripState);
    }
    $manualName = preg_replace('/([^' . PONYDOCS_PRODUCTMANUAL_LEGALCHARS . ']+)/', '', $shortName);
    // TODO: It's silly to do this twice (the other is in LoadManualsForProduct().
    //       We should get the manual object from PonyDocsProductManual
    $static = FALSE;
    if (strpos($shortName, PONYDOCS_PRODUCT_STATIC_PREFIX) === 0) {
        $static = TRUE;
        $manualName = substr($manualName, strlen(PONYDOCS_PRODUCT_STATIC_PREFIX));
    }
    $productName = PonyDocsProduct::GetSelectedProduct();
    $version = PonyDocsProductVersion::GetSelectedVersion($productName);
    // Don't cache Documentation:[product]:Manuals pages because when we switch selected version the content will come from cache
    $parser->disableCache();
    // If static, link to Special:StaticDocImport
    if ($static) {
        $output = "<p><a href=\"" . str_replace('$1', "Special:StaticDocImport/{$productName}/{$manualName}", $wgArticlePath) . "\" style=\"font-size: 1.3em;\">{$longName}</a></p>\n" . "<span style=\"padding-left: 20px;\">Click manual to manage static documentation.</span>\n";
        // Otherwise, link to TOC for current Version OR add a link to create a new TOC if none exists
    } else {
        // TODO: We should call PonyDocsTOC.php or maybe PonyDocsProductManual to see if there's a TOC in this manual
        //       or maybe actually get the manual object and query it
        $dbr = wfGetDB(DB_SLAVE);
        $res = $dbr->select(array('categorylinks', 'page'), 'page_title', array('cl_from = page_id', 'page_namespace = "' . NS_PONYDOCS . '"', "cl_to = 'V:{$productName}:{$version}'", 'cl_type = "page"', "cl_sortkey LIKE '" . $dbr->strencode(strtoupper($productName)) . ':' . $dbr->strencode(strtoupper($manualName)) . "TOC%'"), __METHOD__);
        if (!$res->numRows()) {
            /**
             * Link to create new TOC page -- should link to current version TOC and then add message to explain.
             */
            $output = '<p><a href="' . str_replace('$1', PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':' . $productName . ':' . $manualName . 'TOC' . $version, $wgArticlePath) . '" style="font-size: 1.3em;">' . $longName . "</a></p>\n <span style=\"padding-left: 20px;\">Click manual to create TOC for current version (" . $version . ").</span>\n";
        } else {
            $row = $dbr->fetchObject($res);
            $output = '<p><a href="' . str_replace('$1', PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ":{$row->page_title}", $wgArticlePath) . '" style="font-size: 1.3em;">' . $longName . "</a></p>\n";
        }
    }
    if ($categories != '') {
        $output .= "<br>Categories: {$categories}";
    }
    return $parser->insertStripItem($output, $parser->mStripState);
}
Example #5
0
 /**
  * Create a URL path (e.g. Documentation/Foo/latest/Bar/Bas) for a Topic
  * 
  * @param string $productName
  * @param string $manualName
  * @param string $topicName
  * @param string $versionName - Optional. We'll get the selected version (which defaults to 'latest') if empty
  * 
  * @return string
  * 
  * TODO: We should really be passing a topic object into this and not a string
  */
 public static function getTopicURLPath($productName, $manualName, $topicName, $versionName = NULL)
 {
     global $wgArticlePath;
     if (!isset($versionName)) {
         $versionName = PonyDocsProductVersion::GetSelectedVersion($productName);
     }
     $latestVersion = PonyDocsProductVersion::GetLatestReleasedVersion($productName);
     if ($latestVersion) {
         if ($versionName == $latestVersion->getVersionName()) {
             $versionName = 'latest';
         }
     }
     $base = str_replace('$1', PONYDOCS_DOCUMENTATION_NAMESPACE_NAME, $wgArticlePath);
     return "{$base}/{$productName}/{$versionName}/{$manualName}/{$topicName}";
 }
Example #6
0
    function execute()
    {
        global $action, $IP, $wgArticlePath, $wgContLang, $wgExtraNamespaces, $wgRequest, $wgRevision, $wgTitle, $wgUser;
        PonyDocsProduct::LoadProducts();
        $this->data['selectedProduct'] = PonyDocsProduct::GetSelectedProduct();
        PonyDocsProductVersion::LoadVersionsForProduct($this->data['selectedProduct']);
        PonyDocsProductManual::LoadManualsForProduct($this->data['selectedProduct']);
        $ponydocs = PonyDocsWiki::getInstance($this->data['selectedProduct']);
        $this->data['products'] = $ponydocs->getProductsForTemplate();
        $this->data['versions'] = $ponydocs->getVersionsForProduct($this->data['selectedProduct']);
        $this->data['namespaces'] = $wgExtraNamespaces;
        $this->data['selectedVersion'] = PonyDocsProductVersion::GetSelectedVersion($this->data['selectedProduct']);
        $this->data['pVersion'] = PonyDocsProductVersion::GetVersionByName($this->data['selectedProduct'], $this->data['selectedVersion']);
        if (PONYDOCS_DEBUG) {
            error_log("DEBUG [" . __METHOD__ . "] selected product/version is set to " . $this->data['selectedProduct'] . "/" . $this->data['selectedVersion']);
        }
        $this->data['versionurl'] = $this->data['wgScript'] . '?title=' . $this->data['thispage'] . '&action=changeversion';
        $this->skin = $this->data['skin'];
        // TODO remove this, and replace elsewhere (template files mostly) with $this->skin
        $skin = $this->data['skin'];
        if ($this->skin->getTitle()) {
            $this->data['canonicalURI'] = $this->skin->getTitle()->getFullURL();
        }
        $action = $wgRequest->getText('action');
        // Suppress warnings to prevent notices about missing indexes in $this->data
        wfSuppressWarnings();
        /**
         * When displaying a page we output header.php, then a sub-template, and then footer.php. The namespace
         * which we are in determines the sub-template, which is named 'ns<Namespace>'. It defaults to our
         * nsDefault.php template. 
         */
        $this->data['namespace'] = $wgContLang->getNsText($wgTitle->getNamespace());
        $idx = $this->data['namespace'] ? "NS:{$this->data['namespace']}" : 'T:' . $wgTitle->__toString();
        if (!isset($this->_methodMappings[$idx])) {
            $idx = 0;
        }
        $inDocumentation = FALSE;
        if ($this->data['namespace'] == PONYDOCS_DOCUMENTATION_NAMESPACE_NAME || $wgTitle->__toString() == PONYDOCS_DOCUMENTATION_NAMESPACE_NAME || preg_match('/^' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':/', $wgTitle->__toString())) {
            $inDocumentation = TRUE;
            $this->prepareDocumentation();
        }
        $this->data['versions'] = $ponydocs->getVersionsForProduct($this->data['selectedProduct']);
        $this->html('headelement');
        ?>
		<script type="text/javascript">
			function AjaxChangeProduct_callback( o ) {
				document.getElementById( 'docsProductSelect' ).disabled = true;
				var s = new String( o.responseText );
				document.getElementById( 'docsProductSelect' ).disabled = false;
				window.location.href = s;
			}

			function AjaxChangeProduct() {
				var productIndex = document.getElementById( 'docsProductSelect' ).selectedIndex;
				var product = document.getElementById( 'docsProductSelect' )[productIndex].value;
				var title = '<?php 
        Xml::escapeJsString($this->data['thispage']);
        ?>
';
				sajax_do_call( 'efPonyDocsAjaxChangeProduct', [product,title], AjaxChangeProduct_callback );
			}

			function AjaxChangeVersion_callback( o ) {
				document.getElementById( 'docsVersionSelect' ).disabled = true;
				var s = new String( o.responseText );
				document.getElementById( 'docsVersionSelect' ).disabled = false;
				window.location.href = s;
			}

			function AjaxChangeVersion() {
				var productIndex = document.getElementById( 'docsProductSelect' ).selectedIndex;
				var product = document.getElementById( 'docsProductSelect' )[productIndex].value;
				var versionIndex = document.getElementById( 'docsVersionSelect' ).selectedIndex;
				var version = document.getElementById( 'docsVersionSelect' )[versionIndex].value;
				var title = '<?php 
        Xml::escapeJsString($this->data['thispage']);
        ?>
';
				sajax_do_call( 'efPonyDocsAjaxChangeVersion', [product,version,title], AjaxChangeVersion_callback );
			}

			function changeManual(){
				var url = $( "#docsManualSelect" ).val();
				if ( url != "" ){
					window.location.href = url;
				}
			}
		</script>
		<div id="globalWrapper">

			<div id="column-content">
				<div id="content" <?php 
        $this->html("specialpageattributes");
        ?>
>
					<a id="top"></a>
					<?php 
        if ($this->data['sitenotice']) {
            ?>
						<div id="siteNotice"><?php 
            $this->html('sitenotice');
            ?>
</div>
						<?php 
        }
        ?>

					<?php 
        if (!$inDocumentation) {
            ?>
						<h1 id="firstHeading" class="firstHeading"><?php 
            $this->html('title');
            ?>
</h1>
						<?php 
        }
        ?>
					<div id="bodyContent">
						<h3 id="siteSub"><?php 
        $this->msg('tagline');
        ?>
</h3>
						<div id="contentSub"<?php 
        $this->html('userlangattributes');
        ?>
><?php 
        $this->html('subtitle');
        ?>
</div>
						<?php 
        if ($this->data['undelete']) {
            ?>
							<div id="contentSub2"><?php 
            $this->html('undelete');
            ?>
</div>
							<?php 
        }
        if ($this->data['newtalk']) {
            ?>
							<div class="usermessage"><?php 
            $this->html('newtalk');
            ?>
</div>
							<?php 
        }
        if ($this->data['showjumplinks']) {
            ?>
							<div id="jump-to-nav">
								<?php 
            $this->msg('jumpto');
            ?>
 <a href="#column-one"><?php 
            $this->msg('jumptonavigation');
            ?>
</a>,
								<a href="#searchInput"><?php 
            $this->msg('jumptosearch');
            ?>
</a>
							</div>
							<?php 
        }
        // Version group message, if any
        if ($this->data['versionGroupMessage'] !== null) {
            ?>
							<div class="affectedVersions
								<?php 
            echo implode(" ", $this->data['versionclasses']);
            ?>
">
								<p class="bannerVersion">
									<?php 
            echo $this->data['versionGroupMessage'];
            ?>
								</p>
							</div>
							<?php 
        }
        ?>
						<!-- start content -->
						<?php 
        $this->html('bodytext');
        if ($this->data['catlinks']) {
            $this->html('catlinks');
        }
        ?>
						<!-- end content -->
						<?php 
        if ($this->data['dataAfterContent']) {
            $this->html('dataAfterContent');
        }
        ?>
						<div class="visualClear"></div>
					</div>
				</div>
			</div>
			<div id="column-one"<?php 
        $this->html('userlangattributes');
        ?>
>
				<div id="p-cactions" class="portlet">
					<h5><?php 
        $this->msg('views');
        ?>
</h5>
					<div class="pBody">
						<ul><?php 
        foreach ($this->data['content_actions'] as $key => $tab) {
            echo '
							 <li id="' . Sanitizer::escapeId("ca-{$key}") . '"';
            if ($tab['class']) {
                echo ' class="' . htmlspecialchars($tab['class']) . '"';
            }
            echo '><a href="' . htmlspecialchars($tab['href']) . '"';
            # We don't want to give the watch tab an accesskey if the
            # page is being edited, because that conflicts with the
            # accesskey on the watch checkbox. We also don't want to
            # give the edit tab an accesskey, because that's fairly su-
            # perfluous and conflicts with an accesskey (Ctrl-E) often
            # used for editing in Safari.
            if (in_array($action, array('edit', 'submit')) && in_array($key, array('edit', 'watch', 'unwatch'))) {
                echo $skin->tooltip("ca-{$key}");
            } else {
                echo Xml::expandAttributes($skin->tooltipAndAccesskeyAttribs("ca-{$key}"));
            }
            echo '>' . htmlspecialchars($tab['text']) . '</a></li>';
        }
        ?>

						</ul>
					</div>
				</div>
				<div class="portlet" id="p-personal">
					<h5><?php 
        $this->msg('personaltools');
        ?>
</h5>
					<div class="pBody">
						<ul<?php 
        $this->html('userlangattributes');
        ?>
>
						<?php 
        foreach ($this->data['personal_urls'] as $key => $item) {
            ?>
							<li id="<?php 
            echo Sanitizer::escapeId("pt-{$key}");
            ?>
"
							<?php 
            if ($item['active']) {
                ?>
								class="active"
								<?php 
            }
            ?>
>
								<a href="<?php 
            echo htmlspecialchars($item['href']);
            ?>
"
									<?php 
            echo Xml::expandAttributes($skin->tooltipAndAccesskeyAttribs('pt-' . $key));
            if (!empty($item['class'])) {
                ?>
										class="<?php 
                echo htmlspecialchars($item['class']);
                ?>
"
										<?php 
            }
            ?>
>
									<?php 
            echo htmlspecialchars($item['text']);
            ?>
								</a>
							</li>
							<?php 
        }
        ?>
						</ul>
					</div>
				</div>
				<div class="portlet" id="p-logo">
					<a style="background-image: url(<?php 
        $this->text('logopath');
        ?>
);" 
					   href="<?php 
        echo htmlspecialchars($this->data['nav_urls']['mainpage']['href']);
        ?>
"
						<?php 
        echo Xml::expandAttributes($skin->tooltipAndAccesskeyAttribs('p-logo'));
        ?>
></a><br />
				</div>
				<script type="<?php 
        $this->text('jsmimetype');
        ?>
">
					if ( window.isMSIE55 ) {
						fixalpha();
					} 
				</script>
				<div id="p-documentation" class="portlet">
					<h5>documentation</h5>
					<div id="documentationBody" class="pBody">
						<?php 
        if (!count($this->data['products'])) {
            ?>
							<p>No products defined.</p>
							<?php 
        } else {
            ?>
							<div class="product">
								<label for='docsProductSelect' class="navlabels">Product:&nbsp;</label><br />
								<select id="docsProductSelect" name="selectedProduct" onChange="AjaxChangeProduct();">
									<?php 
            $this->hierarchicalProductSelect();
            ?>
								</select>
							</div>
							<?php 
            $versions = PonyDocsProductVersion::GetVersions($this->data['selectedProduct'], TRUE);
            if (!count($versions)) {
                ?>
									<p>No Product Versions Defined.</p>
									<?php 
            } else {
                $manuals = PonyDocsProductManual::GetDefinedManuals($this->data['selectedProduct'], TRUE);
                if (!count($manuals)) {
                    ?>
										<p>The product manual you requested is not defined, you are not logged in,
											or you do not have the correct permissions to view this content.</p>
										<?php 
                } else {
                    ?>
										<p>
											<div class="productVersion">
												<?php 
                    // do quick manip
                    $found = FALSE;
                    for ($i = count($this->data['versions']) - 1; $i >= 0; $i--) {
                        $this->data['versions'][$i]['label'] = $this->data['versions'][$i]['name'];
                        if (!$found && $this->data['versions'][$i]['status'] == "released") {
                            $this->data['versions'][$i]['label'] .= " (latest release)";
                            $found = TRUE;
                        }
                    }
                    ?>
												<label for='docsVersionSelect' class="navlabels">Product version:&nbsp;</label><br />
												<select id="docsVersionSelect" name="selectedVersion" onChange="AjaxChangeVersion();">
													<?php 
                    foreach ($this->data['versions'] as $idx => $data) {
                        echo '<option value="' . $data['name'] . '" ';
                        if (!strcmp($data['name'], $this->data['selectedVersion'])) {
                            echo 'selected';
                        }
                        echo '>' . $data['label'] . '</option>';
                    }
                    ?>
												</select>
											</div>
											<div class="productManual">
												<label for="docsManualSelect" class="navlabels">Select manual:&nbsp;</label><br />
												<select id="docsManualSelect" name="selectedManual" onChange="changeManual();">
													<?php 
                    $navData = PonyDocsExtension::fetchNavDataForVersion($this->data['selectedProduct'], $this->data['selectedVersion']);
                    print "<option value=''>Pick One...</option>";
                    //loop through nav array and look for current URL
                    foreach ($navData as $manual) {
                        $selected = "";
                        if (!strcmp($this->data['manualname'], $manual['longName'])) {
                            $selected = " selected ";
                        }
                        print "<option value='" . $manual['firstUrl'] . "'   {$selected}>";
                        print $manual['longName'];
                        print "<!-- categories: {$manual['categories']} -->";
                        print '</option>';
                    }
                    ?>
												</select>
											</div>
										</p>
										<p>
											<?php 
                    if (sizeof($this->data['manualtoc'])) {
                        ?>
												<p>
													<a href="<?php 
                        echo str_replace('$1', '', $wgArticlePath);
                        ?>
index.php?title=<?php 
                        echo $wgTitle->__toString();
                        ?>
&action=pdfbook">Pdf Version</a>
												</p>
												<?php 
                        $inUL = FALSE;
                        $listid = "";
                        foreach ($this->data['manualtoc'] as $idx => $data) {
                            if (0 == $data['level']) {
                                if ($inUL) {
                                    echo '</ul></div>';
                                    $inUL = FALSE;
                                }
                                $listid = "list" . $idx;
                                echo '<div class="wikiSidebarBox collapsible">';
                                echo '<h3>' . $data['text'] . '</h3>';
                                echo '<ul>';
                                $inUL = TRUE;
                            } elseif (1 == $data['level']) {
                                if ($data['current']) {
                                    echo '<li class="expanded">' . $data['text'] . '</li>';
                                } else {
                                    echo '<li><a href="' . wfUrlencode($data['link']) . '">' . $data['text'] . '</a></li>';
                                }
                            } else {
                                if ($data['current']) {
                                    echo '<li class="expanded" style="margin-left: 13px;">' . $data['text'] . '</li>';
                                } else {
                                    echo '<li style="margin-left: 13px;"><a href="' . wfUrlencode($data['link']) . '">' . $data['text'] . '</a></li>';
                                }
                            }
                        }
                        if ($inUL) {
                            echo '</ul></div>';
                        }
                    }
                    ?>
										</p>
										<?php 
                }
            }
        }
        ?>
					</div>
				</div>
				<?php 
        $sidebar = $this->data['sidebar'];
        if (!isset($sidebar['SEARCH'])) {
            $sidebar['SEARCH'] = TRUE;
        }
        if (!isset($sidebar['TOOLBOX'])) {
            $sidebar['TOOLBOX'] = TRUE;
        }
        if (!isset($sidebar['LANGUAGES'])) {
            $sidebar['LANGUAGES'] = TRUE;
        }
        foreach ($sidebar as $boxName => $cont) {
            if ($boxName == 'SEARCH') {
                $this->searchBox();
            } elseif ($boxName == 'TOOLBOX') {
                $this->toolbox();
            } elseif ($boxName == 'LANGUAGES') {
                $this->languageBox();
            } else {
                $this->customBox($boxName, $cont);
            }
        }
        ?>
			</div><!-- end of the left (by default at least) column -->
			<div class="visualClear"></div>
			<div id="footer"<?php 
        $this->html('userlangattributes');
        ?>
>
				<?php 
        if ($this->data['poweredbyico']) {
            ?>
					<div id="f-poweredbyico"><?php 
            $this->html('poweredbyico');
            ?>
</div>
					<?php 
        }
        if ($this->data['copyrightico']) {
            ?>
					<div id="f-copyrightico"><?php 
            $this->html('copyrightico');
            ?>
</div>
					<?php 
        }
        // Generate additional footer links
        $footerlinks = array('lastmod', 'viewcount', 'numberofwatchingusers', 'credits', 'copyright', 'privacy', 'about', 'disclaimer', 'tagline');
        $validFooterLinks = array();
        foreach ($footerlinks as $aLink) {
            if (isset($this->data[$aLink]) && $this->data[$aLink]) {
                $validFooterLinks[] = $aLink;
            }
        }
        if (count($validFooterLinks) > 0) {
            ?>
	
					<ul id="f-list">
						<?php 
            foreach ($validFooterLinks as $aLink) {
                if (isset($this->data[$aLink]) && $this->data[$aLink]) {
                    ?>
								<li id="<?php 
                    echo $aLink;
                    ?>
"><?php 
                    $this->html($aLink);
                    ?>
</li>
								<?php 
                }
            }
            ?>
					</ul>
					<?php 
        }
        ?>
			</div>
		</div>
		<?php 
        $this->html('bottomscripts');
        /* JS call to runBodyOnloadHook */
        ?>
		<?php 
        $this->html('reporttime');
        ?>
		<?php 
        if ($this->data['debug']) {
            ?>
			<!-- Debug output: <?php 
            $this->text('debug');
            ?>
 -->
			<?php 
        }
        ?>
	</body>
</html>
		<?php 
        wfRestoreWarnings();
    }
Example #7
0
 /**
  * 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;
 }
Example #8
0
    /**
     * This is called upon loading the special page.  It should write output to the page with $wgOut.
     */
    public function execute()
    {
        global $wgOut, $wgArticlePath, $wgScriptPath;
        global $wgUser;
        $dbr = wfGetDB(DB_SLAVE);
        $this->setHeaders();
        $wgOut->setPagetitle('Documentation Branch And Inheritance');
        // if title is set we have our product and manual, else take selected product
        if (isset($_GET['titleName'])) {
            if (!preg_match('/' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':(.*):(.*):(.*):(.*)/', $_GET['titleName'], $match)) {
                throw new Exception("Invalid Title to Branch From");
            }
            $forceProduct = $match[1];
            $forceManual = $match[2];
        } else {
            $forceProduct = PonyDocsProduct::GetSelectedProduct();
            $ponydocs = PonyDocsWiki::getInstance($forceProduct);
            $products = $ponydocs->getProductsForTemplate();
        }
        // Security Check
        $authProductGroup = PonyDocsExtension::getDerivedGroup(PonyDocsExtension::ACCESS_GROUP_PRODUCT, $forceProduct);
        $groups = $wgUser->getGroups();
        if (!in_array($authProductGroup, $groups)) {
            $wgOut->addHTML("<p>Sorry, but you do not have permission to access this Special page.</p>");
            return;
        }
        // Static product check
        if (PonyDocsProduct::GetProductByShortName($forceProduct)->isStatic()) {
            $wgOut->addHTML("<p>Sorry, but you cannot branch/inherit a static product.</p>");
            return;
        }
        ob_start();
        // Grab all versions available for product
        // We need to get all versions from PonyDocsProductVersion
        $versions = PonyDocsProductVersion::GetVersions($forceProduct);
        if (isset($_GET['titleName'])) {
            ?>
			<input type="hidden" id="force_titleName" value="<?php 
            echo $_GET['titleName'];
            ?>
" />
			<input type="hidden" id="force_sourceVersion" value="<?php 
            echo PonyDocsProductVersion::GetVersionByName($forceProduct, PonyDocsProductVersion::GetSelectedVersion($forceProduct))->getVersionName();
            ?>
" />
			<input type="hidden" id="force_manual" value="<?php 
            echo $forceManual;
            ?>
" />
			<?php 
        }
        ?>

		<input type="hidden" id="force_product" value="<?php 
        echo $forceProduct;
        ?>
" />
		<div id="docbranchinherit">
		<a name="top"></a>
		<div class="versionselect">
			<h1>Branch and Inheritance Console</h1>

			Begin by selecting your product, source version material and a target version below.  You will then be presented with additional screens to specify branch and inherit behavior.
			<?php 
        if (isset($_GET['titleName'])) {
            ?>
				<p>
				Requested Operation on Single Topic: <strong><?php 
            echo $_GET['titleName'];
            ?>
</strong>
				</p>
				<?php 
        }
        ?>

			<h2>Choose a Product</h2>

			<?php 
        if (isset($_GET['titleName'])) {
            ?>
				You have selected a product: <?php 
            echo $forceProduct;
            ?>
			<?php 
        } else {
            if (!count($products)) {
                print "<p>No products defined.</p>";
            } else {
                ?>
				<div class="product">
					<select id="docsProductSelect1" name="selectedProduct" onChange="AjaxChangeProduct1();">
					<?php 
                foreach ($products as $idx => $data) {
                    echo '<option value="' . $data['name'] . '" ';
                    if (!strcmp($data['name'], $forceProduct)) {
                        echo 'selected';
                    }
                    echo '>' . $data['label'] . '</option>';
                }
                ?>
					</select>
				</div>

				<script language="javascript">
				function AjaxChangeProduct1_callback( o ) {
					document.getElementById('docsProductSelect1').disabled = true;
					var s = new String( o.responseText );
					document.getElementById('docsProductSelect1').disabled = false;
					window.location.href = s;
				}

				function AjaxChangeProduct1( ) {
					var productIndex = document.getElementById('docsProductSelect1').selectedIndex;
					var product = document.getElementById('docsProductSelect1')[productIndex].value;
					var title = '<?php 
                echo $_SERVER['REQUEST_URI'];
                ?>
'; // TODO fix this title
					var force = true;
					sajax_do_call( 'efPonyDocsAjaxChangeProduct', [product,title,force], AjaxChangeProduct1_callback,true);
				}
				</script>


			<?php 
            }
        }
        ?>

			<h2>Choose a Source Version</h2>
			<?php 
        // Determine if topic was set, if so, we should fetch version from currently selected version.
        if (isset($_GET['titleName'])) {
            $version = PonyDocsProductVersion::GetVersionByName($forceProduct, PonyDocsProductVersion::GetSelectedVersion($forceProduct));
            ?>
					You have selected a topic.  We are using the version you are currently browsing: <?php 
            echo $version->getVersionName();
            ?>
					<?php 
        } else {
            ?>
					<select name="version" id="versionselect_sourceversion">
						<?php 
            foreach ($versions as $version) {
                ?>
							<option value="<?php 
                echo $version->getVersionName();
                ?>
"><?php 
                echo $version->getVersionName() . " - " . $version->getVersionStatus();
                ?>
</option>
							<?php 
            }
            ?>
					</select>
					<?php 
        }
        ?>
			<h2>Choose a Target Version</h2>
			<select name="version" id="versionselect_targetversion">
				<?php 
        foreach ($versions as $version) {
            ?>
					<option value="<?php 
            echo $version->getVersionName();
            ?>
"><?php 
            echo $version->getVersionName() . " - " . $version->getVersionStatus();
            ?>
</option>
					<?php 
        }
        ?>
			</select>
			<p>
			<input type="button" id="versionselect_submit" value="Continue to Manuals" />
			</p>
		</div>

		<div class="manualselect" style="display: none;">
			<?php 
        if (isset($_GET['titleName'])) {
            ?>
				<p>
				Requested Operation on Single Topic: <strong><?php 
            echo $_GET['titleName'];
            ?>
</strong>
				</p>
				<?php 
        }
        ?>
			<p class="summary">
				<strong>Source Version:</strong> <span class="sourceversion"></span> <strong>Target Version:</strong> <span class="targetversion"></span>
			</p>
			<h1>Choose Manuals To Branch/Inherit From</h1>	
			<div id="manualselect_manuals">

			</div>
			<h1>Choose Default Action For Topics</h1>
			<input type="radio" selected="selected" name="manualselect_action" value="ignore" id="manualselect_action_ignore"><label for="manualselect_action_ignore">Ignore - Do Nothing</label><br />
			<input type="radio" name="manualselect_action" value="inherit" id="manualselect_action_inherit"><label for="manualselect_action_inherit">Inherit - Add Target Version to Existing Topic</label><br />
			<input type="radio" name="manualselect_action" value="branch" id="manualselect_action_branch"><label for="manualselect_action_branch">Branch - Create a copy of existing topic with Target Version</label><br />
			<br />
			<input type="button" id="manualselect_submit" value="Continue to Topics" />
		</div>
		<div class="topicactions" style="display: none;">
			<?php 
        if (isset($_GET['titleName'])) {
            ?>
				<p>
				Requested Operation on Single Topic: <strong><?php 
            echo $_GET['titleName'];
            ?>
</strong>
				</p>
				<?php 
        }
        ?>
			<p class="summary">
			<strong>Source Version:</strong> <span class="sourceversion"></span> <strong>Target Version:</strong> <span class="targetversion"></span>
			</p>

			<h1>Specify Topic Actions</h1>
			<div class="container">
			</div>
			<br />
			<br />
			<input type="button" id="topicactions_submit" value="Process Request" />
			<div id="progressconsole"></div>
		</div>
		<div class="completed" style="display: none;">
			<p class="summary">
				<strong>Source Version:</strong> <span class="sourceversion"></span> <strong>Target Version:</strong> <span class="targetversion"></span>
			</p>

			<h2>Process Complete</h2>
			The following is the log of the processed job.  Look it over for any potential issues that may have 
			occurred during the branch/inherit job.
			<div>
				<div class="logconsole" style="font-family: monospace; font-size: 10px;">

				</div>
			</div>
		</div>
		</div>
		<?php 
        $buffer = ob_get_clean();
        $wgOut->addHTML($buffer);
        return true;
    }