protected function parseWikitext($title, $newRevId)
 {
     $apiParams = array('action' => 'parse', 'page' => $title->getPrefixedDBkey(), 'oldid' => $newRevId, 'prop' => 'text|revid|categorieshtml|displaytitle|modules|jsconfigvars');
     $api = new ApiMain(new DerivativeRequest($this->getRequest(), $apiParams, false), true);
     $api->execute();
     if (defined('ApiResult::META_CONTENT')) {
         $result = $api->getResult()->getResultData(null, array('BC' => array(), 'Types' => array(), 'Strip' => 'all'));
     } else {
         $result = $api->getResultData();
     }
     $content = isset($result['parse']['text']['*']) ? $result['parse']['text']['*'] : false;
     $categorieshtml = isset($result['parse']['categorieshtml']['*']) ? $result['parse']['categorieshtml']['*'] : false;
     $links = isset($result['parse']['links']) ? $result['parse']['links'] : array();
     $revision = Revision::newFromId($result['parse']['revid']);
     $timestamp = $revision ? $revision->getTimestamp() : wfTimestampNow();
     $displaytitle = isset($result['parse']['displaytitle']) ? $result['parse']['displaytitle'] : false;
     $modules = isset($result['parse']['modules']) ? $result['parse']['modules'] : array();
     $jsconfigvars = isset($result['parse']['jsconfigvars']) ? $result['parse']['jsconfigvars'] : array();
     if ($content === false || strlen($content) && $revision === null) {
         return false;
     }
     if ($displaytitle !== false) {
         // Escape entities as in OutputPage::setPageTitle()
         $displaytitle = Sanitizer::normalizeCharReferences(Sanitizer::removeHTMLtags($displaytitle));
     }
     return array('content' => $content, 'categorieshtml' => $categorieshtml, 'basetimestamp' => $timestamp, 'starttimestamp' => wfTimestampNow(), 'displayTitleHtml' => $displaytitle, 'modules' => $modules, 'jsconfigvars' => $jsconfigvars);
 }
 public function testCrossDomainMangling()
 {
     $config = new HashConfig(array('MangleFlashPolicy' => false));
     $context = new RequestContext();
     $context->setConfig(new MultiConfig(array($config, $context->getConfig())));
     $main = new ApiMain($context);
     $main->getResult()->addValue(null, null, '< Cross-Domain-Policy >');
     if (!function_exists('wfOutputHandler')) {
         function wfOutputHandler($s)
         {
             return $s;
         }
     }
     $printer = $main->createPrinterByName('php');
     ob_start('wfOutputHandler');
     $printer->initPrinter();
     $printer->execute();
     $printer->closePrinter();
     $ret = ob_get_clean();
     $this->assertSame('a:1:{i:0;s:23:"< Cross-Domain-Policy >";}', $ret);
     $config->set('MangleFlashPolicy', true);
     $printer = $main->createPrinterByName('php');
     ob_start('wfOutputHandler');
     try {
         $printer->initPrinter();
         $printer->execute();
         $printer->closePrinter();
         ob_end_clean();
         $this->fail('Expected exception not thrown');
     } catch (UsageException $ex) {
         ob_end_clean();
         $this->assertSame('This response cannot be represented using format=php. See https://phabricator.wikimedia.org/T68776', $ex->getMessage(), 'Expected exception');
     }
 }
Example #3
0
 static function saveCat($filename, $category)
 {
     global $wgContLang, $wgUser;
     $mediaString = strtolower($wgContLang->getNsText(NS_FILE));
     $title = $mediaString . ':' . $filename;
     $text = "\n[[" . $category . "]]";
     $wgEnableWriteAPI = true;
     $params = new FauxRequest(array('action' => 'edit', 'section' => 'new', 'title' => $title, 'text' => $text, 'token' => $wgUser->editToken()), true, $_SESSION);
     $enableWrite = true;
     // This is set to false by default, in the ApiMain constructor
     $api = new ApiMain($params, $enableWrite);
     $api->execute();
     if (defined('ApiResult::META_CONTENT')) {
         $data = $api->getResult()->getResultData();
     } else {
         $data =& $api->getResultData();
     }
     return $mediaString;
     /* This code does the same and is better, but for some reason it doesn't update the categorylinks table
     		global $wgContLang, $wgUser;
     		$title = Title::newFromText( $filename, NS_FILE );
     		$page = new WikiPage( $title );
     		$text = $page->getText();
     		$text .= "\n\n[[" . $category . "]]";
     		$summary = wfMessage( 'msu-comment' );
     		$status = $page->doEditContent( $text, $summary, EDIT_UPDATE, false, $wgUser );
     		$value = $status->value;
     		$revision = $value['revision'];
     		$page->doEditUpdates( $revision, $wgUser );
     		return true;
     */
 }
 /**
  * Get the formatter output for the given input data
  * @param array $params Query parameters
  * @param array $data Data to encode
  * @param string $class Printer class to use instead of the normal one
  * @return string
  * @throws Exception
  */
 protected function encodeData(array $params, array $data, $class = null)
 {
     $context = new RequestContext();
     $context->setRequest(new FauxRequest($params, true));
     $main = new ApiMain($context);
     if ($class !== null) {
         $main->getModuleManager()->addModule($this->printerName, 'format', $class);
     }
     $result = $main->getResult();
     $result->addArrayType(null, 'default');
     foreach ($data as $k => $v) {
         $result->addValue(null, $k, $v);
     }
     $printer = $main->createPrinterByName($this->printerName);
     $printer->initPrinter();
     $printer->execute();
     ob_start();
     try {
         $printer->closePrinter();
         return ob_get_clean();
     } catch (Exception $ex) {
         ob_end_clean();
         throw $ex;
     }
 }
 /** @dataProvider provideTokenClasses */
 public function testTokenRetrieval($id, $class)
 {
     // Make sure we have the right to get the token
     global $wgGroupPermissions;
     $wgGroupPermissions['*'][$class::getRight()] = true;
     RequestContext::getMain()->getUser()->clearInstanceCache();
     // Reread above global
     // We should be getting anonymous user token
     $expected = $class::getToken();
     $this->assertNotSame(false, $expected, 'We did not get a valid token');
     $actionString = TranslateUtils::getTokenAction($id);
     $params = wfCgiToArray($actionString);
     $req = new FauxRequest($params);
     $api = new ApiMain($req);
     $api->execute();
     if (defined('ApiResult::META_CONTENT')) {
         $data = $api->getResult()->getResultData(null, array('Strip' => 'all'));
     } else {
         $data = $api->getResultData();
     }
     if (isset($data['query'])) {
         foreach ($data['query']['pages'] as $page) {
             $this->assertSame($expected, $page[$id . 'token']);
         }
     } else {
         $this->assertArrayHasKey('tokens', $data, 'Result has tokens');
         $this->assertSame($expected, $data['tokens'][$id . 'token']);
     }
 }
Example #6
0
 /**
  * Does the API request and returns the result.
  *
  * The returned value is an array containing
  * - the result data (array)
  * - the request (WebRequest)
  * - the session data of the request (array)
  * - if $appendModule is true, the Api module $module
  *
  * @param array $params
  * @param array|null $session
  * @param bool $appendModule
  * @param User|null $user
  *
  * @return array
  */
 protected function doApiRequest(array $params, array $session = null, $appendModule = false, User $user = null)
 {
     global $wgRequest, $wgUser;
     if (is_null($session)) {
         // re-use existing global session by default
         $session = $wgRequest->getSessionArray();
     }
     // set up global environment
     if ($user) {
         $wgUser = $user;
     }
     $wgRequest = new FauxRequest($params, true, $session);
     RequestContext::getMain()->setRequest($wgRequest);
     RequestContext::getMain()->setUser($wgUser);
     // set up local environment
     $context = $this->apiContext->newTestContext($wgRequest, $wgUser);
     $module = new ApiMain($context, true);
     // run it!
     $module->execute();
     // construct result
     $results = array($module->getResult()->getResultData(null, array('Strip' => 'all')), $context->getRequest(), $context->getRequest()->getSessionArray());
     if ($appendModule) {
         $results[] = $module;
     }
     return $results;
 }
 public function run()
 {
     $scope = RequestContext::importScopedSession($this->params['session']);
     $context = RequestContext::getMain();
     try {
         $user = $context->getUser();
         if (!$user->isLoggedIn()) {
             $this->setLastError("Could not load the author user from session.");
             return false;
         }
         if (count($_SESSION) === 0) {
             // Empty session probably indicates that we didn't associate
             // with the session correctly. Note that being able to load
             // the user does not necessarily mean the session was loaded.
             // Most likely cause by suhosin.session.encrypt = On.
             $this->setLastError("Error associating with user session. " . "Try setting suhosin.session.encrypt = Off");
             return false;
         }
         UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Poll', 'stage' => 'publish', 'status' => Status::newGood()));
         $upload = new UploadFromStash($user);
         // @todo initialize() causes a GET, ideally we could frontload the antivirus
         // checks and anything else to the stash stage (which includes concatenation and
         // the local file is thus already there). That way, instead of GET+PUT, there could
         // just be a COPY operation from the stash to the public zone.
         $upload->initialize($this->params['filekey'], $this->params['filename']);
         // Check if the local file checks out (this is generally a no-op)
         $verification = $upload->verifyUpload();
         if ($verification['status'] !== UploadBase::OK) {
             $status = Status::newFatal('verification-error');
             $status->value = array('verification' => $verification);
             UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'publish', 'status' => $status));
             $this->setLastError("Could not verify upload.");
             return false;
         }
         // Upload the stashed file to a permanent location
         $status = $upload->performUpload($this->params['comment'], $this->params['text'], $this->params['watch'], $user);
         if (!$status->isGood()) {
             UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'publish', 'status' => $status));
             $this->setLastError($status->getWikiText());
             return false;
         }
         // Build the image info array while we have the local reference handy
         $apiMain = new ApiMain();
         // dummy object (XXX)
         $imageInfo = $upload->getImageInfo($apiMain->getResult());
         // Cleanup any temporary local file
         $upload->cleanupTempFile();
         // Cache the info so the user doesn't have to wait forever to get the final info
         UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Success', 'stage' => 'publish', 'filename' => $upload->getLocalFile()->getName(), 'imageinfo' => $imageInfo, 'status' => Status::newGood()));
     } catch (MWException $e) {
         UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'publish', 'status' => Status::newFatal('api-error-publishfailed')));
         $this->setLastError(get_class($e) . ": " . $e->getText());
         // To prevent potential database referential integrity issues.
         // See bug 32551.
         MWExceptionHandler::rollbackMasterChangesAndLog($e);
         return false;
     }
     return true;
 }
Example #8
0
 /**
  * Test that the API will accept a FauxRequest and execute.
  */
 public function testApi()
 {
     $api = new ApiMain(new FauxRequest(array('action' => 'query', 'meta' => 'siteinfo')));
     $api->execute();
     $data = $api->getResult()->getResultData();
     $this->assertInternalType('array', $data);
     $this->assertArrayHasKey('query', $data);
 }
