function run()
 {
     // Initialization
     $title = $this->title;
     list(, $code) = TranslateUtils::figureMessage($title->getPrefixedText());
     // Return the actual translation page...
     $page = TranslatablePage::isTranslationPage($title);
     if (!$page) {
         var_dump($this->params);
         var_dump($title);
         throw new MWException("Oops, this should not happen!");
     }
     $group = $page->getMessageGroup();
     $collection = $group->initCollection($code);
     $text = $page->getParse()->getTranslationPageText($collection);
     // Other stuff
     $user = $this->getUser();
     $summary = $this->getSummary();
     $flags = $this->getFlags();
     $page = WikiPage::factory($title);
     // @todo FuzzyBot hack
     PageTranslationHooks::$allowTargetEdit = true;
     $content = ContentHandler::makeContent($text, $page->getTitle());
     $page->doEditContent($content, $summary, $flags, false, $user);
     PageTranslationHooks::$allowTargetEdit = false;
     return true;
 }
 /**
  * @dataProvider provideTestFiles
  */
 public function testParsing($file)
 {
     $filename = basename($file);
     list($pagename, ) = explode('.', $filename, 2);
     $title = Title::newFromText($pagename);
     $translatablePage = TranslatablePage::newFromText($title, file_get_contents($file));
     $pattern = $file;
     if ($filename === 'FailNotAtomic.ptfile') {
         $this->markTestSkipped('Extended validation not yet implemented');
     }
     $failureExpected = strpos($pagename, 'Fail') === 0;
     if ($failureExpected) {
         $this->setExpectedException('TPException');
     }
     $parse = $translatablePage->getParse();
     $this->assertInstanceOf('TPParse', $parse);
     if (file_exists("{$pattern}.ptsource")) {
         $source = $parse->getSourcePageText();
         $this->assertEquals($source, file_get_contents("{$pattern}.ptsource"));
     }
     if (file_exists("{$pattern}.pttarget")) {
         $target = $parse->getTranslationPageText(MessageCollection::newEmpty('foo'));
         $this->assertEquals($target, file_get_contents("{$pattern}.pttarget"));
     }
     // Custom tests written in php
     if (file_exists("{$pattern}.pttest")) {
         require "{$pattern}.pttest";
     }
 }
 public function testGetTranslationPageText()
 {
     $title = Title::newFromText(__CLASS__);
     $page = TranslatablePage::newFromText($title, '<translate>Hello <tvar|abc>peter!</></translate>');
     $prefix = $title->getPrefixedDBKey() . '/';
     $parse = $page->getParse();
     $collection = array();
     $expected = 'Hello peter!';
     $actual = $parse->getTranslationPageText($collection);
     $this->assertEquals($expected, $actual, 'Variable declarations are substituted when no translation');
     foreach ($parse->sections as $section) {
         $key = $prefix . $section->id;
         $message = new FatMessage($key, $section->getText());
         $message->setTranslation($section->getText());
         $collection[$key] = $message;
     }
     $actual = $parse->getTranslationPageText($collection);
     $this->assertEquals($expected, $actual, 'Variable declarations are substituted in source language');
     foreach ($parse->sections as $section) {
         $key = $prefix . $section->id;
         $message = new FatMessage($key, $section->getText());
         $message->setTranslation($section->getTextForTrans());
         $collection[$key] = $message;
     }
     $actual = $parse->getTranslationPageText($collection);
     $this->assertEquals($expected, $actual, 'Variable declarations are substituted in translation');
 }
	/**
	 * Returns only translation subpages.
	 * @return Array of titles.
	 */
	protected function getTranslationPages() {
		if ( $this->singleLanguage() ) {
			return array( $this->title );
		}

		if ( !isset( $this->translationPages ) ) {
			$this->translationPages = $this->page->getTranslationPages();
		}
		return $this->translationPages;
	}
