public function execute()
 {
     $params = $this->extractRequestParams();
     $result = $this->getResult();
     if (is_null($params['lang'])) {
         $langCode = false;
     } elseif (!Language::isValidCode($params['lang'])) {
         $this->dieUsage('Invalid language code for parameter lang', 'invalidlang');
     } else {
         $langCode = $params['lang'];
     }
     $pageSet = $this->getPageSet();
     $pageSet->execute();
     $titles = $pageSet->getGoodTitles();
     // page_id => Title object
     if (!count($titles)) {
         $result->addValue(null, 'pages', (object) array());
         return;
     }
     $db = $this->getDB();
     $res = $db->select('page_props', array('pp_page', 'pp_value'), array('pp_page' => array_keys($titles), 'pp_propname' => 'templatedata'), __METHOD__, array('ORDER BY', 'pp_page'));
     $resp = array();
     foreach ($res as $row) {
         $rawData = $row->pp_value;
         $tdb = TemplateDataBlob::newFromDatabase($rawData);
         $status = $tdb->getStatus();
         if (!$status->isOK()) {
             $this->dieUsage('Page #' . intval($row->pp_page) . ' templatedata contains invalid data: ' . $status->getMessage(), 'templatedata-corrupt');
         }
         if ($langCode) {
             $data = $tdb->getDataInLanguage($langCode);
         } else {
             $data = $tdb->getData();
         }
         $resp[$row->pp_page] = array('title' => strval($titles[$row->pp_page])) + (array) $data;
     }
     // Set top level element
     $result->addValue(null, 'pages', (object) $resp);
     $values = $pageSet->getNormalizedTitlesAsResult();
     if ($values) {
         $result->addValue(null, 'normalized', $values);
     }
     $redirects = $pageSet->getRedirectTitlesAsResult();
     if ($redirects) {
         $result->addValue(null, 'redirects', $redirects);
     }
 }
 /**
  * Parser hook for <templatedata>.
  * If there is any JSON provided, render the template documentation on the page.
  *
  * @param string $input: The content of the tag.
  * @param array $args: The attributes of the tag.
  * @param Parser $parser: Parser instance available to render
  *  wikitext into html, or parser methods.
  * @param PPFrame $frame: Can be used to see what template parameters ("{{{1}}}", etc.)
  *  this hook was used with.
  *
  * @return string: HTML to insert in the page.
  */
 public static function render($input, $args, $parser, $frame)
 {
     $ti = TemplateDataBlob::newFromJSON($input);
     $status = $ti->getStatus();
     if (!$status->isOK()) {
         $parser->getOutput()->ext_templatedata_status = $status;
         return '<div class="errorbox">' . $status->getHtml() . '</div>';
     }
     $parser->getOutput()->setProperty('templatedata', $ti->getJSONForDatabase());
     $parser->getOutput()->addModules('ext.templateData');
     return $ti->getHtml($parser->getOptions()->getUserLangObj());
 }
 /**
  * @dataProvider provideGetDataInLanguage
  */
 public function testGetDataInLanguage(array $case)
 {
     // Change content-language to be non-English so we can distinguish between the
     // last 'en' fallback and the content language in our tests
     $this->setMwGlobals(array('wgLanguageCode' => 'nl', 'wgContLang' => Language::factory('nl')));
     if (!isset($case['msg'])) {
         $case['msg'] = is_string($case['status']) ? $case['status'] : 'TemplateData assertion';
     }
     $t = TemplateDataBlob::newFromJSON($case['input']);
     $status = $t->getStatus();
     $this->assertTrue($status->isGood() ?: self::getStatusText($status), 'Status is good: ' . $case['msg']);
     $actual = $t->getDataInLanguage($case['lang']);
     $this->assertJsonStringEqualsJsonString($case['output'], json_encode($actual), $case['msg']);
 }