Example #9
0
 protected function doApiRequest(array $params, array $unused = null, $appendModule = false, User $user = null)
 {
     global $wgRequest;
     $req = new FauxRequest($params, true, $wgRequest->getSession());
     $module = new ApiMain($req, true);
     $module->execute();
     return array($module->getResult()->getResultData(null, array('Strip' => 'all')), $req);
 }
 /**
  *
  * @param <type> $params the array of keys and values that would have appeared in the URL if this were a normal request. See API documentation
  * @return <type>
  */
 public function make_fake_request($params)
 {
     $request = new FauxRequest($params, true);
     $api = new ApiMain($request);
     // Process data & use an output buffer to capture the resutls
     $api->execute();
     $result = $api->getResult();
     $data =& $result->getData();
     return $data;
 }
Example #11
0
 protected function doApiRequest(array $params, array $unused = null, $appendModule = false, User $user = null)
 {
     $sessionId = session_id();
     session_write_close();
     $req = new FauxRequest($params, true, $_SESSION);
     $module = new ApiMain($req, true);
     $module->execute();
     wfSetupSession($sessionId);
     return array($module->getResult()->getResultData(null, array('Strip' => 'all')), $req);
 }
 public function run()
 {
     $scope = RequestContext::importScopedSession($this->params['session']);
     $this->addTeardownCallback(function () use(&$scope) {
         ScopedCallback::consume($scope);
         // T126450
     });
     $context = RequestContext::getMain();
     $user = $context->getUser();
     try {
         if (!$user->isLoggedIn()) {
             $this->setLastError("Could not load the author user from session.");
             return false;
         }
         UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Poll', 'stage' => 'publish', 'status' => Status::newGood()]);
         $upload = new UploadFromStash($user);
         // @todo initialize() causes a GET, ideally we could frontload the antivirus
         // checks and anything else to the stash stage (which includes concatenation and
         // the local file is thus already there). That way, instead of GET+PUT, there could
         // just be a COPY operation from the stash to the public zone.
         $upload->initialize($this->params['filekey'], $this->params['filename']);
         // Check if the local file checks out (this is generally a no-op)
         $verification = $upload->verifyUpload();
         if ($verification['status'] !== UploadBase::OK) {
             $status = Status::newFatal('verification-error');
             $status->value = ['verification' => $verification];
             UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Failure', 'stage' => 'publish', 'status' => $status]);
             $this->setLastError("Could not verify upload.");
             return false;
         }
         // Upload the stashed file to a permanent location
         $status = $upload->performUpload($this->params['comment'], $this->params['text'], $this->params['watch'], $user, isset($this->params['tags']) ? $this->params['tags'] : []);
         if (!$status->isGood()) {
             UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Failure', 'stage' => 'publish', 'status' => $status]);
             $this->setLastError($status->getWikiText(false, false, 'en'));
             return false;
         }
         // Build the image info array while we have the local reference handy
         $apiMain = new ApiMain();
         // dummy object (XXX)
         $imageInfo = $upload->getImageInfo($apiMain->getResult());
         // Cleanup any temporary local file
         $upload->cleanupTempFile();
         // Cache the info so the user doesn't have to wait forever to get the final info
         UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Success', 'stage' => 'publish', 'filename' => $upload->getLocalFile()->getName(), 'imageinfo' => $imageInfo, 'status' => Status::newGood()]);
     } catch (Exception $e) {
         UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Failure', 'stage' => 'publish', 'status' => Status::newFatal('api-error-publishfailed')]);
         $this->setLastError(get_class($e) . ": " . $e->getMessage());
         // To prevent potential database referential integrity issues.
         // See bug 32551.
         MWExceptionHandler::rollbackMasterChangesAndLog($e);
         return false;
     }
     return true;
 }
 /**
  * Gets ApiContributionTracking's response in array format, for the given
  * $request params.
  * @global FauxRequest $wgRequest used to shoehorn in our own request vars.
  * @param <type> $request Request vars we are sending to
  * ApiContributionTracking.
  * @return array Values to be returned by ApiContributionTracking
  */
 function getAPIResultData($request)
 {
     global $wgRequest;
     $request['format'] = 'xml';
     $request['action'] = 'contributiontracking';
     $wgRequest = new FauxRequest($request);
     $ctapi = new ApiMain($wgRequest, true);
     $ctapi->execute();
     $api_response = $ctapi->getResult()->getData();
     return $api_response;
 }
 /**
  * Returns an array of languages that the page is available in
  * @return array
  */
 private function getLanguages()
 {
     $api = new ApiMain(new DerivativeRequest($this->getRequest(), array('action' => 'query', 'prop' => 'langlinks', 'llprop' => 'url', 'lllimit' => 'max', 'titles' => $this->title->getPrefixedText())));
     $api->execute();
     if (defined('ApiResult::META_CONTENT')) {
         $data = (array) $api->getResult()->getResultData(array('query', 'pages'), array('Strip' => 'all'));
     } else {
         $data = $api->getResult()->getData();
         // Paranoia
         if (!isset($data['query']['pages'])) {
             return array();
         }
         $data = $data['query']['pages'];
     }
     // Silly strict php
     $pages = array_values($data);
     $page = array_shift($pages);
     if (isset($page['langlinks'])) {
         // Set the name of each lanugage based on the system list of language names
         $languageMap = Language::fetchLanguageNames();
         $languages = $page['langlinks'];
         foreach ($page['langlinks'] as $code => $langObject) {
             if (!isset($languageMap[$langObject['lang']])) {
                 // Bug T93500: DB might still have preantiquated rows with bogus languages
                 unset($languages[$code]);
                 continue;
             }
             $langObject['langname'] = $languageMap[$langObject['lang']];
             $langObject['url'] = MobileContext::singleton()->getMobileUrl($langObject['url']);
             $languages[$code] = $langObject;
         }
         return $languages;
     } else {
         // No langlinks available
         return array();
     }
 }
 public function run()
 {
     $scope = RequestContext::importScopedSession($this->params['session']);
     $context = RequestContext::getMain();
     try {
         $user = $context->getUser();
         if (!$user->isLoggedIn()) {
             $this->setLastError("Could not load the author user from session.");
             return false;
         }
         if (count($_SESSION) === 0) {
             // Empty session probably indicates that we didn't associate
             // with the session correctly. Note that being able to load
             // the user does not necessarily mean the session was loaded.
             // Most likely cause by suhosin.session.encrypt = On.
             $this->setLastError("Error associating with user session. " . "Try setting suhosin.session.encrypt = Off");
             return false;
         }
         UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Poll', 'stage' => 'assembling', 'status' => Status::newGood()));
         $upload = new UploadFromChunks($user);
         $upload->continueChunks($this->params['filename'], $this->params['filekey'], $context->getRequest());
         // Combine all of the chunks into a local file and upload that to a new stash file
         $status = $upload->concatenateChunks();
         if (!$status->isGood()) {
             UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'assembling', 'status' => $status));
             $this->setLastError($status->getWikiText());
             return false;
         }
         // We have a new filekey for the fully concatenated file
         $newFileKey = $upload->getLocalFile()->getFileKey();
         // Remove the old stash file row and first chunk file
         $upload->stash->removeFileNoAuth($this->params['filekey']);
         // Build the image info array while we have the local reference handy
         $apiMain = new ApiMain();
         // dummy object (XXX)
         $imageInfo = $upload->getImageInfo($apiMain->getResult());
         // Cleanup any temporary local file
         $upload->cleanupTempFile();
         // Cache the info so the user doesn't have to wait forever to get the final info
         UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Success', 'stage' => 'assembling', 'filekey' => $newFileKey, 'imageinfo' => $imageInfo, 'status' => Status::newGood()));
     } catch (MWException $e) {
         UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'assembling', 'status' => Status::newFatal('api-error-stashfailed')));
         $this->setLastError(get_class($e) . ": " . $e->getText());
         // To be extra robust.
         MWExceptionHandler::rollbackMasterChangesAndLog($e);
         return false;
     }
     return true;
 }
 /**
  * @param Title $title
  * @param string $submodule
  * @param array $request
  * @param bool $requiredBlock
  * @return array
  * @throws MWException
  */
 public function flowApi(Title $title, $submodule, array $request, $requiredBlock = false)
 {
     $request = new FauxRequest($request + array('action' => 'flow', 'submodule' => $submodule, 'page' => $title->getPrefixedText()));
     $api = new ApiMain($request);
     $api->execute();
     $flowData = $api->getResult()->getResultData(array('flow', $submodule, 'result'));
     if ($flowData === null) {
         throw new MWException("API response has no Flow data");
     }
     $flowData = ApiResult::stripMetadata($flowData);
     if ($requiredBlock !== false && !isset($flowData[$requiredBlock])) {
         throw new MWException("No {$requiredBlock} block in API response");
     }
     return $flowData;
 }
 public function run()
 {
     $scope = RequestContext::importScopedSession($this->params['session']);
     $this->addTeardownCallback(function () use(&$scope) {
         ScopedCallback::consume($scope);
         // T126450
     });
     $context = RequestContext::getMain();
     $user = $context->getUser();
     try {
         if (!$user->isLoggedIn()) {
             $this->setLastError("Could not load the author user from session.");
             return false;
         }
         UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Poll', 'stage' => 'assembling', 'status' => Status::newGood()]);
         $upload = new UploadFromChunks($user);
         $upload->continueChunks($this->params['filename'], $this->params['filekey'], new WebRequestUpload($context->getRequest(), 'null'));
         // Combine all of the chunks into a local file and upload that to a new stash file
         $status = $upload->concatenateChunks();
         if (!$status->isGood()) {
             UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Failure', 'stage' => 'assembling', 'status' => $status]);
             $this->setLastError($status->getWikiText(false, false, 'en'));
             return false;
         }
         // We can only get warnings like 'duplicate' after concatenating the chunks
         $status = Status::newGood();
         $status->value = ['warnings' => $upload->checkWarnings()];
         // We have a new filekey for the fully concatenated file
         $newFileKey = $upload->getStashFile()->getFileKey();
         // Remove the old stash file row and first chunk file
         $upload->stash->removeFileNoAuth($this->params['filekey']);
         // Build the image info array while we have the local reference handy
         $apiMain = new ApiMain();
         // dummy object (XXX)
         $imageInfo = $upload->getImageInfo($apiMain->getResult());
         // Cleanup any temporary local file
         $upload->cleanupTempFile();
         // Cache the info so the user doesn't have to wait forever to get the final info
         UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Success', 'stage' => 'assembling', 'filekey' => $newFileKey, 'imageinfo' => $imageInfo, 'status' => $status]);
     } catch (Exception $e) {
         UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Failure', 'stage' => 'assembling', 'status' => Status::newFatal('api-error-stashfailed')]);
         $this->setLastError(get_class($e) . ": " . $e->getMessage());
         // To be extra robust.
         MWExceptionHandler::rollbackMasterChangesAndLog($e);
         return false;
     }
     return true;
 }
 private function doTest(array $params, $expected)
 {
     $params += array('action' => 'parse');
     $req = new FauxRequest($params);
     $api = new ApiMain($req);
     $api->execute();
     if (defined('ApiResult::META_CONTENT')) {
         $data = $api->getResult()->getResultData(null, array('BC' => array(), 'Types' => array()));
     } else {
         $data = $api->getResultData();
     }
     $this->assertFalse(isset($data['errors']));
     $text = preg_replace("/[\r\n]/", '', trim($data['parse']['text']['*']));
     $expected = preg_replace("/[\r\n]/", '', trim($expected));
     $this->assertEquals($expected, $text);
 }
 public function run()
 {
     $scope = RequestContext::importScopedSession($this->params['session']);
     $context = RequestContext::getMain();
     try {
         $user = $context->getUser();
         if (!$user->isLoggedIn()) {
             $this->setLastError("Could not load the author user from session.");
             return false;
         }
         UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Poll', 'stage' => 'assembling', 'status' => Status::newGood()));
         $upload = new UploadFromChunks($user);
         $upload->continueChunks($this->params['filename'], $this->params['filekey'], $context->getRequest());
         // Combine all of the chunks into a local file and upload that to a new stash file
         $status = $upload->concatenateChunks();
         if (!$status->isGood()) {
             UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'assembling', 'status' => $status));
             $this->setLastError($status->getWikiText());
             return false;
         }
         // We have a new filekey for the fully concatenated file
         $newFileKey = $upload->getLocalFile()->getFileKey();
         // Remove the old stash file row and first chunk file
         $upload->stash->removeFileNoAuth($this->params['filekey']);
         // Build the image info array while we have the local reference handy
         $apiMain = new ApiMain();
         // dummy object (XXX)
         $imageInfo = $upload->getImageInfo($apiMain->getResult());
         // Cleanup any temporary local file
         $upload->cleanupTempFile();
         // Cache the info so the user doesn't have to wait forever to get the final info
         UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Success', 'stage' => 'assembling', 'filekey' => $newFileKey, 'imageinfo' => $imageInfo, 'status' => Status::newGood()));
     } catch (MWException $e) {
         UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'assembling', 'status' => Status::newFatal('api-error-stashfailed')));
         $this->setLastError(get_class($e) . ": " . $e->getText());
         return false;
     }
     return true;
 }
 protected function cacheSourceText($code, $ids)
 {
     $cache = wfGetCache(CACHE_DB);
     $key = wfMemckey(__CLASS__, 'cc', $code);
     $text = $cache->get($key);
     if (!is_string($text)) {
         $snippets = array();
         $ids = explode('|', $ids);
         $len = count($ids);
         if ($len < 1000) {
             $this->output("{$code}: {$len} SKIPPED\n");
             return '';
         } else {
             $this->output("{$code} PROCESSING\n");
         }
         $time = microtime(true);
         foreach ($ids as $id) {
             $params = new FauxRequest(array('pageid' => $id, 'action' => 'parse', 'prop' => 'text', 'disablepp' => 'true'));
             $api = new ApiMain($params);
             $api->execute();
             if (defined('ApiResult::META_CONTENT')) {
                 $result = $api->getResult()->getResultData(null, array('BC' => array()));
             } else {
                 $result = $api->getResultData();
             }
             $text = $result['parse']['text']['*'];
             $text = strip_tags($text);
             $text = str_replace('!!FUZZY!!', '', $text);
             $text = preg_replace('/\\$[0-9]/', '', $text);
             $text = trim($text);
             $snippets[] = $text;
         }
         $text = implode("   ", $snippets);
         $cache->set($key, $text, 3600 * 24);
         $delta = microtime(true) - $time;
         $this->output("{$code} TOOK {$delta}\n");
     } else {
         $this->output("{$code} FROM CACHE\n");
     }
     return $text;
 }
 /**
  * Return page image and extracts
  * @param array $pageIds
  * @return array
  */
 private function getPages($pageIds)
 {
     $result = array();
     $api = new ApiMain(new DerivativeRequest($this->getRequest(), array('action' => 'query', 'list' => 'allpages', 'pageids' => implode('|', $pageIds), 'prop' => 'extracts|pageimages', 'explaintext' => true, 'exsentences' => self::EXTRACT_SENTENCES, 'exlimit' => count($pageIds), 'exintro' => true, 'piprop' => 'name', 'continue' => '')));
     $api->execute();
     $data = $api->getResult()->getResultData(null, array('Strip' => 'all'));
     if (isset($data['query']['pages'])) {
         $result = $data['query']['pages'];
     }
     return $result;
 }
