public function testParsing()
 {
     $title = Title::newFromText('MediaWiki:Ugakey/nl');
     $page = WikiPage::factory($title);
     $content = ContentHandler::makeContent('$1 van $2', $title);
     $status = $page->doEditContent($content, __METHOD__);
     $value = $status->getValue();
     /**
      * @var Revision $rev
      */
     $rev = $value['revision'];
     $revision = $rev->getId();
     $dbw = wfGetDB(DB_MASTER);
     $conds = array('rt_page' => $title->getArticleID(), 'rt_type' => RevTag::getType('fuzzy'), 'rt_revision' => $revision);
     $index = array_keys($conds);
     $dbw->replace('revtag', array($index), $conds, __METHOD__);
     $handle = new MessageHandle($title);
     $this->assertTrue($handle->isValid(), 'Message is known');
     $this->assertTrue($handle->isFuzzy(), 'Message is fuzzy after database fuzzying');
     // Update the translation without the fuzzy string
     $content = ContentHandler::makeContent('$1 van $2', $title);
     $page->doEditContent($content, __METHOD__);
     $this->assertFalse($handle->isFuzzy(), 'Message is unfuzzy after edit');
     $content = ContentHandler::makeContent('!!FUZZY!!$1 van $2', $title);
     $page->doEditContent($content, __METHOD__);
     $this->assertTrue($handle->isFuzzy(), 'Message is fuzzy after manual fuzzying');
     // Update the translation without the fuzzy string
     $content = ContentHandler::makeContent('$1 van $2', $title);
     $page->doEditContent($content, __METHOD__);
     $this->assertFalse($handle->isFuzzy(), 'Message is unfuzzy after edit');
 }
	public function execute() {
		global $wgUser;
		if ( !$wgUser->isallowed( self::$right ) ) {
			$this->dieUsage( 'Permission denied', 'permissiondenied' );
		}

		$params = $this->extractRequestParams();

		$revision = Revision::newFromId( $params['revision'] );
		if ( !$revision ) {
			$this->dieUsage( 'Invalid revision', 'invalidrevision' );
		}

		$title = $revision->getTitle();
		$handle = new MessageHandle( $title );
		if ( !$handle->isValid() ) {
			$this->dieUsage( 'Unknown message', 'unknownmessage' );
		}

		if ( $handle->isFuzzy() ) {
			$this->dieUsage( 'Cannot review fuzzy translations', 'fuzzymessage' );
		}

		if ( $revision->getUser() == $wgUser->getId() ) {
			$this->dieUsage( 'Cannot review own translations', 'owntranslation' );
		}

		$dbw = wfGetDB( DB_MASTER );
		$table = 'translate_reviews';
		$row = array(
			'trr_user' => $wgUser->getId(),
			'trr_page' => $revision->getPage(),
			'trr_revision' => $revision->getId(),
		);
		$options = array( 'IGNORE' );
		$res = $dbw->insert( $table, $row, __METHOD__, $options );
		if ( !$dbw->affectedRows() ) {
			$this->setWarning( 'Already marked as reviewed by you' );
		} else {
			$logger = new LogPage( 'translationreview' );
			$params = array( $revision->getId() );
			$logger->addEntry( 'message', $title, null, $params, $wgUser );
		}

		$output = array( 'review' => array(
			'title' => $title->getPrefixedText(),
			'pageid' => $revision->getPage(),
			'revision' => $revision->getId()
		) );

		$this->getResult()->addValue( null, $this->getModuleName(), $output );
	}
 public function execute()
 {
     $params = $this->extractRequestParams();
     $title = Title::newFromText($params['title']);
     if (!$title) {
         $this->dieUsage('Invalid title');
     }
     $handle = new MessageHandle($title);
     if (!$handle->isValid()) {
         $this->dieUsage('Title does not correspond to a translatable message');
     }
     $base = Title::makeTitle($title->getNamespace(), $handle->getKey());
     $namespace = $base->getNamespace();
     $message = $base->getDBKey();
     $dbr = wfGetDB(DB_SLAVE);
     $res = $dbr->select('page', array('page_namespace', 'page_title'), array('page_namespace' => $namespace, 'page_title ' . $dbr->buildLike("{$message}/", $dbr->anyString())), __METHOD__, array('ORDER BY' => 'page_title', 'USE INDEX' => 'name_title'));
     $titles = array();
     foreach ($res as $row) {
         $titles[] = $row->page_title;
     }
     $pageInfo = TranslateUtils::getContents($titles, $namespace);
     $result = $this->getResult();
     $pages = array();
     $count = 0;
     foreach ($pageInfo as $key => $info) {
         if (++$count <= $params['offset']) {
             continue;
         }
         $tTitle = Title::makeTitle($namespace, $key);
         $tHandle = new MessageHandle($tTitle);
         $data = array('title' => $tTitle->getPrefixedText(), 'language' => $tHandle->getCode(), 'lasttranslator' => $info[1]);
         $fuzzy = MessageHandle::hasFuzzyString($info[0]) || $tHandle->isFuzzy();
         if ($fuzzy) {
             $data['fuzzy'] = 'fuzzy';
         }
         $translation = str_replace(TRANSLATE_FUZZY, '', $info[0]);
         $result->setContent($data, $translation);
         $fit = $result->addValue(array('query', $this->getModuleName()), null, $data);
         if (!$fit) {
             $this->setContinueEnumParameter('offset', $count);
             break;
         }
     }
     $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'message');
 }
 public function execute()
 {
     $params = $this->extractRequestParams();
     $title = Title::newFromText($params['title']);
     if (!$title) {
         $this->dieUsage('Invalid title', 'invalidtitle');
     }
     $handle = new MessageHandle($title);
     if (!$handle->isValid()) {
         $this->dieUsage('Title does not correspond to a translatable message', 'nomessagefortitle');
     }
     $namespace = $title->getNamespace();
     $pageInfo = self::getTranslations($handle);
     $result = $this->getResult();
     $count = 0;
     foreach ($pageInfo as $key => $info) {
         if (++$count <= $params['offset']) {
             continue;
         }
         $tTitle = Title::makeTitle($namespace, $key);
         $tHandle = new MessageHandle($tTitle);
         $data = array('title' => $tTitle->getPrefixedText(), 'language' => $tHandle->getCode(), 'lasttranslator' => $info[1]);
         $fuzzy = MessageHandle::hasFuzzyString($info[0]) || $tHandle->isFuzzy();
         if ($fuzzy) {
             $data['fuzzy'] = 'fuzzy';
         }
         $translation = str_replace(TRANSLATE_FUZZY, '', $info[0]);
         if (defined('ApiResult::META_CONTENT')) {
             ApiResult::setContentValue($data, 'translation', $translation);
         } else {
             ApiResult::setContent($data, $translation);
         }
         $fit = $result->addValue(array('query', $this->getModuleName()), null, $data);
         if (!$fit) {
             $this->setContinueEnumParameter('offset', $count);
             break;
         }
     }
     if (defined('ApiResult::META_CONTENT')) {
         $result->addIndexedTagName(array('query', $this->getModuleName()), 'message');
     } else {
         $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'message');
     }
 }
 /**
  * Get the translations in all languages. Cached for performance.
  * Fuzzy translation are not included.
  *
  * @return array Language code => Translation
  */
 public function getTranslations()
 {
     static $cache = array();
     $key = $this->handle->getTitle()->getPrefixedText();
     if (array_key_exists($key, $cache)) {
         return $cache[$key];
     }
     $data = ApiQueryMessageTranslations::getTranslations($this->handle);
     $namespace = $this->handle->getTitle()->getNamespace();
     $cache[$key] = array();
     foreach ($data as $page => $info) {
         $tTitle = Title::makeTitle($namespace, $page);
         $tHandle = new MessageHandle($tTitle);
         $fuzzy = MessageHandle::hasFuzzyString($info[0]) || $tHandle->isFuzzy();
         if ($fuzzy) {
             continue;
         }
         $code = $tHandle->getCode();
         $cache[$key][$code] = $info[0];
     }
     return $cache[$key];
 }
 /**
  * @param MessageGroup $group
  * @param string $code
  * @param string $type
  * @param array $params
  * @param int $limit
  * @return string HTML
  */
 protected function formatChange(MessageGroup $group, $code, $type, $params, &$limit)
 {
     $key = $params['key'];
     $title = Title::makeTitleSafe($group->getNamespace(), "{$key}/{$code}");
     $id = self::changeId($group->getId(), $code, $type, $key);
     if ($title && $title->exists() && $type === 'addition') {
         // The message has for some reason dropped out from cache
         // or perhaps it is being reused. In any case treat it
         // as a change for display, so the admin can see if
         // action is needed and let the message be processed.
         // Otherwise it will end up in the postponed category
         // forever and will prevent rebuilding the cache, which
         // leads to many other annoying problems.
         $type = 'change';
     } elseif ($title && !$title->exists() && ($type === 'deletion' || $type === 'change')) {
         return '';
     }
     $text = '';
     if ($type === 'deletion') {
         $wiki = ContentHandler::getContentText(Revision::newFromTitle($title)->getContent());
         $oldContent = ContentHandler::makeContent($wiki, $title);
         $newContent = ContentHandler::makeContent('', $title);
         $this->diff->setContent($oldContent, $newContent);
         $text = $this->diff->getDiff(Linker::link($title), '');
     } elseif ($type === 'addition') {
         $oldContent = ContentHandler::makeContent('', $title);
         $newContent = ContentHandler::makeContent($params['content'], $title);
         $this->diff->setContent($oldContent, $newContent);
         $text = $this->diff->getDiff('', Linker::link($title));
     } elseif ($type === 'change') {
         $wiki = ContentHandler::getContentText(Revision::newFromTitle($title)->getContent());
         $handle = new MessageHandle($title);
         if ($handle->isFuzzy()) {
             $wiki = '!!FUZZY!!' . str_replace(TRANSLATE_FUZZY, '', $wiki);
         }
         $label = $this->msg('translate-manage-action-ignore')->text();
         $actions = Xml::checkLabel($label, "i/{$id}", "i/{$id}");
         $limit--;
         if ($group->getSourceLanguage() === $code) {
             $label = $this->msg('translate-manage-action-fuzzy')->text();
             $actions .= ' ' . Xml::checkLabel($label, "f/{$id}", "f/{$id}", true);
             $limit--;
         }
         $oldContent = ContentHandler::makeContent($wiki, $title);
         $newContent = ContentHandler::makeContent($params['content'], $title);
         $this->diff->setContent($oldContent, $newContent);
         $text .= $this->diff->getDiff(Linker::link($title), $actions);
     }
     $hidden = Html::hidden($id, 1);
     $limit--;
     $text .= $hidden;
     $classes = "mw-translate-smg-change smg-change-{$type}";
     if ($limit < 0) {
         // Don't add if one of the fields might get dropped of at submission
         return '';
     }
     return Html::rawElement('div', array('class' => $classes), $text);
 }
	/**
	 * Check if a title is marked as fuzzy.
	 * @param $title Title
	 * @return \bool If title is marked fuzzy.
	 */
	public static function isFuzzy( Title $title ) {
		# wfDeprecated( __METHOD__, '1.19' );
		$handle = new MessageHandle( $title );
		return $handle->isFuzzy();
	}
 /**
  * Builds a table with all translations of $title.
  *
  * @param Title $title (default: null)
  */
 function showTranslations(Title $title)
 {
     $handle = new MessageHandle($title);
     $namespace = $title->getNamespace();
     $message = $handle->getKey();
     if (!$handle->isValid()) {
         $this->getOutput()->addWikiMsg('translate-translations-no-message', $title->getPrefixedText());
         return;
     }
     $dbr = wfGetDB(DB_SLAVE);
     $res = $dbr->select('page', array('page_namespace', 'page_title'), array('page_namespace' => $namespace, 'page_title ' . $dbr->buildLike("{$message}/", $dbr->anyString())), __METHOD__, array('ORDER BY' => 'page_title', 'USE INDEX' => 'name_title'));
     if (!$res->numRows()) {
         $this->getOutput()->addWikiMsg('translate-translations-no-message', $title->getPrefixedText());
         return;
     } else {
         $this->getOutput()->addWikiMsg('translate-translations-count', $this->getLanguage()->formatNum($res->numRows()));
     }
     // Normal output.
     $titles = array();
     foreach ($res as $s) {
         $titles[] = $s->page_title;
     }
     $pageInfo = TranslateUtils::getContents($titles, $namespace);
     $tableheader = Xml::openElement('table', array('class' => 'mw-sp-translate-table sortable'));
     $tableheader .= Xml::openElement('tr');
     $tableheader .= Xml::element('th', null, $this->msg('allmessagesname')->text());
     $tableheader .= Xml::element('th', null, $this->msg('allmessagescurrent')->text());
     $tableheader .= Xml::closeElement('tr');
     // Adapted version of TranslateUtils:makeListing() by Nikerabbit.
     $out = $tableheader;
     $canTranslate = $this->getUser()->isAllowed('translate');
     $ajaxPageList = array();
     $historyText = "&#160;<sup>" . $this->msg('translate-translations-history-short')->escaped() . "</sup>&#160;";
     $separator = $this->msg('word-separator')->plain();
     foreach ($res as $s) {
         $key = $s->page_title;
         $tTitle = Title::makeTitle($s->page_namespace, $key);
         $ajaxPageList[] = $tTitle->getPrefixedDBkey();
         $tHandle = new MessageHandle($tTitle);
         $code = $tHandle->getCode();
         $text = TranslateUtils::getLanguageName($code, $this->getLanguage()->getCode());
         $text .= $separator;
         $text .= $this->msg('parentheses')->params($code)->plain();
         $text = htmlspecialchars($text);
         if ($canTranslate) {
             $tools['edit'] = TranslationHelpers::ajaxEditLink($tTitle, $text);
         } else {
             $tools['edit'] = Linker::link($tTitle, $text);
         }
         $tools['history'] = Linker::link($tTitle, $historyText, array('action', 'title' => $this->msg('history-title', $tTitle->getPrefixedDBkey())->text()), array('action' => 'history'));
         if (MessageHandle::hasFuzzyString($pageInfo[$key][0]) || $tHandle->isFuzzy()) {
             $class = 'orig';
         } else {
             $class = 'def';
         }
         $leftColumn = $tools['history'] . $tools['edit'];
         $out .= Xml::tags('tr', array('class' => $class), Xml::tags('td', null, $leftColumn) . Xml::tags('td', array('lang' => $code, 'dir' => Language::factory($code)->getDir()), TranslateUtils::convertWhiteSpaceToHTML($pageInfo[$key][0])));
     }
     $out .= Xml::closeElement('table');
     $this->getOutput()->addHTML($out);
     $vars = array('trlKeys' => $ajaxPageList);
     $this->getOutput()->addScript(Skin::makeVariablesScript($vars));
 }
 /**
  * Validates review action by checking permissions and other things.
  * @param User $user
  * @param Revision $revision
  * @return string Error key or empty string if review is allowed.
  * @since 2012-09-24
  */
 public static function getReviewBlockers(User $user, Revision $revision)
 {
     if (!$user->isAllowed(self::$right)) {
         return 'permissiondenied';
     }
     if ($user->isBlocked()) {
         return 'blocked';
     }
     $title = $revision->getTitle();
     $handle = new MessageHandle($title);
     if (!$handle->isValid()) {
         return 'unknownmessage';
     }
     if ($revision->getUser() == $user->getId()) {
         return 'owntranslation';
     }
     if ($handle->isFuzzy()) {
         return 'fuzzymessage';
     }
     return '';
 }