Пример #5
0
	function run() {
		global $wgUser;

		// Initialization
		$title = $this->title;
		// Other stuff
		$user    = $this->getUser();
		$summary = $this->getSummary();
		$base    = $this->getBase();

		PageTranslationHooks::$allowTargetEdit = true;
		$oldUser = $wgUser;
		$wgUser = $user;

		$error = '';
		$article = new Article( $title, 0 );
		$ok = $article->doDeleteArticle( $summary, false, 0, true, $error );
		if ( !$ok ) {
			$logger = new LogPage( 'pagetranslation' );
			$params = array(
				'user' => $this->getPerformer(),
				'target' => $base,
				'error' => base64_encode( serialize( $ok ) ), // This is getting ridiculous
			);
			$doer = User::newFromName( $this->getPerformer() );
			$msg = $this->getFull() ? 'deletefnok' : 'deletelnok';
			$logger->addEntry( $msg, $title, null, array( serialize( $params ) ), $doer );
		}

		PageTranslationHooks::$allowTargetEdit = false;

		$cache = wfGetCache( CACHE_DB );
		$pages = (array) $cache->get( wfMemcKey( 'pt-base', $base ) );
		$lastitem = array_pop( $pages );
		if ( $title->getPrefixedText() === $lastitem ) {
			$cache->delete( wfMemcKey( 'pt-base', $base ) );
			$logger = new LogPage( 'pagetranslation' );
			$params = array( 'user' => $this->getPerformer() );
			$doer = User::newFromName( $this->getPerformer() );
			$msg = $this->getFull() ? 'deletefok' : 'deletelok';
			$logger->addEntry( $msg, Title::newFromText( $base ), null, array( serialize( $params ) ), $doer );

			$tpage = TranslatablePage::newFromTitle( $title );
			$tpage->getTranslationPercentages( true );
			foreach ( $tpage->getTranslationPages() as $page ) {
				$page->invalidateCache();
			}
			$title->invalidateCache();
		}

		$wgUser = $oldUser;

		return true;
	}
	public function execute() {
		$dir = dirname( __FILE__ );
		$testDirectory = "$dir/../tests/pagetranslation";
		$testFiles = glob( "$testDirectory/*.ptfile" );

		foreach ( $testFiles as $file ) {
			$filename = basename( $file );
			list( $pagename, ) = explode( '.', $filename, 2 );
			$title = Title::newFromText( $pagename );
			$translatablePage = TranslatablePage::newFromText( $title, file_get_contents( $file ) );

			$pattern = realpath( "$testDirectory" ) . "/$pagename";

			$failureExpected = strpos( $pagename, 'Fail' ) === 0;

			try {
				$parse = $translatablePage->getParse();
				if ( $failureExpected ) {
					$target = $parse->getTranslationPageText( MessageCollection::newEmpty( "foo" ) );
					$this->output( "Testfile $filename should have failed... see $pattern.pttarget.fail\n" );
					file_put_contents( "$pattern.pttarget.fail", $target );
				}
			} catch ( TPException $e ) {
				if ( !$failureExpected ) {
					$this->output( "Testfile $filename failed to parse... see $pattern.ptfile.fail\n" );
					file_put_contents( "$pattern.ptfile.fail", $e->getMessage() );
				}
				continue;
			}

			if ( file_exists( "$pattern.ptsource" ) ) {
				$source = $parse->getSourcePageText();
				if ( $source !== file_get_contents( "$pattern.ptsource" ) ) {
					$this->output( "Testfile $filename failed with source page output... writing $pattern.ptsource.fail\n" );
					file_put_contents( "$pattern.ptsource.fail", $source );
				}
			}

			if ( file_exists( "$pattern.pttarget" ) ) {
				$target = $parse->getTranslationPageText( MessageCollection::newEmpty( "foo" ) );
				if ( $target !== file_get_contents( "$pattern.pttarget" ) ) {
					$this->output( "Testfile $filename failed with target page output... writing $pattern.pttarget.fail\n" );
					file_put_contents( "$pattern.pttarget.fail", $target );
				}
			}

			// Custom tests written in php
			if ( file_exists( "$pattern.pttest" ) ) {
				require( "$pattern.pttest" );
			}
		}
	}
 public function execute()
 {
     $groups = MessageGroups::singleton()->getGroups();
     /** @var MessageGroup $group */
     foreach ($groups as $group) {
         if (!$group instanceof WikiPageMessageGroup) {
             continue;
         }
         // Get all translation subpages and refresh each one of them
         $page = TranslatablePage::newFromTitle($group->getTitle());
         $translationPages = $page->getTranslationPages();
         foreach ($translationPages as $subpage) {
             $job = TranslateRenderJob::newJob($subpage);
             $job->run();
         }
     }
 }
 function run()
 {
     // Initialization
     $title = $this->title;
     // Other stuff
     $user = $this->getUser();
     $summary = $this->getSummary();
     $base = $this->getBase();
     $doer = User::newFromName($this->getPerformer());
     PageTranslationHooks::$allowTargetEdit = true;
     $error = '';
     $wikipage = new WikiPage($title);
     $ok = $wikipage->doDeleteArticle($summary, false, 0, true, $error, $user);
     if (!$ok) {
         $params = array('target' => $base, 'error' => $ok);
         $type = $this->getFull() ? 'deletefnok' : 'deletelnok';
         $entry = new ManualLogEntry('pagetranslation', $type);
         $entry->setPerformer($doer);
         $entry->setTarget($title);
         $entry->setParameters($params);
         $logid = $entry->insert();
         $entry->publish($logid);
     }
     PageTranslationHooks::$allowTargetEdit = false;
     $cache = wfGetCache(CACHE_DB);
     $pages = (array) $cache->get(wfMemcKey('pt-base', $base));
     $lastitem = array_pop($pages);
     if ($title->getPrefixedText() === $lastitem) {
         $cache->delete(wfMemcKey('pt-base', $base));
         $type = $this->getFull() ? 'deletefok' : 'deletelok';
         $entry = new ManualLogEntry('pagetranslation', $type);
         $entry->setPerformer($doer);
         $entry->setTarget(Title::newFromText($base));
         $logid = $entry->insert();
         $entry->publish($logid);
         $tpage = TranslatablePage::newFromTitle($title);
         $tpage->getTranslationPercentages(true);
         foreach ($tpage->getTranslationPages() as $page) {
             $page->invalidateCache();
         }
         $title->invalidateCache();
     }
     return true;
 }
 /**
  * Keep the usual diiba daaba hidden from translators.
  * Hook: AlternateEdit
  */
 public static function intro(EditPage $editpage)
 {
     $handle = new MessageHandle($editpage->getTitle());
     if ($handle->isValid()) {
         $editpage->suppressIntro = true;
         $group = $handle->getGroup();
         $languages = $group->getTranslatableLanguages();
         if ($handle->getCode() && $languages !== null && !isset($languages[$handle->getCode()])) {
             $editpage->getArticle()->getContext()->getOutput()->wrapWikiMsg("<div class='error'>\$1</div>", 'translate-language-disabled');
             return false;
         }
         return true;
     }
     $msg = wfMessage('translate-edit-tag-warning')->inContentLanguage();
     if (!$msg->isDisabled() && TranslatablePage::isSourcePage($editpage->getTitle())) {
         $editpage->editFormTextTop .= $editpage->getArticle()->getContext()->getOutput()->parse($msg->plain());
     }
     return true;
 }
 public function testTranslationPageRestrictions()
 {
     $superUser = new MockSuperUser();
     $title = Title::newFromText('Translatable page');
     $page = WikiPage::factory($title);
     $content = ContentHandler::makeContent('<translate>Hello</translate>', $title);
     $status = $page->doEditContent($content, 'New page', 0, false, $superUser);
     $revision = $status->value['revision']->getId();
     $translatablePage = TranslatablePage::newFromRevision($title, $revision);
     $translatablePage->addMarkedTag($revision);
     MessageGroups::singleton()->recache();
     $translationPage = Title::newFromText('Translatable page/fi');
     TranslateRenderJob::newJob($translationPage)->run();
     $this->assertTrue($translationPage->userCan('read', $superUser), 'Users can read existing translation pages');
     $this->assertFalse($translationPage->userCan('edit', $superUser), 'Users can not edit existing translation pages');
     $translationPage = Title::newFromText('Translatable page/ab');
     $this->assertTrue($translationPage->userCan('read', $superUser), 'Users can read non-existing translation pages');
     $this->assertFalse($translationPage->userCan('edit', $superUser), 'Users can not edit non-existing translation pages');
 }