Example #22
0
 /**
  * Makes an internal request to the API to get the needed revision.
  *
  * @since 0.3
  *
  * @param Title $title
  *
  * @return array or false
  */
 protected function getPageRevision(Title $title)
 {
     $revId = PushFunctions::getRevisionToPush($title);
     $requestData = array('action' => 'query', 'format' => 'json', 'prop' => 'revisions', 'rvprop' => 'timestamp|user|comment|content', 'titles' => $title->getFullText(), 'rvstartid' => $revId, 'rvendid' => $revId);
     $api = new ApiMain(new FauxRequest($requestData, true), true);
     $api->execute();
     if (defined('ApiResult::META_CONTENT')) {
         $response = $api->getResult()->getResultData(null, array('BC' => array(), 'Types' => array(), 'Strip' => 'all'));
     } else {
         $response = $api->getResultData();
     }
     $revision = false;
     if ($response !== false && array_key_exists('query', $response) && array_key_exists('pages', $response['query']) && count($response['query']['pages']) > 0) {
         foreach ($response['query']['pages'] as $key => $value) {
             $first = $key;
             break;
         }
         if (array_key_exists('revisions', $response['query']['pages'][$first]) && count($response['query']['pages'][$first]['revisions']) > 0) {
             $revision = $response['query']['pages'][$first]['revisions'][0];
         } else {
             $this->dieUsage(wfMsg('push-special-err-pageget-failed'), 'page-get-failed');
         }
     } else {
         $this->dieUsage(wfMsg('push-special-err-pageget-failed'), 'page-get-failed');
     }
     return $revision;
 }
 /**
  * Gets the edit token and timestamps in some ugly array structure. Needs to
  * be cleaned up.
  * @throws MWException
  * @return \array
  */
 protected function getEditInfo()
 {
     $params = new FauxRequest(array('action' => 'query', 'prop' => 'info|revisions', 'intoken' => 'edit', 'titles' => $this->getTitle(), 'rvprop' => 'timestamp'));
     $api = new ApiMain($params);
     $api->execute();
     if (defined('ApiResult::META_CONTENT')) {
         $data = $api->getResult()->getResultData();
     } else {
         $data = $api->getResultData();
     }
     if (!isset($data['query']['pages'])) {
         throw new MWException('Api query failed');
     }
     $data = $data['query']['pages'];
     if (defined('ApiResult::META_CONTENT')) {
         $data = ApiResult::stripMetadataNonRecursive($data);
     }
     $data = array_shift($data);
     return $data;
 }
 protected function getLangLinks($title)
 {
     $apiParams = array('action' => 'query', 'prop' => 'langlinks', 'lllimit' => 500, 'titles' => $title->getPrefixedDBkey(), 'indexpageids' => 1);
     $api = new ApiMain(new DerivativeRequest($this->getRequest(), $apiParams, false), true);
     $api->execute();
     if (defined('ApiResult::META_CONTENT')) {
         $result = $api->getResult()->getResultData(null, array('BC' => array(), 'Types' => array(), 'Strip' => 'all'));
     } else {
         $result = $api->getResultData();
     }
     if (!isset($result['query']['pages'][$title->getArticleID()]['langlinks'])) {
         return false;
     }
     $langlinks = $result['query']['pages'][$title->getArticleID()]['langlinks'];
     $langnames = Language::fetchLanguageNames();
     foreach ($langlinks as $i => $lang) {
         $langlinks[$i]['langname'] = $langnames[$langlinks[$i]['lang']];
     }
     return $langlinks;
 }
