/**
  * Retrieves the text for display in FormattingHelp. Called via AJAX.
  * @param string $sOutput rendered HTML output that is to be displayed.
  * @return bool allow other hooked methods to be executed. Always true.
  */
 public static function getFormattingHelp()
 {
     if (BsCore::checkAccessAdmission('edit') === false) {
         return true;
     }
     $sOutput = "<table id='bs-formattinghelp-table' class='wikitable'>\n\t\t\t<thead>\n\t\t\t\t<tr>\n\t\t\t\t\t<th></th>\n\t\t\t\t\t<th>" . wfMessage('bs-formattinghelp-help-syntax')->escaped() . "</th>\n\t\t\t\t</tr>\n\t\t\t</thead>\n\t\t\t<tbody>\n\t\t\t\t<tr>\n\t\t\t\t\t<td width='20%'><strong>" . wfMessage('bs-formattinghelp-help-bold')->escaped() . "</strong></td>\n\t\t\t\t\t<td><nowiki>'''" . wfMessage('bs-formattinghelp-help-example-text')->escaped() . "'''</nowiki></td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td width='20%'><strong>" . wfMessage('bs-formattinghelp-help-italic')->escaped() . "</strong></td>\n\t\t\t\t\t<td><nowiki>''" . wfMessage('bs-formattinghelp-help-example-text')->escaped() . "''</nowiki></td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td><strong>" . wfMessage('bs-formattinghelp-help-whitespace')->escaped() . "</strong></td>\n\t\t\t\t\t<td>&amp;nbsp;</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td><strong>" . wfMessage('bs-formattinghelp-help-nowiki')->escaped() . "</strong></td>\n\t\t\t\t\t<td>&lt;nowiki&gt;'''" . wfMessage('bs-formattinghelp-help-example-text')->escaped() . "'''&lt;/nowiki&gt;</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td><strong>" . wfMessage('bs-formattinghelp-help-color')->escaped() . "</strong></td>\n\t\t\t\t\t<td>&lt;font color=\"#DDBB65\"&gt;" . wfMessage('bs-formattinghelp-help-example-text')->escaped() . "&lt;/font&gt;</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td><strong>" . wfMessage('bs-formattinghelp-help-headline')->escaped() . "</strong></td>\n\t\t\t\t\t<td>= " . wfMessage('bs-formattinghelp-help-headline')->escaped() . " 1 =<br/>\n\t\t\t\t\t\t== " . wfMessage('bs-formattinghelp-help-headline')->escaped() . " 2 ==<br/>\n\t\t\t\t\t\t=== " . wfMessage('bs-formattinghelp-help-headline')->escaped() . " 3 ===<br/>\n\t\t\t\t\t\t==== " . wfMessage('bs-formattinghelp-help-headline')->escaped() . " 4 ====<br/>\n\t\t\t\t\t\t===== " . wfMessage('bs-formattinghelp-help-headline')->escaped() . " 5 =====<br/>\n\t\t\t\t\t\t====== " . wfMessage('bs-formattinghelp-help-headline')->escaped() . " 6 ======</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td><strong>" . wfMessage('bs-formattinghelp-help-linebreak')->escaped() . "</strong></td>\n\t\t\t\t\t<td>&lt;br /&gt;</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td><strong>" . wfMessage('bs-formattinghelp-help-ul')->escaped() . "</strong></td>\n\t\t\t\t\t<td>* " . wfMessage('bs-formattinghelp-help-listitem')->escaped() . "<br/>\n\t\t\t\t\t\t** " . wfMessage('bs-formattinghelp-help-subitem')->escaped() . "<br/>\n\t\t\t\t\t\t* " . wfMessage('bs-formattinghelp-help-listitem')->escaped() . "</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td><strong>" . wfMessage('bs-formattinghelp-help-numberedlist')->escaped() . "</strong></td>\n\t\t\t\t\t<td># " . wfMessage('bs-formattinghelp-help-listitem')->escaped() . "<br/>\n\t\t\t\t\t\t## " . wfMessage('bs-formattinghelp-help-subitem')->escaped() . "<br/>\n\t\t\t\t\t\t# " . wfMessage('bs-formattinghelp-help-listitem')->escaped() . "</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td><strong>" . wfMessage('bs-formattinghelp-help-link')->escaped() . "</strong></td>\n\t\t\t\t\t<td><nowiki>[[" . wfMessage('bs-formattinghelp-help-example-text')->escaped() . "]]</nowiki></td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td><strong>" . wfMessage('bs-formattinghelp-help-link-alt')->escaped() . "</strong></td>\n\t\t\t\t\t<td><nowiki>[[" . wfMessage('bs-ns')->escaped() . ":" . wfMessage('bs-formattinghelp-help-example-text')->escaped() . "|" . wfMessage('bs-formattinghelp-help-caption')->escaped() . "]]</nowiki></td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td><strong>" . wfMessage('bs-formattinghelp-help-extlink')->escaped() . "</strong></td>\n\t\t\t\t\t<td><nowiki>[http://www.hallowelt.biz http://www.hallowelt.biz]</nowiki></td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td><strong>" . wfMessage('bs-formattinghelp-help-hr')->escaped() . "</strong></td>\n\t\t\t\t\t<td>----</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td><strong>" . wfMessage('bs-formattinghelp-help-template')->escaped() . "</strong></td>\n\t\t\t\t\t<td><nowiki>{{" . wfMessage('bs-formattinghelp-help-templatename')->escaped() . "}}</nowiki></td>\n\t\t\t\t</tr>\n\t\t\t</tbody>\n\t\t\t</table>";
     return $sOutput;
 }
 /**
  * Renders a link that points to a complete list of blog entries
  * @return string HTML of link. 
  */
 public function renderShowAll()
 {
     if (!$this->getOption('showall')) {
         return '';
     }
     $sOut = $this->renderLink(array('href' => BsCore::getRequestURI(), 'query' => 'showall=true', 'title' => wfMessage('bs-blog-show-all')->plain()), wfMessage('bs-blog-show-all')->plain());
     return $sOut;
 }
 /**
  * This method actually generates the output
  * @return string HTML output
  */
 public function execute($aParam = false)
 {
     $sSearch = str_replace(BsCore::getForbiddenCharsInArticleTitle(), '', $this->getOption('search'));
     $oTitle = Title::newFromText($sSearch);
     $sSearchUrlencoded = urlencode($sSearch);
     $sSearchHtmlEntities = htmlentities($sSearch, ENT_QUOTES, 'UTF-8');
     $sCreatesuggest = '<ul>';
     wfRunHooks('BSExtendedSearchAdditionalActions', array(&$sCreatesuggest, &$sSearchUrlencoded, &$sSearchHtmlEntities, &$oTitle));
     $sCreatesuggest .= '</ul>';
     $sCreatesuggest .= '<br />';
     return $sCreatesuggest;
 }
 /**
  * The default contructor of the SpecialUniversalExport class
  */
 function __construct()
 {
     parent::__construct('UniversalExport', 'universalexport-export', true);
     $this->oOutputPage = $this->getOutput();
     //Set up default parameters and metadata
     $this->aParams = BsConfig::get('MW::UniversalExport::ParamsDefaults');
     $this->aParams['webroot-filesystempath'] = BsCore::getMediaWikiWebrootPath();
     $this->aMetadata = FormatJson::decode(BsConfig::get('MW::UniversalExport::MetadataDefaults'), true);
     //Set up Black- and Whitelists
     $this->aCategoryWhitelist = BsConfig::get('MW::UniversalExport::CategoryWhitelist');
     $this->aCategoryBlacklist = BsConfig::get('MW::UniversalExport::CategoryBlacklist');
 }
 /**
  * Initializes required fields.
  */
 private function initFields()
 {
     if ($this->oUser === null) {
         throw new BsException(__METHOD__ . ' - No user specified.');
     }
     $this->sUserDisplayName = BsCore::getInstance()->getUserDisplayName($this->oUser);
     $sUserImage = $this->oUser->getOption('MW::UserImage', '');
     //BsConfig::get() won't work on first call
     //Is it a URL? Some external image?
     $aParsedUrl = parse_url($sUserImage);
     if (!empty($sUserImage) && ($sUserImage[0] == '/' || isset($aParsedUrl['scheme']))) {
         $this->sImageUploadPath = SpecialPage::getTitleFor('Preferences')->getLinkUrl();
         $aPathInfo = pathinfo($aParsedUrl['path']);
         $aFileExtWhitelist = array('gif', 'jpg', 'jpeg', 'png');
         $this->sImagePath = $aParsedUrl['scheme'] . '://' . $aParsedUrl['host'] . $aParsedUrl['path'];
         if (!in_array(strtolower($aPathInfo['extension']), $aFileExtWhitelist)) {
             $this->sImagePath = BsConfig::get('MW::AnonUserImage');
         }
         return;
     }
     $oUserImageFile = RepoGroup::singleton()->getLocalRepo()->newFile($sUserImage);
     if ($oUserImageFile) {
         $UserImageArticle = new ImagePage($oUserImageFile->getTitle());
         $this->sImageUploadPath = $UserImageArticle->getUploadUrl();
         if ($oUserImageFile->exists() === false) {
             $this->sImagePath = BsConfig::get('MW::DefaultUserImage');
         } else {
             $oUserThumbnail = $oUserImageFile->transform(array('width' => 64, 'height' => 64));
             if ($oUserThumbnail !== false) {
                 $this->sImagePath = $oUserThumbnail->getUrl();
             } else {
                 $this->sImagePath = $oUserImageFile->getUrl();
             }
         }
     } else {
         $this->sImagePath = BsConfig::get('MW::DefaultUserImage');
     }
 }
 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));
 }
 /**
  * Delete a given namespace.
  */
 public function deleteNamespace($iNS, $iDoArticle)
 {
     if (wfReadOnly()) {
         global $wgReadOnly;
         return FormatJson::encode(array('success' => false, 'message' => wfMessage('bs-readonly', $wgReadOnly)->plain()));
     }
     if (BsCore::checkAccessAdmission('wikiadmin') === false) {
         return true;
     }
     $iNS = BsCore::sanitize($iNS, '', BsPARAMTYPE::INT);
     if (!$iNS) {
         return FormatJson::encode(array('success' => false, 'message' => wfMessage('bs-namespacemanager-invalid-id')->plain()));
     }
     global $wgContLang;
     $aUserNamespaces = self::getUserNamespaces(true);
     $aNamespacesToRemove = array(array($iNS, 0));
     $sNamespace = $aUserNamespaces[$iNS]['name'];
     if (!strstr($sNamespace, '_' . $wgContLang->getNsText(NS_TALK))) {
         if (isset($aUserNamespaces[$iNS + 1]) && strstr($aUserNamespaces[$iNS + 1]['name'], '_' . $wgContLang->getNsText(NS_TALK))) {
             $aNamespacesToRemove[] = array($iNS + 1, 1);
             $sNamespace = $aUserNamespaces[$iNS + 1]['name'];
         }
     }
     $bErrors = false;
     if (empty($iDoArticle)) {
         $iDoArticle = 0;
     }
     switch ($iDoArticle) {
         case 0:
             foreach ($aNamespacesToRemove as $aNamespace) {
                 $iNs = $aNamespace[0];
                 if (!NamespaceNuker::removeAllNamespacePages($iNs, $aUserNamespaces[$iNs]['name'])) {
                     $bErrors = true;
                 } else {
                     $aUserNamespaces[$aNamespace[0]] = false;
                 }
             }
             break;
         case 1:
             foreach ($aNamespacesToRemove as $aNamespace) {
                 $iNs = $aNamespace[0];
                 if (!NamespaceNuker::moveAllPagesIntoMain($iNs, $aUserNamespaces[$iNs]['name'])) {
                     $bErrors = true;
                 } else {
                     $aUserNamespaces[$aNamespace[0]] = false;
                 }
             }
             break;
         case 2:
         default:
             foreach ($aNamespacesToRemove as $aNamespace) {
                 $iNs = $aNamespace[0];
                 if (!NamespaceNuker::moveAllPagesIntoMain($iNs, $aUserNamespaces[$iNs]['name'], true)) {
                     $bErrors = true;
                 } else {
                     $aUserNamespaces[$aNamespace[0]] = false;
                 }
             }
             break;
     }
     if (!$bErrors) {
         $aResult = self::setUserNamespaces($aUserNamespaces);
         $aResult['message'] = wfMessage('bs-namespacemanager-nsremoved')->plain();
         return FormatJson::encode($aResult);
     } else {
         return FormatJson::encode(array('success' => false, 'message' => wfMessage('bs-namespacemanager-error_on_remove_namespace')->plain()));
     }
 }
 /**
  * Builds the ContentAction Array fort the current page
  * @return Array The ContentAction Array
  */
 private function buildContentAction()
 {
     $aCurrentQueryParams = $this->getRequest()->getValues();
     if (isset($aCurrentQueryParams['title'])) {
         $sTitle = $aCurrentQueryParams['title'];
     } else {
         $sTitle = '';
     }
     $sSpecialPageParameter = BsCore::sanitize($sTitle, '', BsPARAMTYPE::STRING);
     $oSpecialPage = SpecialPage::getTitleFor('UniversalExport', $sSpecialPageParameter);
     if (isset($aCurrentQueryParams['title'])) {
         unset($aCurrentQueryParams['title']);
     }
     $aCurrentQueryParams['ue[module]'] = 'pdf';
     return array('id' => 'bs-ta-uemodulepdf', 'href' => $oSpecialPage->getLinkUrl($aCurrentQueryParams), 'title' => wfMessage('bs-uemodulepdf-widgetlink-single-no-attachments-title')->text(), 'text' => wfMessage('bs-uemodulepdf-widgetlink-single-no-attachments-text')->text(), 'class' => 'icon-file-pdf');
 }
 private function getAuthorsViewForAfterContent($oSkin, &$aDetails)
 {
     $oTitle = $oSkin->getTitle();
     //Read in config variables
     $iLimit = BsConfig::get('MW::Authors::Limit');
     $aBlacklist = BsConfig::get('MW::Authors::Blacklist');
     $sMoreImage = BsConfig::get('MW::Authors::MoreImage');
     $aParams = array();
     $aParams['width'] = BsConfig::get('MW::Authors::ImageWidth');
     $aParams['height'] = BsConfig::get('MW::Authors::ImageHeight');
     $sPrintable = $oSkin->getRequest()->getVal('printable', 'no');
     $iArticleId = $oTitle->getArticleID();
     $sKey = BsCacheHelper::getCacheKey('BlueSpice', 'Authors', $iArticleId);
     $aData = BsCacheHelper::get($sKey);
     if ($aData !== false) {
         wfDebugLog('BsMemcached', __CLASS__ . ': Fetched AuthorsView and Details from cache');
         $oAuthorsView = $aData['view'];
         $aDetails = $aData['details'];
     } else {
         wfDebugLog('BsMemcached', __CLASS__ . ': Fetching AuthorsView and Details from DB');
         //HINT: Maybe we want to use MW interface Article::getContributors() to have better caching
         //HINT2: Check if available in MW 1.17+
         // SW: There is still no caching in WikiPage::getContributors()! 17.07.2014
         $dbr = wfGetDB(DB_SLAVE);
         $res = $dbr->select(array('revision'), array('rev_user_text', 'MAX(rev_timestamp) AS ts'), array('rev_page' => $iArticleId), __METHOD__, array('GROUP BY' => 'rev_user_text', 'ORDER BY' => 'ts DESC'));
         if ($res->numRows() == 0) {
             return true;
         }
         $oAuthorsView = new ViewAuthors();
         if ($sPrintable == 'yes') {
             $oAuthorsView->setOption('print', true);
         }
         $aUserNames = array();
         foreach ($res as $row) {
             $aUserNames[] = $row->rev_user_text;
         }
         $iCount = count($aUserNames);
         $aDetails['count'] = $iCount;
         $sOriginatorUserName = $oTitle->getFirstRevision()->getUserText();
         $sOriginatorUserName = $this->checkOriginatorForBlacklist($sOriginatorUserName, $oTitle->getFirstRevision(), $aBlacklist);
         if ($iCount > 1) {
             array_unshift($aUserNames, $sOriginatorUserName);
             $iCount++;
         }
         $bAddMore = false;
         if ($iCount > $iLimit) {
             $bAddMore = true;
         }
         $i = 0;
         $iItems = 0;
         $aDetails['username'] = '';
         while ($i < $iCount) {
             if ($iItems > $iLimit) {
                 break;
             }
             $sUserName = $aUserNames[$i];
             if (User::isIP($sUserName)) {
                 unset($aUserNames[$i]);
                 $i++;
                 continue;
             }
             $oAuthorUser = User::newFromName($sUserName);
             if (!is_object($oAuthorUser) || in_array($oAuthorUser->getName(), $aBlacklist)) {
                 unset($aUserNames[$i]);
                 $i++;
                 continue;
             }
             $aDetails['username'] = $oAuthorUser->getName();
             $oUserMiniProfileView = BsCore::getInstance()->getUserMiniProfile($oAuthorUser, $aParams);
             if ($sPrintable == 'yes') {
                 $oUserMiniProfileView->setOption('print', true);
             }
             $iItems++;
             $i++;
             $oAuthorsView->addItem($oUserMiniProfileView);
         }
         if ($bAddMore === true) {
             $oMoreAuthorsView = BsCore::getInstance()->getUserMiniProfile(new User(), $aParams);
             $oMoreAuthorsView->setOption('userdisplayname', wfMessage('bs-authors-show-all-authors')->plain());
             $oMoreAuthorsView->setOption('userimagesrc', $this->getImagePath(true) . '/' . $sMoreImage);
             $oMoreAuthorsView->setOption('linktargethref', $oTitle->getLocalURL(array('action' => 'history')));
             $oMoreAuthorsView->setOption('classes', array('bs-authors-more-icon'));
             if ($sPrintable == 'yes') {
                 $oMoreAuthorsView->setOption('print', true);
             }
             $oAuthorsView->addItem($oMoreAuthorsView);
         }
         $dbr->freeResult($res);
         BsCacheHelper::set($sKey, array('view' => $oAuthorsView, 'details' => $aDetails));
     }
     return $oAuthorsView;
 }
 /**
  * Sends a notification after adding an user.
  * @param User $oUser
  * @param Boolean $bByEmail
  * @return bool allow other hooked methods to be executed. Always true.
  */
 public function onAddNewAccount($oUser, $bByEmail)
 {
     wfProfileIn('BS::' . __METHOD__);
     if ($oUser->isAllowed('bot')) {
         return true;
     }
     EchoEvent::create(array('type' => 'bs-newuser', 'extra' => array('user' => $oUser->getName(), 'username' => $oUser->getName(), 'userlink' => true, 'realname' => BsCore::getUserDisplayName($oUser))));
     wfProfileOut('BS::' . __METHOD__);
     return true;
 }
 /**
  * Creates a Widget object
  * @return ViewWidget
  */
 public function getWidget()
 {
     $sAction = $this->getRequest()->getVal('action', 'view');
     if (!in_array($sAction, array('view', 'historysubmit'))) {
         return null;
     }
     $oCurrentTitle = $this->getTitle();
     if ($oCurrentTitle->quickUserCan('universalexport-export') === false) {
         return null;
     }
     $aCurrentQueryParams = $this->getRequest()->getValues();
     $sTitle = isset($aCurrentQueryParams['title']) ? $aCurrentQueryParams['title'] : "";
     $sSpecialPageParameter = BsCore::sanitize($sTitle, '', BsPARAMTYPE::STRING);
     $oSpecialPage = SpecialPage::getTitleFor('UniversalExport', $sSpecialPageParameter);
     if (isset($aCurrentQueryParams['title'])) {
         unset($aCurrentQueryParams['title']);
     }
     $aModules = array();
     wfRunHooks('BSUniversalExportGetWidget', array($this, &$aModules, $oSpecialPage, $oCurrentTitle, $aCurrentQueryParams));
     if (empty($aModules)) {
         return null;
     }
     $sList = '';
     foreach ($aModules as $oModuleView) {
         if ($oModuleView instanceof ViewBaseElement) {
             $sList .= $oModuleView->execute();
         } else {
             wfDebugLog('BS::UniversalExport', 'getWidget: Invalid view.');
         }
     }
     $oWidgetView = new ViewWidget();
     $oWidgetView->setId('universalexport')->setTitle(wfMessage('bs-universalexport-widget-title')->plain())->setBody($sList)->setTooltip(wfMessage('bs-universalexport-widget-tooltip')->plain());
     return $oWidgetView;
 }
 function onSuperListBuildDataSets(&$aRows)
 {
     if (!count($aRows)) {
         return true;
     }
     $aPageIds = array_keys($aRows);
     $dbr = wfGetDB(DB_READ);
     $aTables = array('bs_responsible_editors', 'user');
     $aJoinConditions = array('user' => array('JOIN', 're_user_id=user_id'));
     $sField = "re_page_id, re_position, user_id";
     $sCondition = "re_page_id IN (" . implode(',', $aPageIds) . ")";
     $aOptions = array('ORDER BY' => 're_page_id, re_position');
     $res = $dbr->select($aTables, $sField, $sCondition, __METHOD__, $aOptions, $aJoinConditions);
     $aData = array();
     $aUserIds = array();
     while ($row = $res->fetchObject()) {
         $oUser = User::newFromId($row->user_id);
         if ($oUser === null) {
             continue;
         }
         $aUserIds[$row->re_page_id][] = $row->user_id;
         $aData[$row->re_page_id][] = '<li>' . '<a class="bs-re-superlist-editor" href="#">' . BsCore::getUserDisplayName($oUser) . '</a>' . '</li>';
     }
     foreach ($aRows as $iKey => $aRowSet) {
         if (array_key_exists($iKey, $aData)) {
             $aRows[$iKey]['responsible_editors'] = Html::rawElement('ul', array('data-articleId' => $iKey, 'data-editorIds' => FormatJson::encode($aUserIds[$iKey])), implode('', $aData[$iKey]));
         }
     }
     return true;
 }
 public static function setUserGroups($aUserIds, $aGroups)
 {
     $res = $resDelGroups = $resInsGroups = $resERealUser = false;
     $aAnswer = array('success' => true, 'errors' => array(), 'message' => array());
     if (wfReadOnly()) {
         global $wgReadOnly;
         $aAnswer['success'] = false;
         $aAnswer['message'][] = wfMessage('bs-readonly', $wgReadOnly)->plain();
     }
     if (BsCore::checkAccessAdmission('wikiadmin') === false) {
         $aAnswer['success'] = false;
         $aAnswer['message'][] = wfMessage('bs-wikiadmin-notallowed')->plain();
     }
     global $wgUser;
     if (in_array($wgUser->getId(), $aUserIds) && in_array('sysop', $wgUser->getEffectiveGroups()) && !in_array('sysop', $aGroups)) {
         $aAnswer['success'] = false;
         $aAnswer['errors'][] = array('id' => 'groups', 'message' => wfMessage('bs-usermanager-no-self-desysop')->plain());
     }
     if ($aAnswer['success']) {
         $dbw = wfGetDB(DB_MASTER);
         $resDelGroups = $dbw->delete('user_groups', array('ug_user' => $aUserIds));
         $resInsGroups = true;
         if (is_array($aGroups)) {
             foreach ($aGroups as $sGroup) {
                 if (in_array($sGroup, self::$excludegroups)) {
                     continue;
                 }
                 foreach ($aUserIds as $iUserId) {
                     $resInsGroups = $dbw->insert('user_groups', array('ug_user' => (int) $iUserId, 'ug_group' => addslashes($sGroup)));
                     if ($resInsGroups === false) {
                         break;
                     }
                 }
             }
         }
     }
     if ($resDelGroups === false || $resInsGroups === false) {
         $aAnswer['success'] = false;
         $aAnswer['message'][] = wfMessage('bs-usermanager-db-error')->plain();
     }
     if ($aAnswer['success']) {
         $aAnswer['message'][] = wfMessage('bs-usermanager-save-successful')->plain();
     }
     return FormatJson::encode($aAnswer);
 }
 public static function getPages()
 {
     if (BsCore::checkAccessAdmission('read') === false) {
         return true;
     }
     global $wgUser, $wgContLang;
     $dbr = wfGetDB(DB_SLAVE);
     $dbr->clearFlag(DBO_TRX);
     $aNamespaces = $wgContLang->getNamespaces();
     $res = $dbr->select('page', array('page_title', 'page_namespace'), array(), __METHOD__, array('ORDER BY' => 'page_title'));
     $oSpecialRSS = SpecialPage::getTitleFor('RSSFeeder');
     $sUserName = $wgUser->getName();
     $sUserToken = $wgUser->getToken();
     $aPageRSS = array();
     while ($row = $res->fetchObject()) {
         $sNSPrefix = '';
         if ($row->page_namespace && isset($aNamespaces[$row->page_namespace])) {
             $sNSPrefix = ' (NS:' . $aNamespaces[$row->page_namespace] . ')';
         }
         $aPageRSS[] = array('page' => str_replace('_', ' ', $row->page_title . $sNSPrefix), 'url' => $oSpecialRSS->getLinkUrl(array('Page' => 'followPage', 'p' => $row->page_title, 'ns' => $row->page_namespace, 'u' => $sUserName, 'h' => $sUserToken)));
     }
     return FormatJson::encode(array('pages' => $aPageRSS));
 }
 /**
  * Creates the HTML for &lt;bs:watchlist /&gt; tag
  * @param string $sInput Inner HTML of the tag. Not used.
  * @param array $aAttributes List of the tag's attributes.
  * @param Parser $oParser MediaWiki parser object.
  * @return string Rendered HTML.
  */
 public function onWatchlistTag($sInput, $aAttributes, $oParser)
 {
     //Get arguments
     $iCount = BsCore::sanitizeArrayEntry($aAttributes, 'count', 5, BsPARAMTYPE::INT);
     $iMaxTitleLength = BsCore::sanitizeArrayEntry($aAttributes, 'maxtitlelength', 20, BsPARAMTYPE::INT);
     $sOrder = BsCore::sanitizeArrayEntry($aAttributes, 'order', 'pagename', BsPARAMTYPE::SQL_STRING);
     //'pagename|time'
     //Validation
     $oErrorListView = new ViewTagErrorList($this);
     $oValidationICount = BsValidator::isValid('IntegerRange', $iCount, array('fullResponse' => true, 'lowerBoundary' => 1, 'upperBoundary' => 1000));
     if ($oValidationICount->getErrorCode()) {
         $oErrorListView->addItem(new ViewTagError('count: ' . wfMessage($oValidationICount->getI18N())->text()));
     }
     $oValidationIMaxTitleLength = BsValidator::isValid('IntegerRange', $iMaxTitleLength, array('fullResponse' => true, 'lowerBoundary' => 5, 'upperBoundary' => 500));
     if ($oValidationIMaxTitleLength->getErrorCode()) {
         $oErrorListView->addItem(new ViewTagError('maxtitlelength: ' . wfMessage($oValidationIMaxTitleLength->getI18N())->text()));
     }
     $oValidationResult = BsValidator::isValid('SetItem', $sOrder, array('fullResponse' => true, 'setname' => 'sort', 'set' => array('time', 'pagename')));
     if ($oValidationResult->getErrorCode()) {
         $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N()));
     }
     if ($oErrorListView->hasItems()) {
         return $oErrorListView->execute();
     }
     $oWatchList = $this->fetchWatchlist($this->getUser(), $iCount, $iMaxTitleLength, $sOrder);
     return $this->mCore->parseWikiText($oWatchList->execute(), $this->getTitle());
 }
 protected static function writeGroupSettings($aGroupPermissions, $aNamespacePermissionLockdown)
 {
     global $bsgPermissionManagerGroupSettingsFile;
     if (wfReadOnly()) {
         global $wgReadOnly;
         return array('success' => false, 'msg' => wfMessage('bs-readonly', $wgReadOnly)->plain());
     }
     if (BsCore::checkAccessAdmission('wikiadmin') === false) {
         return true;
     }
     wfRunHooks('BsNamespacemanageOnSavePermission', array(&$aNamespacePermissionLockdown, &$aGroupPermissions));
     wfRunHooks('BsPermissionManager::writeGroupSettings', array(&$aNamespacePermissionLockdown, &$aGroupPermissions));
     self::backupExistingSettings();
     $sSaveContent = "<?php\n";
     foreach ($aGroupPermissions as $sGroup => $aPermissions) {
         foreach ($aPermissions as $sPermission => $bValue) {
             $sSaveContent .= "\$wgGroupPermissions['{$sGroup}']['{$sPermission}'] = " . ($bValue ? 'true' : 'false') . ";\n";
         }
     }
     if (is_array($aNamespacePermissionLockdown)) {
         foreach ($aNamespacePermissionLockdown as $iNS => $aPermissions) {
             $isReadLockdown = false;
             $sNsCanonicalName = MWNamespace::getCanonicalName($iNS);
             if ($iNS == NS_MAIN) {
                 $sNsCanonicalName = 'MAIN';
             }
             $sNsConstant = 'NS_' . strtoupper($sNsCanonicalName);
             foreach ($aPermissions as $sPermission => $aGroups) {
                 if (empty($aGroups)) {
                     continue;
                 }
                 $sSaveContent .= "\$wgNamespacePermissionLockdown[{$sNsConstant}]['{$sPermission}']" . " = array(" . (count($aGroups) ? "'" . implode("','", $aGroups) . "'" : '') . ");\n";
                 if ($sPermission == 'read') {
                     $isReadLockdown = true;
                 }
             }
             if ($isReadLockdown) {
                 $sSaveContent .= "\$wgNonincludableNamespaces[] = {$sNsConstant};\n";
             }
         }
     }
     $res = file_put_contents($bsgPermissionManagerGroupSettingsFile, $sSaveContent);
     if ($res) {
         return array('success' => true);
     } else {
         return array('success' => false, 'msg' => 'Not able to create or write "' . $bsgPermissionManagerGroupSettingsFile . '".');
     }
 }
 /**
  * Searches the DOM for <img>-Tags and <a> Tags with class 'internal', 
  * resolves the local filesystem path and adds it to $aFiles array.
  * @param DOMDocument $oHtml The markup to be searched.
  * @return boolean Well, always true.
  */
 protected function findFiles(&$oHtml)
 {
     //Find all images
     $oImageElements = $oHtml->getElementsByTagName('img');
     foreach ($oImageElements as $oImageElement) {
         $sSrcUrl = urldecode($oImageElement->getAttribute('src'));
         $sSrcFilename = basename($sSrcUrl);
         $bIsThumb = UploadBase::isThumbName($sSrcFilename);
         $sTmpFilename = $sSrcFilename;
         if ($bIsThumb) {
             //HINT: Thumbname-to-filename-conversion taken from includes/Upload/UploadBase.php
             //Check for filenames like 50px- or 180px-, these are mostly thumbnails
             $sTmpFilename = substr($sTmpFilename, strpos($sTmpFilename, '-') + 1);
         }
         $oFileTitle = Title::newFromText($sTmpFilename, NS_FILE);
         $oImage = RepoGroup::singleton()->findFile($oFileTitle);
         if ($oImage instanceof File && $oImage->exists()) {
             $oFileRepoLocalRef = $oImage->getRepo()->getLocalReference($oImage->getPath());
             if (!is_null($oFileRepoLocalRef)) {
                 $sAbsoluteFileSystemPath = $oFileRepoLocalRef->getPath();
             }
             $sSrcFilename = $oImage->getName();
         } else {
             $sAbsoluteFileSystemPath = $this->getFileSystemPath($sSrcUrl);
         }
         // TODO RBV (05.04.12 11:48): Check if urlencode has side effects
         $oImageElement->setAttribute('src', 'images/' . urlencode($sSrcFilename));
         $sFileName = $sSrcFilename;
         wfRunHooks('BSUEModulePDFWebserviceFindFiles', array($this, $oImageElement, $sAbsoluteFileSystemPath, $sFileName, 'IMAGE'));
         $this->aFiles['IMAGE'][$sFileName] = $sAbsoluteFileSystemPath;
     }
     $oDOMXPath = new DOMXPath($oHtml);
     /*
     * This is now in template
     		//Find all CSS files
     		$oLinkElements = $oHtml->getElementsByTagName( 'link' ); // TODO RBV (02.02.11 16:48): Limit to rel="stylesheet" and type="text/css"
     		foreach( $oLinkElements as $oLinkElement ) {
     			$sHrefUrl = $oLinkElement->getAttribute( 'href' );
     			$sHrefFilename           = basename( $sHrefUrl );
     			$sAbsoluteFileSystemPath = $this->getFileSystemPath( $sHrefUrl );
     			$this->aFiles[ $sAbsoluteFileSystemPath ] = array( $sHrefFilename, 'STYLESHEET' );
     			$oLinkElement->setAttribute( 'href', 'stylesheets/'.$sHrefFilename );
     		}
     */
     //Find all files for attaching and merging...
     if ($this->aParams['pdf-merging'] == '1' || $this->aParams['attachments'] == '1') {
         $sUploadPath = BsCore::getInstance()->getAdapter()->get('UploadPath');
         // TODO RBV (08.02.11 15:15): Necessary to exclude images?
         $oFileAnchorElements = $oDOMXPath->query("//a[contains(@class,'internal') and not(contains(@class, 'image'))]");
         foreach ($oFileAnchorElements as $oFileAnchorElement) {
             $sHref = urldecode($oFileAnchorElement->getAttribute('href'));
             $vUploadPathIndex = strpos($sHref, $sUploadPath);
             if ($vUploadPathIndex !== false) {
                 $sRelativeHref = substr($sHref, $vUploadPathIndex);
                 $sHrefFilename = basename($sRelativeHref);
                 $sAbsoluteFileSystemPath = $this->getFileSystemPath($sRelativeHref);
                 if ($this->aParams['attachments'] == '1') {
                     wfRunHooks('BSUEModulePDFWebserviceFindFiles', array($this, $oFileAnchorElement, $sAbsoluteFileSystemPath, $sHrefFilename, 'ATTACHMENT'));
                     $this->aFiles['ATTACHMENT'][$sHrefFilename] = $sAbsoluteFileSystemPath;
                 }
             }
         }
     }
     return true;
 }
 /**
  * Send email notification to next user(s) on review list.
  * @param BsReviewProcess $oReviewProcess Review process users should be notified for.
  * @return Status
  */
 public function emailNotifyNextUsers($oReviewProcess)
 {
     $aNextUsers = $oReviewProcess->getNextUsers();
     // Identify owner
     $oOwner = User::newFromId($oReviewProcess->getOwner());
     $sOwnerRealName = BsCore::getUserDisplayName($oOwner);
     $oTitle = Title::newFromID($oReviewProcess->pid);
     $sTitleText = $oTitle->getPrefixedText();
     $sLink = BsLinkProvider::makeLink($oTitle, $oTitle->getFullURL());
     foreach ($aNextUsers as $aReviewer) {
         // dirty workaround, sometimes id comes as username
         if (is_numeric($aReviewer['id'])) {
             $oReviewer = User::newFromId($aReviewer['id']);
         } else {
             $oReviewer = User::newFromName($aReviewer['id']);
         }
         if (!BsConfig::getVarForUser('MW::Review::EmailNotifyReviewer', $oReviewer->getName())) {
             continue;
         }
         // Identify reviewer
         //PW(10.03.2015): Echo notifications
         $sReviewerMail = $oReviewer->getEmail();
         if (!$sReviewerMail) {
             continue;
         }
         $sReviewerLang = $oReviewer->getOption('language');
         $sSubject = wfMessage('bs-review-mail-invite-header', $sTitleText)->inLanguage($sReviewerLang)->text();
         $sMsg = wfMessage('bs-review-mail-invite-body', $sOwnerRealName, $oOwner->getName(), $sTitleText)->inLanguage($sReviewerLang)->text();
         $sMsg .= "\n\n" . $sLink;
         if ($aReviewer['comment']) {
             $sMsg .= "\n" . wfMessage('bs-review-mail-comment', $aReviewer['comment'])->inLanguage($sReviewerLang)->text();
         }
         //Send mail to next user in queue
         BsMailer::getInstance('MW')->send($oReviewer, $sSubject, $sMsg);
     }
 }
 /**
  * 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;
 }
 /**
  * PW(25.03.2015) TODO: Use API
  * @global User $wgUser
  * @global Language $wgLang
  * @return string
  */
 public static function doSaveArticle()
 {
     $aResult = $aOutput = array('saveresult' => 'fail', 'message' => '', 'edittime' => '', 'summary' => '', 'starttime' => wfTimestamp(TS_MW, time() + 2));
     if (BsCore::checkAccessAdmission('read') === false) {
         $aResult['message'] = wfMessage('bs-permissionerror')->plain();
         return FormatJson::encode($aResult);
     }
     global $wgLang, $wgRequest;
     $sArticleId = $wgRequest->getInt('articleId', 0);
     $sText = $wgRequest->getVal('text', '');
     $sPageName = $wgRequest->getVal('pageName', '');
     $sSummary = $wgRequest->getVal('summary', '');
     $iSection = $wgRequest->getInt('editsection', 0);
     $sReturnEditTime = wfTimestampNow();
     if ($sSummary == 'false') {
         $sSummary = '/* ' . wfMessage('bs-visualeditor-no-summary')->plain() . ' */';
     }
     //PW(25.03.2015) TODO: Use Wikipage
     $oArticle = Article::newFromID($sArticleId);
     if (is_null($oArticle)) {
         $oTitle = Title::newFromText($sPageName);
         if (is_null($oTitle) || !$oTitle->exists()) {
             $aResult['message'] = wfMessage('badtitle')->plain();
             return FormatJson::encode($aResult);
         }
         $oArticle = new Article($oTitle);
     }
     if ($iSection) {
         $sText = $oArticle->replaceSection($iSection, $sText);
     }
     //PW(25.03.2015) TODO: Deprecated since MW 1.21 use
     //Wikipage::doEditContent instead
     $oSaveResult = $oArticle->doEdit($sText, $sSummary);
     if ($oSaveResult->isGood()) {
         $sTime = $wgLang->timeanddate($sReturnEditTime, true);
         $aResult['edittime'] = $sReturnEditTime;
         $aResult['saveresult'] = 'ok';
         $aResult['message'] = wfMessage('bs-visualeditor-save-message', $sTime, $sSummary)->plain();
         $aResult['summary'] = $sSummary;
     } else {
         $aResult['message'] = $oSaveResult->getMessage()->plain();
     }
     return FormatJson::encode($aResult);
 }
 /**
  * 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;
 }
 /**
  * Generates list of most edited pages
  * @return String list of pages or empty
  */
 public function getActivePortlet($iCount, $iTime)
 {
     $oDbr = wfGetDB(DB_SLAVE);
     $iCount = BsCore::sanitize($iCount, 10, BsPARAMTYPE::INT);
     $iTime = BsCore::sanitize($iTime, 0, BsPARAMTYPE::INT);
     $aConditions = array();
     if ($iTime !== 0) {
         $this->getTimestampForQuery($aConditions, $iTime);
     }
     $res = $oDbr->select('revision', array('COUNT(rev_user) as edit_count', 'rev_user'), $aConditions, __METHOD__, array('GROUP BY' => 'rev_user', 'ORDER BY' => 'edit_count DESC'));
     $aList = array();
     if ($oDbr->numRows($res) > 0) {
         $aList[] = '<ol>';
         $i = 1;
         foreach ($res as $row) {
             if ($i > $iCount) {
                 break;
             }
             $oUser = User::newFromId($row->rev_user);
             if ($oUser->isIP($oUser->getName())) {
                 continue;
             }
             $oTitle = Title::makeTitle(NS_USER, $oUser->getName());
             $sLink = BsLinkProvider::makeLink($oTitle);
             $aList[] = '<li>' . $sLink . ' (' . $row->edit_count . ')</li>';
             $i++;
         }
         $aList[] = '</ol>';
     }
     $oDbr->freeResult($res);
     return implode("\n", $aList);
 }
 /**
  * Adds a user based greeting to the text mail
  * @param Message $message
  * @param User $oUser
  * @return String
  */
 public function userBasedDecorateIntro($message, $oUser)
 {
     $sRealname = BsCore::getUserDisplayName($oUser);
     $sReturn = wfMessage('bs-email-greeting-receiver')->params($oUser->getName(), $sRealname)->inLanguage($oUser->getOption('language'))->text();
     return $sReturn . "\n\n" . $message->text();
 }
 /**
  * Deletes an interwiki link. Called via AJAX function
  * @return bool allow other hooked methods to be executed. always true.
  */
 public static function doDeleteInterWikiLink($iw_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 ($aAnswer['success']) {
         $dbw = wfGetDB(DB_MASTER);
         $res1 = $dbw->delete('interwiki', array('iw_prefix' => $iw_prefix));
     }
     if ($res1 === false) {
         $aAnswer['success'] = false;
         $aAnswer['errors'][] = array('message' => wfMessage('bs-interwikilinks-nourl')->plain());
     }
     if ($aAnswer['success']) {
         $aAnswer['message'][] = wfMessage('bs-interwikilinks-link-deleted')->plain();
     }
     self::purgeTitles($iw_prefix);
     return FormatJson::encode($aAnswer);
 }
 /**
  * This method actually generates the output
  * @param array $aParams not used here
  * @return string HTML output
  */
 public function execute($aParams = false)
 {
     global $wgUser;
     $sUserName = $this->oUser->getName();
     $sUserRealName = $this->oUser->getRealName();
     //Fallback for old entries without user_id
     if ($this->oUser->isAnon()) {
         $sUserName = $this->sUsername;
     }
     $aOut = array();
     $aOut[] = '<li class="bs-sb-listitem clearfix" id="bs-sb-' . $this->iShoutID . '">';
     $aOut[] = '  <div class="bs-user-image">';
     if ($this->oMiniProfile instanceof ViewUserMiniProfile) {
         $aOut[] = $this->oMiniProfile->execute();
     }
     $aOut[] = '  </div>';
     $aOut[] = '  <div class="bs-sb-message">';
     $aOut[] = '    <div class="bs-sb-message-head">';
     $aOut[] = '      <strong>' . $sUserName . '</strong>';
     if (!empty($sUserRealName)) {
         $aOut[] = '      <span class="bs-sb-meassage-head-small">' . $sUserRealName . '</span>';
     }
     $aOut[] = '    </div>';
     if (isset($this->sDate)) {
         $aOut[] = '<div class="bs-sb-message-time">' . $this->sDate;
         $aOut[] = '</div> ';
     }
     $aOut[] = '    <div class="bs-sb-message-text">' . nl2br($this->sMessage);
     $aOut[] = '    </div> ';
     $aOut[] = '  </div>';
     $sArchiveButton = '';
     $sArchiveButtonEnabled = '  <div class="bs-sb-archive"></div>';
     //set button if user has the right to archive
     if (BsCore::checkAccessAdmission('archiveshoutbox')) {
         $sArchiveButton = $sArchiveButtonEnabled;
     }
     //if setting for "allow own entries to be archived" is set + username == shoutbox-entry-username => set button
     if (BsConfig::get('MW::ShoutBox::AllowArchive') && $wgUser->getName() == $sUserName) {
         $sArchiveButton = $sArchiveButtonEnabled;
     }
     $aOut[] = $sArchiveButton;
     $aOut[] = '</li>';
     return implode("\n", $aOut);
 }
 /**
  * Creates a new review from JSON imput.
  * @param string $sJSON JSON input the review should be created from.
  * @param array $aErrors List of errors in case anything goes wrong.
  * @return mixed BsReviewProcess or false if anything goes wrong.
  */
 static function newFromJSON($sJSON = '', &$aErrors)
 {
     $aErrors = array();
     $oJsonReview = json_decode($sJSON);
     $oReviewProcess = new BsReviewProcess();
     // rv_pid is stored in table hw_review as a smallint(5) unsigned
     $oReviewProcess->pid = BsCore::sanitize($oJsonReview->pid, -1, BsPARAMTYPE::NUMERIC);
     $oReviewProcess->editable = !!$oJsonReview->editable;
     $oReviewProcess->sequential = !!$oJsonReview->sequential;
     $oReviewProcess->abortable = !!$oJsonReview->abortable;
     if (!$oJsonReview->startdate) {
         $aErrors[] = 'startdate-missing';
     }
     $oReviewProcess->startdate = date("YmdHis", strtotime(BsCore::sanitize($oJsonReview->startdate, '', BsPARAMTYPE::STRING)));
     if (!$oJsonReview->enddate) {
         $aErrors[] = 'enddate-missing';
     }
     $oReviewProcess->enddate = date("YmdHis", strtotime(BsCore::sanitize($oJsonReview->enddate, '', BsPARAMTYPE::STRING)));
     if ($oReviewProcess->startdate > $oReviewProcess->enddate) {
         $aErrors[] = 'startdate-after-enddate';
     }
     $paramRvSteps = $oJsonReview->steps;
     if (count($paramRvSteps) <= 0) {
         $aErrors[] = 'no-reviewers';
     }
     // TODO an MRG: wir dieser block noch benötigt oder ist er inzwischen deprecated ??
     // Fixed mit isset
     if (isset($oJsonReview->tmpl_save) && $oJsonReview->tmpl_save) {
         $oReviewProcess->tmpl_save = true;
         $oReviewProcess->tmpl_name = addslashes($oJsonReview->tmpl_name);
         $oReviewProcess->tmpl_choice = $oJsonReview->tmpl_choice;
     }
     foreach ($paramRvSteps as $oStep) {
         if ($oStep->status == '' || $oStep->status == 'unknown') {
             $oStep->status = '-1';
         }
         if ($oStep->status == 'yes') {
             $oStep->status = '1';
         }
         if ($oStep->status == 'no') {
             $oStep->status = '0';
         }
         $sComment = BsCore::sanitize($oStep->comment, '', BsPARAMTYPE::STRING);
         if (strlen($sComment) > 255) {
             $aErrors[] = 'comment-too-long';
         }
         if (!$oStep->userid || !is_numeric($oStep->userid)) {
             //TODO: make sure you get a valid id
             //PW: wont work with realname!
             $oStep->userid = User::idFromName($oStep->name);
             if (!$oStep->userid) {
                 $aErrors[] = 'user-not-found';
             }
         } else {
             $oTmpUser = User::newFromId($oStep->userid);
             if (!$oTmpUser) {
                 $aErrors[] = 'user-not-found';
             }
         }
         $oReviewProcess->steps[] = BsReviewProcessStep::newFromData(BsCore::sanitize($oStep->userid, '', BsPARAMTYPE::INT), $sComment, BsCore::sanitize($oStep->status, '-1', BsPARAMTYPE::STRING));
     }
     if (is_array($aErrors) && count($aErrors) > 0) {
         return false;
     } else {
         return $oReviewProcess;
     }
 }
 /**
  * Renders the body of a blog item
  * @return string Rendered HTML
  */
 protected function renderArticle()
 {
     $sOut = '__NOTOC__ __NOEDITSECTION__';
     if ($this->getOption('showInfo')) {
         if ($this->mAuthorPage) {
             $sAuthorUserPageWikiLink = '[[' . $this->mAuthorPage . '|' . $this->mAuthorName . ']]';
         } else {
             $sAuthorUserPageWikiLink = $this->mAuthorName;
         }
         $sOut .= "\n" . '<div class="bs-blog-item-info">' . $this->mEntryDate . ' - ' . $sAuthorUserPageWikiLink . '</div>' . "\n";
     }
     $sOut .= "\n";
     $sOut .= $this->mContent;
     if ($this->getOption('moreAtEndOfEntry')) {
         $sOut .= '&nbsp;';
     } else {
         $sOut .= "\n";
     }
     $sParsedOut = BsCore::getInstance()->parseWikiText($sOut, RequestContext::getMain()->getTitle());
     $sOut = $sParsedOut;
     if ($this->getOption('more')) {
         $aLinkOptions = array('href' => $this->mUrl, 'class' => 'bs-blog-item-read-more', 'title' => wfMessage('bs-blog-read-more')->plain());
         if ($this->getOption('moreInNewWindow')) {
             $aLinkOptions['openInNewWindow'] = true;
         }
         $sContent = wfMessage('bs-blog-read-more')->plain();
         if ($this->getOption('moreAtEndOfEntry')) {
             $sContent .= '...';
         }
         $sOut .= $this->renderLink($aLinkOptions, $sContent);
         if (!$this->getOption('moreAtEndOfEntry')) {
             $sOut .= $this->mActionDivisor;
         } else {
             $sOut .= '<br />';
         }
     }
     return $sOut;
 }
 /**
  * Renders bs:whoisonline:popup output.
  * @param Parser $oParser MediaWiki parser object.
  * @param string $sLinkTitle Label of the link that is the anchor of the flyout
  * @return array Rendered HTML and flags. Used by magic word function hook as well as by onUsersLinkTag.
  */
 public function onUsersLink($oParser, $sLinkTitle = '')
 {
     $oParser->disableCache();
     wfProfileIn('BS::' . __METHOD__);
     $sLinkTitle = BsCore::sanitize($sLinkTitle, '', BsPARAMTYPE::STRING);
     if (empty($sLinkTitle)) {
         $sLinkTitle = wfMessage('bs-whoisonline-widget-title')->plain();
     }
     $oWhoIsOnlineTagView = new ViewWhoIsOnlineTag();
     $oWhoIsOnlineTagView->setOption('title', $sLinkTitle);
     $oWhoIsOnlineTagView->setPortlet($this->getPortlet());
     $sOut = $oWhoIsOnlineTagView->execute();
     wfProfileOut('BS::' . __METHOD__);
     return $oParser->insertStripItem($sOut, $oParser->mStripState);
 }
 /**
  * removes a usergroup
  * @param string $output the ajax output string
  */
 public static function removeGroup($sGroup)
 {
     if (wfReadOnly()) {
         global $wgReadOnly;
         return FormatJson::encode(array('success' => false, 'message' => wfMessage('bs-readonly', $wgReadOnly)->plain()));
     }
     if (BsCore::checkAccessAdmission('wikiadmin') === false) {
         return true;
     }
     global $wgGroupPermissions, $wgAdditionalGroups, $wgNamespacePermissionLockdown;
     $output = FormatJson::encode(array('success' => true, 'message' => wfMessage('bs-groupmanager-grpremoved')->plain()));
     if ($sGroup) {
         if (!isset($wgAdditionalGroups[$sGroup])) {
             return FormatJson::encode(array('success' => false, 'message' => wfMessage('bs-groupmanager-msgnotremovable')->plain()));
         }
         $wgAdditionalGroups[$sGroup] = false;
         $dbw = wfGetDB(DB_MASTER);
         $res = $dbw->delete('user_groups', array('ug_group' => $sGroup));
         if ($res === false) {
             return FormatJson::encode(array('success' => false, 'message' => wfMessage('bs-groupmanager-removegroup-message-unknown')->plain()));
         }
         $result = BsExtensionManager::getExtension('GroupManager')->saveData();
         wfRunHooks("BSGroupManagerGroupDeleted", array($sGroup, &$result));
         if ($result['success'] === false) {
             return FormatJson::encode($result);
         }
     }
     return $output;
 }
 /**
  * Callback from preg_replace, replaces the mention with a link to the user page
  * @param array $sMatch
  * @return String The link to the user page
  */
 public static function replaceUsernameInMessage($sMatch)
 {
     $oUser = User::newFromName($sMatch[1]);
     return Linker::link($oUser->getUserPage(), BsCore::getUserDisplayName($oUser));
 }