Пример #11
0
	function run() {
		// Initialization
		$title = $this->title;
		list( , $code ) = TranslateUtils::figureMessage( $title->getPrefixedText() );

		// Return the actual translation page...
		$page = TranslatablePage::isTranslationPage( $title );
		if ( !$page ) {
			var_dump( $this->params );
			var_dump( $title );
			throw new MWException( "Oops, this should not happen!" );
		}

		$group = $page->getMessageGroup();
		$collection = $group->initCollection( $code );
		$collection->loadTranslations( DB_MASTER );

		$text = $page->getParse()->getTranslationPageText( $collection );

		// Other stuff
		$user    = $this->getUser();
		$summary = $this->getSummary();
		$flags   = $this->getFlags();

		$article = new Article( $title, 0 );

		// @todo FuzzyBot hack
		PageTranslationHooks::$allowTargetEdit = true;

		// Do the edit
		$status = $article->doEdit( $text, $summary, $flags, false, $user );
		SpecialPageTranslation::superDebug( __METHOD__, 'edit', $user, $title, $flags, $status );

		PageTranslationHooks::$allowTargetEdit = false;

		// purge cache
		$page->getTranslationPercentages( true );

		return true;
	}
	protected function checkMoveBlockers() {
		$blockers = array();

		$target = $this->newTitle;

		if ( !$target ) {
			$blockers[] = array( 'pt-movepage-block-base-invalid' );
			return $blockers;
		}

		if ( $target->getNamespace() == NS_MEDIAWIKI || $target->getNamespace() == NS_TRANSLATIONS ) {
			$blockers[] = array( 'immobile-target-namespace', $target->getNsText() );
			return $blockers;
		}

		$base = $this->oldTitle->getPrefixedText();

		if ( $target->exists() ) {
			$blockers[] = array( 'pt-movepage-block-base-exists', $target->getPrefixedText() );
		} else {
			$errors = $this->oldTitle->isValidMoveOperation( $target, true, $this->reason );
			if ( is_array( $errors ) ) $blockers = array_merge( $blockers, $errors );
		}

		// Don't spam the same errors for all pages if base page fails
		if ( $blockers ) return $blockers;

		$translationPages = $this->getTranslationPages();
		foreach ( $translationPages as $old ) {
			$new = $this->newPageTitle( $base, $old, $target );
			if ( !$new ) {
				$blockers[] = array( 'pt-movepage-block-tp-invalid', $old->getPrefixedText() );
			} elseif ( $new->exists() ) {
				$blockers[] = array( 'pt-movepage-block-tp-exists', $old->getPrefixedText(), $new->getPrefixedText() );
			} else {
				$errors = $old->isValidMoveOperation( $target, false );
				if ( is_array( $errors ) ) $blockers = array_merge( $blockers, $errors );
			}
		}

		$sections = $this->getSectionPages();
		foreach ( $sections as $old ) {
			$new = $this->newPageTitle( $base, $old, $target );
			if ( !$new ) {
				$blockers[] = array( 'pt-movepage-block-section-invalid', $old->getPrefixedText() );
			} elseif ( $new->exists() ) {
				$blockers[] = array( 'pt-movepage-block-section-exists', $old->getPrefixedText(), $new->getPrefixedText() );
			} else {
				$errors = $old->isValidMoveOperation( $target, false );
				if ( is_array( $errors ) ) $blockers = array_merge( $blockers, $errors );
			}
		}

		if ( $this->moveSubpages ) {
			$subpages = $this->getSubpages();
			foreach ( $subpages as $old ) {
				if ( TranslatablePage::isTranslationPage( $old ) ) {
					continue;
				}

				$new = $this->newPageTitle( $base, $old, $target );

				if ( !$new ) {
					$blockers[] = array( 'pt-movepage-block-subpage-invalid', $old->getPrefixedText() );
				} elseif ( $new->exists() ) {
					$blockers[] = array( 'pt-movepage-block-subpage-exists', $old->getPrefixedText(), $new->getPrefixedText() );
				} else {
					$errors = $old->isValidMoveOperation( $target, false );
					if ( is_array( $errors ) ) $blockers = array_merge( $blockers, $errors );
				}
			}
		}

		return $blockers;
	}
 /**
  * Hook to update source and destination translation pages on moving translation units
  * Hook: TitleMoveComplete
  * @since 2014.08
  */
 public static function onMoveTranslationUnits(Title &$ot, Title &$nt, User &$user, $oldid, $newid, $reason)
 {
     // Do the update only once. In case running by job queue, the update is not done here
     if (self::$jobQueueRunning) {
         return;
     }
     $groupLast = null;
     foreach (array($ot, $nt) as $title) {
         $handle = new MessageHandle($title);
         if (!$handle->isValid()) {
             continue;
         }
         // Documentation pages are never translation pages
         if ($handle->isDoc()) {
             continue;
         }
         $group = $handle->getGroup();
         if (!$group instanceof WikiPageMessageGroup) {
             continue;
         }
         $language = $handle->getCode();
         // Ignore pages such as Translations:Page/unit without language code
         if (strval($code) === '') {
             continue;
         }
         // Update the page only once if source and destination units
         // belong to the same page
         if ($group !== $groupLast) {
             $groupLast = $group;
             $page = TranslatablePage::newFromTitle($group->getTitle());
             self::updateTranslationPage($page, $language, $user, 0, $reason);
         }
     }
 }
 /**
  * @param Title $title
  * @return bool|TranslatablePage
  */
 public static function isTranslationPage(Title $title)
 {
     $handle = new MessageHandle($title);
     $key = $handle->getKey();
     $code = $handle->getCode();
     if ($key === '' || $code === '') {
         return false;
     }
     $codes = Language::fetchLanguageNames();
     global $wgTranslateDocumentationLanguageCode;
     unset($codes[$wgTranslateDocumentationLanguageCode]);
     if (!isset($codes[$code])) {
         return false;
     }
     $newtitle = self::changeTitleText($title, $key);
     if (!$newtitle) {
         return false;
     }
     $page = TranslatablePage::newFromTitle($newtitle);
     if ($page->getMarkedTag() === false) {
         return false;
     }
     return $page;
 }
