public function onAfterUpdate($object, array $old, array $new, array $metadata)
 {
     $entry = $this->getTopicListEntry($new['workflow_id']);
     if ($entry) {
         $row = TopicListEntry::toStorageRow($entry);
         $this->topicListLastUpdatedIndex->onAfterUpdate($entry, array('workflow_last_update_timestamp' => $old['workflow_last_update_timestamp']) + $row, array('workflow_last_update_timestamp' => $new['workflow_last_update_timestamp']) + $row, $metadata);
     }
 }
 /**
  * Saves a PostRevision to storage.
  * Be sure to add the required tables to $tablesUsed and add @group Database
  * to the class' phpDoc.
  *
  * @param PostRevision $revision
  */
 protected function store(PostRevision $revision)
 {
     if ($revision->isTopicTitle()) {
         $root = $revision;
     } else {
         /** @var PostCollection $parentCollection */
         $parentCollection = PostCollection::newFromId($revision->getReplyToId());
         $root = $parentCollection->getRoot()->getLastRevision();
     }
     $topicWorkflow = $this->workflows[$root->getCollectionId()->getAlphadecimal()];
     $boardWorkflow = Container::get('factory.loader.workflow')->createWorkflowLoader($topicWorkflow->getOwnerTitle())->getWorkflow();
     $metadata = array('workflow' => $topicWorkflow, 'board-workflow' => $boardWorkflow);
     // check if this topic (+ workflow + board workflow + board page) have
     // already been inserted or do so now
     $found = $this->getStorage()->find('TopicListEntry', array('topic_id' => $topicWorkflow->getId()));
     if (!$found) {
         $title = $boardWorkflow->getOwnerTitle();
         $user = User::newFromName('127.0.0.1', false);
         /** @var OccupationController $occupationController */
         $occupationController = Container::get('occupation_controller');
         // make sure user has rights to create board
         $user->mRights = array_merge($user->getRights(), array('flow-create-board'));
         $occupationController->allowCreation($title, $user);
         $occupationController->ensureFlowRevision(new \Article($title), $boardWorkflow);
         $topicListEntry = TopicListEntry::create($boardWorkflow, $topicWorkflow);
         $this->getStorage()->put($boardWorkflow, $metadata);
         $this->getStorage()->put($topicWorkflow, $metadata);
         $this->getStorage()->put($topicListEntry, $metadata);
     }
     $this->getStorage()->put($revision, $metadata);
     /** @var SplQueue $deferredQueue */
     $deferredQueue = Container::get('deferred_queue');
     while (!$deferredQueue->isEmpty()) {
         try {
             DeferredUpdates::addCallableUpdate($deferredQueue->dequeue());
             // doing updates 1 by 1 so an exception doesn't break others in
             // the queue
             DeferredUpdates::doUpdates();
         } catch (\MWException $e) {
             // ignoring exceptions for now, not all are phpunit-proof yet
         }
     }
     // save for removal at end of tests
     $this->revisions[] = $revision;
 }
 public static function onIRCLineURLProvider()
 {
     // data providers do not run in the same context as the actual test, as such we
     // can't create Title objects because they can have the wrong wikiID.  Instead we
     // pass closures into the test that create the objects within the correct context.
     $newHeader = function (User $user) {
         $title = Title::newFromText('Talk:Hook_test');
         $workflow = Container::get('factory.loader.workflow')->createWorkflowLoader($title)->getWorkflow();
         $header = Header::create($workflow, $user, 'header content', 'wikitext');
         $metadata = array('workflow' => $workflow, 'revision' => $header);
         /** @var OccupationController $occupationController */
         $occupationController = Container::get('occupation_controller');
         // make sure user has rights to create board
         $user->mRights = array_merge($user->getRights(), array('flow-create-board'));
         $occupationController->allowCreation($title, $user);
         $occupationController->ensureFlowRevision(new \Article($title), $workflow);
         Container::get('storage')->put($workflow, $metadata);
         return $metadata;
     };
     $freshTopic = function (User $user) {
         $title = Title::newFromText('Talk:Hook_test');
         $boardWorkflow = Container::get('factory.loader.workflow')->createWorkflowLoader($title)->getWorkflow();
         $topicWorkflow = Workflow::create('topic', $boardWorkflow->getArticleTitle());
         $topicList = TopicListEntry::create($boardWorkflow, $topicWorkflow);
         $topicTitle = PostRevision::create($topicWorkflow, $user, 'some content', 'wikitext');
         $metadata = array('workflow' => $topicWorkflow, 'board-workflow' => $boardWorkflow, 'topic-title' => $topicTitle, 'revision' => $topicTitle);
         /** @var OccupationController $occupationController */
         $occupationController = Container::get('occupation_controller');
         // make sure user has rights to create board
         $user->mRights = array_merge($user->getRights(), array('flow-create-board'));
         $occupationController->allowCreation($title, $user);
         $occupationController->ensureFlowRevision(new \Article($title), $boardWorkflow);
         $storage = Container::get('storage');
         $storage->put($boardWorkflow, $metadata);
         $storage->put($topicWorkflow, $metadata);
         $storage->put($topicList, $metadata);
         $storage->put($topicTitle, $metadata);
         return $metadata;
     };
     $replyToTopic = function (User $user) use($freshTopic) {
         $metadata = $freshTopic($user);
         $firstPost = $metadata['topic-title']->reply($metadata['workflow'], $user, 'ffuts dna ylper', 'wikitext');
         $metadata = array('first-post' => $firstPost, 'revision' => $firstPost) + $metadata;
         Container::get('storage.post')->put($firstPost, $metadata);
         return $metadata;
     };
     return array(array('Freshly created topic', $freshTopic, array('action' => 'history')), array('Reply to topic', $replyToTopic, array('action' => 'history')), array('Edit topic title', function ($user) use($freshTopic) {
         $metadata = $freshTopic($user);
         $title = $metadata['workflow']->getArticleTitle();
         return array('revision' => $metadata['revision']->newNextRevision($user, 'gnihtemos gnihtemos', 'wikitext', 'edit-title', $title)) + $metadata;
     }, array('action' => 'compare-post-revisions')), array('Edit post', function ($user) use($replyToTopic) {
         $metadata = $replyToTopic($user);
         $title = $metadata['workflow']->getArticleTitle();
         return array('revision' => $metadata['revision']->newNextRevision($user, 'IT\'S CAPS LOCKS DAY!', 'wikitext', 'edit-post', $title)) + $metadata;
     }, array('action' => 'compare-post-revisions')), array('Edit board header', function ($user) use($newHeader) {
         $metadata = $newHeader($user);
         $title = $metadata['workflow']->getArticleTitle();
         return array('revision' => $metadata['revision']->newNextRevision($user, 'STILL CAPS LOCKS DAY!', 'wikitext', 'edit-header', $title)) + $metadata;
     }, array('action' => 'compare-header-revisions')), array('Moderate a post', function ($user) use($replyToTopic) {
         $metadata = $replyToTopic($user);
         return array('revision' => $metadata['revision']->moderate($user, $metadata['revision']::MODERATED_DELETED, 'delete-post', 'something about cruise control')) + $metadata;
     }, array('action' => 'history')), array('Moderate a topic', function ($user) use($freshTopic) {
         $metadata = $freshTopic($user);
         return array('revision' => $metadata['revision']->moderate($user, $metadata['revision']::MODERATED_HIDDEN, 'hide-topic', 'adorable kittens')) + $metadata;
     }, array('action' => 'history')));
 }
 /**
  * Creates the objects about to be inserted into storage:
  * * $this->topicWorkflow
  * * $this->topicListEntry
  * * $this->topicTitle
  * * $this->firstPost
  *
  * @throws \MWException
  * @throws \Flow\Exception\FailCommitException
  * @return array Array of [$topicWorkflow, $topicListEntry, $topicTitle, $firstPost]
  */
 protected function create()
 {
     $title = $this->workflow->getArticleTitle();
     $user = $this->context->getUser();
     $topicWorkflow = Workflow::create('topic', $title);
     $topicListEntry = TopicListEntry::create($this->workflow, $topicWorkflow);
     $topicTitle = PostRevision::create($topicWorkflow, $user, $this->submitted['topic'], 'wikitext');
     $firstPost = null;
     if (!empty($this->submitted['content'])) {
         $firstPost = $topicTitle->reply($topicWorkflow, $user, $this->submitted['content'], isset($this->submitted['format']) ? $this->submitted['format'] : 'wikitext');
         $topicTitle->setChildren(array($firstPost));
     }
     return array($topicWorkflow, $topicListEntry, $topicTitle, $firstPost);
 }
 /**
  * @param PageImportState $state
  * @param IImportTopic    $importTopic
  * @return TopicImportState
  */
 protected function createTopicState(PageImportState $state, IImportTopic $importTopic)
 {
     $state->logger->info('Importing new topic');
     $topicWorkflow = Workflow::create('topic', $state->boardWorkflow->getArticleTitle());
     $state->setWorkflowTimestamp($topicWorkflow, $this->getFirstRevision($importTopic)->getTimestamp());
     $topicListEntry = TopicListEntry::create($state->boardWorkflow, $topicWorkflow);
     $titleRevisions = $this->importObjectWithHistory($importTopic, function (IObjectRevision $rev) use($state, $topicWorkflow) {
         return PostRevision::create($topicWorkflow, $state->createUser($rev->getAuthor()), $rev->getText(), 'wikitext');
     }, 'edit-title', $state, $topicWorkflow->getArticleTitle());
     $topicState = new TopicImportState($state, $topicWorkflow, end($titleRevisions));
     $topicMetadata = $topicState->getMetadata();
     // This should all match the order in TopicListBlock->commit (board/
     // discussion workflow is inserted before this method is called).
     $state->put($topicWorkflow, $topicMetadata);
     // TLE must be before topic title, otherwise you get an error importing the Topic Title
     // Flow/includes/Data/Index/BoardHistoryIndex.php:
     // No topic list contains topic XXX, called for revision YYY
     $state->put($topicListEntry, $topicMetadata);
     $state->put($titleRevisions, $topicMetadata);
     $state->recordAssociation($topicWorkflow->getId(), $importTopic);
     $state->logger->info('Finished importing topic title with ' . count($titleRevisions) . ' revisions');
     return $topicState;
 }