Example #1
0
 /**
  * The general method for handling the communication with the service.
  */
 public function request($resourceName, $getParams = [], $postData = [], $extraRequestOptions = [])
 {
     // Crash if we cannot make HTTP requests.
     \Wikia\Util\Assert::true(\MWHttpRequest::canMakeRequests());
     // Add client_id and client_secret to the GET data.
     $getParams['client_id'] = $this->clientId;
     $getParams['client_secret'] = $this->clientSecret;
     // Request URI pre-processing.
     $uri = "{$this->baseUri}{$resourceName}?" . http_build_query($getParams);
     // Request options pre-processing.
     $options = ['method' => 'GET', 'timeout' => 5, 'postData' => $postData, 'noProxy' => true, 'followRedirects' => false, 'returnInstance' => true, 'internalRequest' => true];
     $options = array_merge($options, $extraRequestOptions);
     /*
      * MediaWiki's MWHttpRequest class heavily relies on Messaging API
      * (wfMessage()) which happens to rely on the value of $wgLang.
      * $wgLang is set after $wgUser. On per-request authentication with
      * an access token we use MWHttpRequest before wgUser is created so
      * we need $wgLang to be present. With GlobalStateWrapper we can set
      * the global variable in the local, function's scope, so it is the
      * same as the already existing $wgContLang.
      */
     global $wgContLang;
     $wrapper = new GlobalStateWrapper(['wgLang' => $wgContLang]);
     // Request execution.
     /** @var \MWHttpRequest $request */
     $request = $wrapper->wrap(function () use($options, $uri) {
         return \Http::request($options['method'], $uri, $options);
     });
     $this->status = $request->status;
     $output = json_decode($request->getContent());
     if (!$output) {
         throw new ClientException('Invalid response.');
     }
     return $output;
 }