Example #25
0
 /**
  * Returns the names of the images embedded in a set of pages.
  * 
  * @param array $pages
  * 
  * @return array
  */
 protected static function getImagesForPages(array $pages)
 {
     $images = array();
     $requestData = array('action' => 'query', 'format' => 'json', 'prop' => 'images', 'titles' => implode('|', $pages), 'imlimit' => 500);
     $api = new ApiMain(new FauxRequest($requestData, true), true);
     $api->execute();
     if (defined('ApiResult::META_CONTENT')) {
         $response = $api->getResult()->getResultData(null, array('Strip' => 'all'));
     } else {
         $response = $api->getResultData();
     }
     if (is_array($response) && array_key_exists('query', $response) && array_key_exists('pages', $response['query'])) {
         foreach ($response['query']['pages'] as $page) {
             if (array_key_exists('images', $page)) {
                 foreach ($page['images'] as $image) {
                     $title = Title::newFromText($image['title'], NS_FILE);
                     if (!is_null($title) && $title->getNamespace() == NS_FILE && $title->exists()) {
                         $images[] = $image['title'];
                     }
                 }
             }
         }
     }
     return array_unique($images);
 }
Example #26
0
function wfParseText($text, $action = 'parse', $format = 'xml')
{
    # Initialise faux request
    $cliRequest = new FauxRequest(array('action' => &$action, 'text' => &$text, 'format' => &$format));
    # Initialise api and execute
    $processor = new ApiMain($cliRequest);
    $processor->execute();
    # generate result and print the result
    $printer = $processor->createPrinterByName($format);
    $result = $processor->getResult();
    if ($printer->getNeedsRawData()) {
        $result->setRawMode();
    }
    $result->cleanUpUTF8();
    #$printer->profileIn();
    $printer->initPrinter(false);
    $printer->execute();
    $printer->closePrinter();
    #$printer->profileOut();
    return true;
}
 protected function saveWikitext($title, $wikitext, $params)
 {
     global $wgContentTranslationHighMTCategory;
     $categories = array();
     $sourceLink = '[[:' . $params['from'] . ':Special:Redirect/revision/' . $params['sourcerevision'] . '|' . $params['sourcetitle'] . ']]';
     if ($params['categories']) {
         $categories = explode('|', $params['categories']);
     }
     $progress = json_decode($params['progress'], true);
     if ($progress && $wgContentTranslationHighMTCategory && $this->hasHighMT($progress)) {
         $categories[] = $wgContentTranslationHighMTCategory;
     }
     if (count($categories)) {
         $categoryText = "\n[[" . implode("]]\n[[", $categories) . ']]';
         // If publishing to User namespace, wrap categories in <nowiki>
         // to avoid blocks by abuse filter. See T88007.
         if ($title->inNamespace(NS_USER)) {
             $categoryText = "\n<nowiki>{$categoryText}</nowiki>";
         }
         $wikitext .= $categoryText;
     }
     $summary = $this->msg('cx-publish-summary', $sourceLink)->inContentLanguage()->text();
     $apiParams = array('action' => 'edit', 'title' => $title->getPrefixedDBkey(), 'text' => $wikitext, 'summary' => $summary);
     $request = $this->getRequest();
     $api = new ApiMain(new DerivativeRequest($request, $apiParams + $request->getValues(), true), true);
     $api->execute();
     return $api->getResult()->getResultData();
 }
 /**
  * Collects metadata and additional resources for this page
  * @param Title $oTitle
  * @param DOMDocument $oPageDOM
  * @param array $aParams
  * @return array array( 'meta' => ..., 'resources' => ...);
  */
 private static function collectData($oTitle, $oPageDOM, $aParams)
 {
     $aMeta = array();
     $aResources = array('ATTACHMENT' => array(), 'STYLESHEET' => array(), 'IMAGE' => array());
     // TODO RBV (01.02.12 13:51): Handle oldid
     $aCategories = array();
     if ($oTitle->exists()) {
         // TODO RBV (27.06.12 11:47): Throws an exception. Maybe better use try ... catch instead of $oTitle->exists()
         $aAPIParams = new FauxRequest(array('action' => 'parse', 'page' => $oTitle->getPrefixedText(), 'prop' => 'images|categories|links'));
         $oAPI = new ApiMain($aAPIParams);
         $oAPI->execute();
         if (defined('ApiResult::META_CONTENT')) {
             $aResult = $oAPI->getResult()->getResultData(null, array('BC' => array(), 'Types' => array(), 'Strip' => 'all'));
         } else {
             $aResult = $oAPI->getResultData();
         }
         foreach ($aResult['parse']['categories'] as $aCat) {
             $aCategories[] = $aCat['*'];
         }
     }
     /*
     		//For future use...
     		foreach($aResult['parse']['images'] as $sFileName ) {
     			$oImage = RepoGroup::singleton()->getLocalRepo()->newFile( Title::newFromText( $sFileName, NS_FILE ) );
     			if( $oImage->exists() ) {
     				$sAbsoluteFileSystemPath = $oImage->getFullPath();
     			}
     		}
     */
     //Dublin Core:
     $aMeta['DC.title'] = $oTitle->getPrefixedText();
     $aMeta['DC.date'] = wfTimestamp(TS_ISO_8601);
     // TODO RBV (14.12.10 14:01): Check for conformity. Maybe there is a better way to acquire than wfTimestamp()?
     //Custom
     global $wgLang;
     $sCurrentTS = $wgLang->userAdjust(wfTimestampNow());
     $aMeta['title'] = $oTitle->getPrefixedText();
     $aMeta['exportdate'] = $wgLang->sprintfDate('d.m.Y', $sCurrentTS);
     $aMeta['exporttime'] = $wgLang->sprintfDate('H:i', $sCurrentTS);
     $aMeta['exporttimeexact'] = $wgLang->sprintfDate('H:i:s', $sCurrentTS);
     //Custom - Categories->Keywords
     $aMeta['keywords'] = implode(', ', $aCategories);
     $oDOMXPath = new DOMXPath($oPageDOM);
     $oMetadataElements = $oDOMXPath->query("//div[@class='bs-universalexport-meta']");
     foreach ($oMetadataElements as $oMetadataElement) {
         if ($oMetadataElement->hasAttributes()) {
             foreach ($oMetadataElement->attributes as $oAttribute) {
                 if ($oAttribute->name !== 'class') {
                     $aMeta[$oAttribute->name] = $oAttribute->value;
                 }
             }
         }
         $oMetadataElement->parentNode->removeChild($oMetadataElement);
     }
     //If it's a normal article
     if (!in_array($oTitle->getNamespace(), array(NS_SPECIAL, NS_IMAGE, NS_CATEGORY))) {
         $oArticle = new Article($oTitle);
         $aMeta['author'] = $oArticle->getUserText();
         // TODO RBV (14.12.10 12:19): Realname/Username -> DisplayName
         $aMeta['date'] = $wgLang->sprintfDate('d.m.Y', $oArticle->getTouched());
     }
     wfRunHooks('BSUEModulePDFcollectMetaData', array($oTitle, $oPageDOM, &$aParams, $oDOMXPath, &$aMeta));
     $aMetaDataOverrides = json_decode(BsConfig::get('MW::UniversalExport::MetadataOverrides'), true);
     $aMeta = array_merge($aMeta, $aMetaDataOverrides);
     return array('meta' => $aMeta, 'resources' => $aResources);
 }
 /**
  * Make a nested call to the API to request watchlist items in the last $hours.
  * Wrap the result as an RSS/Atom feed.
  */
 public function execute()
 {
     $config = $this->getConfig();
     $feedClasses = $config->get('FeedClasses');
     try {
         $params = $this->extractRequestParams();
         if (!$config->get('Feed')) {
             $this->dieUsage('Syndication feeds are not available', 'feed-unavailable');
         }
         if (!isset($feedClasses[$params['feedformat']])) {
             $this->dieUsage('Invalid subscription feed type', 'feed-invalid');
         }
         // limit to the number of hours going from now back
         $endTime = wfTimestamp(TS_MW, time() - intval($params['hours'] * 60 * 60));
         // Prepare parameters for nested request
         $fauxReqArr = array('action' => 'query', 'meta' => 'siteinfo', 'siprop' => 'general', 'list' => 'watchlist', 'wlprop' => 'title|user|comment|timestamp|ids', 'wldir' => 'older', 'wlend' => $endTime, 'wllimit' => min(50, $this->getConfig()->get('FeedLimit')));
         if ($params['wlowner'] !== null) {
             $fauxReqArr['wlowner'] = $params['wlowner'];
         }
         if ($params['wltoken'] !== null) {
             $fauxReqArr['wltoken'] = $params['wltoken'];
         }
         if ($params['wlexcludeuser'] !== null) {
             $fauxReqArr['wlexcludeuser'] = $params['wlexcludeuser'];
         }
         if ($params['wlshow'] !== null) {
             $fauxReqArr['wlshow'] = $params['wlshow'];
         }
         if ($params['wltype'] !== null) {
             $fauxReqArr['wltype'] = $params['wltype'];
         }
         // Support linking directly to sections when possible
         // (possible only if section name is present in comment)
         if ($params['linktosections']) {
             $this->linkToSections = true;
         }
         // Check for 'allrev' parameter, and if found, show all revisions to each page on wl.
         if ($params['allrev']) {
             $fauxReqArr['wlallrev'] = '';
         }
         // Create the request
         $fauxReq = new FauxRequest($fauxReqArr);
         // Execute
         $module = new ApiMain($fauxReq);
         $module->execute();
         $data = $module->getResult()->getResultData(array('query', 'watchlist'));
         $feedItems = array();
         foreach ((array) $data as $key => $info) {
             if (ApiResult::isMetadataKey($key)) {
                 continue;
             }
             $feedItem = $this->createFeedItem($info);
             if ($feedItem) {
                 $feedItems[] = $feedItem;
             }
         }
         $msg = wfMessage('watchlist')->inContentLanguage()->text();
         $feedTitle = $this->getConfig()->get('Sitename') . ' - ' . $msg . ' [' . $this->getConfig()->get('LanguageCode') . ']';
         $feedUrl = SpecialPage::getTitleFor('Watchlist')->getFullURL();
         $feed = new $feedClasses[$params['feedformat']]($feedTitle, htmlspecialchars($msg), $feedUrl);
         ApiFormatFeedWrapper::setResult($this->getResult(), $feed, $feedItems);
     } catch (Exception $e) {
         // Error results should not be cached
         $this->getMain()->setCacheMaxAge(0);
         // @todo FIXME: Localise  brackets
         $feedTitle = $this->getConfig()->get('Sitename') . ' - Error - ' . wfMessage('watchlist')->inContentLanguage()->text() . ' [' . $this->getConfig()->get('LanguageCode') . ']';
         $feedUrl = SpecialPage::getTitleFor('Watchlist')->getFullURL();
         $feedFormat = isset($params['feedformat']) ? $params['feedformat'] : 'rss';
         $msg = wfMessage('watchlist')->inContentLanguage()->escaped();
         $feed = new $feedClasses[$feedFormat]($feedTitle, $msg, $feedUrl);
         if ($e instanceof UsageException) {
             $errorCode = $e->getCodeString();
         } else {
             // Something is seriously wrong
             $errorCode = 'internal_api_error';
         }
         $errorText = $e->getMessage();
         $feedItems[] = new FeedItem("Error ({$errorCode})", $errorText, '', '', '');
         ApiFormatFeedWrapper::setResult($this->getResult(), $feed, $feedItems);
     }
 }