Пример #15
0
 public static function replaceSubtitle(&$subpages, $skin = null, $out = null)
 {
     global $wgOut;
     // $out was only added in some MW version
     if ($out === null) {
         $out = $wgOut;
     }
     $linker = class_exists('DummyLinker') ? new DummyLinker() : new Linker();
     if (!TranslatablePage::isTranslationPage($out->getTitle()) && !TranslatablePage::isSourcePage($out->getTitle())) {
         return true;
     }
     // Copied from Skin::subPageSubtitle()
     if ($out->isArticle() && MWNamespace::hasSubpages($out->getTitle()->getNamespace())) {
         $ptext = $out->getTitle()->getPrefixedText();
         if (preg_match('/\\//', $ptext)) {
             $links = explode('/', $ptext);
             array_pop($links);
             // Also pop of one extra for language code is needed
             if (TranslatablePage::isTranslationPage($out->getTitle())) {
                 array_pop($links);
             }
             $c = 0;
             $growinglink = '';
             $display = '';
             foreach ($links as $link) {
                 $growinglink .= $link;
                 $display .= $link;
                 $linkObj = Title::newFromText($growinglink);
                 if (is_object($linkObj) && $linkObj->exists()) {
                     $getlink = $linker->linkKnown(SpecialPage::getTitleFor('MyLanguage', $growinglink), htmlspecialchars($display));
                     $c++;
                     if ($c > 1) {
                         $subpages .= wfMsgExt('pipe-separator', 'escapenoentities');
                     } else {
                         // This one is stupid imho, doesn't work with chihuahua
                         // $subpages .= '&lt; ';
                     }
                     $subpages .= $getlink;
                     $display = '';
                 } else {
                     $display .= '/';
                 }
                 $growinglink .= '/';
             }
         }
         return false;
     }
     return true;
 }
	protected function checkTransrevRevision( $revId ) {
		static $cache = array();

		if ( isset( $cache[$revId] ) ) {
			return $cache[$revId];
		}

		$revision = Revision::newFromId( $revId );
		if ( !$revision ) {
			$cache[$revId] = 'no such revision';
		} else {
			$title = $revision->getTitle();
			if ( !$title ) {
				$cache[$revId] = 'no title for the revision';
			} else {
				$page = TranslatablePage::newFromTitle( $title );
				if ( $page->getMarkedTag() === false ) {
					$cache[$revId] = 'revision belongs to a page that is not marked for translation';
				} else {
					$cache[$revId] = true;
				}
			}
		}

		return $cache[$revId];
	}
