/**
  * @param stdClass $row
  * @return array
  * @throws TimestampException
  * @throws \Flow\Exception\FlowException
  * @throws \Flow\Exception\InvalidInputException
  */
 public function update($row)
 {
     $uuid = UUID::create($row->workflow_id);
     switch ($row->workflow_type) {
         case 'discussion':
             $revision = $this->storage->get('Header', $uuid);
             break;
         case 'topic':
             // fetch topic (has same id as workflow) via RootPostLoader so
             // all children are populated
             $revision = $this->rootPostLoader->get($uuid);
             break;
         default:
             throw new FlowException('Unknown workflow type: ' . $row->workflow_type);
     }
     if (!$revision) {
         return array();
     }
     $timestamp = $this->getUpdateTimestamp($revision)->getTimestamp(TS_MW);
     if ($timestamp === $row->workflow_last_update_timestamp) {
         // correct update timestamp already, nothing to update
         return array();
     }
     return array('workflow_last_update_timestamp' => $timestamp);
 }
 /**
  * While topic's themselves are plaintext and do not contain any references,
  * moderation actions change what references are visible.  When transitioning
  * from or to a generically visible state (unmoderated or locked) the entire
  * topic + summary needs to be re-evaluated.
  *
  * @param Workflow $workflow
  * @param PostRevision $current Topic revision object that was inserted
  * @return array Contains two arrays, first the references to add a second
  *  the references to remove
  * @throws FlowException
  */
 protected function calculateChangesFromTopic(Workflow $workflow, PostRevision $current)
 {
     if ($current->isFirstRevision()) {
         return array(array(), array());
     }
     $previous = $this->storage->get('PostRevision', $current->getPrevRevisionId());
     if (!$previous) {
         throw new FlowException('Expcted previous revision of ' . $current->getPrevRevisionId()->getAlphadecimal());
     }
     $isHidden = self::isHidden($current);
     $wasHidden = self::isHidden($previous);
     if ($isHidden === $wasHidden) {
         return array(array(), array());
     }
     // re-run
     $revisions = $this->collectTopicRevisions($workflow);
     $added = array();
     $removed = array();
     foreach ($revisions as $revision) {
         list($add, $remove) = $this->calculateChangesFromExisting($workflow, $revision, $current);
         $added = array_merge($added, $add);
         $removed = array_merge($removed, $remove);
     }
     return array($added, $removed);
 }
 /**
  * @param object $row Single row from database
  * @return AbstractRevision|null
  */
 protected function loadFromRevision($row)
 {
     $revTypes = array('header' => 'Flow\\Model\\Header', 'post-summary' => 'Flow\\Model\\PostSummary', 'post' => 'Flow\\Model\\PostRevision');
     if (!isset($revTypes[$row->rev_type])) {
         wfDebugLog('Flow', __METHOD__ . ': Unknown revision type ' . $row->rev_type . ' did not merge ' . UUID::create($row->rev_id)->getAlphadecimal());
         return null;
     }
     return $this->storage->get($revTypes[$row->rev_type], $row->rev_id);
 }
 /**
  * Gets a Workflow object given its ID
  * @param  UUID   $workflowId The Workflow ID to retrieve.
  * @return Workflow           The Workflow.
  */
 protected function getWorkflowById(UUID $workflowId)
 {
     $alpha = $workflowId->getAlphadecimal();
     if (isset($this->workflowCache[$alpha])) {
         return $this->workflowCache[$alpha];
     } else {
         return $this->workflowCache[$alpha] = $this->storage->get('Workflow', $workflowId);
     }
 }
 /**
  * Gets the given object from storage
  *
  * @param  string $type Class name to retrieve
  * @param  UUID   $id   ID of the object to retrieve
  * @return Object|false
  */
 public function get($type, UUID $id)
 {
     return $this->storage->get($type, $id);
 }