@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Phriction - kill the old PhrictionDocumentEditor

Summary:
Ref T4029. Long live PhrictionTransactionEditor...! this means that all existing functionality runs 100% through the modern transactions + editor framework. this diff does a few things in sum

- kills the old editor
- moves conduit-based edits to new editor
- moves stubbing out documents to new editor
- deletes moving of wiki docs for projects functionality... (T4021#59511 is a better bigger battle plan here.)

Test Plan: edited a phriction document via conduit and it worked. created a new phriction document /that/was/deep/ and verified ancestral documents were properly stubbed out. changed a project name and noted no wiki page moves.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin, epriestley

Maniphest Tasks: T4029

Differential Revision: https://secure.phabricator.com/D10792

+79 -440
-2
src/__phutil_library_map__.php
··· 2767 2767 'PhrictionDiffController' => 'applications/phriction/controller/PhrictionDiffController.php', 2768 2768 'PhrictionDocument' => 'applications/phriction/storage/PhrictionDocument.php', 2769 2769 'PhrictionDocumentController' => 'applications/phriction/controller/PhrictionDocumentController.php', 2770 - 'PhrictionDocumentEditor' => 'applications/phriction/editor/PhrictionDocumentEditor.php', 2771 2770 'PhrictionDocumentPHIDType' => 'applications/phriction/phid/PhrictionDocumentPHIDType.php', 2772 2771 'PhrictionDocumentPreviewController' => 'applications/phriction/controller/PhrictionDocumentPreviewController.php', 2773 2772 'PhrictionDocumentQuery' => 'applications/phriction/query/PhrictionDocumentQuery.php', ··· 5979 5978 'PhabricatorDestructibleInterface', 5980 5979 ), 5981 5980 'PhrictionDocumentController' => 'PhrictionController', 5982 - 'PhrictionDocumentEditor' => 'PhabricatorEditor', 5983 5981 'PhrictionDocumentPHIDType' => 'PhabricatorPHIDType', 5984 5982 'PhrictionDocumentPreviewController' => 'PhrictionController', 5985 5983 'PhrictionDocumentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+15 -6
src/applications/phriction/conduit/PhrictionEditConduitAPIMethod.php
··· 34 34 $doc = id(new PhrictionDocumentQuery()) 35 35 ->setViewer($request->getUser()) 36 36 ->withSlugs(array(PhabricatorSlug::normalize($slug))) 37 + ->needContent(true) 37 38 ->requireCapabilities( 38 39 array( 39 40 PhabricatorPolicyCapability::CAN_VIEW, ··· 44 45 throw new Exception(pht('No such document.')); 45 46 } 46 47 47 - $editor = id(PhrictionDocumentEditor::newForSlug($slug)) 48 + $xactions = array(); 49 + $xactions[] = id(new PhrictionTransaction()) 50 + ->setTransactionType(PhrictionTransaction::TYPE_TITLE) 51 + ->setNewValue($request->getValue('title')); 52 + $xactions[] = id(new PhrictionTransaction()) 53 + ->setTransactionType(PhrictionTransaction::TYPE_CONTENT) 54 + ->setNewValue($request->getValue('content')); 55 + 56 + $editor = id(new PhrictionTransactionEditor()) 48 57 ->setActor($request->getUser()) 49 - ->setTitle($request->getValue('title')) 50 - ->setContent($request->getValue('content')) 51 - ->setDescription($request->getvalue('description')) 52 - ->save(); 58 + ->setContentSourceFromConduitRequest($request) 59 + ->setContinueOnNoEffect(true) 60 + ->setDescription($request->getValue('description')) 61 + ->applyTransactions($doc, $xactions); 53 62 54 - return $this->buildDocumentInfoDictionary($editor->getDocument()); 63 + return $this->buildDocumentInfoDictionary($doc); 55 64 } 56 65 57 66 }
-379
src/applications/phriction/editor/PhrictionDocumentEditor.php
··· 1 - <?php 2 - 3 - /** 4 - * Create or update Phriction documents. 5 - */ 6 - final class PhrictionDocumentEditor extends PhabricatorEditor { 7 - 8 - private $document; 9 - private $content; 10 - 11 - private $newTitle; 12 - private $newContent; 13 - private $description; 14 - 15 - // For the Feed Story when moving documents 16 - private $fromDocumentPHID; 17 - 18 - private function __construct() { 19 - // <restricted> 20 - } 21 - 22 - public static function newForSlug($slug) { 23 - $slug = PhabricatorSlug::normalize($slug); 24 - 25 - // TODO: Get rid of this. 26 - $document = id(new PhrictionDocument())->loadOneWhere( 27 - 'slug = %s', 28 - $slug); 29 - $content = null; 30 - 31 - if ($document) { 32 - $content = id(new PhrictionContent())->load($document->getContentID()); 33 - } else { 34 - $document = new PhrictionDocument(); 35 - $document->setSlug($slug); 36 - } 37 - 38 - if (!$content) { 39 - $default_title = PhabricatorSlug::getDefaultTitle($slug); 40 - $content = new PhrictionContent(); 41 - $content->setSlug($slug); 42 - $content->setTitle($default_title); 43 - $content->setContent(''); 44 - } 45 - 46 - $obj = new PhrictionDocumentEditor(); 47 - $obj->document = $document; 48 - $obj->content = $content; 49 - 50 - return $obj; 51 - } 52 - 53 - public function setTitle($title) { 54 - $this->newTitle = $title; 55 - return $this; 56 - } 57 - 58 - public function setContent($content) { 59 - $this->newContent = $content; 60 - return $this; 61 - } 62 - 63 - public function setDescription($description) { 64 - $this->description = $description; 65 - return $this; 66 - } 67 - 68 - public function getDocument() { 69 - return $this->document; 70 - } 71 - 72 - public function moveAway($new_doc_id) { 73 - return $this->execute( 74 - PhrictionChangeType::CHANGE_MOVE_AWAY, true, $new_doc_id); 75 - } 76 - 77 - public function moveHere($old_doc_id, $old_doc_phid) { 78 - $this->fromDocumentPHID = $old_doc_phid; 79 - return $this->execute( 80 - PhrictionChangeType::CHANGE_MOVE_HERE, false, $old_doc_id); 81 - } 82 - 83 - private function execute( 84 - $change_type, $del_new_content = true, $doc_ref = null) { 85 - 86 - $actor = $this->requireActor(); 87 - 88 - $document = $this->document; 89 - $content = $this->content; 90 - 91 - $new_content = $this->buildContentTemplate($document, $content); 92 - $new_content->setChangeType($change_type); 93 - 94 - if ($del_new_content) { 95 - $new_content->setContent(''); 96 - } 97 - 98 - if ($doc_ref) { 99 - $new_content->setChangeRef($doc_ref); 100 - } 101 - 102 - return $this->updateDocument($document, $content, $new_content); 103 - } 104 - 105 - public function delete() { 106 - return $this->execute(PhrictionChangeType::CHANGE_DELETE, true); 107 - } 108 - 109 - public function stub() { 110 - return $this->execute(PhrictionChangeType::CHANGE_STUB, true); 111 - } 112 - 113 - public function save() { 114 - $actor = $this->requireActor(); 115 - 116 - if ($this->newContent === '') { 117 - // If this is an edit which deletes all the content, just treat it as 118 - // a delete. NOTE: null means "don't change the content", not "delete 119 - // the page"! Thus the strict type check. 120 - return $this->delete(); 121 - } 122 - 123 - $document = $this->document; 124 - $content = $this->content; 125 - 126 - $new_content = $this->buildContentTemplate($document, $content); 127 - 128 - return $this->updateDocument($document, $content, $new_content); 129 - } 130 - 131 - private function buildContentTemplate( 132 - PhrictionDocument $document, 133 - PhrictionContent $content) { 134 - 135 - $new_content = new PhrictionContent(); 136 - $new_content->setSlug($document->getSlug()); 137 - $new_content->setAuthorPHID($this->getActor()->getPHID()); 138 - $new_content->setChangeType(PhrictionChangeType::CHANGE_EDIT); 139 - 140 - $new_content->setTitle( 141 - coalesce( 142 - $this->newTitle, 143 - $content->getTitle())); 144 - 145 - $new_content->setContent( 146 - coalesce( 147 - $this->newContent, 148 - $content->getContent())); 149 - 150 - if (strlen($this->description)) { 151 - $new_content->setDescription($this->description); 152 - } 153 - 154 - return $new_content; 155 - } 156 - 157 - private function updateDocument($document, $content, $new_content) { 158 - 159 - $is_new = false; 160 - if (!$document->getID()) { 161 - $is_new = true; 162 - } 163 - 164 - $new_content->setVersion($content->getVersion() + 1); 165 - 166 - $change_type = $new_content->getChangeType(); 167 - switch ($change_type) { 168 - case PhrictionChangeType::CHANGE_EDIT: 169 - $doc_status = PhrictionDocumentStatus::STATUS_EXISTS; 170 - $feed_action = $is_new 171 - ? PhrictionActionConstants::ACTION_CREATE 172 - : PhrictionActionConstants::ACTION_EDIT; 173 - break; 174 - case PhrictionChangeType::CHANGE_DELETE: 175 - $doc_status = PhrictionDocumentStatus::STATUS_DELETED; 176 - $feed_action = PhrictionActionConstants::ACTION_DELETE; 177 - if ($is_new) { 178 - throw new Exception( 179 - "You can not delete a document which doesn't exist yet!"); 180 - } 181 - break; 182 - case PhrictionChangeType::CHANGE_STUB: 183 - $doc_status = PhrictionDocumentStatus::STATUS_STUB; 184 - $feed_action = null; 185 - break; 186 - case PhrictionChangeType::CHANGE_MOVE_AWAY: 187 - $doc_status = PhrictionDocumentStatus::STATUS_MOVED; 188 - $feed_action = null; 189 - break; 190 - case PhrictionChangeType::CHANGE_MOVE_HERE: 191 - $doc_status = PhrictionDocumentStatus::STATUS_EXISTS; 192 - $feed_action = PhrictionActionConstants::ACTION_MOVE_HERE; 193 - break; 194 - default: 195 - throw new Exception( 196 - "Unsupported content change type '{$change_type}'!"); 197 - } 198 - 199 - $document->setStatus($doc_status); 200 - 201 - // TODO: This should be transactional. 202 - 203 - if ($is_new) { 204 - $document->save(); 205 - } 206 - 207 - $new_content->setDocumentID($document->getID()); 208 - $new_content->save(); 209 - 210 - $document->setContentID($new_content->getID()); 211 - $document->save(); 212 - 213 - $document->attachContent($new_content); 214 - 215 - id(new PhabricatorSearchIndexer()) 216 - ->queueDocumentForIndexing($document->getPHID()); 217 - 218 - // Stub out empty parent documents if they don't exist 219 - $ancestral_slugs = PhabricatorSlug::getAncestry($document->getSlug()); 220 - if ($ancestral_slugs) { 221 - $ancestors = id(new PhrictionDocument())->loadAllWhere( 222 - 'slug IN (%Ls)', 223 - $ancestral_slugs); 224 - $ancestors = mpull($ancestors, null, 'getSlug'); 225 - foreach ($ancestral_slugs as $slug) { 226 - // We check for change type to prevent near-infinite recursion 227 - if (!isset($ancestors[$slug]) && 228 - $new_content->getChangeType() != PhrictionChangeType::CHANGE_STUB) { 229 - 230 - id(PhrictionDocumentEditor::newForSlug($slug)) 231 - ->setActor($this->getActor()) 232 - ->setTitle(PhabricatorSlug::getDefaultTitle($slug)) 233 - ->setContent('') 234 - ->setDescription(pht('Empty Parent Document')) 235 - ->stub(); 236 - } 237 - } 238 - } 239 - 240 - $project_phid = null; 241 - $slug = $document->getSlug(); 242 - if (PhrictionDocument::isProjectSlug($slug)) { 243 - $project = id(new PhabricatorProjectQuery()) 244 - ->setViewer($this->requireActor()) 245 - ->withPhrictionSlugs(array( 246 - PhrictionDocument::getProjectSlugIdentifier($slug), 247 - )) 248 - ->executeOne(); 249 - if ($project) { 250 - $project_phid = $project->getPHID(); 251 - } 252 - } 253 - 254 - $related_phids = array( 255 - $document->getPHID(), 256 - $this->getActor()->getPHID(), 257 - ); 258 - 259 - if ($project_phid) { 260 - $related_phids[] = $project_phid; 261 - } 262 - 263 - if ($this->fromDocumentPHID) { 264 - $related_phids[] = $this->fromDocumentPHID; 265 - } 266 - 267 - if ($feed_action) { 268 - $content_str = id(new PhutilUTF8StringTruncator()) 269 - ->setMaximumGlyphs(140) 270 - ->truncateString($new_content->getContent()); 271 - id(new PhabricatorFeedStoryPublisher()) 272 - ->setRelatedPHIDs($related_phids) 273 - ->setStoryAuthorPHID($this->getActor()->getPHID()) 274 - ->setStoryTime(time()) 275 - ->setStoryType(PhabricatorFeedStoryTypeConstants::STORY_PHRICTION) 276 - ->setStoryData( 277 - array( 278 - 'phid' => $document->getPHID(), 279 - 'action' => $feed_action, 280 - 'content' => $content_str, 281 - 'project' => $project_phid, 282 - 'movedFromPHID' => $this->fromDocumentPHID, 283 - )) 284 - ->publish(); 285 - } 286 - 287 - // TODO: Migrate to ApplicationTransactions fast, so we get rid of this code 288 - $subscribers = PhabricatorSubscribersQuery::loadSubscribersForPHID( 289 - $document->getPHID()); 290 - $this->sendMailToSubscribers($subscribers, $content); 291 - 292 - return $this; 293 - } 294 - 295 - private function getChangeTypeDescription($const, $title) { 296 - $map = array( 297 - PhrictionChangeType::CHANGE_EDIT => 298 - pht('Phriction Document %s was edited.', $title), 299 - PhrictionChangeType::CHANGE_DELETE => 300 - pht('Phriction Document %s was deleted.', $title), 301 - PhrictionChangeType::CHANGE_MOVE_HERE => 302 - pht('Phriction Document %s was moved here.', $title), 303 - PhrictionChangeType::CHANGE_MOVE_AWAY => 304 - pht('Phriction Document %s was moved away.', $title), 305 - PhrictionChangeType::CHANGE_STUB => 306 - pht('Phriction Document %s was created through child.', $title), 307 - ); 308 - return idx($map, $const, pht('Something magical occurred.')); 309 - } 310 - 311 - private function sendMailToSubscribers(array $subscribers, $old_content) { 312 - if (!$subscribers) { 313 - return; 314 - } 315 - 316 - $author_phid = $this->getActor()->getPHID(); 317 - $document = $this->document; 318 - $content = $document->getContent(); 319 - $slug_uri = PhrictionDocument::getSlugURI($document->getSlug()); 320 - $diff_uri = new PhutilURI('/phriction/diff/'.$document->getID().'/'); 321 - $prod_uri = PhabricatorEnv::getProductionURI(''); 322 - 323 - $vs_head = $diff_uri 324 - ->alter('l', $old_content->getVersion()) 325 - ->alter('r', $content->getVersion()); 326 - 327 - $old_title = $old_content->getTitle(); 328 - $title = $content->getTitle(); 329 - $name = $this->getChangeTypeDescription($content->getChangeType(), $title); 330 - $action = PhrictionChangeType::getChangeTypeLabel( 331 - $content->getChangeType()); 332 - 333 - $body = array($name); 334 - // Content may have changed, you never know 335 - if ($content->getChangeType() == PhrictionChangeType::CHANGE_EDIT) { 336 - 337 - if ($old_title != $title) { 338 - $body[] = pht('Title was changed from "%s" to "%s"', 339 - $old_title, $title); 340 - } 341 - 342 - $body[] = pht("Link to new version:\n%s", 343 - $prod_uri.$slug_uri.'?v='.$content->getVersion()); 344 - 345 - $body[] = pht("Link to diff:\n%s", $prod_uri.$vs_head); 346 - } else if ($content->getChangeType() == 347 - PhrictionChangeType::CHANGE_MOVE_AWAY) { 348 - 349 - $target_document = id(new PhrictionDocument()) 350 - ->load($content->getChangeRef()); 351 - $slug_uri = PhrictionDocument::getSlugURI($target_document->getSlug()); 352 - $body[] = pht("Link to destination document:\n%s", $prod_uri.$slug_uri); 353 - } 354 - 355 - $body = implode("\n\n", $body); 356 - 357 - $subject_prefix = $this->getMailSubjectPrefix(); 358 - 359 - $mail = new PhabricatorMetaMTAMail(); 360 - $mail->setSubject($name) 361 - ->setSubjectPrefix($subject_prefix) 362 - ->setVarySubjectPrefix('['.$action.']') 363 - ->addHeader('Thread-Topic', $name) 364 - ->setFrom($author_phid) 365 - ->addTos($subscribers) 366 - ->setBody($body) 367 - ->setRelatedPHID($document->getPHID()) 368 - ->setIsBulk(true); 369 - 370 - $mail->saveAndSend(); 371 - } 372 - 373 - /* --( For less copy-pasting when switching to ApplicationTransactions )--- */ 374 - 375 - protected function getMailSubjectPrefix() { 376 - return PhabricatorEnv::getEnvConfig('metamta.phriction.subject-prefix'); 377 - } 378 - 379 - }
+38 -14
src/applications/phriction/editor/PhrictionTransactionEditor.php
··· 7 7 private $oldContent; 8 8 private $newContent; 9 9 private $moveAwayDocument; 10 + private $skipAncestorCheck; 10 11 11 12 public function setDescription($description) { 12 13 $this->description = $description; ··· 33 34 34 35 private function getNewContent() { 35 36 return $this->newContent; 37 + } 38 + 39 + public function setSkipAncestorCheck($bool) { 40 + $this->skipAncestorCheck = $bool; 41 + return $this; 42 + } 43 + 44 + public function getSkipAncestorCheck() { 45 + return $this->skipAncestorCheck; 36 46 } 37 47 38 48 public function getEditorApplicationClass() { ··· 216 226 $object->attachContent($content); 217 227 } 218 228 219 - if ($this->getIsNewObject()) { 229 + if ($this->getIsNewObject() && !$this->getSkipAncestorCheck()) { 220 230 // Stub out empty parent documents if they don't exist 221 231 $ancestral_slugs = PhabricatorSlug::getAncestry($object->getSlug()); 222 232 if ($ancestral_slugs) { 223 - $ancestors = id(new PhrictionDocument())->loadAllWhere( 224 - 'slug IN (%Ls)', 225 - $ancestral_slugs); 233 + $ancestors = id(new PhrictionDocumentQuery()) 234 + ->setViewer(PhabricatorUser::getOmnipotentUser()) 235 + ->withSlugs($ancestral_slugs) 236 + ->needContent(true) 237 + ->execute(); 226 238 $ancestors = mpull($ancestors, null, 'getSlug'); 239 + $stub_type = PhrictionChangeType::CHANGE_STUB; 227 240 foreach ($ancestral_slugs as $slug) { 241 + $ancestor_doc = idx($ancestors, $slug); 228 242 // We check for change type to prevent near-infinite recursion 229 - if (!isset($ancestors[$slug]) && 230 - $content->getChangeType() != 231 - PhrictionChangeType::CHANGE_STUB) { 232 - id(PhrictionDocumentEditor::newForSlug($slug)) 233 - ->setActor($this->getActor()) 234 - ->setTitle(PhabricatorSlug::getDefaultTitle($slug)) 235 - ->setContent('') 236 - ->setDescription(pht('Empty Parent Document')) 237 - ->stub(); 238 - } 243 + if (!$ancestor_doc && $content->getChangeType() != $stub_type) { 244 + $ancestor_doc = PhrictionDocument::initializeNewDocument( 245 + $this->getActor(), 246 + $slug); 247 + $stub_xactions = array(); 248 + $stub_xactions[] = id(new PhrictionTransaction()) 249 + ->setTransactionType(PhrictionTransaction::TYPE_TITLE) 250 + ->setNewValue(PhabricatorSlug::getDefaultTitle($slug)) 251 + ->setMetadataValue('stub:create:phid', $object->getPHID()); 252 + $stub_xactions[] = id(new PhrictionTransaction()) 253 + ->setTransactionType(PhrictionTransaction::TYPE_CONTENT) 254 + ->setNewValue(''); 255 + $sub_editor = id(new PhrictionTransactionEditor()) 256 + ->setActor($this->getActor()) 257 + ->setContentSource($this->getContentSource()) 258 + ->setContinueOnNoEffect($this->getContinueOnNoEffect()) 259 + ->setSkipAncestorCheck(true) 260 + ->setDescription(pht('Empty Parent Document')) 261 + ->applyTransactions($ancestor_doc, $stub_xactions); 262 + } 239 263 } 240 264 } 241 265 }
+25 -4
src/applications/phriction/storage/PhrictionTransaction.php
··· 33 33 case self::TYPE_MOVE_AWAY: 34 34 $phids[] = $new['phid']; 35 35 break; 36 + case self::TYPE_TITLE: 37 + if ($this->getMetadataValue('stub:create:phid')) { 38 + $phids[] = $this->getMetadataValue('stub:create:phid'); 39 + } 40 + break; 36 41 } 37 42 38 43 ··· 70 75 case self::TYPE_MOVE_TO: 71 76 case self::TYPE_MOVE_AWAY: 72 77 return true; 78 + case self::TYPE_TITLE: 79 + return $this->getMetadataValue('stub:create:phid', false); 73 80 } 74 81 return parent::shouldHideForMail($xactions); 75 82 } ··· 79 86 case self::TYPE_MOVE_TO: 80 87 case self::TYPE_MOVE_AWAY: 81 88 return true; 89 + case self::TYPE_TITLE: 90 + return $this->getMetadataValue('stub:create:phid', false); 82 91 } 83 92 return parent::shouldHideForFeed(); 84 93 } ··· 106 115 switch ($this->getTransactionType()) { 107 116 case self::TYPE_TITLE: 108 117 if ($old === null) { 109 - return pht('Created'); 118 + if ($this->getMetadataValue('stub:create:phid')) { 119 + return pht('Stubbed'); 120 + } else { 121 + return pht('Created'); 122 + } 110 123 } 111 124 112 125 return pht('Retitled'); ··· 156 169 switch ($this->getTransactionType()) { 157 170 case self::TYPE_TITLE: 158 171 if ($old === null) { 159 - return pht( 160 - '%s created this document.', 161 - $this->renderHandleLink($author_phid)); 172 + if ($this->getMetadataValue('stub:create:phid')) { 173 + return pht( 174 + '%s stubbed out this document when creating %s.', 175 + $this->renderHandleLink($author_phid), 176 + $this->renderHandleLink( 177 + $this->getMetadataValue('stub:create:phid'))); 178 + } else { 179 + return pht( 180 + '%s created this document.', 181 + $this->renderHandleLink($author_phid)); 182 + } 162 183 } 163 184 return pht( 164 185 '%s changed the title from "%s" to "%s".',
+1 -35
src/applications/project/editor/PhabricatorProjectTransactionEditor.php
··· 127 127 switch ($xaction->getTransactionType()) { 128 128 case PhabricatorProjectTransaction::TYPE_NAME: 129 129 // First, remove the old and new slugs. Removing the old slug is 130 - // important when changing the project's capitalization or puctuation. 130 + // important when changing the project's capitalization or punctuation. 131 131 // Removing the new slug is important when changing the project's name 132 132 // so that one of its secondary slugs is now the primary slug. 133 133 if ($old !== null) { ··· 140 140 ->setProjectPHID($object->getPHID()) 141 141 ->save(); 142 142 143 - // TODO -- delete all of the below once we sever automagical project 144 - // to phriction stuff 145 - if ($xaction->getOldValue() === null) { 146 - // Project was just created, we don't need to move anything. 147 - return; 148 - } 149 - 150 - $clone_object = clone $object; 151 - $clone_object->setPhrictionSlug($xaction->getOldValue()); 152 - $old_slug = $clone_object->getFullPhrictionSlug(); 153 - 154 - $old_document = id(new PhrictionDocument()) 155 - ->loadOneWhere('slug = %s', $old_slug); 156 - if ($old_document && $old_document->getStatus() == 157 - PhrictionDocumentStatus::STATUS_EXISTS) { 158 - $content = id(new PhrictionContent()) 159 - ->load($old_document->getContentID()); 160 - $from_editor = id(PhrictionDocumentEditor::newForSlug($old_slug)) 161 - ->setActor($this->getActor()) 162 - ->setTitle($content->getTitle()) 163 - ->setContent($content->getContent()) 164 - ->setDescription($content->getDescription()); 165 - 166 - $target_editor = id(PhrictionDocumentEditor::newForSlug( 167 - $object->getFullPhrictionSlug())) 168 - ->setActor($this->getActor()) 169 - ->setTitle($content->getTitle()) 170 - ->setContent($content->getContent()) 171 - ->setDescription($content->getDescription()) 172 - ->moveHere($old_document->getID(), $old_document->getPHID()); 173 - 174 - $target_document = $target_editor->getDocument(); 175 - $from_editor->moveAway($target_document->getID()); 176 - } 177 143 return; 178 144 case PhabricatorProjectTransaction::TYPE_SLUGS: 179 145 $old = $xaction->getOldValue();