[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class PhrictionTransactionEditor 4 extends PhabricatorApplicationTransactionEditor { 5 6 private $description; 7 private $oldContent; 8 private $newContent; 9 private $moveAwayDocument; 10 private $skipAncestorCheck; 11 private $contentVersion; 12 private $processContentVersionError = true; 13 private $heraldEmailPHIDs = array(); 14 15 public function setDescription($description) { 16 $this->description = $description; 17 return $this; 18 } 19 20 private function getDescription() { 21 return $this->description; 22 } 23 24 private function setOldContent(PhrictionContent $content) { 25 $this->oldContent = $content; 26 return $this; 27 } 28 29 private function getOldContent() { 30 return $this->oldContent; 31 } 32 33 private function setNewContent(PhrictionContent $content) { 34 $this->newContent = $content; 35 return $this; 36 } 37 38 private function getNewContent() { 39 return $this->newContent; 40 } 41 42 public function setSkipAncestorCheck($bool) { 43 $this->skipAncestorCheck = $bool; 44 return $this; 45 } 46 47 public function getSkipAncestorCheck() { 48 return $this->skipAncestorCheck; 49 } 50 51 public function setContentVersion($version) { 52 $this->contentVersion = $version; 53 return $this; 54 } 55 56 public function getContentVersion() { 57 return $this->contentVersion; 58 } 59 60 public function setProcessContentVersionError($process) { 61 $this->processContentVersionError = $process; 62 return $this; 63 } 64 65 public function getProcessContentVersionError() { 66 return $this->processContentVersionError; 67 } 68 69 public function getEditorApplicationClass() { 70 return 'PhabricatorPhrictionApplication'; 71 } 72 73 public function getEditorObjectsDescription() { 74 return pht('Phriction Documents'); 75 } 76 77 public function getTransactionTypes() { 78 $types = parent::getTransactionTypes(); 79 80 $types[] = PhabricatorTransactions::TYPE_COMMENT; 81 $types[] = PhrictionTransaction::TYPE_TITLE; 82 $types[] = PhrictionTransaction::TYPE_CONTENT; 83 $types[] = PhrictionTransaction::TYPE_DELETE; 84 $types[] = PhrictionTransaction::TYPE_MOVE_TO; 85 $types[] = PhrictionTransaction::TYPE_MOVE_AWAY; 86 87 $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; 88 $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; 89 90 return $types; 91 } 92 93 protected function getCustomTransactionOldValue( 94 PhabricatorLiskDAO $object, 95 PhabricatorApplicationTransaction $xaction) { 96 97 switch ($xaction->getTransactionType()) { 98 case PhrictionTransaction::TYPE_TITLE: 99 if ($this->getIsNewObject()) { 100 return null; 101 } 102 return $this->getOldContent()->getTitle(); 103 case PhrictionTransaction::TYPE_CONTENT: 104 if ($this->getIsNewObject()) { 105 return null; 106 } 107 return $this->getOldContent()->getContent(); 108 case PhrictionTransaction::TYPE_DELETE: 109 case PhrictionTransaction::TYPE_MOVE_TO: 110 case PhrictionTransaction::TYPE_MOVE_AWAY: 111 return null; 112 } 113 } 114 115 protected function getCustomTransactionNewValue( 116 PhabricatorLiskDAO $object, 117 PhabricatorApplicationTransaction $xaction) { 118 119 switch ($xaction->getTransactionType()) { 120 case PhrictionTransaction::TYPE_TITLE: 121 case PhrictionTransaction::TYPE_CONTENT: 122 case PhrictionTransaction::TYPE_DELETE: 123 return $xaction->getNewValue(); 124 case PhrictionTransaction::TYPE_MOVE_TO: 125 $document = $xaction->getNewValue(); 126 // grab the real object now for the sub-editor to come 127 $this->moveAwayDocument = $document; 128 $dict = array( 129 'id' => $document->getID(), 130 'phid' => $document->getPHID(), 131 'content' => $document->getContent()->getContent(),); 132 return $dict; 133 case PhrictionTransaction::TYPE_MOVE_AWAY: 134 $document = $xaction->getNewValue(); 135 $dict = array( 136 'id' => $document->getID(), 137 'phid' => $document->getPHID(), 138 'content' => $document->getContent()->getContent(),); 139 return $dict; 140 } 141 } 142 143 protected function shouldApplyInitialEffects( 144 PhabricatorLiskDAO $object, 145 array $xactions) { 146 147 foreach ($xactions as $xaction) { 148 switch ($xaction->getTransactionType()) { 149 case PhrictionTransaction::TYPE_TITLE: 150 case PhrictionTransaction::TYPE_CONTENT: 151 case PhrictionTransaction::TYPE_DELETE: 152 case PhrictionTransaction::TYPE_MOVE_TO: 153 case PhrictionTransaction::TYPE_MOVE_AWAY: 154 return true; 155 } 156 } 157 return parent::shouldApplyInitialEffects($object, $xactions); 158 } 159 160 protected function applyInitialEffects( 161 PhabricatorLiskDAO $object, 162 array $xactions) { 163 164 $this->setOldContent($object->getContent()); 165 $this->setNewContent($this->buildNewContentTemplate($object)); 166 } 167 168 protected function applyCustomInternalTransaction( 169 PhabricatorLiskDAO $object, 170 PhabricatorApplicationTransaction $xaction) { 171 172 switch ($xaction->getTransactionType()) { 173 case PhrictionTransaction::TYPE_TITLE: 174 case PhrictionTransaction::TYPE_CONTENT: 175 case PhrictionTransaction::TYPE_MOVE_TO: 176 $object->setStatus(PhrictionDocumentStatus::STATUS_EXISTS); 177 return; 178 case PhrictionTransaction::TYPE_MOVE_AWAY: 179 $object->setStatus(PhrictionDocumentStatus::STATUS_MOVED); 180 return; 181 case PhrictionTransaction::TYPE_DELETE: 182 $object->setStatus(PhrictionDocumentStatus::STATUS_DELETED); 183 return; 184 } 185 } 186 187 protected function expandTransaction( 188 PhabricatorLiskDAO $object, 189 PhabricatorApplicationTransaction $xaction) { 190 191 $xactions = parent::expandTransaction($object, $xaction); 192 switch ($xaction->getTransactionType()) { 193 case PhrictionTransaction::TYPE_CONTENT: 194 if ($this->getIsNewObject()) { 195 break; 196 } 197 $content = $xaction->getNewValue(); 198 if ($content === '') { 199 $xactions[] = id(new PhrictionTransaction()) 200 ->setTransactionType(PhrictionTransaction::TYPE_DELETE) 201 ->setNewValue(true); 202 } 203 break; 204 case PhrictionTransaction::TYPE_MOVE_TO: 205 $document = $xaction->getNewValue(); 206 $xactions[] = id(new PhrictionTransaction()) 207 ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY) 208 ->setNewValue($document->getViewPolicy()); 209 $xactions[] = id(new PhrictionTransaction()) 210 ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY) 211 ->setNewValue($document->getEditPolicy()); 212 break; 213 default: 214 break; 215 216 } 217 218 return $xactions; 219 } 220 221 protected function applyCustomExternalTransaction( 222 PhabricatorLiskDAO $object, 223 PhabricatorApplicationTransaction $xaction) { 224 225 switch ($xaction->getTransactionType()) { 226 case PhrictionTransaction::TYPE_TITLE: 227 $this->getNewContent()->setTitle($xaction->getNewValue()); 228 break; 229 case PhrictionTransaction::TYPE_CONTENT: 230 $this->getNewContent()->setContent($xaction->getNewValue()); 231 break; 232 case PhrictionTransaction::TYPE_DELETE: 233 $this->getNewContent()->setContent(''); 234 $this->getNewContent()->setChangeType( 235 PhrictionChangeType::CHANGE_DELETE); 236 break; 237 case PhrictionTransaction::TYPE_MOVE_TO: 238 $dict = $xaction->getNewValue(); 239 $this->getNewContent()->setContent($dict['content']); 240 $this->getNewContent()->setChangeType( 241 PhrictionChangeType::CHANGE_MOVE_HERE); 242 $this->getNewContent()->setChangeRef($dict['id']); 243 break; 244 case PhrictionTransaction::TYPE_MOVE_AWAY: 245 $dict = $xaction->getNewValue(); 246 $this->getNewContent()->setContent(''); 247 $this->getNewContent()->setChangeType( 248 PhrictionChangeType::CHANGE_MOVE_AWAY); 249 $this->getNewContent()->setChangeRef($dict['id']); 250 break; 251 default: 252 break; 253 } 254 } 255 256 protected function applyFinalEffects( 257 PhabricatorLiskDAO $object, 258 array $xactions) { 259 260 $save_content = false; 261 foreach ($xactions as $xaction) { 262 switch ($xaction->getTransactionType()) { 263 case PhrictionTransaction::TYPE_TITLE: 264 case PhrictionTransaction::TYPE_CONTENT: 265 case PhrictionTransaction::TYPE_DELETE: 266 case PhrictionTransaction::TYPE_MOVE_AWAY: 267 case PhrictionTransaction::TYPE_MOVE_TO: 268 $save_content = true; 269 break; 270 default: 271 break; 272 } 273 } 274 275 if ($save_content) { 276 $content = $this->getNewContent(); 277 $content->setDocumentID($object->getID()); 278 $content->save(); 279 280 $object->setContentID($content->getID()); 281 $object->save(); 282 $object->attachContent($content); 283 } 284 285 if ($this->getIsNewObject() && !$this->getSkipAncestorCheck()) { 286 // Stub out empty parent documents if they don't exist 287 $ancestral_slugs = PhabricatorSlug::getAncestry($object->getSlug()); 288 if ($ancestral_slugs) { 289 $ancestors = id(new PhrictionDocumentQuery()) 290 ->setViewer(PhabricatorUser::getOmnipotentUser()) 291 ->withSlugs($ancestral_slugs) 292 ->needContent(true) 293 ->execute(); 294 $ancestors = mpull($ancestors, null, 'getSlug'); 295 $stub_type = PhrictionChangeType::CHANGE_STUB; 296 foreach ($ancestral_slugs as $slug) { 297 $ancestor_doc = idx($ancestors, $slug); 298 // We check for change type to prevent near-infinite recursion 299 if (!$ancestor_doc && $content->getChangeType() != $stub_type) { 300 $ancestor_doc = PhrictionDocument::initializeNewDocument( 301 $this->getActor(), 302 $slug); 303 $stub_xactions = array(); 304 $stub_xactions[] = id(new PhrictionTransaction()) 305 ->setTransactionType(PhrictionTransaction::TYPE_TITLE) 306 ->setNewValue(PhabricatorSlug::getDefaultTitle($slug)) 307 ->setMetadataValue('stub:create:phid', $object->getPHID()); 308 $stub_xactions[] = id(new PhrictionTransaction()) 309 ->setTransactionType(PhrictionTransaction::TYPE_CONTENT) 310 ->setNewValue('') 311 ->setMetadataValue('stub:create:phid', $object->getPHID()); 312 $stub_xactions[] = id(new PhrictionTransaction()) 313 ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY) 314 ->setNewValue($object->getViewPolicy()); 315 $stub_xactions[] = id(new PhrictionTransaction()) 316 ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY) 317 ->setNewValue($object->getEditPolicy()); 318 $sub_editor = id(new PhrictionTransactionEditor()) 319 ->setActor($this->getActor()) 320 ->setContentSource($this->getContentSource()) 321 ->setContinueOnNoEffect($this->getContinueOnNoEffect()) 322 ->setSkipAncestorCheck(true) 323 ->setDescription(pht('Empty Parent Document')) 324 ->applyTransactions($ancestor_doc, $stub_xactions); 325 } 326 } 327 } 328 } 329 330 if ($this->moveAwayDocument !== null) { 331 $move_away_xactions = array(); 332 $move_away_xactions[] = id(new PhrictionTransaction()) 333 ->setTransactionType(PhrictionTransaction::TYPE_MOVE_AWAY) 334 ->setNewValue($object); 335 $sub_editor = id(new PhrictionTransactionEditor()) 336 ->setActor($this->getActor()) 337 ->setContentSource($this->getContentSource()) 338 ->setContinueOnNoEffect($this->getContinueOnNoEffect()) 339 ->setDescription($this->getDescription()) 340 ->applyTransactions($this->moveAwayDocument, $move_away_xactions); 341 } 342 343 return $xactions; 344 } 345 346 protected function shouldSendMail( 347 PhabricatorLiskDAO $object, 348 array $xactions) { 349 return true; 350 } 351 352 protected function getMailSubjectPrefix() { 353 return '[Phriction]'; 354 } 355 356 protected function getMailTo(PhabricatorLiskDAO $object) { 357 return array( 358 $object->getContent()->getAuthorPHID(), 359 $this->getActingAsPHID(), 360 ); 361 } 362 363 protected function getMailCC(PhabricatorLiskDAO $object) { 364 $phids = array(); 365 366 foreach ($this->heraldEmailPHIDs as $phid) { 367 $phids[] = $phid; 368 } 369 370 return $phids; 371 } 372 373 public function getMailTagsMap() { 374 return array( 375 PhrictionTransaction::MAILTAG_TITLE => 376 pht("A document's title changes."), 377 PhrictionTransaction::MAILTAG_CONTENT => 378 pht("A document's content changes."), 379 PhrictionTransaction::MAILTAG_DELETE => 380 pht('A document is deleted.'), 381 ); 382 } 383 384 protected function buildReplyHandler(PhabricatorLiskDAO $object) { 385 return id(new PhrictionReplyHandler()) 386 ->setMailReceiver($object); 387 } 388 389 protected function buildMailTemplate(PhabricatorLiskDAO $object) { 390 $id = $object->getID(); 391 $title = $object->getContent()->getTitle(); 392 393 return id(new PhabricatorMetaMTAMail()) 394 ->setSubject($title) 395 ->addHeader('Thread-Topic', $object->getPHID()); 396 } 397 398 protected function buildMailBody( 399 PhabricatorLiskDAO $object, 400 array $xactions) { 401 402 $body = parent::buildMailBody($object, $xactions); 403 404 if ($this->getIsNewObject()) { 405 $body->addTextSection( 406 pht('DOCUMENT CONTENT'), 407 $object->getContent()->getContent()); 408 } else { 409 410 foreach ($xactions as $xaction) { 411 switch ($xaction->getTransactionType()) { 412 case PhrictionTransaction::TYPE_CONTENT: 413 $diff_uri = id(new PhutilURI( 414 '/phriction/diff/'.$object->getID().'/')) 415 ->alter('l', $this->getOldContent()->getVersion()) 416 ->alter('r', $this->getNewContent()->getVersion()); 417 $body->addLinkSection( 418 pht('DOCUMENT DIFF'), 419 PhabricatorEnv::getProductionURI($diff_uri)); 420 break 2; 421 default: 422 break; 423 } 424 } 425 426 } 427 428 $body->addLinkSection( 429 pht('DOCUMENT DETAIL'), 430 PhabricatorEnv::getProductionURI( 431 PhrictionDocument::getSlugURI($object->getSlug()))); 432 433 return $body; 434 } 435 436 protected function shouldPublishFeedStory( 437 PhabricatorLiskDAO $object, 438 array $xactions) { 439 return $this->shouldSendMail($object, $xactions); 440 } 441 442 protected function getFeedRelatedPHIDs( 443 PhabricatorLiskDAO $object, 444 array $xactions) { 445 446 $phids = parent::getFeedRelatedPHIDs($object, $xactions); 447 448 foreach ($xactions as $xaction) { 449 switch ($xaction->getTransactionType()) { 450 case PhrictionTransaction::TYPE_MOVE_TO: 451 $dict = $xaction->getNewValue(); 452 $phids[] = $dict['phid']; 453 break; 454 } 455 } 456 457 return $phids; 458 } 459 460 protected function validateTransaction( 461 PhabricatorLiskDAO $object, 462 $type, 463 array $xactions) { 464 465 $errors = parent::validateTransaction($object, $type, $xactions); 466 467 foreach ($xactions as $xaction) { 468 switch ($type) { 469 case PhrictionTransaction::TYPE_TITLE: 470 $title = $object->getContent()->getTitle(); 471 $missing = $this->validateIsEmptyTextField( 472 $title, 473 $xactions); 474 475 if ($missing) { 476 $error = new PhabricatorApplicationTransactionValidationError( 477 $type, 478 pht('Required'), 479 pht('Document title is required.'), 480 nonempty(last($xactions), null)); 481 482 $error->setIsMissingFieldError(true); 483 $errors[] = $error; 484 } else if ($this->getProcessContentVersionError()) { 485 $error = $this->validateContentVersion($object, $type, $xaction); 486 if ($error) { 487 $this->setProcessContentVersionError(false); 488 $errors[] = $error; 489 } 490 } 491 break; 492 493 case PhrictionTransaction::TYPE_CONTENT: 494 if ($xaction->getMetadataValue('stub:create:phid')) { 495 continue; 496 } 497 498 $missing = false; 499 if ($this->getIsNewObject()) { 500 $content = $object->getContent()->getContent(); 501 $missing = $this->validateIsEmptyTextField( 502 $content, 503 $xactions); 504 } 505 506 if ($missing) { 507 $error = new PhabricatorApplicationTransactionValidationError( 508 $type, 509 pht('Required'), 510 pht('Document content is required.'), 511 nonempty(last($xactions), null)); 512 513 $error->setIsMissingFieldError(true); 514 $errors[] = $error; 515 } else if ($this->getProcessContentVersionError()) { 516 $error = $this->validateContentVersion($object, $type, $xaction); 517 if ($error) { 518 $this->setProcessContentVersionError(false); 519 $errors[] = $error; 520 } 521 } 522 break; 523 524 case PhrictionTransaction::TYPE_MOVE_TO: 525 $source_document = $xaction->getNewValue(); 526 switch ($source_document->getStatus()) { 527 case PhrictionDocumentStatus::STATUS_DELETED: 528 $e_text = pht('A deleted document can not be moved.'); 529 break; 530 case PhrictionDocumentStatus::STATUS_MOVED: 531 $e_text = pht('A moved document can not be moved again.'); 532 break; 533 case PhrictionDocumentStatus::STATUS_STUB: 534 $e_text = pht('A stub document can not be moved.'); 535 break; 536 default: 537 $e_text = null; 538 break; 539 } 540 541 if ($e_text) { 542 $error = new PhabricatorApplicationTransactionValidationError( 543 $type, 544 pht('Can not move document.'), 545 $e_text, 546 $xaction); 547 $errors[] = $error; 548 } 549 550 // NOTE: We use the ominpotent user because we can't let users 551 // overwrite documents even if they can't see them. 552 $target_document = id(new PhrictionDocumentQuery()) 553 ->setViewer(PhabricatorUser::getOmnipotentUser()) 554 ->withSlugs(array($object->getSlug())) 555 ->needContent(true) 556 ->executeOne(); 557 558 // Prevent overwrites and no-op moves. 559 $exists = PhrictionDocumentStatus::STATUS_EXISTS; 560 if ($target_document) { 561 if ($target_document->getSlug() == $source_document->getSlug()) { 562 $message = pht( 563 'You can not move a document to its existing location. '. 564 'Choose a different location to move the document to.'); 565 } else if ($target_document->getStatus() == $exists) { 566 $message = pht( 567 'You can not move this document there, because it would '. 568 'overwrite an existing document which is already at that '. 569 'location. Move or delete the existing document first.'); 570 } 571 572 $error = new PhabricatorApplicationTransactionValidationError( 573 $type, 574 pht('Invalid'), 575 $message, 576 $xaction); 577 $errors[] = $error; 578 } 579 break; 580 581 case PhrictionTransaction::TYPE_DELETE: 582 switch ($object->getStatus()) { 583 case PhrictionDocumentStatus::STATUS_DELETED: 584 $e_text = pht('An already deleted document can not be deleted.'); 585 break; 586 case PhrictionDocumentStatus::STATUS_MOVED: 587 $e_text = pht('A moved document can not be deleted.'); 588 break; 589 case PhrictionDocumentStatus::STATUS_STUB: 590 $e_text = pht('A stub document can not be deleted.'); 591 break; 592 default: 593 break 2; 594 } 595 596 $error = new PhabricatorApplicationTransactionValidationError( 597 $type, 598 pht('Can not delete document.'), 599 $e_text, 600 $xaction); 601 $errors[] = $error; 602 break; 603 } 604 } 605 606 return $errors; 607 } 608 609 private function validateContentVersion( 610 PhabricatorLiskDAO $object, 611 $type, 612 PhabricatorApplicationTransaction $xaction) { 613 614 $error = null; 615 if ($this->getContentVersion() && 616 ($object->getContent()->getVersion() != $this->getContentVersion())) { 617 $error = new PhabricatorApplicationTransactionValidationError( 618 $type, 619 pht('Edit Conflict'), 620 pht( 621 'Another user made changes to this document after you began '. 622 'editing it. Do you want to overwrite their changes? '. 623 '(If you choose to overwrite their changes, you should review '. 624 'the document edit history to see what you overwrote, and '. 625 'then make another edit to merge the changes if necessary.)'), 626 $xaction); 627 } 628 return $error; 629 } 630 protected function requireCapabilities( 631 PhabricatorLiskDAO $object, 632 PhabricatorApplicationTransaction $xaction) { 633 634 /* 635 * New objects have a special case. If a user can't see 636 * x/y 637 * then definitely don't let them make some 638 * x/y/z 639 * We need to load the direct parent to handle this case. 640 */ 641 if ($this->getIsNewObject()) { 642 $actor = $this->requireActor(); 643 $parent_doc = null; 644 $ancestral_slugs = PhabricatorSlug::getAncestry($object->getSlug()); 645 // No ancestral slugs is "/"; the first person gets to play with "/". 646 if ($ancestral_slugs) { 647 $parent = end($ancestral_slugs); 648 $parent_doc = id(new PhrictionDocumentQuery()) 649 ->setViewer($actor) 650 ->withSlugs(array($parent)) 651 ->executeOne(); 652 // If the $actor can't see the $parent_doc then they can't create 653 // the child $object; throw a policy exception. 654 if (!$parent_doc) { 655 id(new PhabricatorPolicyFilter()) 656 ->setViewer($actor) 657 ->raisePolicyExceptions(true) 658 ->rejectObject( 659 $object, 660 $object->getEditPolicy(), 661 PhabricatorPolicyCapability::CAN_EDIT); 662 } 663 664 // If the $actor can't edit the $parent_doc then they can't create 665 // the child $object; throw a policy exception. 666 if (!PhabricatorPolicyFilter::hasCapability( 667 $actor, 668 $parent_doc, 669 PhabricatorPolicyCapability::CAN_EDIT)) { 670 id(new PhabricatorPolicyFilter()) 671 ->setViewer($actor) 672 ->raisePolicyExceptions(true) 673 ->rejectObject( 674 $object, 675 $object->getEditPolicy(), 676 PhabricatorPolicyCapability::CAN_EDIT); 677 } 678 } 679 } 680 return parent::requireCapabilities($object, $xaction); 681 } 682 683 protected function supportsSearch() { 684 return true; 685 } 686 687 protected function shouldApplyHeraldRules( 688 PhabricatorLiskDAO $object, 689 array $xactions) { 690 return true; 691 } 692 693 protected function buildHeraldAdapter( 694 PhabricatorLiskDAO $object, 695 array $xactions) { 696 697 return id(new PhrictionDocumentHeraldAdapter()) 698 ->setDocument($object); 699 } 700 701 protected function didApplyHeraldRules( 702 PhabricatorLiskDAO $object, 703 HeraldAdapter $adapter, 704 HeraldTranscript $transcript) { 705 706 $xactions = array(); 707 708 $cc_phids = $adapter->getCcPHIDs(); 709 if ($cc_phids) { 710 $value = array_fuse($cc_phids); 711 $xactions[] = id(new PhrictionTransaction()) 712 ->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS) 713 ->setNewValue(array('+' => $value)); 714 } 715 716 $this->heraldEmailPHIDs = $adapter->getEmailPHIDs(); 717 718 return $xactions; 719 } 720 721 private function buildNewContentTemplate( 722 PhrictionDocument $document) { 723 724 $new_content = id(new PhrictionContent()) 725 ->setSlug($document->getSlug()) 726 ->setAuthorPHID($this->getActor()->getPHID()) 727 ->setChangeType(PhrictionChangeType::CHANGE_EDIT) 728 ->setTitle($this->getOldContent()->getTitle()) 729 ->setContent($this->getOldContent()->getContent()); 730 if (strlen($this->getDescription())) { 731 $new_content->setDescription($this->getDescription()); 732 } 733 $new_content->setVersion($this->getOldContent()->getVersion() + 1); 734 735 return $new_content; 736 } 737 738 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |