/** * Fetches the requested pages markup, cleans it and returns a DOMDocument. * @param array $aParams Needs the 'article-id' or 'title' key to be set and valid. * @return array */ public static function getPage($aParams) { wfRunHooks('BSUEModulePDFbeforeGetPage', array(&$aParams)); $oBookmarksDOM = new DOMDocument(); $oBookmarksDOM->loadXML('<bookmarks></bookmarks>'); $oTitle = null; if (isset($aParams['article-id'])) { $oTitle = Title::newFromID($aParams['article-id']); } if ($oTitle == null) { //HINT: This is probably the wrong place for urldecode(); Should be //done by caller. I.e. BookExportModulePDF $oTitle = Title::newFromText(urldecode($aParams['title'])); } $oPCP = new BsPageContentProvider(); $oPageDOM = $oPCP->getDOMDocumentContentFor($oTitle, $aParams + array('follow-redirects' => true)); // TODO RBV (06.12.11 17:09): Follow Redirect... setting or default? //Collect Metadata $aData = self::collectData($oTitle, $oPageDOM, $aParams); //Cleanup DOM self::cleanUpDOM($oTitle, $oPageDOM, $aParams); $oBookmarkNode = BsUniversalExportHelper::getBookmarkElementForPageDOM($oPageDOM); //HINT: http://www.mm-newmedia.de/blog/2010/05/wrong-document-error-wtf/ $oBookmarksDOM->documentElement->appendChild($oBookmarksDOM->importNode($oBookmarkNode, true)); $oDOMXPath = new DOMXPath($oPageDOM); $oFirstHeading = $oDOMXPath->query("//*[contains(@class, 'firstHeading')]")->item(0); $oBodyContent = $oDOMXPath->query("//*[contains(@class, 'bodyContent')]")->item(0); // TODO RBV (01.02.12 11:28): What if no TOC? $oTOCULElement = $oDOMXPath->query("//*[contains(@class, 'toc')]//ul")->item(0); if (isset($aParams['display-title'])) { $oBookmarkNode->setAttribute('name', $aParams['display-title']); $oFirstHeading->nodeValue = $aParams['display-title']; $aData['meta']['title'] = $aParams['display-title']; } $aPage = array('resources' => $aData['resources'], 'dom' => $oPageDOM, 'firstheading-element' => $oFirstHeading, 'bodycontent-element' => $oBodyContent, 'toc-ul-element' => $oTOCULElement, 'bookmarks-dom' => $oBookmarksDOM, 'bookmark-element' => $oBookmarkNode, 'meta' => $aData['meta']); wfRunHooks('BSUEModulePDFgetPage', array($oTitle, &$aPage, &$aParams, $oDOMXPath)); return $aPage; }
/** * Getter for $aNavigationSites array * @param boolean $bForceReload * @return array */ public static function getNavigationSites($bForceReload = false) { if (!$bForceReload && !is_null(self::$aNavigationSites)) { return self::$aNavigationSites; } self::$aNavigationSites = array(); $oTopBarMenuTitle = Title::makeTitle(NS_MEDIAWIKI, 'TopBarMenu'); if (is_null($oTopBarMenuTitle) || !$oTopBarMenuTitle->exists()) { return self::$aNavigationSites; } $sContent = BsPageContentProvider::getInstance()->getContentFromTitle($oTopBarMenuTitle); $aLines = explode("\n", trim($sContent)); $iMaxMainEntries = BsConfig::get('MW::TopMenuBarCustomizer::NumberOfMainEntries'); $iMaxSubEntries = BsConfig::get('MW::TopMenuBarCustomizer::NumberOfSubEntries'); $iAllowedLevels = BsConfig::get('MW::TopMenuBarCustomizer::NuberOfLevels'); self::$aNavigationSites = self::parseArticleContentLines($aLines, $iAllowedLevels, $iMaxMainEntries, $iMaxSubEntries); return self::$aNavigationSites; }
/** * Renders the pagetemplates form which is displayed when creating a new article * @param bool $bReturnHTML If set, the form is returned as HTML, otherwise as wiki code. * @return string The rendered output */ protected function renderPageTemplates() { global $wgDBtype; $oTitle = $this->getTitle(); // if we are not on a wiki page, return. This is important when calling import scripts that try to create nonexistent pages, e.g. importImages if (!is_object($oTitle)) { return true; } $aRes = array(); $aOutNs = array(); $dbr = wfGetDB(DB_SLAVE); $aConds = array(); if (BsConfig::get('MW::PageTemplates::HideIfNotInTargetNs')) { if ($wgDBtype == 'postgres') { $aConds[] = "pt_target_namespace IN ('" . $oTitle->getNamespace() . "', '-99')"; } else { $aConds[] = 'pt_target_namespace IN (' . $oTitle->getNamespace() . ', -99)'; } } if ($wgDBtype == 'postgres') { $aFields = array("pt_template_title, pt_template_namespace, pt_label, pt_desc, pt_target_namespace"); } else { $aFields = array('pt_template_title', 'pt_template_namespace', 'pt_label', 'pt_desc', 'pt_target_namespace'); } $res = $dbr->select(array('bs_pagetemplate'), $aFields, $aConds, __METHOD__, array('ORDER BY' => 'pt_label')); // There is always one template for empty page it is added some lines beneath that $iCount = $dbr->numRows($res) + 1; $sOut = wfMessage('bs-pagetemplates-choose-template', $iCount)->parse(); $sOutAll = ''; $oTargetNsTitle = null; $sOut .= '<br /><br /><ul><li>'; $sOut .= BsLinkProvider::makeLink($oTitle, wfMessage('bs-pagetemplates-empty-page')->plain(), array(), array('preload' => '')); $sOut .= '<br />' . wfMessage('bs-pagetemplates-empty-page-desc')->plain(); $sOut .= '</li></ul>'; $oSortingTitle = Title::makeTitle(NS_MEDIAWIKI, 'PageTemplatesSorting'); $vOrder = BsPageContentProvider::getInstance()->getContentFromTitle($oSortingTitle); $vOrder = explode('*', $vOrder); $vOrder = array_map('trim', $vOrder); if ($res && $dbr->numRows($res) > 0) { while ($row = $dbr->fetchObject($res)) { $aRes[] = $row; } } $dbr->freeResult($res); foreach ($aRes as $row) { $oNsTitle = Title::makeTitle($row->pt_template_namespace, $row->pt_template_title); // TODO MRG (06.09.11 12:53): -99 is "all namespaces". Pls use a more telling constant if (BsConfig::get('MW::PageTemplates::ForceNamespace') && $row->pt_target_namespace != "-99" || $row->pt_target_namespace == $oTitle->getNamespace() || BsConfig::get('MW::PageTemplates::HideIfNotInTargetNs') == false) { $sNamespaceName = BsNamespaceHelper::getNamespaceName($row->pt_target_namespace); if (!isset($aOutNs[$sNamespaceName])) { $aOutNs[$sNamespaceName] = array(); } if (BsConfig::get('MW::PageTemplates::ForceNamespace')) { $oTargetNsTitle = Title::makeTitle($row->pt_target_namespace, $oTitle->getText()); } else { $oTargetNsTitle = $oTitle; } $sLink = BsLinkProvider::makeLink($oTargetNsTitle, $row->pt_label, array(), array('preload' => $oNsTitle->getPrefixedText())); $sLink = '<li>' . $sLink; if ($row->pt_desc) { $sLink .= '<br/>' . $row->pt_desc; } $sLink .= '</li>'; $aOutNs[$sNamespaceName][] = array('link' => $sLink, 'id' => $row->pt_target_namespace); } elseif ($row->pt_target_namespace == "-99") { $sLink = BsLinkProvider::makeLink($oTitle, $row->pt_label, array(), array('preload' => $oNsTitle->getPrefixedText())); $sOutAll .= '<li>' . $sLink; if ($row->pt_desc) { $sOutAll .= '<br />' . $row->pt_desc; } $sOutAll .= '</li>'; } } if (!empty($vOrder)) { $aTmp = array(); foreach ($vOrder as $key => $value) { if (empty($value)) { continue; } if (array_key_exists($value, $aOutNs)) { $aTmp[$value] = $aOutNs[$value]; } } $aOutNs = $aTmp + array_diff_key($aOutNs, $aTmp); } $aLeftCol = array(); $aRightCol = array(); foreach ($aOutNs as $sNs => $aTmpOut) { foreach ($aTmpOut as $key => $aAttribs) { $sNamespaceName = BsNamespaceHelper::getNamespaceName($aAttribs['id']); if ($aAttribs['id'] == $oTitle->getNamespace() || $aAttribs['id'] == -99) { $aLeftCol[$sNamespaceName][] = '<ul>' . $aAttribs['link'] . '</ul>'; } else { $aRightCol[$sNamespaceName][] = '<ul>' . $aAttribs['link'] . '</ul>'; } } } if ($sOutAll !== '') { $sSectionGeneral = wfMessage('bs-pagetemplates-general-section')->plain(); $aLeftCol[$sSectionGeneral][] = '<ul>' . $sOutAll . '</ul>'; } $sOut .= '<br />'; if (!empty($aLeftCol) || !empty($aRightCol) && BsConfig::get('MW::PageTemplates::HideIfNotInTargetNs') == false) { $sOut .= '<table><tr>'; if (!empty($aLeftCol)) { $sOut .= '<td style="vertical-align:top;">'; foreach ($aLeftCol as $sNamespace => $aHtml) { if ($sNamespace == wfMessage('bs-ns_all')->plain()) { $sNamespace = wfMessage('bs-pagetemplates-general-section')->plain(); } $sOut .= '<br />'; $sOut .= '<h3>' . $sNamespace . '</h3>'; $sOut .= implode('', $aHtml); } $sOut .= '</td>'; } if (BsConfig::get('MW::PageTemplates::HideIfNotInTargetNs') == false) { if (!empty($aRightCol)) { $sOut .= '<td style="vertical-align:top;">'; foreach ($aRightCol as $sNamespace => $aHtml) { $sOut .= '<br />'; $sOut .= '<h3>' . $sNamespace . '</h3>'; $sOut .= implode('', $aHtml); } $sOut .= '</td>'; } } $sOut .= '</tr></table>'; } return $sOut; }
/** * Reads in a template file to a DOMDocuments and collects additional * information. * @param array $aParams Has to contain a valid 'template' entry. * @return array with the DOMDocument and some references. */ public static function getTemplate($aParams) { $aParams = array_merge(array('language' => 'en', 'meta' => array()), $aParams); $sPath = realpath($aParams['path']); $sTemplatePath = $sPath . '/' . $aParams['template']; if (!file_exists($sTemplatePath)) { throw new BsException('Requested template not found! Path:' . $sTemplatePath); } $sTemplateDescriptor = $sTemplatePath . '/template.php'; $sTemplateMarkup = $sTemplatePath . '/template.html'; $aTemplate = (include $sTemplateDescriptor); $oTemplateDOM = new DOMDocument(); $oTemplateDOM->formatOutput = true; $oTemplateDOM->load($sTemplateMarkup); $oHeadElement = $oTemplateDOM->getElementsByTagName('head')->item(0); $oBodyElement = $oTemplateDOM->getElementsByTagName('body')->item(0); $oTitleElement = $oTemplateDOM->getElementsByTagName('title')->item(0); $aResources = array(); foreach ($aTemplate['resources'] as $sType => $aFiles) { foreach ($aFiles as $sFile) { $aResources[$sType][basename($sFile)] = $sTemplatePath . '/' . $sFile; } } //Substitue MSG elements $oMsgTags = $oTemplateDOM->getElementsByTagName('msg'); //Get the message data; If not available use "en" as fallback $aMsgs = isset($aTemplate['messages'][$aParams['language']]) ? $aTemplate['messages'][$aParams['language']] : $aTemplate['messages']['en']; //Be careful with "replaceChild" within "foreach"! //HINT: http://stackoverflow.com/questions/7035202/why-does-getelementsbytagname-only-grab-every-other-element-here $i = $oMsgTags->length - 1; while ($i > -1) { $oMsgTag = $oMsgTags->item($i); $sKey = $oMsgTag->getAttribute('key'); $sReplacement = ''; if (isset($aMsgs[$sKey])) { $sReplacement = $aMsgs[$sKey]; } $oReplacmentElement = $oTemplateDOM->createTextNode($sReplacement); $oMsgTag->parentNode->replaceChild($oReplacmentElement, $oMsgTag); $i--; } //Substitute META elements $oMetaTags = $oTemplateDOM->getElementsByTagName('meta'); $i = $oMetaTags->length - 1; while ($i > -1) { $oMetaTag = $oMetaTags->item($i); $sKey = $oMetaTag->getAttribute('key'); if (isset($aParams['meta'][$sKey])) { $oReplacmentElement = $oTemplateDOM->createTextNode($aParams['meta'][$sKey]); $oMetaTag->parentNode->replaceChild($oReplacmentElement, $oMetaTag); } else { $oMetaTag->parentNode->removeChild($oMetaTag); } $i--; } //Add meta tags to head foreach ($aParams['meta'] as $sKey => $sValue) { $oMetaTag = $oTemplateDOM->createElement('meta'); $oMetaTag->setAttribute('name', $sKey); $oMetaTag->setAttribute('content', $sValue); $oHeadElement->appendChild($oMetaTag); } //Find CONTENT elements $oContentTags = $oTemplateDOM->getElementsByTagName('content'); $aContentTagRefs = array(); foreach ($oContentTags as $oContentTag) { $sKey = $oContentTag->getAttribute('key'); $aContentTagRefs[$sKey] = $oContentTag; } //Create a bookmarks tag within the head element; $oBookmarksNode = $oTemplateDOM->createElement('bookmarks'); $oHeadElement->appendChild($oBookmarksNode); //Get additional stylesheets from wiki context $aStyleBlocks = array(); global $wgUseSiteCss; if ($wgUseSiteCss) { $oTitle = Title::makeTitle(NS_MEDIAWIKI, 'Common.css'); $aStyleBlocks['MediaWiki:Common.css'] = BsPageContentProvider::getInstance()->getContentFromTitle($oTitle); } wfRunHooks('BSUEModulePDFBeforeAddingStyleBlocks', array(&$aTemplate, &$aStyleBlocks)); foreach ($aStyleBlocks as $sBlockName => $sCss) { $sCss = "\n/* " . $sBlockName . " */\n" . $sCss . "\n"; $oStyleElement = $oTemplateDOM->createElement('style'); $oStyleElement->appendChild($oTemplateDOM->createCDATASection($sCss)); $oStyleElement->setAttribute('type', 'text/css'); $oStyleElement->setAttribute('rel', 'stylesheet'); $oHeadElement->appendChild($oStyleElement); } return array('resources' => $aResources, 'dom' => $oTemplateDOM, 'content-elements' => $aContentTagRefs, 'bookmarks-element' => $oBookmarksNode, 'head-element' => $oHeadElement, 'body-element' => $oBodyElement, 'title-element' => $oTitleElement); }
public function buildRssNsBlog() { global $wgSitename, $wgContLang; $oRequest = $this->getRequest(); $sTitle = $oRequest->getVal('p', ''); $iNSid = $oRequest->getInt('ns', 0); $aNamespaces = $wgContLang->getNamespaces(); if ($iNSid != 0) { $sPageName = $aNamespaces[$iNSid] . ':' . $sTitle; } else { $sPageName = $sTitle; } /*$dbr = wfGetDB( DB_SLAVE ); $res = $dbr->select( array( 'page', 'recentchanges' ), '*', array( 'page_title' => $sTitle, 'page_namespace' => $iNSid, 'rc_timestamp > '. $dbr->timestamp( time() - intval( 7 * 86400 ) ) ), __METHOD__, array( 'ORDER BY' => 'rc_timestamp DESC' ), array( 'page'=> array( 'LEFT JOIN', 'rc_cur_id = page_id' ) ) );*/ $oChannel = RSSCreator::createChannel(RSSCreator::xmlEncode($wgSitename . ' - ' . $sPageName), 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'], wfMessage('bs-rssstandards-description_page')->plain()); $oTitle = Title::makeTitle($iNSid, 'Blog'); $aSubpages = $oTitle->getSubpages(); foreach ($aSubpages as $oSubpage) { // $oPageCP = new BsPageContentProvider(); if ($oSubpage instanceof Title) { } $entry = RSSItemCreator::createItem($oSubpage->getText(), $oSubpage->getFullURL(), BsPageContentProvider::getInstance()->getContentFromTitle($oSubpage)); $entry->setPubDate(wfTimestamp(TS_UNIX, $oSubpage->getTouched())); $oChannel->addItem($entry); } return $oChannel->buildOutput(); }
/** * Renders the Progress tag. Called by parser function. * @param string $input Inner HTML of InfoBox tag. Not used. * @param array $args List of tag attributes. * @param Parser $parser MediaWiki parser object * @return string HTML output that is to be displayed. */ public function onTagProgress($input, $args, $parser) { $iBaseCount = BsCore::sanitizeArrayEntry($args, 'basecount', 100, BsPARAMTYPE::INT); $sBaseItem = BsCore::sanitizeArrayEntry($args, 'baseitem', '', BsPARAMTYPE::STRING); $sFraction = BsCore::sanitizeArrayEntry($args, 'progressitem', 'OK', BsPARAMTYPE::STRING); $iWidth = BsCore::sanitizeArrayEntry($args, 'width', 100, BsPARAMTYPE::INT); // no Article when in cli mode if (!is_object($this->getTitle())) { return ''; } $sText = BsPageContentProvider::getInstance()->getContentFromTitle($this->getTitle()); // substract 1 because one item is in the progressitem attribute $iFraction = substr_count($sText, $sFraction) - 1; if ($sBaseItem) { $iBase = substr_count($sText, $sBaseItem) - 1; } else { $iBase = $iBaseCount; } $fPercent = $iFraction / $iBase; $iWidthGreen = floor($iWidth * $fPercent); $iWidthRemain = $iWidth - $iWidthGreen; $sPercent = sprintf("%0.1f", $fPercent * 100); $sOut = '<div style="background-color:green;border:2px solid #DDDDDD;width:' . $iWidthGreen . 'px;height:25px;float:left;color:#DDDDDD;text-align:center;border-right:0px;text-weight:bold;vertical-align:middle;">' . $sPercent . '%</div>'; $sOut .= '<div style="border:2px solid #DDDDDD;border-left:0px;width:' . $iWidthRemain . 'px;height:25px;float:left;"></div>'; return $sOut; }
public static function addCategoriesToArticle($iArticleId) { if (BsCore::checkAccessAdmission('read') === false) { return FormatJson::encode(array('success' => false)); } if (wfReadOnly()) { global $wgReadOnly; return FormatJson::encode(array('success' => false, 'msg' => wfMessage('bs-readonly', $wgReadOnly)->plain())); } $sTags = RequestContext::getMain()->getRequest()->getVal('categories'); $aTags = empty($sTags) ? array() : explode(',', $sTags); $oTitle = Title::newFromID($iArticleId); if (is_null($oTitle) || !$oTitle->exists()) { $oRequest = RequestContext::getMain()->getRequest(); $sPageName = $oRequest->getVal("page_name", ""); $oTitle = Title::newFromText($sPageName); } $sCat = BsNamespaceHelper::getNamespaceName(NS_CATEGORY); $sText = BsPageContentProvider::getInstance()->getContentFromTitle($oTitle, Revision::RAW); // Remove all before adding $sPattern = '#^\\[\\[' . $sCat . ':.*?\\]\\]#im'; $sText = preg_replace($sPattern, '', $sText); if (!empty($aTags)) { foreach ($aTags as $sTag) { $sText .= "\n[[" . $sCat . ":{$sTag}]]"; } } $oWikiPage = new WikiPage($oTitle); $oUser = RequestContext::getMain()->getUser(); $oContent = new WikitextContent($sText); $oStatus = $oWikiPage->doEditContent($oContent, "", 0, false, $oUser); if (!$oStatus->isGood()) { return FormatJson::encode(array('success' => false, 'msg' => $oStatus->getMessage())); } return FormatJson::encode(array('success' => true)); }
/** * Actually renders the SmartList list view. * @param int $aArgs['count'] Maximum number of items in list. * @param string $aArgs['namespaces'] Comma separated list of namespaces that should be considered. * @param string $aArgs['categories'] Comma separated list of categories that should be considered. * @param string $aArgs['period'] Period of time that should be considered (-|day|week|month) * @param string $aArgs['mode'] Defines the basic criteria of pages that should be considered. Default: recentchanges. Other Extensions can hook into SmartList and define their own mode. * @param bool $aArgs['showMinorChanges'] Should minor changes be considered * @param bool $aArgs['showOnlyNewArtiles'] Should edits be considered or only page creations * @param int $aArgs['trim'] Maximum number of title characters. * @param bool $aArgs['showtext'] Also display article text. * @param int $aArgs['trimtext'] Maximum number of text characters. * @param string $aArgs['order'] Sort order for list. (time|title) * @param bool $aArgs['showns'] Show namespace befor title. * @return string HTML output that is to be displayed. */ private function getCustomList($aArgs) { /* * Contains the items that need to be displayed * @var List of objects with three properties: title, namespace and timestamp */ $aObjectList = array(); $oErrorListView = new ViewTagErrorList($this); $oValidationResult = BsValidator::isValid('ArgCount', $aArgs['count'], array('fullResponse' => true)); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } /* * Validation of namespaces and categories */ $oValidationResult = BsValidator::isValid('SetItem', $aArgs['categoryMode'], array('fullResponse' => true, 'setname' => 'catmode', 'set' => array('AND', 'OR'))); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } $oValidationResult = BsValidator::isValid('SetItem', $aArgs['period'], array('fullResponse' => true, 'setname' => 'period', 'set' => array('-', 'day', 'week', 'month'))); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } $oValidationResult = BsValidator::isValid('PositiveInteger', $aArgs['trim'], array('fullResponse' => true)); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } $oValidationResult = BsValidator::isValid('PositiveInteger', $aArgs['trimtext'], array('fullResponse' => true)); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } $oValidationResult = BsValidator::isValid('SetItem', $aArgs['sort'], array('fullResponse' => true, 'setname' => 'sort', 'set' => array('time', 'title'))); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } $oValidationResult = BsValidator::isValid('SetItem', $aArgs['order'], array('fullResponse' => true, 'setname' => 'order', 'set' => array('ASC', 'DESC'))); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } if ($aArgs['mode'] == 'recentchanges') { $dbr = wfGetDB(DB_SLAVE); $aConditions = array(); switch ($aArgs['period']) { case 'month': $sMinTimestamp = $dbr->timestamp(time() - 30 * 24 * 60 * 60); break; case 'week': $sMinTimestamp = $dbr->timestamp(time() - 7 * 24 * 60 * 60); break; case 'day': $sMinTimestamp = $dbr->timestamp(time() - 24 * 60 * 60); break; default: break; } try { $aNamespaceIds = BsNamespaceHelper::getNamespaceIdsFromAmbiguousCSVString($aArgs['namespaces']); $aConditions[] = 'rc_namespace IN (' . implode(',', $aNamespaceIds) . ')'; } catch (BsInvalidNamespaceException $ex) { $sInvalidNamespaces = implode(', ', $ex->getListOfInvalidNamespaces()); $oErrorListView->addItem(new ViewTagError(wfMessage('bs-smartlist-invalid-namespaces')->numParams(count($ex->getListOfInvalidNamespaces()))->params($sInvalidNamespaces)->text())); } $this->makeCategoriesFilterCondition($aConditions, $aArgs, 'rc_cur_id'); switch ($aArgs['sort']) { case 'title': $sOrderSQL = 'rc_title'; break; default: // ORDER BY MAX() - this one was tricky. It makes sure, only the changes with the maximum date are selected. $sOrderSQL = 'MAX(rc_timestamp)'; break; } switch ($aArgs['order']) { case 'ASC': $sOrderSQL .= ' ASC'; break; default: $sOrderSQL .= ' DESC'; break; } if (!$aArgs['showMinorChanges']) { $aConditions[] = 'rc_minor = 0'; } if ($aArgs['showOnlyNewArticles']) { $sOrderSQL = 'MIN(rc_timestamp) DESC'; $aConditions[] = 'rc_new = 1'; } if (!empty($aArgs['period']) && $aArgs['period'] !== '-') { $aConditions[] = "rc_timestamp > '" . $sMinTimestamp . "'"; } $aConditions[] = 'rc_title = page_title AND rc_namespace = page_namespace'; //prevent display of deleted articles $aConditions[] = 'NOT (rc_type = 3)'; //prevent moves and deletes from being displayed $aFields = array('rc_title as title', 'rc_namespace as namespace'); if (isset($aArgs['meta']) && $aArgs['meta'] == true) { $aFields[] = 'MAX(rc_timestamp) as time, rc_user_text as username'; } if (BsConfig::get('MW::SmartList::Comments')) { $aFields[] = 'MAX(rc_comment) as comment'; } $res = $dbr->select(array('recentchanges', 'page'), $aFields, $aConditions, __METHOD__, array('GROUP BY' => 'rc_title, rc_namespace', 'ORDER BY' => $sOrderSQL)); $iCount = 0; foreach ($res as $row) { if ($iCount == $aArgs['count']) { break; } $oTitle = Title::makeTitleSafe($row->namespace, $row->title); if (!$oTitle || !$oTitle->quickUserCan('read')) { continue; } $aObjectList[] = $row; $iCount++; } $dbr->freeResult($res); } elseif ($aArgs['mode'] == 'whatlinkshere') { //PW(25.02.2015) TODO: //There could be filters - see Special:Whatlinkshere $oTargetTitle = empty($aArgs['target']) ? $this->getContext()->getTitle() : Title::newFromText($aArgs['target']); if (is_null($oTargetTitle)) { $oErrorListView->addItem(new ViewTagError(wfMessage('bs-smartlist-invalid-target')->text())); return $oErrorListView->execute(); } $dbr = wfGetDB(DB_SLAVE); $aTables = array('pagelinks', 'page'); $aFields = array('title' => 'page_title', 'namespace' => 'page_namespace'); $aConditions = array("page_id = pl_from", "pl_namespace = {$oTargetTitle->getNamespace()}", "pl_from NOT IN ({$oTargetTitle->getArticleID()})", "pl_title = '{$oTargetTitle->getDBkey()}'"); $aOptions = array(); try { $aNamespaceIds = BsNamespaceHelper::getNamespaceIdsFromAmbiguousCSVString($aArgs['namespaces']); $aConditions['page_namespace'] = $aNamespaceIds; } catch (BsInvalidNamespaceException $ex) { $sInvalidNamespaces = implode(', ', $ex->getListOfInvalidNamespaces()); $oErrorListView->addItem(new ViewTagError(wfMessage('bs-smartlist-invalid-namespaces')->numParams(count($ex->getListOfInvalidNamespaces()))->params($sInvalidNamespaces)->text())); return $oErrorListView->execute(); } $this->makeCategoriesFilterCondition($aConditions, $aArgs, 'page_id'); //Default: time $aOptions['ORDER BY'] = $aArgs['sort'] == 'title' ? 'page_title' : 'page_id'; //Default DESC $aOptions['ORDER BY'] .= $aArgs['order'] == 'ASC' ? ' ASC' : ' DESC'; $res = $dbr->select($aTables, $aFields, $aConditions, __METHOD__, $aOptions); $iCount = 0; foreach ($res as $row) { if ($iCount == $aArgs['count']) { break; } $oTitle = Title::makeTitleSafe($row->namespace, $row->title); if (!$oTitle || !$oTitle->quickUserCan('read')) { continue; } $aObjectList[] = $row; $iCount++; } $dbr->freeResult($res); } else { wfRunHooks('BSSmartListCustomMode', array(&$aObjectList, $aArgs, $this)); } if ($oErrorListView->hasEntries()) { return $oErrorListView->execute(); } $oSmartListListView = new ViewBaseElement(); $oSmartListListView->setAutoElement(false); $iItems = 1; if (count($aObjectList)) { foreach ($aObjectList as $row) { $oTitle = Title::makeTitleSafe($row->namespace, $row->title); // Security here: only show pages the user can read. $sText = ''; $sMeta = ''; $sComment = ''; $sTitle = $oTitle->getText(); if (BsConfig::get('MW::SmartList::Comments')) { $sComment = strlen($row->comment) > 50 ? substr($row->comment, 0, 50) . '...' : $row->comment; $sComment = wfMessage('bs-smartlist-comment')->params($sComment)->escaped(); } if (isset($aArgs['meta']) && $aArgs['meta'] == true) { $sMeta = ' - <i>(' . $row->username . ', ' . $this->getLanguage()->date($row->time, true, true) . ')</i>'; } $oSmartListListEntryView = new ViewBaseElement(); if ($aArgs['showtext'] && $iItems <= $aArgs['numwithtext']) { $oSmartListListEntryView->setTemplate('*[[:{NAMESPACE}:{TITLE}|{DISPLAYTITLE}]]{META}<br/>{TEXT}' . "\n"); $sText = BsPageContentProvider::getInstance()->getContentFromTitle($oTitle); $sText = Sanitizer::stripAllTags($sText); $sText = BsStringHelper::shorten($sText, array('max-length' => $aArgs['trimtext'], 'position' => 'end')); $sText = '<nowiki>' . $sText . '</nowiki>'; } else { $oSmartListListEntryView->setTemplate('*[[:{NAMESPACE}:{TITLE}|{DISPLAYTITLE}]] {COMMENT} {META}' . "\n"); } if ($aArgs['showns'] == true) { $sDisplayTitle = $oTitle->getFullText(); } else { $sDisplayTitle = $oTitle->getText(); } $sDisplayTitle = BsStringHelper::shorten($sDisplayTitle, array('max-length' => $aArgs['trim'], 'position' => 'middle')); $sNamespaceText = ''; if ($row->namespace > 0 && $row->namespace != null) { $sNamespaceText = MWNamespace::getCanonicalName($row->namespace); } $aData = array('NAMESPACE' => $sNamespaceText, 'TITLE' => $sTitle, 'DISPLAYTITLE' => $sDisplayTitle, 'COMMENT' => $sComment, 'META' => $sMeta, 'TEXT' => $sText); wfRunHooks('BSSmartListBeforeEntryViewAddData', array(&$aData, $aArgs, $oSmartListListEntryView, $row)); $oSmartListListEntryView->addData($aData); $oSmartListListView->addItem($oSmartListListEntryView); $iItems++; } } else { return ''; } return $this->mCore->parseWikiText($oSmartListListView->execute(), $this->getTitle()); }
/** * * @param type $input * @param type $args * @param Parser $parser * @return type */ public function onMagicWordBsCountCharacters($input, $args, $parser) { $parser->disableCache(); if (empty($input)) { $oErrorView = new ViewTagError(wfMessage('bs-countthings-error-no-input')->plain()); return $oErrorView->execute(); } $sMode = isset($args['mode']) ? str_replace(' ', '', $args['mode']) : 'all'; $aModes = explode(',', $sMode); $aAvailableModes = array('chars', 'words', 'pages', 'all'); $sOut = ''; $bValidModeProvided = false; foreach ($aModes as $sMode) { if (!in_array($sMode, $aAvailableModes)) { $oErrorView = new ViewTagError(wfMessage('bs-countthings-error-invalid-mode', $sMode)->plain()); $sOut .= $oErrorView->execute(); continue; } $bValidModeProvided = true; } if ($bValidModeProvided == false) { $aModes = array('all'); } $aTitleTexts = explode(',', $input); foreach ($aTitleTexts as $sTitleText) { $oTitle = Title::newFromText(trim($sTitleText)); if ($oTitle == null || $oTitle->exists() == false) { $oErrorView = new ViewTagError(wfMessage('bs-countthings-error-not-exist', $sTitleText)->plain()); $sOut .= $oErrorView->execute(); continue; } $sContent = BsPageContentProvider::getInstance()->getContentFromTitle($oTitle); //Old: last revision $oCountView = new ViewCountCharacters(); $oCountView->setTitle($oTitle); if (in_array('all', $aModes)) { $iChars = strlen(preg_replace("/\\s+/", " ", $sContent)); $iWords = sizeof(explode(' ', $sContent)); $iPages = ceil($iChars / 2000); $oCountView->setChars($iChars); $oCountView->setWords($iWords); $oCountView->setPages($iPages); $sOut .= $oCountView->execute(); continue; } // TODO RBV (17.02.12 15:34): Find better logic for this... if (in_array('chars', $aModes)) { $iChars = strlen(preg_replace("/\\s+/", " ", $sContent)); $oCountView->setChars($iChars); } if (in_array('words', $aModes)) { $iChars = strlen(preg_replace("/\\s+/", " ", $sContent)); $iWords = sizeof(explode(' ', $sContent)); $oCountView->setWords($iWords); } if (in_array('pages', $aModes)) { $iChars = strlen(preg_replace("/\\s+/", " ", $sContent)); $iWords = sizeof(explode(' ', $sContent)); $iPages = ceil($iChars / 2000); $oCountView->setPages($iPages); } $sOut .= $oCountView->execute(); } return $sOut; }
/** * Getter for the $aNavigationSites array - either from hook, TopBarMenu title or cache * @global string $wgSitename * @return array */ public static function getNavigationSites() { if (!is_null(self::$aNavigationSites)) { return self::$aNavigationSites; } $sKey = BsExtensionManager::getExtension('TopMenuBarCustomizer')->getCacheKey('NavigationSitesData'); self::$aNavigationSites = BsCacheHelper::get($sKey); if (self::$aNavigationSites !== false) { return self::$aNavigationSites; } self::$aNavigationSites = array(); $oTopBarMenuTitle = Title::makeTitle(NS_MEDIAWIKI, 'TopBarMenu'); if (!is_null($oTopBarMenuTitle) && $oTopBarMenuTitle->exists()) { $sContent = BsPageContentProvider::getInstance()->getContentFromTitle($oTopBarMenuTitle); // Force unset of all menu items by creating an empty page if (!empty($sContent)) { self::$aNavigationSites = TopMenuBarCustomizerParser::getNavigationSites(); } BsCacheHelper::set($sKey, self::$aNavigationSites, 60 * 1440); //max cache time 24h return self::$aNavigationSites; } global $wgSitename; $oCurrentTitle = RequestContext::getMain()->getTitle(); $oMainPage = Title::newMainPage(); self::$aNavigationSites[] = array('id' => 'wiki', 'href' => $oMainPage->getFullURL(), 'text' => $wgSitename, 'active' => $oCurrentTitle->equals($oMainPage), 'level' => 1, 'containsactive' => false, 'external' => false, 'children' => array()); wfRunHooks('BSTopMenuBarCustomizerRegisterNavigationSites', array(&self::$aNavigationSites)); BsCacheHelper::set($sKey, self::$aNavigationSites, 60 * 1440); //max cache time 24h return self::$aNavigationSites; }
/** * Extracts the edit sections out of a given text * @param object $oTitle Text to be parsed * @return array array of sections */ public function extractEditSections($oTitle) { $aSections = array(); if (!$oTitle instanceof Title) { return $aSections; } $sText = BsPageContentProvider::getInstance()->getContentFromTitle($oTitle); $aMatches = array(); $aLines = explode("\n", $sText); foreach ($aLines as $sLine) { if (preg_match('#^(=){1,6}(.*?)(=){1,6}$#', $sLine, $aMatches)) { $aSections[] = trim($aMatches[2]); } } return $aSections; }
/** * * @param Title $oTitle * @return array An Array of Title objects */ public function getTitleListFromTitle($oTitle) { $sKey = BsCacheHelper::getCacheKey('BlueSpice', 'WantedArticle', $oTitle->getPrefixedText()); $aData = BsCacheHelper::get($sKey); if ($aData !== false) { wfDebugLog('BsMemcached', __CLASS__ . ': Fetching WantedArticle list from cache'); $aTitleList = $aData; } else { wfDebugLog('BsMemcached', __CLASS__ . ': Fetching WantedArticle list from DB'); $oArticleContent = BsPageContentProvider::getInstance()->getContentFromTitle($oTitle); $aTitleList = array(); $aLines = explode("\n", $oArticleContent); foreach ($aLines as $sLine) { $sLine = trim($sLine); if (empty($sLine) || $sLine[0] != '*') { continue; } $aMatches = array(); #*[[Title]] --[[Spezial:Beiträge/0:0:0:0:0:0:0:1|0:0:0:0:0:0:0:1]] 12:31, 7. Jan. 2013 (AST) #*[[Title2]]--[[Benutzer:WikiSysop|WikiSysop]] ([[Benutzer Diskussion:WikiSysop|Diskussion]]) 17:47, 4. Jan. 2013 (AST) preg_match('#\\*.*?\\[\\[(.*?)\\]\\]( ?--\\[\\[.*?:(.*?/)?(.*?)\\|.*?\\]\\].*?\\)? (\\(.*?\\))? ?(.*?))?$#si', $sLine, $aMatches); if (empty($aMatches) || !isset($aMatches[1])) { continue; } $sTitle = $aMatches[1]; $sUsername = isset($aMatches[4]) ? $aMatches[4] : ''; $sSignature = isset($aMatches[2]) ? $aMatches[2] : ''; $oT = Title::newFromText($sTitle); if ($oT === null) { continue; } $aTitleList[] = array('title' => $oT, 'username' => $sUsername, 'signature' => $sSignature); } BsCacheHelper::set($sKey, $aTitleList); } return $aTitleList; }