Пример #17
0
 /**
  * This constructs the list of all groups from multiple different
  * sources. When possible, a cache dependency is created to automatically
  * recreate the cache when configuration changes.
  * @todo Reduce the ways of which messages can be added. Target is just
  * to have three ways: Yaml files, translatable pages and with the hook.
  * @todo In conjuction with the above, reduce the number of global
  * variables like wgTranslate#C and have the message groups specify
  * their own cache dependencies.
  */
 protected static function loadGroupDefinitions()
 {
     global $wgTranslateAddMWExtensionGroups;
     global $wgEnablePageTranslation, $wgTranslateGroupFiles;
     global $wgTranslateAC, $wgTranslateEC, $wgTranslateCC;
     global $wgAutoloadClasses;
     global $wgTranslateWorkflowStates;
     $deps = array();
     $deps[] = new GlobalDependency('wgTranslateAddMWExtensionGroups');
     $deps[] = new GlobalDependency('wgEnablePageTranslation');
     $deps[] = new GlobalDependency('wgTranslateGroupFiles');
     $deps[] = new GlobalDependency('wgTranslateAC');
     $deps[] = new GlobalDependency('wgTranslateEC');
     $deps[] = new GlobalDependency('wgTranslateCC');
     $deps[] = new GlobalDependency('wgTranslateExtensionDirectory');
     $deps[] = new GlobalDependency('wgTranslateWorkflowStates');
     $deps[] = new FileDependency(dirname(__FILE__) . '/groups/mediawiki-defines.txt');
     $deps[] = new FileDependency(dirname(__FILE__) . '/groups/Wikia/extensions.txt');
     $deps[] = new FileDependency(dirname(__FILE__) . '/groups/Toolserver/toolserver-textdomains.txt');
     if ($wgTranslateAddMWExtensionGroups) {
         $a = new PremadeMediawikiExtensionGroups();
         $a->addAll();
     }
     if ($wgEnablePageTranslation) {
         $dbr = wfGetDB(DB_MASTER);
         $tables = array('page', 'revtag');
         $vars = array('page_id', 'page_namespace', 'page_title');
         $conds = array('page_id=rt_page', 'rt_type' => RevTag::getType('tp:mark'));
         $options = array('GROUP BY' => 'rt_page');
         $res = $dbr->select($tables, $vars, $conds, __METHOD__, $options);
         foreach ($res as $r) {
             $title = Title::makeTitle($r->page_namespace, $r->page_title);
             $id = TranslatablePage::getMessageGroupIdFromTitle($title);
             $wgTranslateCC[$id] = new WikiPageMessageGroup($id, $title);
             $wgTranslateCC[$id]->setLabel($title->getPrefixedText());
         }
     }
     if ($wgTranslateWorkflowStates) {
         $wgTranslateCC['translate-workflow-states'] = new WorkflowStatesMessageGroup();
     }
     $autoload = array();
     wfRunHooks('TranslatePostInitGroups', array(&$wgTranslateCC, &$deps, &$autoload));
     foreach ($wgTranslateGroupFiles as $configFile) {
         wfDebug($configFile . "\n");
         $deps[] = new FileDependency(realpath($configFile));
         $fgroups = TranslateYaml::parseGroupFile($configFile);
         foreach ($fgroups as $id => $conf) {
             if (!empty($conf['AUTOLOAD']) && is_array($conf['AUTOLOAD'])) {
                 $dir = dirname($configFile);
                 foreach ($conf['AUTOLOAD'] as $class => $file) {
                     // For this request and for caching.
                     $wgAutoloadClasses[$class] = "{$dir}/{$file}";
                     $autoload[$class] = "{$dir}/{$file}";
                 }
             }
             $group = MessageGroupBase::factory($conf);
             $wgTranslateCC[$id] = $group;
         }
     }
     $key = wfMemckey('translate-groups');
     $value = array('ac' => $wgTranslateAC, 'ec' => $wgTranslateEC, 'cc' => $wgTranslateCC, 'autoload' => $autoload);
     $wrapper = new DependencyWrapper($value, $deps);
     $wrapper->storeToCache(self::getCache(), $key, 60 * 60 * 2);
     wfDebug(__METHOD__ . "-end\n");
 }
