/** * This is an ArticleSaveComplete hook that creates topics which don't exist yet when saving a TOC. * * @param WikiPage $article * @param User $user * @param string $text * @param string $summary * @param boolean $minor * @param boolean $watch * @param $sectionanchor * @param integer $flags * * @deprecated Replace with PageContentSaveComplete hook */ public static function onArticleSave_CheckTOC(&$article, &$user, $text, $summary, $minor, $watch, $sectionanchor, &$flags) { // Dangerous. Only set the flag if you know that you should be skipping this processing. // Currently used for branch/inherit. if (PonyDocsExtension::isSpeedProcessingEnabled()) { return TRUE; } $title = $article->getTitle(); $realArticle = Article::newFromWikiPage($article, RequestContext::getMain()); $matches = array(); if (preg_match('/' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':([' . PONYDOCS_PRODUCT_LEGALCHARS . ']*):([' . PONYDOCS_PRODUCTMANUAL_LEGALCHARS . ']*)TOC([' . PONYDOCS_PRODUCTVERSION_LEGALCHARS . ']*)/i', $title->__toString(), $match)) { $dbr = wfGetDB(DB_MASTER); /** * Get all topics */ $topicRegex = '/' . PonyDocsTopic::getTopicRegex() . '/'; preg_match_all($topicRegex, $text, $matches, PREG_SET_ORDER); /** * Create any topics which do not already exist in the saved TOC. */ $pProduct = PonyDocsProduct::GetProductByShortName($match[1]); $pManual = PonyDocsProductManual::GetManualByShortName($pProduct->getShortName(), $match[2]); $pManualTopic = new PonyDocsTopic($realArticle); $manVersionList = $pManualTopic->getProductVersions(); if (!sizeof($manVersionList)) { return TRUE; } // Clear all TOC cache entries for each version. if ($pManual) { foreach ($manVersionList as $version) { PonyDocsTOC::clearTOCCache($pManual, $version, $pProduct); PonyDocsProductVersion::clearNAVCache($version); } } $earliestVersion = PonyDocsProductVersion::findEarliest($pProduct->getShortName(), $manVersionList); foreach ($matches as $m) { $wikiTopic = preg_replace('/([^' . str_replace(' ', '', Title::legalChars()) . '])/', '', $m[1]); $wikiPath = PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':' . $match[1] . ':' . $match[2] . ':' . $wikiTopic; $versionIn = array(); foreach ($manVersionList as $pV) { $versionIn[] = $pProduct->getShortName() . ':' . $pV->getVersionName(); } $res = $dbr->select(array('categorylinks'), 'cl_from', array("cl_to IN ('V:" . implode("','V:", $versionIn) . "')", 'cl_type = "page"', "cl_sortkey LIKE '" . $dbr->strencode(strtoupper("{$match[1]}:{$match[2]}:{$wikiTopic}")) . ":%'"), __METHOD__); $topicName = ''; if (!$res->numRows()) { /** * No match -- so this is a "new" topic. Set name and create. */ $topicName = PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':' . $match[1] . ':' . $match[2] . ':' . $wikiTopic . ':' . $earliestVersion->getVersionName(); $topicArticle = new Article(Title::newFromText($topicName)); if (!$topicArticle->exists()) { $content = "= " . $m[1] . "=\n\n"; foreach ($manVersionList as $pVersion) { $content .= '[[Category:V:' . $pProduct->getShortName() . ':' . $pVersion->getVersionName() . ']]'; } $topicArticle->doEdit($content, 'Auto-creation of topic ' . $topicName . ' via TOC ' . $title->__toString(), EDIT_NEW); if (PONYDOCS_DEBUG) { error_log("DEBUG [" . __METHOD__ . ":" . __LINE__ . "] Auto-created {$topicName} from TOC " . $title->__toString()); } } } } } return TRUE; }
/** * This expects to find: * {{#topic:Text Name}} * * @param Parser $parser * @param string $param1 Full text name of topic, must be converted to wiki topic name. * @return array * * TODO: Much of this function duplicates code above in efGetTitleFromMarkup(), can we DRY? * There really shouldn't be any real code in this file, just calls to class methods... */ function efTopicParserFunction_Render(&$parser, $param1 = '') { global $wgArticlePath, $wgTitle, $action; if (PonyDocsExtension::isSpeedProcessingEnabled()) { return TRUE; } /** * We ignore this parser function if not in a TOC management page. */ if (!preg_match('/' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':(.*):(.*)TOC(.*)/i', $wgTitle->__toString(), $matches)) { return FALSE; } $manualShortName = $matches[2]; $productShortName = $matches[1]; PonyDocsWiki::getInstance($productShortName); /** * Get the earliest tagged version of this TOC page and append it to the wiki page? * Ensure the manual is valid then use PonyDocsManual::getManualByShortName(). * Next attempt to get the version tags for this page -- which may be NONE -- * and from this determine the "earliest" version to which this page applies. * * TODO: This comment is duplicated above in efGetTitleFromMarkup, can we DRY? */ if (!PonyDocsProductManual::IsManual($productShortName, $manualShortName)) { return FALSE; } $pManual = PonyDocsProductManual::GetManualByShortName($productShortName, $manualShortName); $pTopic = new PonyDocsTopic(new Article($wgTitle)); /** * @FIXME: If TOC page is NOT tagged with any versions we cannot create the pages/links to the * topics, right? */ $manVersionList = $pTopic->getProductVersions(); if (!sizeof($manVersionList)) { return $parser->insertStripItem($param1, $parser->mStripState); } $earliestVersion = PonyDocsProductVersion::findEarliest($productShortName, $manVersionList); /** * Clean up the full text name into a wiki-form. This means remove spaces, #, ?, and a few other * characters which are not valid or wanted. It's not important HOW this is done as long as it is * consistent. */ $wikiTopic = preg_replace('/([^' . str_replace(' ', '', Title::legalChars()) . '])/', '', $param1); $wikiPath = PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':' . $productShortName . ':' . $manualShortName . ':' . $wikiTopic; $dbr = wfGetDB(DB_SLAVE); /** * Now look in the database for any instance of this topic name PLUS :<version>. * We need to look in categorylinks for it to find a record with a cl_to (version tag) * which is equal to the set of the versions for this TOC page. * For instance, if the TOC page was for versions 1.0 and 1.1 and our topic was 'How To Foo' * we need to find any cl_sortkey which is 'HowToFoo:%' and has a cl_to equal to 1.0 or 1.1. * There should only be 0 or 1, so we ignore anything beyond 1. * If found, we use THAT cl_sortkey as the link; * if NOT found we create a new topic, the name being the compressed topic name plus the earliest TOC version * ($earliestVersion->getName()). * We then need to ACTUALLY create it in the database, tag it with all the versions the TOC mgmt page is tagged with, * and set the H1 to the text inside the parser function. * * @fixme: Can we test if $action=save here so we don't do this on every page view? */ $versionIn = array(); foreach ($manVersionList as $pV) { $versionIn[] = $productShortName . ':' . $pV->getVersionName(); } $res = $dbr->select(array('categorylinks', 'page'), 'page_title', array('cl_from = page_id', 'page_namespace = "' . NS_PONYDOCS . '"', "cl_to IN ('V:" . implode("','V:", $versionIn) . "')", 'cl_type = "page"', "cl_sortkey LIKE '" . $dbr->strencode(strtoupper($productShortName . ':' . $manualShortName . ':' . $wikiTopic)) . ":%'"), __METHOD__); $topicName = ''; if (!$res->numRows()) { /** * No match -- so this is a "new" topic. Set name. */ $topicName = PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':' . $productShortName . ':' . $manualShortName . ':' . $wikiTopic . ':' . $earliestVersion->getVersionName(); } else { $row = $dbr->fetchObject($res); $topicName = PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ":{$row->page_title}"; } $output = '<a href="' . wfUrlencode(str_replace('$1', $topicName, $wgArticlePath)) . '">' . $param1 . '</a>'; return $parser->insertStripItem($output, $parser->mStripState); }