/**
  * Gets the recently visited pages of the current user.
  * @param int $iCount The number of pages to display
  * @param string $sNamespaces Comma separated list of requested namespaces, i.e. "1,5,Category,101"
  * @param int $iCurrentNamespaceId To determin wether the current namespace is in the list of requested namespaces
  * @param string $sSortOrder Defines the sorting of the list. 'time|pagename', default is 'time'
  * @return ViewBaseElement Contains the list in its _data member. The predefined template is '*[[{LINK}|{TITLE}]]\n'
  */
 private function makePagesVisitedWikiList($iCount = 5, $sNamespaces = 'all', $iCurrentNamespaceId = 0, $iMaxTitleLength = 20, $sSortOrder = 'time')
 {
     $oCurrentUser = $this->getUser();
     if (is_null($oCurrentUser)) {
         return null;
     }
     // in CLI
     //$sCacheKey = md5( $oCurrentUser->getName().$iCount.$sNamespaces.$iCurrentNamespaceId.$iMaxTitleLength );
     //if( isset( self::$prResultListViewCache[$sCacheKey] ) ) return self::$prResultListViewCache[$sCacheKey];
     $oErrorListView = new ViewTagErrorList($this);
     $oErrorView = null;
     $aConditions = array();
     $aNamespaceIndexes = array(0);
     try {
         $aNamespaceIndexes = BsNamespaceHelper::getNamespaceIdsFromAmbiguousCSVString($sNamespaces);
         //Returns array of integer indexes
     } catch (BsInvalidNamespaceException $oException) {
         $aInvalidNamespaces = $oException->getListOfInvalidNamespaces();
         $oVisitedPagesListView = new ViewBaseElement();
         $oVisitedPagesListView->setTemplate('<ul><li><em>{TEXT}</em></li></ul>' . "\n");
         $iCount = count($aInvalidNamespaces);
         $sNs = implode(', ', $aInvalidNamespaces);
         $sErrorMsg = wfMessage('bs-pagesvisited-error-nsnotvalid', $iCount, $sNs)->text();
         $oVisitedPagesListView->addData(array('TEXT' => $sErrorMsg));
         //self::$prResultListViewCache[$sCacheKey] = $oVisitedPagesListView;
         return $oVisitedPagesListView;
     }
     $aConditions = array('wo_user_id' => $oCurrentUser->getId(), 'wo_action' => 'view');
     $aConditions[] = 'wo_page_namespace IN (' . implode(',', $aNamespaceIndexes) . ')';
     //Add IN clause to conditions-array
     $aConditions[] = 'wo_page_namespace != -1';
     // TODO RBV (24.02.11 13:54): Filter SpecialPages because there are difficulties to list them
     $aOptions = array('GROUP BY' => 'wo_page_id, wo_page_namespace, wo_page_title', 'ORDER BY' => 'MAX(wo_timestamp) DESC');
     if ($sSortOrder == 'pagename') {
         $aOptions['ORDER BY'] = 'wo_page_title ASC';
     }
     //If the page the extension is used on appears in the result set we have to fetch one row more than neccessary.
     if (in_array($iCurrentNamespaceId, $aNamespaceIndexes)) {
         $aOptions['OFFSET'] = 1;
     }
     $aFields = array('wo_page_id', 'wo_page_namespace', 'wo_page_title');
     $sTable = 'bs_whoisonline';
     $dbr = wfGetDB(DB_SLAVE);
     global $wgDBtype;
     if ($wgDBtype == 'oracle') {
         $sRowNumField = 'rnk';
         $sTable = mb_strtoupper($dbr->tablePrefix() . $sTable);
         $sFields = implode(',', $aFields);
         $sConditions = $dbr->makeList($aConditions, LIST_AND);
         $aOptions['ORDER BY'] = $sSortOrder == 'pagename' ? $aOptions['ORDER BY'] : 'wo_timestamp DESC';
         $res = $dbr->query("SELECT " . $sFields . " FROM (\n\t\t\t\t\t\t\t\t\t\t\tSELECT " . $sFields . ", row_number() over (order by " . $aOptions['ORDER BY'] . ") " . $sRowNumField . "\n\t\t\t\t\t\t\t\t\t\t\tFROM " . $sTable . "\n\t\t\t\t\t\t\t\t\t\t\tWHERE " . $sConditions . "\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\tWHERE " . $sRowNumField . " BETWEEN (0) AND (" . $iCount . ") GROUP BY " . $aOptions["GROUP BY"] . "");
     } else {
         $res = $dbr->select($sTable, $aFields, $aConditions, __METHOD__, $aOptions);
     }
     $oVisitedPagesListView = new ViewBaseElement();
     $oVisitedPagesListView->setTemplate('*{WIKILINK}' . "\n");
     $iItems = 1;
     foreach ($res as $row) {
         if ($iItems > $iCount) {
             break;
         }
         $oVisitedPageTitle = Title::newFromID($row->wo_page_id);
         /*
         // TODO RBV (24.02.11 13:52): Make SpecialPages work...
         $oVisitedPageTitle = ( $row->wo_page_namespace != NS_SPECIAL )
         					? Title::newFromID( $row->wo_page_id )
         					//: SpecialPage::getTitleFor( $row->wo_page_title );
         					: Title::makeTitle( NS_SPECIAL, $row->wo_page_title );
         */
         if ($oVisitedPageTitle == null || $oVisitedPageTitle->exists() === false || $oVisitedPageTitle->quickUserCan('read') === false) {
             continue;
         }
         $sDisplayTitle = BsStringHelper::shorten($oVisitedPageTitle->getPrefixedText(), array('max-length' => $iMaxTitleLength, 'position' => 'middle'));
         $oVisitedPagesListView->addData(array('WIKILINK' => BsLinkProvider::makeEscapedWikiLinkForTitle($oVisitedPageTitle, $sDisplayTitle)));
         $iItems++;
     }
     //$dbr->freeResult( $res );
     //self::$prResultListViewCache[$sCacheKey] = $oVisitedPagesListView;
     return $oVisitedPagesListView;
 }
 /**
  *
  * @param User $oCurrentUser
  * @param int $iCount
  * @param int $iMaxTitleLength
  * @param string $sOrder
  * @return ViewBaseElement
  */
 private function fetchWatchlist($oCurrentUser, $iCount = 10, $iMaxTitleLength = 50, $sOrder = 'pagename')
 {
     $aWatchlist = array();
     $aOptions = array();
     if ($sOrder == 'pagename') {
         $aOptions['ORDER BY'] = 'wl_title';
     }
     $aOptions['LIMIT'] = $iCount;
     $dbr = wfGetDB(DB_SLAVE);
     $res = $dbr->select('watchlist', array('wl_namespace', 'wl_title'), array('wl_user' => $oCurrentUser->getId(), 'NOT wl_notificationtimestamp' => NULL), __METHOD__, $aOptions);
     $oWatchedArticlesListView = new ViewBaseElement();
     $oWatchedArticlesListView->setTemplate('*{WIKILINK}' . "\n");
     foreach ($res as $row) {
         $oWatchedTitle = Title::newFromText($row->wl_title, $row->wl_namespace);
         if ($oWatchedTitle === null || $oWatchedTitle->exists() === false || $oWatchedTitle->userCan('read') === false) {
             continue;
         }
         $sDisplayTitle = BsStringHelper::shorten($oWatchedTitle->getPrefixedText(), array('max-length' => $iMaxTitleLength, 'position' => 'middle'));
         $oWatchedArticlesListView->addData(array('WIKILINK' => BsLinkProvider::makeEscapedWikiLinkForTitle($oWatchedTitle, $sDisplayTitle)));
     }
     return $oWatchedArticlesListView;
 }
 /**
  * Creates a Widget and returns it
  * @return ViewWidget
  */
 public function onWidgetListKeyword()
 {
     $sTitle = wfMessage('bs-wantedarticle-tag-default-title')->plain();
     $aWishList = $this->getTitleListFromTitle($this->getDataSourceTemplateArticle()->getTitle());
     $sSort = BsConfig::get('MW::WantedArticle::Sort');
     switch ($sSort) {
         case 'title':
             $aTitleList = $this->sortWishListByTitle($aWishList);
             break;
         case 'time':
         default:
             $aTitleList = $this->getDefaultTitleList($aWishList);
     }
     if (BsConfig::get('MW::WantedArticle::Order') == 'DESC') {
         $aTitleList = array_reverse($aTitleList);
     }
     $iIncludeLimit = BsConfig::get('MW::WantedArticle::IncludeLimit');
     $iCount = count($aTitleList);
     $iCount = $iCount > $iIncludeLimit ? $iIncludeLimit : $iCount;
     $aWikiCodeList = array();
     $oTitle = null;
     $sWishTitle = '';
     for ($i = 0; $i < $iCount; $i++) {
         $oTitle = $aTitleList[$i];
         $sWishTitle = BsStringHelper::shorten($oTitle->getPrefixedText(), array('max-length' => 30, 'position' => 'middle'));
         $aWikiCodeList[] = '*' . BsLinkProvider::makeEscapedWikiLinkForTitle($oTitle, $sWishTitle);
     }
     $sBody = $this->mCore->parseWikiText(implode("\n", $aWikiCodeList), $this->getTitle());
     $oWidgetView = new ViewWidget();
     $oWidgetView->setTitle($sTitle)->setBody($sBody)->setTooltip($sTitle)->setAdditionalBodyClasses(array('bs-nav-links'));
     //For correct margin and fontsize
     return $oWidgetView;
 }