Пример #18
0
 /**
  * @param $title Title
  * @return bool|TranslatablePage
  */
 public static function isTranslationPage(Title $title)
 {
     list($key, $code) = TranslateUtils::figureMessage($title->getText());
     if ($key === '' || $code === '') {
         return false;
     }
     $codes = Language::getLanguageNames(false);
     global $wgTranslateDocumentationLanguageCode;
     unset($codes[$wgTranslateDocumentationLanguageCode]);
     if (!isset($codes[$code])) {
         return false;
     }
     $newtitle = self::changeTitleText($title, $key);
     if (!$newtitle) {
         return false;
     }
     $page = TranslatablePage::newFromTitle($newtitle);
     if ($page->getMarkedTag() === false) {
         return false;
     }
     return $page;
 }
	/**
	 * Keep the usual diiba daaba hidden from translators.
	 * Hook: AlternateEdit
	 */
	public static function intro( EditPage $editpage ) {
		$handle = new MessageHandle( $editpage->mTitle );
		if ( $handle->isValid() ) {
			$editpage->suppressIntro = true;
			return true;
		}

		$msg = wfMsgForContent( 'translate-edit-tag-warning' );

		if ( $msg !== '' && $msg !== '-' && TranslatablePage::isSourcePage( $editpage->mTitle ) ) {
			global $wgOut;
			$editpage->editFormTextTop .= $wgOut->parse( $msg );
		}

		return true;
	}
 protected function checkMoveBlockers()
 {
     $blockers = array();
     $target = $this->newTitle;
     if (!$target) {
         $blockers[] = array('pt-movepage-block-base-invalid');
         return $blockers;
     }
     if ($target->getNamespace() == NS_MEDIAWIKI || $target->getNamespace() == NS_TRANSLATIONS) {
         $blockers[] = array('immobile-target-namespace', $target->getNsText());
         return $blockers;
     }
     $base = $this->oldTitle->getPrefixedText();
     if ($target->exists()) {
         $blockers[] = array('pt-movepage-block-base-exists', $target->getPrefixedText());
     } else {
         $errors = $this->oldTitle->isValidMoveOperation($target, true, $this->reason);
         if (is_array($errors)) {
             $blockers = array_merge($blockers, $errors);
         }
     }
     // Don't spam the same errors for all pages if base page fails
     if ($blockers) {
         return $blockers;
     }
     // Collect all the old and new titles for checcks
     $titles = array();
     $pages = $this->getTranslationPages();
     foreach ($pages as $old) {
         $titles['tp'][] = array($old, $this->newPageTitle($base, $old, $target));
     }
     $pages = $this->getSectionPages();
     foreach ($pages as $old) {
         $titles['section'][] = array($old, $this->newPageTitle($base, $old, $target));
     }
     $subpages = array();
     if ($this->moveSubpages) {
         $subpages = $this->getSubpages();
     }
     foreach ($subpages as $old) {
         if (!TranslatablePage::isTranslationPage($old)) {
             $titles['subpage'][] = array($old, $this->newPageTitle($base, $old, $target));
         }
     }
     // Check that all new titles are valid
     $lb = new LinkBatch();
     foreach ($titles as $type => $list) {
         // Give grep a chance to find the usages:
         // pt-movepage-block-tp-invalid, pt-movepage-block-section-invalid,
         // pt-movepage-block-subpage-invalid
         foreach ($list as $pair) {
             list($old, $new) = $pair;
             if ($new === null) {
                 $blockers[] = array("pt-movepage-block-{$type}-invalid", $old->getPrefixedText());
                 continue;
             }
             $lb->addObj($old);
             $lb->addObj($new);
         }
     }
     if ($blockers) {
         return $blockers;
     }
     // Check that there are no move blockers
     $lb->execute();
     foreach ($titles as $type => $list) {
         // Give grep a chance to find the usages:
         // pt-movepage-block-tp-exists, pt-movepage-block-section-exists,
         // pt-movepage-block-subpage-exists
         foreach ($list as $pair) {
             list($old, $new) = $pair;
             if ($new->exists()) {
                 $blockers[] = array("pt-movepage-block-{$type}-exists", $old->getPrefixedText(), $new->getPrefixedText());
             } else {
                 /* This method has terrible performance:
                  * - 2 queries by core
                  * - 3 queries by lqt
                  * - and no obvious way to preload the data! */
                 $errors = $old->isValidMoveOperation($target, false);
                 if (is_array($errors)) {
                     $blockers = array_merge($blockers, $errors);
                 }
                 /* Because of the above, check only one of the possibly thousands
                  * of section pages and assume rest are fine. */
                 if ($type === 'section') {
                     break;
                 }
             }
         }
     }
     return $blockers;
 }
 public static function getTranslatablePages(array &$groups, array &$deps, array &$autoload)
 {
     global $wgEnablePageTranslation;
     $deps[] = new GlobalDependency('wgEnablePageTranslation');
     if (!$wgEnablePageTranslation) {
         return;
     }
     $db = wfGetDB(DB_MASTER);
     $tables = array('page', 'revtag');
     $vars = array('page_id', 'page_namespace', 'page_title');
     $conds = array('page_id=rt_page', 'rt_type' => RevTag::getType('tp:mark'));
     $options = array('GROUP BY' => 'rt_page');
     $res = $db->select($tables, $vars, $conds, __METHOD__, $options);
     foreach ($res as $r) {
         $title = Title::newFromRow($r);
         $id = TranslatablePage::getMessageGroupIdFromTitle($title);
         $groups[$id] = new WikiPageMessageGroup($id, $title);
         $groups[$id]->setLabel($title->getPrefixedText());
     }
 }
 /**
  * Returns translation page with all possible translations replaced in
  * and ugly translation tags removed.
  *
  * @param MessageCollection $collection Collection that holds translated messages.
  * @return string Whole page as wikitext.
  */
 public function getTranslationPageText($collection)
 {
     $text = $this->template;
     // The source
     // For finding the messages
     $prefix = $this->title->getPrefixedDBKey() . '/';
     if ($collection instanceof MessageCollection) {
         $collection->loadTranslations(DB_MASTER);
         $collection->filter('translated', false);
     }
     foreach ($this->sections as $ph => $s) {
         $sectiontext = null;
         if (isset($collection[$prefix . $s->id])) {
             /**
              * @var TMessage $msg
              */
             $msg = $collection[$prefix . $s->id];
             $sectiontext = $msg->translation();
         }
         // Use the original text if no translation is available.
         // For the source language, this will actually be the source, which
         // contains variable declarations (tvar) instead of variables ($1).
         // The getTextWithVariables will convert declarations to normal variables
         // for us so that the variable substitutions below will also work
         // for the source language.
         if ($sectiontext === null || $sectiontext === $s->getText()) {
             $sectiontext = $s->getTextWithVariables();
         }
         // Substitute variables into section text and substitute text into document
         $sectiontext = strtr($sectiontext, $s->getVariables());
         $text = str_replace($ph, $sectiontext, $text);
     }
     $nph = array();
     $text = TranslatablePage::armourNowiki($nph, $text);
     // Remove translation markup from the template to produce final text
     $cb = array(__CLASS__, 'replaceTagCb');
     $text = preg_replace_callback('~(<translate>)(.*)(</translate>)~sU', $cb, $text);
     $text = TranslatablePage::unArmourNowiki($nph, $text);
     return $text;
 }
