/** * Renders the blog. Called by parser function for bs:blog tag and also from Blog::onUnknownAction. * @param string $input Inner HTML of bs:blog 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 onBlog($input, $args, $parser) { $oTitle = null; if ($parser instanceof Parser) { $oTitle = $parser->getTitle(); $parser->disableCache(); } else { $oTitle = $this->getTitle(); } $sKey = BsCacheHelper::getCacheKey('BlueSpice', 'Blog', $oTitle->getArticleID()); $aData = BsCacheHelper::get($sKey); if ($aData !== false) { return $aData; } // initialize local variables $oErrorListView = new ViewTagErrorList($this); BsExtensionManager::setContext('MW::Blog::ShowBlog'); // get all config options $iShowLimit = BsConfig::get('MW::Blog::ShowLimit'); //$blogShowTrackback = BsConfig::get('MW::Blog::ShowTrackback'); // see comment below $bShowPermalink = BsConfig::get('MW::Blog::ShowPermalink'); $bShowInfo = BsConfig::get('MW::Blog::ShowInfo'); $sSortBy = BsConfig::get('MW::Blog::SortBy'); $bMoreInNewWindow = BsConfig::get('MW::Blog::MoreInNewWindow'); $bShowAll = BsConfig::get('MW::Blog::ShowAll'); $bMoreAtEndOfEntry = BsConfig::get('MW::Blog::MoreAtEndOfEntry'); $bShowNewEntryField = BsConfig::get('MW::Blog::ShowNewEntryField'); $bNewEntryFieldPosition = BsConfig::get('MW::Blog::NewEntryFieldPosition'); $sImageRenderMode = BsConfig::get('MW::Blog::ImageRenderMode'); $sImageFloatDirection = BsConfig::get('MW::Blog::ThumbFloatDirection'); $iMaxEntryCharacters = BsConfig::get('MW::Blog::MaxEntryCharacters'); // Trackbacks are not supported the way we intend it to be. From http://www.mediawiki.org/wiki/Manual:$wgUseTrackbacks // When MediaWiki receives a trackback ping, a box will show up at the bottom of the article containing a link to the originating page //if (!$wgUseTrackbacks) $bShowTrackback = false; // get tag attributes $argsIShowLimit = BsCore::sanitizeArrayEntry($args, 'count', $iShowLimit, BsPARAMTYPE::NUMERIC | BsPARAMOPTION::DEFAULT_ON_ERROR); $argsSCategory = BsCore::sanitizeArrayEntry($args, 'cat', false, BsPARAMTYPE::STRING); $argsINamespace = BsNamespaceHelper::getNamespaceIndex(BsCore::sanitizeArrayEntry($args, 'ns', NS_BLOG, BsPARAMTYPE::STRING)); $argsBNewEntryField = BsCore::sanitizeArrayEntry($args, 'newentryfield', $bShowNewEntryField, BsPARAMTYPE::BOOL); $argsSNewEntryFieldPosition = BsCore::sanitizeArrayEntry($args, 'newentryfieldposition', $bNewEntryFieldPosition, BsPARAMTYPE::STRING); $argsSImageRenderMode = BsCore::sanitizeArrayEntry($args, 'imagerendermode', $sImageRenderMode, BsPARAMTYPE::STRING); $argsSImageFloatDirection = BsCore::sanitizeArrayEntry($args, 'imagefloatdirection', $sImageFloatDirection, BsPARAMTYPE::STRING); $argsIMaxEntryCharacters = BsCore::sanitizeArrayEntry($args, 'maxchars', $iMaxEntryCharacters, BsPARAMTYPE::INT); $argsSSortBy = BsCore::sanitizeArrayEntry($args, 'sort', $sSortBy, BsPARAMTYPE::STRING); $argsBShowInfo = BsCore::sanitizeArrayEntry($args, 'showinfo', $bShowInfo, BsPARAMTYPE::BOOL); $argsBMoreInNewWindow = BsCore::sanitizeArrayEntry($args, 'moreinnewwindow', $bMoreInNewWindow, BsPARAMTYPE::BOOL); $argsBShowPermalink = BsCore::sanitizeArrayEntry($args, 'showpermalink', $bShowPermalink, BsPARAMTYPE::BOOL); $argsModeNamespace = BsCore::sanitizeArrayEntry($args, 'mode', null, BsPARAMTYPE::STRING); if ($argsModeNamespace === 'ns' && is_object($oTitle)) { $argsINamespace = $oTitle->getNamespace(); } // validate tag attributes $validateIShowLimit = BsValidator::isValid('ArgCount', $argsIShowLimit, array('fullResponse' => true)); if ($validateIShowLimit->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($validateIShowLimit->getI18N())); } if ($argsSCategory) { $validateSCategory = BsValidator::isValid('Category', $argsSCategory, array('fullResponse' => true)); if ($validateSCategory->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($validateSCategory->getI18N())); } } $oValidationResult = BsValidator::isValid('SetItem', $argsSImageRenderMode, array('fullResponse' => true, 'setname' => 'imagerendermode', 'set' => array('full', 'thumb', 'none'))); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } $oValidationResult = BsValidator::isValid('SetItem', $argsSImageFloatDirection, array('fullResponse' => true, 'setname' => 'imagefloatdirection', 'set' => array('left', 'right', 'none'))); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } $oValidationResult = BsValidator::isValid('SetItem', $argsSSortBy, array('fullResponse' => true, 'setname' => 'sort', 'set' => array('title', 'creation'))); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } // if there are errors, abort with a message if ($oErrorListView->hasEntries()) { return $oErrorListView->execute(); } if (BsConfig::get('MW::Blog::ShowTagFormWhenNotLoggedIn') != true) { $oPermissionTest = Title::newFromText('PermissionTest', $argsINamespace); if (!$oPermissionTest->userCan('edit')) { $argsBNewEntryField = false; } } // get array of article ids from Blog/subpages $oBlogTitle = Title::makeTitleSafe($oTitle->getNamespace(), 'Blog'); $aSubpages = $oBlogTitle->getSubpages(); $iLimit = 0; // for later use $aArticleIds = array(); foreach ($aSubpages as $oSubpage) { $aArticleIds[] = $oSubpage->getArticleID(); $iLimit++; // for later use } if (count($aArticleIds) < 1) { $aArticleIds = 0; } $aTables = array('page'); $aFields = array('entry_page_id' => 'page_id'); $aConditions = array(); $aOptions = array(); $aJoins = array(); $dbr = wfGetDB(DB_SLAVE); // get blog entries if ($argsSSortBy == 'title') { $aOptions['ORDER BY'] = 'page_title ASC'; } else { //Creation: Also fetch possible custom timestamps from page_props table $aOptions['ORDER BY'] = 'entry_timestamp DESC'; $aOptions['GROUP BY'] = 'page_id'; global $wgDBtype; switch ($wgDBtype) { case 'oracle': $aFields['entry_timestamp'] = "NVL( pp_value, rev_timestamp )"; $aConditions[] = "NVL( pp_value, rev_timestamp ) < " . wfTimestampNow(); break; case 'mssql': $aFields['entry_timestamp'] = "ISNULL( pp_value, rev_timestamp )"; $aConditions[] = "ISNULL( pp_value, rev_timestamp ) < " . wfTimestampNow(); break; case 'postgres': $aFields['entry_timestamp'] = "NULLIF( pp_value, rev_timestamp )"; $aConditions[] = "NULLIF( pp_value, rev_timestamp ) < " . wfTimestampNow(); break; default: //MySQL, SQLite //use pp_value if exists $aFields['entry_timestamp'] = "IFNULL( pp_value, rev_timestamp )"; //also do not list future entries $aConditions[] = "IFNULL( pp_value, rev_timestamp ) < " . wfTimestampNow(); } $aTables[] = 'revision'; $aTables[] = 'page_props'; $aConditions[] = 'rev_page = page_id'; $aJoins['page_props'] = array('LEFT JOIN', "pp_page = rev_page AND pp_propname = 'blogtime'"); } if ($argsSCategory) { $aTables[] = 'categorylinks'; $aConditions['cl_to'] = $argsSCategory; $aConditions[] = 'cl_from = page_id'; } else { if ($argsModeNamespace === 'ns') { $aConditions['page_id'] = $aArticleIds; } $aConditions['page_namespace'] = $argsINamespace; } $res = $dbr->select($aTables, $aFields, $aConditions, __METHOD__, $aOptions, $aJoins); $iNumberOfEntries = $dbr->numRows($res); $iLimit = $iNumberOfEntries; //All // Sole importance is the existence of param 'showall' $paramBShowAll = $this->getRequest()->getFuzzyBool('showall', false); if ($paramBShowAll == false) { $iLimit = $argsIShowLimit; } // abort if there are no entries if ($iNumberOfEntries < 1) { $oBlogView = new ViewBlog(); $oBlogView->setOption('shownewentryfield', $argsBNewEntryField); $oBlogView->setOption('newentryfieldposition', $argsSNewEntryFieldPosition); $oBlogView->setOption('namespace', BsNamespaceHelper::getNamespaceName($argsINamespace)); if ($argsSCategory) { $oBlogView->setOption('blogcat', $argsSCategory); } // actually create blog output $sOut = $oBlogView->execute(); $sOut .= wfMessage('bs-blog-no-entries')->plain(); return $sOut; } $oBlogView = new ViewBlog(); // prepare views per blog item $iLoop = 0; foreach ($res as $row) { // prepare data for view class $oEntryTitle = Title::newFromID($row->entry_page_id); if (!$oEntryTitle->userCan('read')) { $iNumberOfEntries--; continue; } $bMore = false; $aContent = preg_split('#<(bs:blog:)?more */>#', BsPageContentProvider::getInstance()->getContentFromTitle($oEntryTitle)); if (sizeof($aContent) > 1) { $bMore = true; } $aContent = trim($aContent[0]); // Prevent recursive rendering of blog tag $aContent = preg_replace('/<(bs:)blog[^>]*?>/', '', $aContent); // Thumbnail images $sNamespaceRegEx = implode('|', BsNamespaceHelper::getNamespaceNamesAndAliases(NS_IMAGE)); switch ($argsSImageRenderMode) { case 'none': $aContent = preg_replace('/(\\[\\[(' . $sNamespaceRegEx . '):[^\\|\\]]*)(\\|)?(.*?)(\\]\\])/', '', $aContent); break; case 'full': // do nothing break; case 'thumb': default: $aContent = preg_replace('/(\\[\\[(' . $sNamespaceRegEx . '):[^\\|\\]]*)(\\|)?(.*?)(\\]\\])/', "\$1|thumb|{$argsSImageFloatDirection}\$3\$4|150px\$5", $aContent); break; } if (strlen($aContent) > $argsIMaxEntryCharacters) { $bMore = true; } $aContent = BsStringHelper::shorten($aContent, array('max-length' => $argsIMaxEntryCharacters, 'ignore-word-borders' => false, 'position' => 'end')); $resComment = $dbr->selectRow('revision', 'COUNT( rev_id ) AS cnt', array('rev_page' => $oEntryTitle->getTalkPage()->getArticleID())); $iCount = $resComment->cnt; // set data for view class $oBlogItemView = new ViewBlogItem(); // use magic set $oBlogItemView->setOption('showInfo', $argsBShowInfo); $oBlogItemView->setOption('showLimit', $argsIShowLimit); $oBlogItemView->setOption('showTrackback', $bShowTrackback); $oBlogItemView->setOption('showPermalink', $argsBShowPermalink); $oBlogItemView->setOption('moreInNewWindow', $argsBMoreInNewWindow); $oBlogItemView->setOption('showAll', $bShowAll); $oBlogItemView->setOption('moreAtEndOfEntry', $bMoreAtEndOfEntry); $oBlogItemView->setOption('more', $bMore); //TODO: magic_call? if ($argsModeNamespace === 'ns') { $sTitle = substr($oEntryTitle->getText(), 5); } else { $sTitle = $oEntryTitle->getText(); } $aTalkParams = array(); if (!$oEntryTitle->getTalkPage()->exists()) { $aTalkParams = array('action' => 'edit'); } $oRevision = Revision::newFromTitle($oEntryTitle); $oBlogItemView->setTitle($sTitle); $oBlogItemView->setRevId($oRevision->getId()); $oBlogItemView->setURL($oEntryTitle->getLocalURL()); $oBlogItemView->setTalkURL($oEntryTitle->getTalkPage()->getLocalURL($aTalkParams)); $oBlogItemView->setTalkCount($iCount); $oBlogItemView->setTrackbackUrl($oEntryTitle->getLocalURL()); if ($bShowInfo) { $oFirstRevision = $oEntryTitle->getFirstRevision(); $sTimestamp = $oFirstRevision->getTimestamp(); $sLocalDateTimeString = BsFormatConverter::timestampToAgeString(wfTimestamp(TS_UNIX, $sTimestamp)); $oBlogItemView->setEntryDate($sLocalDateTimeString); $iUserId = $oFirstRevision->getUser(); if ($iUserId != 0) { $oAuthorUser = User::newFromId($iUserId); $oBlogItemView->setAuthorPage($oAuthorUser->getUserPage()->getPrefixedText()); $oBlogItemView->setAuthorName($this->mCore->getUserDisplayName($oAuthorUser)); } else { $oBlogItemView->setAuthorName($oFirstRevision->getUserText()); } } $oBlogItemView->setContent($aContent); $oBlogView->addItem($oBlogItemView); $iLoop++; if ($iLoop >= $iLimit) { break; } } $dbr->freeResult($res); // prepare complete blog output if ($bShowAll && !$paramBShowAll && $iNumberOfEntries > $argsIShowLimit) { $oBlogView->setOption('showall', true); } $oBlogView->setOption('shownewentryfield', $argsBNewEntryField); $oBlogView->setOption('newentryfieldposition', $argsSNewEntryFieldPosition); $oBlogView->setOption('namespace', BsNamespaceHelper::getNamespaceName($argsINamespace, false)); $oBlogView->setOption('blogcat', $argsSCategory); if ($argsModeNamespace === 'ns') { $oBlogView->setOption('parentpage', 'Blog/'); } // actually create blog output $sOut = $oBlogView->execute(); //Use cache only in NS_BLOG - there is curently no functionality to //figure out in what type of blog tag a entry is showen and why //(coditions). Possible blog by categories or subpages... //Needs rework. if (in_array($oTitle->getNamespace(), array(NS_BLOG, NS_BLOG_TALK))) { $aKey = array($sKey); $sTagsKey = BsCacheHelper::getCacheKey('BlueSpice', 'Blog', 'Tags'); $aTagsData = BsCacheHelper::get($sTagsKey); if ($aTagsData !== false) { if (!in_array($sKey, $aTagsData)) { $aTagsData = array_merge($aTagsData, $aKey); } } else { $aTagsData = $aKey; } BsCacheHelper::set($sTagsKey, $aTagsData, 60 * 1440); // one day BsCacheHelper::set($sKey, $sOut, 60 * 1440); // one day } return $sOut; }
/** * Creates or edits an interwiki link. Called via AJAX function * @return bool allow other hooked methods to be executed. always true. */ public static function doEditInterWikiLink($bEditMode, $iw_prefix, $iw_url, $iw_old_prefix = '') { if (wfReadOnly()) { global $wgReadOnly; return FormatJson::encode(array('success' => false, 'message' => array(wfMessage('bs-readonly', $wgReadOnly)->plain()))); } if (BsCore::checkAccessAdmission('wikiadmin') === false) { return true; } $aAnswer = array('success' => true, 'errors' => array(), 'message' => array()); if (strlen($iw_prefix) > 32) { $aAnswer['success'] = false; $aAnswer['errors'][] = array('id' => 'iweditprefix', 'message' => wfMessage('bs-interwikilinks-pfxtoolong')->plain()); } if ($iw_prefix == '') { $aAnswer['success'] = false; $aAnswer['errors'][] = array('id' => 'iweditprefix', 'message' => wfMessage('bs-interwikilinks-nopfx')->plain()); } if ($iw_url == '') { $aAnswer['success'] = false; $aAnswer['errors'][] = array('id' => 'iwediturl', 'message' => wfMessage('bs-interwikilinks-nourl')->plain()); } $oValidationResult = BsValidator::isValid('Url', $iw_url, array('fullResponse' => true)); if ($oValidationResult->getErrorCode()) { $aAnswer['success'] = false; $aAnswer['errors'][] = array('id' => 'iwediturl', 'message' => $oValidationResult->getI18N()); } if (substr_count($iw_prefix, ' ') || substr_count($iw_prefix, '"') || substr_count($iw_prefix, '&') || substr_count($iw_prefix, ':')) { $aAnswer['success'] = false; $aAnswer['errors'][] = array('id' => 'iweditprefix', 'message' => wfMessage('bs-interwikilinks-invalid-pfx-spc')->plain()); } if (strpos($iw_url, ' ')) { $aAnswer['success'] = false; $aAnswer['errors'][] = array('id' => 'iwediturl', 'message' => wfMessage('bs-interwikilinks-invalid-url-spc')->plain()); } if ($bEditMode == 'true') { $sSearchPrefix = $iw_old_prefix; } else { $sSearchPrefix = $iw_prefix; } $dbr = wfGetDB(DB_SLAVE); $res = $dbr->select('interwiki', 'iw_prefix', array("iw_prefix" => $sSearchPrefix)); $num_row = $dbr->numRows($res); if ($bEditMode == 'false') { if ($num_row >= 1) { $aAnswer['success'] = false; $aAnswer['errors'][] = array('message' => wfMessage('bs-interwikilinks-pfxexists')->plain()); } } else { if ($num_row < 1) { $aAnswer['success'] = false; $aAnswer['errors'][] = array('message' => wfMessage('bs-interwikilinks-nooldpfx')->plain()); } } if ($aAnswer['success']) { $dbw = wfGetDB(DB_MASTER); if ($bEditMode == 'false') { $dbw->insert('interwiki', array('iw_prefix' => $iw_prefix, 'iw_url' => $iw_url, 'iw_local' => '0')); } else { $dbw->update('interwiki', array('iw_prefix' => $iw_prefix, 'iw_url' => $iw_url), array('iw_prefix' => $iw_old_prefix)); } $aAnswer['message'][] = $bEditMode ? wfMessage('bs-interwikilinks-link-added')->plain() : wfMessage('bs-interwikilinks-link-created')->plain(); } self::purgeTitles($iw_prefix); return FormatJson::encode($aAnswer); }
/** * 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()); }
/** * Creates a Widget and returns it * @return ViewWidget */ public function onWidgetListKeyword() { $oCurrentUser = $this->getUser(); if ($oCurrentUser->isAnon()) { return null; } $iCount = BsConfig::get('MW::WatchList::WidgetLimit'); $sOrder = BsConfig::get('MW::WatchList::WidgetSortOdr'); //Validation $oValidationICount = BsValidator::isValid('IntegerRange', $iCount, array('fullResponse' => true, 'lowerBoundary' => 1, 'upperBoundary' => 30)); if ($oValidationICount->getErrorCode()) { $iCount = 10; } if (!in_array($sOrder, array('pagename', 'time'))) { $sOrder = 'pagename'; } $oUserSidebarView = new ViewWidget(); $oUserSidebarView->setTitle(wfMessage('bs-watchlist-title-sidebar')->plain())->setAdditionalBodyClasses(array('bs-nav-links')); //For correct margin and fontsize $oWatchList = $this->fetchWatchlist($oCurrentUser, $iCount, 30, $sOrder); $sWatchListWikiText = $oWatchList->execute(); if (empty($sWatchListWikiText)) { return $oUserSidebarView; } $oUserSidebarView->setBody($this->mCore->parseWikiText($sWatchListWikiText, $this->getTitle(), true), $this->getTitle()); return $oUserSidebarView; }
/** * Creates a Widget view object for the BlueSpice Skin. * @param array &$aViews List of Widget view objects from the BlueSpice Skin. */ private function addWidgetView(&$aViews) { $iCount = BsConfig::get('MW::PagesVisited::WidgetLimit'); $aNamespaces = BsConfig::get('MW::PagesVisited::WidgetNS'); $sSortOrder = BsConfig::get('MW::PagesVisited::WidgetSortOdr'); //Validation $oValidationICount = BsValidator::isValid('IntegerRange', $iCount, array('fullResponse' => true, 'lowerBoundary' => 1, 'upperBoundary' => 30)); if ($oValidationICount->getErrorCode()) { $iCount = 10; } $iCurrentNamespaceId = $this->getTitle()->getNamespace(); // TODO RBV (04.07.11 15:02): Rework method -> implode() is a workaround for legacy code. $oListView = $this->makePagesVisitedWikiList($iCount, implode(',', $aNamespaces), $iCurrentNamespaceId, 30, $sSortOrder); $sOut = $oListView->execute(); if (!$oListView instanceof ViewTagError) { $sOut = $this->mCore->parseWikiText($sOut, $this->getTitle()); } $oWidgetView = new ViewWidget(); $oWidgetView->setTitle(wfMessage('bs-pagesvisited-widget-title')->plain())->setBody($sOut)->setAdditionalBodyClasses(array('bs-nav-links')); //For correct margin and fontsize $aViews[] = $oWidgetView; }
/** * Handles the get wanted articles ajax request. * @param string $sOut The server response string. * @return bool true on correct processing. JSON answer is in $sOut parameter. */ public static function ajaxGetWantedArticles($iCount, $sSort, $sOrder, $sType, $sTitle) { if (BsCore::checkAccessAdmission('read') === false) { return true; } $aResult = array('success' => false, 'view' => '', 'message' => ''); //Validation $oValidationICount = BsValidator::isValid('IntegerRange', $iCount, array('fullResponse' => true, 'lowerBoundary' => 1, 'upperBoundary' => 30)); if ($oValidationICount->getErrorCode()) { return false; } if (!in_array($sSort, array('', 'time', 'title'))) { return false; } if (!in_array($sOrder, array('', 'ASC', 'DESC'))) { return false; } $oWantedArticle = BsExtensionManager::getExtension('WantedArticle'); //Create list $aWishList = $oWantedArticle->getTitleListFromTitle($oWantedArticle->getDataSourceTemplateArticle()->getTitle()); switch ($sSort) { case 'title': $aTitleList = $oWantedArticle->sortWishListByTitle($aWishList); break; case 'time': default: $aTitleList = $oWantedArticle->getDefaultTitleList($aWishList); } if ($sOrder == 'ASC') { $aTitleList = array_reverse($aTitleList); } $oWishListView = new ViewWantedArticleTag(); $oWishListView->setTitle($sTitle)->setType($sType)->setOrder($sOrder)->setSort($sSort)->setCount($iCount)->setList($aTitleList); //result $aResult['success'] = true; $aResult['view'] = $oWishListView->execute(); return json_encode($aResult); }