/**
  * 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 TranslatablePage $page
  * @param array $sections
  * @return array|bool
  */
 public function markForTranslation(TranslatablePage $page, array $sections)
 {
     // Add the section markers to the source page
     $wikiPage = WikiPage::factory($page->getTitle());
     $content = ContentHandler::makeContent($page->getParse()->getSourcePageText(), $page->getTitle());
     $status = $wikiPage->doEditContent($content, $this->msg('tpt-mark-summary')->inContentLanguage()->text(), EDIT_FORCE_BOT | EDIT_UPDATE);
     if (!$status->isOK()) {
         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();
     }
     $inserts = array();
     $changed = array();
     $maxid = intval(TranslateMetadata::get($page->getMessageGroupId(), 'maxid'));
     $pageId = $page->getTitle()->getArticleID();
     /**
      * @var TPSection $s
      */
     foreach (array_values($sections) as $index => $s) {
         $maxid = max($maxid, intval($s->name));
         $changed[] = $s->name;
         if ($this->getRequest()->getCheck("tpt-sect-{$s->id}-action-nofuzzy")) {
             // This will be checked by getTranslationUnitJobs
             $s->type = 'old';
         }
         $inserts[] = array('trs_page' => $pageId, 'trs_key' => $s->name, 'trs_text' => $s->getText(), 'trs_order' => $index);
     }
     $dbw = wfGetDB(DB_MASTER);
     $dbw->delete('translate_sections', array('trs_page' => $page->getTitle()->getArticleID()), __METHOD__);
     $dbw->insert('translate_sections', $inserts, __METHOD__);
     TranslateMetadata::set($page->getMessageGroupId(), 'maxid', $maxid);
     $page->addMarkedTag($newrevision);
     MessageGroups::singleton()->recache();
     $jobs = self::getRenderJobs($page);
     JobQueueGroup::singleton()->push($jobs);
     $jobs = self::getTranslationUnitJobs($page, $sections);
     JobQueueGroup::singleton()->push($jobs);
     // Logging
     $this->handlePriorityLanguages($this->getRequest(), $page);
     $entry = new ManualLogEntry('pagetranslation', 'mark');
     $entry->setPerformer($this->getUser());
     $entry->setTarget($page->getTitle());
     $entry->setParameters(array('revision' => $newrevision, 'changed' => count($changed)));
     $logid = $entry->insert();
     $entry->publish($logid);
     // Clear more caches
     $page->getTitle()->invalidateCache();
     MessageIndexRebuildJob::newJob()->insert();
     return false;
 }
	/**
	 * 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;
	}