Пример #23
0
 protected function getTranslationPageDiff()
 {
     global $wgEnablePageTranslation;
     if (!$wgEnablePageTranslation) {
         return null;
     }
     $this->mustBeKnownMessage();
     if (!$this->group instanceof WikiPageMessageGroup) {
         return null;
     }
     // Shortcuts
     $code = $this->handle->getCode();
     $key = $this->handle->getKey();
     // TODO: encapsulate somewhere
     $page = TranslatablePage::newFromTitle($this->group->getTitle());
     $rev = $page->getTransRev("{$key}/{$code}");
     $latest = $page->getMarkedTag();
     if ($rev === $latest) {
         return null;
     }
     $oldpage = TranslatablePage::newFromRevision($this->group->getTitle(), $rev);
     $oldtext = $newtext = null;
     foreach ($oldpage->getParse()->getSectionsForSave() as $section) {
         if ($this->group->getTitle()->getPrefixedDBKey() . '/' . $section->id === $key) {
             $oldtext = $section->getTextForTrans();
         }
     }
     foreach ($page->getParse()->getSectionsForSave() as $section) {
         if ($this->group->getTitle()->getPrefixedDBKey() . '/' . $section->id === $key) {
             $newtext = $section->getTextForTrans();
         }
     }
     if ($oldtext === $newtext) {
         return null;
     }
     $diff = new DifferenceEngine();
     if (method_exists('DifferenceEngine', 'setTextLanguage')) {
         $diff->setTextLanguage($this->group->getSourceLanguage());
     }
     $diff->setText($oldtext, $newtext);
     $diff->setReducedLineNumbers();
     $diff->showDiffStyle();
     return $diff->getDiff(wfMsgHtml('tpt-diff-old'), wfMsgHtml('tpt-diff-new'));
 }
