protected function getCustomTransactionOldValue(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     switch ($xaction->getTransactionType()) {
         case PhabricatorSpacesNamespaceTransaction::TYPE_NAME:
             $name = $object->getNamespaceName();
             if (!strlen($name)) {
                 return null;
             }
             return $name;
         case PhabricatorSpacesNamespaceTransaction::TYPE_DESCRIPTION:
             if ($this->getIsNewObject()) {
                 return null;
             }
             return $object->getDescription();
         case PhabricatorSpacesNamespaceTransaction::TYPE_ARCHIVE:
             return $object->getIsArchived();
         case PhabricatorSpacesNamespaceTransaction::TYPE_DEFAULT:
             return $object->getIsDefaultNamespace() ? 1 : null;
         case PhabricatorTransactions::TYPE_VIEW_POLICY:
             return $object->getViewPolicy();
         case PhabricatorTransactions::TYPE_EDIT_POLICY:
             return $object->getEditPolicy();
     }
     return parent::getCustomTransactionOldValue($object, $xaction);
 }
 protected function getCustomTransactionOldValue(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     switch ($xaction->getTransactionType()) {
         case PhabricatorTransactions::TYPE_VIEW_POLICY:
             return $object->getViewPolicy();
         case PhabricatorTransactions::TYPE_EDIT_POLICY:
             return $object->getEditPolicy();
         case DifferentialTransaction::TYPE_ACTION:
             return null;
         case DifferentialTransaction::TYPE_INLINE:
             return null;
         case DifferentialTransaction::TYPE_UPDATE:
             if ($this->getIsNewObject()) {
                 return null;
             } else {
                 return $object->getActiveDiff()->getPHID();
             }
     }
     return parent::getCustomTransactionOldValue($object, $xaction);
 }
 private function getTransactionOldValue(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     switch ($xaction->getTransactionType()) {
         case PhabricatorTransactions::TYPE_SUBSCRIBERS:
             return array_values($this->subscribers);
         case PhabricatorTransactions::TYPE_VIEW_POLICY:
             return $object->getViewPolicy();
         case PhabricatorTransactions::TYPE_EDIT_POLICY:
             return $object->getEditPolicy();
         case PhabricatorTransactions::TYPE_JOIN_POLICY:
             return $object->getJoinPolicy();
         case PhabricatorTransactions::TYPE_EDGE:
             $edge_type = $xaction->getMetadataValue('edge:type');
             if (!$edge_type) {
                 throw new Exception("Edge transaction has no 'edge:type'!");
             }
             $old_edges = array();
             if ($object->getPHID()) {
                 $edge_src = $object->getPHID();
                 $old_edges = id(new PhabricatorEdgeQuery())->withSourcePHIDs(array($edge_src))->withEdgeTypes(array($edge_type))->needEdgeData(true)->execute();
                 $old_edges = $old_edges[$edge_src][$edge_type];
             }
             return $old_edges;
         case PhabricatorTransactions::TYPE_CUSTOMFIELD:
             // NOTE: Custom fields have their old value pre-populated when they are
             // built by PhabricatorCustomFieldList.
             return $xaction->getOldValue();
         case PhabricatorTransactions::TYPE_COMMENT:
             return null;
         default:
             return $this->getCustomTransactionOldValue($object, $xaction);
     }
 }
 private function getTransactionOldValue(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     switch ($xaction->getTransactionType()) {
         case PhabricatorTransactions::TYPE_SUBSCRIBERS:
             return array_values($this->subscribers);
         case PhabricatorTransactions::TYPE_VIEW_POLICY:
             return $object->getViewPolicy();
         case PhabricatorTransactions::TYPE_EDIT_POLICY:
             return $object->getEditPolicy();
         case PhabricatorTransactions::TYPE_JOIN_POLICY:
             return $object->getJoinPolicy();
         case PhabricatorTransactions::TYPE_SPACE:
             $space_phid = $object->getSpacePHID();
             if ($space_phid === null) {
                 if ($this->getIsNewObject()) {
                     // In this case, just return `null` so we know this is the initial
                     // transaction and it should be hidden.
                     return null;
                 }
                 $default_space = PhabricatorSpacesNamespaceQuery::getDefaultSpace();
                 if ($default_space) {
                     $space_phid = $default_space->getPHID();
                 }
             }
             return $space_phid;
         case PhabricatorTransactions::TYPE_EDGE:
             $edge_type = $xaction->getMetadataValue('edge:type');
             if (!$edge_type) {
                 throw new Exception(pht("Edge transaction has no '%s'!", 'edge:type'));
             }
             $old_edges = array();
             if ($object->getPHID()) {
                 $edge_src = $object->getPHID();
                 $old_edges = id(new PhabricatorEdgeQuery())->withSourcePHIDs(array($edge_src))->withEdgeTypes(array($edge_type))->needEdgeData(true)->execute();
                 $old_edges = $old_edges[$edge_src][$edge_type];
             }
             return $old_edges;
         case PhabricatorTransactions::TYPE_CUSTOMFIELD:
             // NOTE: Custom fields have their old value pre-populated when they are
             // built by PhabricatorCustomFieldList.
             return $xaction->getOldValue();
         case PhabricatorTransactions::TYPE_COMMENT:
             return null;
         default:
             return $this->getCustomTransactionOldValue($object, $xaction);
     }
 }
 protected function applyFinalEffects(PhabricatorLiskDAO $object, array $xactions)
 {
     $save_content = false;
     foreach ($xactions as $xaction) {
         switch ($xaction->getTransactionType()) {
             case PhrictionTransaction::TYPE_TITLE:
             case PhrictionTransaction::TYPE_CONTENT:
             case PhrictionTransaction::TYPE_DELETE:
             case PhrictionTransaction::TYPE_MOVE_AWAY:
             case PhrictionTransaction::TYPE_MOVE_TO:
                 $save_content = true;
                 break;
             default:
                 break;
         }
     }
     if ($save_content) {
         $content = $this->getNewContent();
         $content->setDocumentID($object->getID());
         $content->save();
         $object->setContentID($content->getID());
         $object->save();
         $object->attachContent($content);
     }
     if ($this->getIsNewObject() && !$this->getSkipAncestorCheck()) {
         // Stub out empty parent documents if they don't exist
         $ancestral_slugs = PhabricatorSlug::getAncestry($object->getSlug());
         if ($ancestral_slugs) {
             $ancestors = id(new PhrictionDocumentQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withSlugs($ancestral_slugs)->needContent(true)->execute();
             $ancestors = mpull($ancestors, null, 'getSlug');
             $stub_type = PhrictionChangeType::CHANGE_STUB;
             foreach ($ancestral_slugs as $slug) {
                 $ancestor_doc = idx($ancestors, $slug);
                 // We check for change type to prevent near-infinite recursion
                 if (!$ancestor_doc && $content->getChangeType() != $stub_type) {
                     $ancestor_doc = PhrictionDocument::initializeNewDocument($this->getActor(), $slug);
                     $stub_xactions = array();
                     $stub_xactions[] = id(new PhrictionTransaction())->setTransactionType(PhrictionTransaction::TYPE_TITLE)->setNewValue(PhabricatorSlug::getDefaultTitle($slug))->setMetadataValue('stub:create:phid', $object->getPHID());
                     $stub_xactions[] = id(new PhrictionTransaction())->setTransactionType(PhrictionTransaction::TYPE_CONTENT)->setNewValue('')->setMetadataValue('stub:create:phid', $object->getPHID());
                     $stub_xactions[] = id(new PhrictionTransaction())->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)->setNewValue($object->getViewPolicy());
                     $stub_xactions[] = id(new PhrictionTransaction())->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)->setNewValue($object->getEditPolicy());
                     $sub_editor = id(new PhrictionTransactionEditor())->setActor($this->getActor())->setContentSource($this->getContentSource())->setContinueOnNoEffect($this->getContinueOnNoEffect())->setSkipAncestorCheck(true)->setDescription(pht('Empty Parent Document'))->applyTransactions($ancestor_doc, $stub_xactions);
                 }
             }
         }
     }
     if ($this->moveAwayDocument !== null) {
         $move_away_xactions = array();
         $move_away_xactions[] = id(new PhrictionTransaction())->setTransactionType(PhrictionTransaction::TYPE_MOVE_AWAY)->setNewValue($object);
         $sub_editor = id(new PhrictionTransactionEditor())->setActor($this->getActor())->setContentSource($this->getContentSource())->setContinueOnNoEffect($this->getContinueOnNoEffect())->setDescription($this->getDescription())->applyTransactions($this->moveAwayDocument, $move_away_xactions);
     }
     // Compute the content diff URI for the publishing phase.
     foreach ($xactions as $xaction) {
         switch ($xaction->getTransactionType()) {
             case PhrictionTransaction::TYPE_CONTENT:
                 $uri = id(new PhutilURI('/phriction/diff/' . $object->getID() . '/'))->alter('l', $this->getOldContent()->getVersion())->alter('r', $this->getNewContent()->getVersion());
                 $this->contentDiffURI = (string) $uri;
                 break 2;
             default:
                 break;
         }
     }
     return $xactions;
 }