Example #2
0
 /**
  * Get connection to flags database
  *
  * Flags database is encoded in utf-8, while in most cases MW communicate with
  * databases using latin1, so sometimes we get strings in wrong encoding.
  * The only way to force utf-8 communication (adding SET NAMES utf8) is setting
  * global variable wgDBmysql5.
  *
  * @see https://github.com/Wikia/app/blob/dev/includes/db/DatabaseMysqlBase.php#L113
  *
  * @param int $dbType master or slave
  * @return \DatabaseBase
  */
 protected function getDatabase($dbType)
 {
     $wrapper = new GlobalStateWrapper(['wgDBmysql5' => true]);
     $db = $wrapper->wrap(function () use($dbType) {
         return wfGetDB($dbType, [], $this->wg->FlagsDB);
     });
     return $db;
 }
 public function getContext(Title $title, $skinName)
 {
     $wrapper = new GlobalStateWrapper(['wgTitle' => $title]);
     $wg = F::app()->wg;
     return $wrapper->wrap(function () use($title, $wg, $skinName) {
         $wikiFactoryHub = WikiFactoryHub::getInstance();
         $hubService = new HubService();
         $adPageTypeService = new AdEngine2PageTypeService();
         $wikiaPageType = new WikiaPageType();
         $sevenOneMediaCombinedUrl = null;
         if (!empty($wg->AdDriverUseSevenOneMedia)) {
             // TODO: implicitly gets the skin from the context!
             $sevenOneMediaCombinedUrl = ResourceLoader::makeCustomURL($wg->Out, ['wikia.ext.adengine.sevenonemedia'], 'scripts');
         }
         $monetizationServiceAds = null;
         if (!empty($wg->AdDriverUseMonetizationService) && !empty($wg->EnableMonetizationModuleExt)) {
             $monetizationServiceAds = F::app()->sendRequest('MonetizationModule', 'index')->getData()['data'];
         }
         $langCode = $title->getPageLanguage()->getCode();
         return ['opts' => $this->filterOutEmptyItems(['adsInContent' => $wg->EnableAdsInContent, 'delayBtf' => $wg->AdDriverDelayBelowTheFold, 'enableAdsInMaps' => $wg->AdDriverEnableAdsInMaps, 'pageType' => $adPageTypeService->getPageType(), 'paidAssetDropConfig' => $wg->PaidAssetDropConfig, 'showAds' => $adPageTypeService->areAdsShowableOnPage(), 'trackSlotState' => $wg->AdDriverTrackState, 'usePostScribe' => $wg->Request->getBool('usepostscribe', false)]), 'targeting' => $this->filterOutEmptyItems(['enablePageCategories' => array_search($langCode, $wg->AdPageLevelCategoryLangs) !== false, 'pageArticleId' => $title->getArticleId(), 'pageIsArticle' => !!$title->getArticleId(), 'pageIsHub' => $wikiaPageType->isWikiaHub(), 'pageName' => $title->getPrefixedDBKey(), 'pageType' => $wikiaPageType->getPageType(), 'sevenOneMediaSub2Site' => $wg->AdDriverSevenOneMediaOverrideSub2Site, 'skin' => $skinName, 'wikiCategory' => $wikiFactoryHub->getCategoryShort($wg->CityId), 'wikiCustomKeyValues' => $wg->DartCustomKeyValues, 'wikiDbName' => $wg->DBname, 'wikiDirectedAtChildren' => $wg->WikiDirectedAtChildrenByFounder || $wg->WikiDirectedAtChildrenByStaff, 'wikiIsCorporate' => $wikiaPageType->isCorporatePage(), 'wikiIsTop1000' => $wg->AdDriverWikiIsTop1000, 'wikiLanguage' => $langCode, 'wikiVertical' => $hubService->getCategoryInfoForCity($wg->CityId)->cat_name]), 'providers' => $this->filterOutEmptyItems(['monetizationService' => $wg->AdDriverUseMonetizationService, 'monetizationServiceAds' => $monetizationServiceAds, 'sevenOneMedia' => $wg->AdDriverUseSevenOneMedia, 'sevenOneMediaCombinedUrl' => $sevenOneMediaCombinedUrl, 'taboola' => $wg->AdDriverUseTaboola]), 'slots' => $this->filterOutEmptyItems(['exitstitial' => $wg->EnableOutboundScreenExt, 'exitstitialRedirectDelay' => $wg->OutboundScreenRedirectDelay, 'invisibleHighImpact' => $wg->AdDriverEnableInvisibleHighImpactSlot]), 'forcedProvider' => $wg->AdDriverForcedProvider];
     });
 }
 /**
  * Get Articles under a category
  *
  * @requestParam string $category [OPTIONAL] The name of a category (e.g. Characters) to use as a filter
  * @requestParam array $namespaces [OPTIONAL] The name of the namespaces (e.g. 0, 14, 5, etc.) to use as a filter, comma separated
  * @requestParam integer $limit [OPTIONAL] The maximum number of results to fetch, defaults to 25
  * @requestParam integer $offset [OPTIONAL] Offset to start fetching data from
  * @requestParam string $expand [OPTIONAL] if set will expand result with getDetails data
  *
  * @responseParam array $items The list of top articles by pageviews matching the optional filtering
  * @responseParam array $basepath domain of a wiki to create a url for an article
  * @responseParam string $offset offset to start next batch of data
  *
  * @example
  * @example &namespaces=14
  * @example &limit=10&namespaces=14
  * @example &limit=10&namespaces=14&offset=R
  * @example &category=Weapons
  * @example &category=Weapons&limit=5
  */
 public function getList()
 {
     wfProfileIn(__METHOD__);
     $category = $this->request->getVal(self::PARAMETER_CATEGORY, null);
     $namespaces = $this->request->getArray(self::PARAMETER_NAMESPACES, null);
     $limit = $this->request->getVal('limit', self::ITEMS_PER_BATCH);
     $offset = $this->request->getVal('offset', '');
     $expand = $this->request->getBool(static::PARAMETER_EXPAND, false);
     if (!empty($category)) {
         $category = self::resolveCategoryName($category);
         if (!is_null($category)) {
             if (!empty($namespaces)) {
                 foreach ($namespaces as &$n) {
                     if (!is_numeric($n)) {
                         throw new InvalidParameterApiException(self::PARAMETER_NAMESPACES);
                     }
                 }
                 $namespaces = implode('|', $namespaces);
             }
             /**
              * Wrapping global wgMiserMode.
              *
              * wgMiserMode = true (default) changes the behavior of categorymembers mediawiki API, causing it to
              * filter by namespace after making database query constrained by $limit and thus resulting
              * in Api returning fewer than $limit results
              *
              * wgMiserMode = false filters on DB level
              */
             $wrapper = new GlobalStateWrapper(['wgMiserMode' => $this->excludeNamespacesFromCategoryMembersDBQuery]);
             $articles = $wrapper->wrap(function () use($category, $limit, $offset, $namespaces) {
                 return self::getCategoryMembers($category->getFullText(), $limit, $offset, $namespaces);
             });
         } else {
             wfProfileOut(__METHOD__);
             throw new InvalidParameterApiException(self::PARAMETER_CATEGORY);
         }
     } else {
         $namespace = $namespaces[0];
         if (!empty($namespace) && !is_numeric($namespace) || $namespace === '' || is_array($namespaces) && count($namespaces) > 1) {
             //throw an error as for now this method accepts only one namespace
             throw new InvalidParameterApiException(self::PARAMETER_NAMESPACES);
         }
         $articles = WikiaDataAccess::cache(self::getCacheKey($offset, self::PAGE_CACHE_ID, [$limit . $namespace]), self::CLIENT_CACHE_VALIDITY, function () use($limit, $offset, $namespace) {
             $params = ['action' => 'query', 'list' => 'allpages', 'aplimit' => $limit, 'apfrom' => $offset];
             //even if this is $namespace empty string allpages fail to fallback to Main namespace
             if (!empty($namespace)) {
                 $params['apnamespace'] = $namespace;
             }
             $pages = ApiService::call($params);
             if (!empty($pages)) {
                 return [$pages['query']['allpages'], !empty($pages['query-continue']) ? $pages['query-continue']['allpages']['apfrom'] : null];
             } else {
                 return null;
             }
         });
     }
     if (is_array($articles) && !empty($articles[0])) {
         $ret = [];
         if ($expand) {
             $articleIds = array_map(function ($item) {
                 if (isset($item['pageid'])) {
                     return $item['pageid'];
                 }
             }, $articles[0]);
             $params = $this->getDetailsParams();
             $ret = $this->getArticlesDetails($articleIds, $params['titleKeys'], $params['width'], $params['height'], $params['length'], true);
         } else {
             foreach ($articles[0] as $article) {
                 $title = Title::newFromText($article['title']);
                 if ($title instanceof Title) {
                     $ret[] = ['id' => $article['pageid'], 'title' => $title->getText(), 'url' => $title->getLocalURL(), 'ns' => $article['ns']];
                 }
             }
         }
         $responseValues = ['items' => $ret, 'basepath' => $this->wg->Server];
         if (!empty($articles[1])) {
             $responseValues['offset'] = $articles[1];
         }
         $this->setResponseData($responseValues, ['imgFields' => 'thumbnail', 'urlFields' => ['thumbnail', 'url']], self::getMetadataCacheTime());
     } else {
         wfProfileOut(__METHOD__);
         throw new NotFoundApiException('No members');
     }
     wfProfileOut(__METHOD__);
 }
 /**
  * move main page to SEO-friendly name
  */
 private function moveMainPage()
 {
     global $wgSitename, $parserMemc, $wgContLanguageCode;
     $source = wfMsgForContent('Mainpage');
     $target = $wgSitename;
     $sourceTitle = \Title::newFromText($source);
     if (!$sourceTitle) {
         $sourceTitle = \Title::newFromText('Main_Page');
         if (!$sourceTitle) {
             $this->error('invalid page title', ['title' => $source]);
             return;
         }
     }
     $mainArticle = new \Article($sourceTitle, 0);
     if ($mainArticle->exists()) {
         /**
          * check target title
          */
         $targetTitle = \Title::newFromText($target);
         if ($targetTitle) {
             $moveContext = ['source' => $sourceTitle->getPrefixedText(), 'target' => $targetTitle->getPrefixedText()];
             if ($sourceTitle->getPrefixedText() !== $targetTitle->getPrefixedText()) {
                 $wikiaUser = \User::newFromName(self::WIKIA_USER);
                 $wrapper = new GlobalStateWrapper(['wgUser' => $wikiaUser]);
                 $err = $wrapper->wrap(function () use($sourceTitle, $targetTitle) {
                     return $sourceTitle->moveTo($targetTitle, false, 'SEO');
                 });
                 if ($err !== true) {
                     $this->error('main page move failed', $moveContext);
                 } else {
                     $this->info('main page moved', $moveContext);
                     /**
                      * fill Mediawiki:Mainpage with new title
                      */
                     $mwMainPageTitle = \Title::newFromText('Mainpage', NS_MEDIAWIKI);
                     $mwMainPageArticle = new \Article($mwMainPageTitle, 0);
                     $mwMainPageArticle->doEdit($targetTitle->getText(), 'SEO', EDIT_SUPPRESS_RC | EDIT_MINOR | EDIT_FORCE_BOT, false, $wikiaUser);
                     $mwMainPageArticle->doPurge();
                     /**
                      * also move associated talk page if it exists
                      */
                     $sourceTalkTitle = $sourceTitle->getTalkPage();
                     $targetTalkTitle = $targetTitle->getTalkPage();
                     if ($sourceTalkTitle instanceof \Title && $sourceTalkTitle->exists() && $targetTalkTitle instanceof \Title) {
                         $moveContext = ['source' => $sourceTalkTitle->getPrefixedText(), 'target' => $targetTalkTitle->getPrefixedText()];
                         $err = $wrapper->wrap(function () use($sourceTalkTitle, $targetTitle) {
                             return $sourceTalkTitle->moveTo($targetTitle->getTalkPage(), false, "SEO");
                         });
                         if ($err === true) {
                             $this->info('talk page moved', $moveContext);
                         } else {
                             $this->warning('talk page move failed', $moveContext);
                         }
                     }
                 }
             } else {
                 $this->info('talk page not moved. source, destination are the same', $moveContext);
             }
         }
     }
     /**
      * clear skin cache for rt#63874
      *
      * @todo establish what $code is exactly in this case
      */
     $parserMemc->delete(wfMemcKey('sidebar', $wgContLanguageCode));
     $parserMemc->delete(wfMemcKey('quartzsidebar'));
     $parserMemc->delete(wfMemcKey('navlinks'));
     $parserMemc->delete(wfMemcKey('MonacoData'));
     $parserMemc->delete(wfMemcKey('MonacoDataOld'));
 }
