/**
  * @param Workflow $workflow
  * @param string $objectType
  * @param UUID $objectId
  */
 public function __construct(Workflow $workflow, $objectType, UUID $objectId)
 {
     $this->workflowId = $workflow->getId();
     $this->title = $workflow->getArticleTitle();
     $this->objectType = $objectType;
     $this->objectId = $objectId;
 }
 /**
  * @param Workflow $topicList
  * @param Workflow $topic
  * @return TopicListEntry
  */
 public static function create(Workflow $topicList, Workflow $topic)
 {
     $obj = new self();
     $obj->topicListId = $topicList->getId();
     $obj->topicId = $topic->getId();
     $obj->topicWorkflowLastUpdated = $topic->getLastModified();
     return $obj;
 }
 /**
  * Create a brand new root post for a brand new topic.  Creating replies to
  * an existing post(incl topic root) should use self::reply.
  *
  * @param Workflow $topic
  * @param User $user
  * @param string $content The title of the topic(they are Collection as well)
  * @param string $format wikitext|html
  * @return PostRevision
  */
 public static function create(Workflow $topic, User $user, $content, $format)
 {
     $obj = static::newFromId($topic->getId(), $user, $content, $format, $topic->getArticleTitle());
     $obj->changeType = 'new-post';
     // A newly created post has no children, a depth of 0, and
     // is the root of its tree.
     $obj->setChildren(array());
     $obj->setDepth(0);
     $obj->rootPost = $obj;
     return $obj;
 }
 /**
  * @param Workflow $workflow
  * @param User $user
  * @param string $content
  * @param string $format wikitext|html
  * @param string[optional] $changeType
  * @return Header
  */
 public static function create(Workflow $workflow, User $user, $content, $format, $changeType = 'create-header')
 {
     $obj = new self();
     $obj->revId = UUID::create();
     $obj->workflowId = $workflow->getId();
     $obj->user = UserTuple::newFromUser($user);
     $obj->prevRevision = null;
     // no prior revision
     $obj->setContent($content, $format, $workflow->getArticleTitle());
     $obj->changeType = $changeType;
     return $obj;
 }
 protected function log(PostRevision $post, Workflow $workflow)
 {
     $moderationChangeTypes = self::getModerationChangeTypes();
     if (!in_array($post->getChangeType(), $moderationChangeTypes)) {
         // Do nothing for non-moderation actions
         return;
     }
     if ($this->moderationLogger->canLog($post, $post->getChangeType())) {
         $workflowId = $workflow->getId();
         $this->moderationLogger->log($post, $post->getChangeType(), $post->getModeratedReason(), $workflowId);
     }
 }
 /**
  * Load the header and topics from the requested discussion.  Does not return
  * anything, the goal here is to populate $this->hashBag.
  *
  * @param Workflow $workflow
  */
 protected function fetchDiscussion(Workflow $workflow)
 {
     $results = array();
     $pagers = array();
     /** @var ManagerGroup $storage */
     $storage = Container::get('storage');
     // 'newest' sort order
     $pagers[] = new Pager($storage->getStorage('TopicListEntry'), array('topic_list_id' => $workflow->getId()), array('pager-limit' => 499));
     // 'updated' sort order
     $pagers[] = new Pager($storage->getStorage('TopicListEntry'), array('topic_list_id' => $workflow->getId()), array('pager-limit' => 499, 'sort' => 'workflow_last_update_timestamp', 'order' => 'desc'));
     // Based on Header::init.
     $storage->find('Header', array('rev_type_id' => $workflow->getId()), array('sort' => 'rev_id', 'order' => 'DESC', 'limit' => 1));
     foreach ($pagers as $pager) {
         foreach ($pager->getPage()->getResults() as $entry) {
             // use array key to de-duplicate
             $results[$entry->getId()->getAlphadecimal()] = $entry->getId();
         }
     }
     $this->fetchTopics($results);
     // purge the board history
     $storage->find('BoardHistoryEntry', array('topic_list_id' => $workflow->getId()), array('sort' => 'rev_id', 'order' => 'DESC', 'limit' => 499));
 }
 /**
  * @dataProvider provideGetReferencesFromRevisionContent
  */
 public function testGetReferencesAfterRevisionInsert($content, $expectedReferences)
 {
     $content = Utils::convert('wikitext', 'html', $content, $this->workflow->getOwnerTitle());
     $revision = $this->generatePost(array('rev_content' => $content));
     // Save to storage to test if ReferenceRecorder listener picks this up
     $this->store($this->revision);
     $this->store($revision);
     $expectedReferences = $this->expandReferences($this->workflow, $revision, $expectedReferences);
     // References will be stored as linked from Topic:<id>
     $title = Title::newFromText($this->workflow->getId()->getAlphadecimal(), NS_TOPIC);
     // Retrieve references from storage
     $foundReferences = $this->updater->getReferencesForTitle($title);
     $this->assertReferenceListsEqual($expectedReferences, $foundReferences);
 }
 /**
  * When a page is taken over by Flow, add a revision.
  *
  * First, it provides a clearer history should Flow be disabled again later,
  * and a descriptive message when people attempt to use regular API to fetch
  * data for this "Page", which will no longer contain any useful content,
  * since Flow has taken over.
  *
  * Also: Parsoid performs an API call to fetch page information, so we need
  * to make sure a page actually exists ;)
  *
  * This method does not do any security checks regarding content model changes
  * or the like.  Those happen much earlier in the request and should be checked
  * before even attempting to create revisions which, when written to the database,
  * trigger this method through the OccupationListener.
  *
  * @param \Article $article
  * @param Workflow $workflow
  * @return Status Status for revision creation; On success (including if it already
  *  had a top-most Flow revision), it will return a good status with an associative
  *  array value.  $status->getValue()['revision'] will be a Revision
  *  $status->getValue()['already-existed'] will be set to true if no revision needed
  *  to be created
  * @throws InvalidInputException
  */
 public function ensureFlowRevision(Article $article, Workflow $workflow)
 {
     // Comment to add to the Revision to indicate Flow taking over
     $comment = '/* Taken over by Flow */';
     $page = $article->getPage();
     $revision = $page->getRevision();
     if ($revision !== null) {
         $content = $revision->getContent();
         if ($content instanceof BoardContent && $content->getWorkflowId()) {
             // Revision is already a valid BoardContent
             return Status::newGood(array('revision' => $revision, 'already-existed' => true));
         }
     }
     $status = $page->doEditContent(new BoardContent(CONTENT_MODEL_FLOW_BOARD, $workflow->isNew() ? null : $workflow->getId()), $comment, EDIT_FORCE_BOT | EDIT_SUPPRESS_RC, false, $this->getTalkpageManager());
     $value = $status->getValue();
     $value['already-existed'] = false;
     $status->setResult($status->isOK(), $value);
     return $status;
 }
 protected function redirect(Workflow $workflow)
 {
     $link = $this->urlGenerator->workflowLink($workflow->getArticleTitle(), $workflow->getId());
     $this->getOutput()->redirect($link->getFullURL());
 }
 protected function buildApiActions(Workflow $workflow)
 {
     return array('newtopic' => array('url' => $this->urlGenerator->newTopicAction($workflow->getArticleTitle(), $workflow->getId())));
 }
 public function getWorkflowId()
 {
     return $this->workflow->getId();
 }
 /**
  * Gets all the 'top' revisions within the topic, namely the posts and the
  * summary. These are used when a topic changes is visibility via moderation
  * to add or remove the relevant references.
  *
  * @param Workflow $workflow
  * @return AbstractRevision[]
  */
 protected function collectTopicRevisions(Workflow $workflow)
 {
     $found = $this->treeRepository->fetchSubtreeNodeList(array($workflow->getId()));
     $queries = array();
     foreach (reset($found) as $uuid) {
         $queries[] = array('rev_type_id' => $uuid);
     }
     $posts = $this->storage->findMulti('PostRevision', $queries, array('sort' => 'rev_id', 'order' => 'DESC', 'limit' => 1));
     // we also need the most recent topic summary if it exists
     $summaries = $this->storage->find('PostSummary', array('rev_type_id' => $workflow->getId()), array('sort' => 'rev_id', 'order' => 'DESC', 'limit' => 1));
     $result = $summaries;
     // we have to unwrap the posts since we used findMulti, it returns
     // a separate result set for each query
     foreach ($posts as $found) {
         $result[] = reset($found);
     }
     return $result;
 }
 public function __construct(PageImportState $parent, Workflow $topicWorkflow, PostRevision $topicTitle)
 {
     $this->parent = $parent;
     $this->topicWorkflow = $topicWorkflow;
     $this->topicTitle = $topicTitle;
     $this->workflowModifiedProperty = new ReflectionProperty('Flow\\Model\\Workflow', 'lastModified');
     $this->workflowModifiedProperty->setAccessible(true);
     $this->lastModified = '';
     $this->recordModificationTime($topicWorkflow->getId());
 }
 public function buildEmptyResult(Workflow $workflow)
 {
     $title = $workflow->getArticleTitle();
     return array('workflowId' => $workflow->getId()->getAlphadecimal(), 'title' => $title->getPrefixedText(), 'actions' => $this->buildApiActions($workflow)) + parent::buildEmptyResult($workflow);
 }