Пример #24
0
	/**
	 * Returns translation page with all possible translations replaced in, ugly
	 * translation tags removed and outdated translation marked with a class
	 * mw-translate-fuzzy.
	 * @todo The class marking has to be more intelligent with span&div use.
	 * @param $collection \type{MessageCollection} Collection that holds translated messages.
	 * @return \string Whole page as wikitext.
	 */
	public function getTranslationPageText( /*MessageCollection*/ $collection ) {
		$text = $this->template; // The source

		// For finding the messages
		$prefix = $this->title->getPrefixedDBKey() . '/';

		if ( $collection instanceof MessageCollection ) {
			$collection->filter( 'hastranslation', false );
			$collection->loadTranslations();
		}

		foreach ( $this->sections as $ph => $s ) {
			$sectiontext = null;

			if ( isset( $collection[$prefix . $s->id] ) ) {
				$msg = $collection[$prefix . $s->id];
				$translation = $msg->translation();

				if ( $translation !== null ) {
					// Ideally we should not have fuzzy here, but old texts do
					$sectiontext = str_replace( TRANSLATE_FUZZY, '', $translation );

					if ( $msg->hasTag( 'fuzzy' ) ) {
						$sectiontext = "<span class=\"mw-translate-fuzzy\">\n$sectiontext\n</span>";
					}
				}
			}

			// Use the original text if no translation is available
			if ( $sectiontext === null ) {
				$sectiontext = $s->getTextForTrans();
			}

			// Substitute variables into section text and substitute text into document
			$sectiontext = self::replaceVariables( $s->getVariables(), $sectiontext );
			$text = str_replace( $ph, $sectiontext, $text );
		}

		$nph = array();
		$text = TranslatablePage::armourNowiki( $nph, $text );

		// Remove translation markup
		$cb = array( __CLASS__, 'replaceTagCb' );
		$text = preg_replace_callback( '~(<translate>)(.*)(</translate>)~sU', $cb, $text );
		$text = TranslatablePage::unArmourNowiki( $nph, $text );

		return $text;
	}
	public function setupRenderJobs( TranslatablePage $page ) {
		$titles = $page->getTranslationPages();
		$this->addInitialRenderJob( $page, $titles );
		$jobs = array();

		foreach ( $titles as $t ) {
			self::superDebug( __METHOD__, 'renderjob', $t );
			$jobs[] = RenderJob::newJob( $t );
		}

		if ( count( $jobs ) < 10 ) {
			self::superDebug( __METHOD__, 'renderjob-immediate' );
			foreach ( $jobs as $j ) {
				$j->run();
			}
		} else {
			// Use the job queue
			self::superDebug( __METHOD__, 'renderjob-delayed' );
			Job::batchInsert( $jobs );
		}
	}
 /**
  * Creates jobs needed to create or update all translation page definitions.
  * @param TranslatablePage $page
  * @param array $sections
  * @return Job[]
  * @since 2013-01-28
  */
 public static function getTranslationUnitJobs(TranslatablePage $page, array $sections)
 {
     $jobs = array();
     $code = $page->getSourceLanguageCode();
     $prefix = $page->getTitle()->getPrefixedText();
     foreach ($sections as $s) {
         $unit = $s->name;
         $title = Title::makeTitle(NS_TRANSLATIONS, "{$prefix}/{$unit}/{$code}");
         $fuzzy = $s->type === 'changed';
         $jobs[] = MessageUpdateJob::newJob($title, $s->getTextWithVariables(), $fuzzy);
     }
     return $jobs;
 }