Example #30
0
 public function actionReply($threads, $params)
 {
     // Validate thread parameter
     if (count($threads) > 1) {
         $this->dieUsage('You may only reply to one thread at a time', 'too-many-threads');
     } elseif (count($threads) < 1) {
         $this->dieUsage('You must specify a thread to reply to', 'no-specified-threads');
     }
     $replyTo = array_pop($threads);
     // Check if we can reply to that thread.
     $user = $this->getUser();
     $perm_result = $replyTo->canUserReply($user);
     if ($perm_result !== true) {
         $this->dieUsage("You cannot reply to this thread, because the " . $perm_result . " is protected from replies.", $perm_result . '-protected');
     }
     // Validate text parameter
     if (empty($params['text'])) {
         $this->dieUsage('You must include text in your post', 'no-text');
     }
     $text = $params['text'];
     $bump = isset($params['bump']) ? $params['bump'] : null;
     // Generate/pull summary
     $summary = wfMessage('lqt-reply-summary', $replyTo->subject(), $replyTo->title()->getPrefixedText())->inContentLanguage()->text();
     if (!empty($params['reason'])) {
         $summary = $params['reason'];
     }
     $signature = null;
     if (isset($params['signature'])) {
         $signature = $params['signature'];
     }
     // Grab data from parent
     $talkpage = $replyTo->article();
     // Generate a reply title.
     $title = Threads::newReplyTitle($replyTo, $user);
     $article = new Article($title, 0);
     // Inform hooks what we're doing
     LqtHooks::$editTalkpage = $talkpage;
     LqtHooks::$editArticle = $article;
     LqtHooks::$editThread = null;
     LqtHooks::$editType = 'reply';
     LqtHooks::$editAppliesTo = $replyTo;
     // Pull token in
     $token = $params['token'];
     // All seems in order. Construct an API edit request
     $requestData = array('action' => 'edit', 'title' => $title->getPrefixedText(), 'text' => $text, 'summary' => $summary, 'token' => $token, 'basetimestamp' => wfTimestampNow(), 'minor' => 0, 'format' => 'json');
     if ($user->isAllowed('bot')) {
         $requestData['bot'] = true;
     }
     $editReq = new DerivativeRequest($this->getRequest(), $requestData, true);
     $internalApi = new ApiMain($editReq, true);
     $internalApi->execute();
     if (defined('ApiResult::META_CONTENT')) {
         $editResult = $internalApi->getResult()->getResultData();
     } else {
         $editResult = $internalApi->getResultData();
     }
     if ($editResult['edit']['result'] != 'Success') {
         $result = array('result' => 'EditFailure', 'details' => $editResult);
         $this->getResult()->addValue(null, $this->getModuleName(), $result);
         return;
     }
     $articleId = $editResult['edit']['pageid'];
     $article->getTitle()->resetArticleID($articleId);
     $title->resetArticleID($articleId);
     $thread = LqtView::replyMetadataUpdates(array('root' => $article, 'replyTo' => $replyTo, 'signature' => $signature, 'summary' => $summary, 'text' => $text, 'bump' => $bump));
     $result = array('action' => 'reply', 'result' => 'Success', 'thread-id' => $thread->id(), 'thread-title' => $title->getPrefixedText(), 'parent-id' => $replyTo->id(), 'parent-title' => $replyTo->title()->getPrefixedText(), 'ancestor-id' => $replyTo->topmostThread()->id(), 'ancestor-title' => $replyTo->topmostThread()->title()->getPrefixedText(), 'modified' => $thread->modified());
     if (!empty($params['render'])) {
         $result['html'] = $this->renderThreadPostAction($thread);
     }
     $result = array('thread' => $result);
     $this->getResult()->addValue(null, $this->getModuleName(), $result);
 }