Example #6
0
 public function postWallMessageToRecipient()
 {
     $defaultWelcomeUser = $this->getDefaultWelcomerUser();
     // some of the lower level methods used in buildNewMessageAndPost do not pass the
     // $user object down the call stack and instead rely on the $wgUser which is
     // not set in a Task environment
     $wrapper = new GlobalStateWrapper(array('wgUser' => $defaultWelcomeUser));
     $this->info("creating a welcome wall message");
     $welcomeMessage = $this->welcomeMessage;
     $recipientName = $this->recipientName;
     $textMessage = $this->getTextVersionOfMessage('welcome-message-log');
     $message = $wrapper->wrap(function () use($defaultWelcomeUser, $welcomeMessage, $recipientName, $textMessage) {
         return $this->executeBuildAndPostWallMessage($defaultWelcomeUser, $welcomeMessage, $recipientName, $textMessage);
     });
     $message = $this->setWallMessagePostedAsBot($message);
     return $message;
 }
 /**
  * @expectedException     InvalidArgumentException
  */
 public function testWrapWithNotCallable()
 {
     $wrapper = new GlobalStateWrapper(array());
     $wrapper->wrap('foo');
 }
 /**
  * @param $content
  * @param bool $useYUI
  * @return string
  * @throws Exception
  */
 public static function minifyJS($content, $useYUI = false)
 {
     global $IP;
     wfProfileIn(__METHOD__);
     $tempInFile = tempnam(sys_get_temp_dir(), 'AMIn');
     file_put_contents($tempInFile, $content);
     $retval = 1;
     if ($useYUI) {
         wfProfileIn(__METHOD__ . '::yui');
         $wrapper = new GlobalStateWrapper(['wgMaxShellMemory' => 0]);
         $out = $wrapper->wrap(function () use($IP, &$retval, $tempInFile) {
             $tempOutFile = tempnam(sys_get_temp_dir(), 'AMOut');
             wfShellExec("nice -n 15 java -jar {$IP}/lib/vendor/yuicompressor-2.4.2.jar --type js -o {$tempOutFile} {$tempInFile}", $retval);
             $out = file_get_contents($tempOutFile);
             unlink($tempOutFile);
             return $out;
         });
         wfProfileOut(__METHOD__ . '::yui');
     } else {
         wfProfileIn(__METHOD__ . '::jsmin');
         $jsmin = "{$IP}/lib/vendor/jsmin";
         $out = wfShellExec("cat {$tempInFile} | {$jsmin}", $retval);
         wfProfileOut(__METHOD__ . '::jsmin');
     }
     unlink($tempInFile);
     if ($retval !== 0) {
         \Wikia\Logger\WikiaLogger::instance()->error('AssetsManagerBaseBuilder::minifyJS failed', ['exception' => new Exception()]);
         throw new Exception('JS minification failed');
     }
     wfProfileOut(__METHOD__);
     return $out;
 }
Example #9
0
 /**
  * Check if the current page should be rendered using Venus
  *
  * @param Title $title
  * @return bool
  */
 public static function showVenusSkin(Title $title)
 {
     global $wgEnableVenusSkin, $wgEnableVenusSpecialSearch, $wgEnableVenusArticle, $wgRequest;
     $wrapper = new GlobalStateWrapper(['wgTitle' => $title]);
     $isSearch = false;
     $isArticlePage = false;
     $wrapper->wrap(function () use(&$isSearch, &$isArticlePage) {
         $isSearch = WikiaPageType::isSearch();
         $isArticlePage = WikiaPageType::isArticlePage();
     });
     $action = $wgRequest->getVal('action');
     $diff = $wgRequest->getVal('diff');
     $isSpecialSearch = $isSearch && $wgEnableVenusSpecialSearch;
     $isSpecialVenusTest = $title->isSpecialPage() && $title->getText() == 'VenusTest';
     $isVenusArticle = $isArticlePage && $wgEnableVenusArticle && (empty($action) || $action == 'view') && empty($diff);
     return $wgEnableVenusSkin && ($isSpecialSearch || $isSpecialVenusTest || $isVenusArticle);
 }