/**
  * Returns all section pages, including those which are currently not active.
  * @return TitleArray.
  */
 protected function getSectionPages()
 {
     if (!isset($this->sectionPages)) {
         $base = $this->page->getTitle()->getPrefixedDBKey();
         $dbw = wfGetDB(DB_MASTER);
         if ($this->singleLanguage()) {
             $like = $dbw->buildLike("{$base}/", $dbw->anyString(), "/{$this->code}");
         } else {
             $like = $dbw->buildLike("{$base}/", $dbw->anyString());
         }
         $fields = array('page_namespace', 'page_title');
         $titleCond = 'page_title ' . $like;
         $conds = array('page_namespace' => NS_TRANSLATIONS, $titleCond);
         $result = $dbw->select('page', $fields, $conds, __METHOD__);
         $this->sectionPages = TitleArray::newFromResult($result);
     }
     return $this->sectionPages;
 }
 /**
  * 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;
 }
 public static function updateTranslationPage(TranslatablePage $page, $code, $user, $flags, $summary)
 {
     $source = $page->getTitle();
     $target = Title::makeTitle($source->getNamespace(), $source->getDBkey() . "/{$code}");
     // We don't know and don't care
     $flags &= ~EDIT_NEW & ~EDIT_UPDATE;
     // Update the target page
     $job = TranslateRenderJob::newJob($target);
     $job->setUser($user);
     $job->setSummary($summary);
     $job->setFlags($flags);
     $job->run();
     // Regenerate translation caches
     $page->getTranslationPercentages('force');
     // Invalidate caches
     $pages = $page->getTranslationPages();
     foreach ($pages as $title) {
         $wikiPage = WikiPage::factory($title);
         $wikiPage->doPurge();
     }
     // And the source page itself too
     $wikiPage = WikiPage::factory($page->getTitle());
     $wikiPage->doPurge();
 }
	/**
	 * This function does the heavy duty of marking a page.
	 * - Updates the source page with section markers.
	 * - Updates translate_sections table
	 * - Updates revtags table
	 * - Setups renderjobs to update the translation pages
	 * - Invalidates caches
	 * @param $page TranslatablePage
	 * @param $sections array
	 * @return array|bool
	 */
	public function markForTranslation( TranslatablePage $page, Array $sections ) {
		global $wgRequest;

		// Add the section markers to the source page
		$article = new Article( $page->getTitle(), 0 );
		$status = $article->doEdit(
			$page->getParse()->getSourcePageText(), // Content
			wfMsgForContent( 'tpt-mark-summary' ),  // Summary
			EDIT_FORCE_BOT | EDIT_UPDATE,           // Flags
			$page->getRevision()                    // Based-on revision
		);

		if ( !$status->isOK() ) {
			self::superDebug( __METHOD__, 'edit-fail', $this->user, $page->getTitle(), $status );
			return array( 'tpt-edit-failed', $status->getWikiText() );
		}

		$newrevision = $status->value['revision'];

		// In theory it is either null or Revision object,
		// never revision object with null id, but who knows
		if ( $newrevision instanceof Revision ) {
			$newrevision = $newrevision->getId();
		}

		if ( $newrevision === null ) {
			// Probably a no-change edit, so no new revision was assigned.
			// Get the latest revision manually
			$newrevision = $page->getTitle()->getLatestRevId();
		}

		self::superDebug( __METHOD__, 'latestrev', $page->getTitle(), $newrevision );

		$inserts = array();
		$changed = array();

		$pageId = $page->getTitle()->getArticleId();
		foreach ( array_values( $sections ) as $index => $s ) {
			if ( $s->type === 'changed' ) {
				// Allow silent changes to avoid fuzzying unnecessary.
				if ( !$wgRequest->getCheck( "tpt-sect-{$s->id}-action-nofuzzy" ) ) {
					$changed[] = $s->name;
				}
			}

			$inserts[] = array(
				'trs_page' => $pageId,
				'trs_key' => $s->name,
				'trs_text' => $s->getText(),
				'trs_order' => $index
			);
		}


		// Don't add stuff if no changes, use the plain null instead for prettiness
		if ( !count( $changed ) ) {
			$changed = null;
		}

		$dbw = wfGetDB( DB_MASTER );
		if ( !$dbw->fieldExists( 'translate_sections', 'trs_order', __METHOD__ ) ) {
			error_log( 'Field trs_order does not exist. Please run update.php.' );
			foreach ( array_keys( $inserts ) as $index ) {
				unset( $inserts[$index]['trs_order'] );
			}
		}
		$dbw->delete( 'translate_sections', array( 'trs_page' => $page->getTitle()->getArticleId() ), __METHOD__ );
		$dbw->insert( 'translate_sections', $inserts, __METHOD__ );

		/* Stores the names of changed sections in the database.
		 * Used for calculating completion percentages for outdated messages */
		$page->addMarkedTag( $newrevision, $changed );
		$this->addFuzzyTags( $page, $changed );

		global $wgUser;
		$logger = new LogPage( 'pagetranslation' );
		$params = array(
			'user' => $wgUser->getName(),
			'revision' => $newrevision,
			'changed' => count( $changed ),
		);
		$logger->addEntry( 'mark', $page->getTitle(), null, array( serialize( $params ) ) );

		$page->getTitle()->invalidateCache();
		$this->setupRenderJobs( $page );

		// Re-generate caches
		MessageGroups::clearCache();
		MessageIndexRebuildJob::newJob()->insert();
		return false;
	}