@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.

Migrate Project image to modular transactions

Summary: I'm not sure you can actually remove a project's image (maybe via the API?), but I kept the code for rendering the relevant title/feed anyway.

Test Plan: Unit tests + adding/changing project pictures.

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: Korvin, epriestley

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

+144 -77
+2
src/__phutil_library_map__.php
··· 3621 3621 'PhabricatorProjectHovercardEngineExtension' => 'applications/project/engineextension/PhabricatorProjectHovercardEngineExtension.php', 3622 3622 'PhabricatorProjectIconSet' => 'applications/project/icon/PhabricatorProjectIconSet.php', 3623 3623 'PhabricatorProjectIconsConfigOptionType' => 'applications/project/config/PhabricatorProjectIconsConfigOptionType.php', 3624 + 'PhabricatorProjectImageTransaction' => 'applications/project/xaction/PhabricatorProjectImageTransaction.php', 3624 3625 'PhabricatorProjectInterface' => 'applications/project/interface/PhabricatorProjectInterface.php', 3625 3626 'PhabricatorProjectListController' => 'applications/project/controller/PhabricatorProjectListController.php', 3626 3627 'PhabricatorProjectListView' => 'applications/project/view/PhabricatorProjectListView.php', ··· 9035 9036 'PhabricatorProjectHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension', 9036 9037 'PhabricatorProjectIconSet' => 'PhabricatorIconSet', 9037 9038 'PhabricatorProjectIconsConfigOptionType' => 'PhabricatorConfigJSONOptionType', 9039 + 'PhabricatorProjectImageTransaction' => 'PhabricatorProjectTransactionType', 9038 9040 'PhabricatorProjectListController' => 'PhabricatorProjectController', 9039 9041 'PhabricatorProjectListView' => 'AphrontView', 9040 9042 'PhabricatorProjectLockController' => 'PhabricatorProjectController',
+2 -1
src/applications/files/controller/PhabricatorFileComposeController.php
··· 48 48 49 49 $xactions = array(); 50 50 $xactions[] = id(new PhabricatorProjectTransaction()) 51 - ->setTransactionType(PhabricatorProjectTransaction::TYPE_IMAGE) 51 + ->setTransactionType( 52 + PhabricatorProjectImageTransaction::TRANSACTIONTYPE) 52 53 ->setNewValue($file->getPHID()); 53 54 54 55 $editor = id(new PhabricatorProjectTransactionEditor())
+2 -1
src/applications/project/controller/PhabricatorProjectEditPictureController.php
··· 78 78 79 79 $xactions = array(); 80 80 $xactions[] = id(new PhabricatorProjectTransaction()) 81 - ->setTransactionType(PhabricatorProjectTransaction::TYPE_IMAGE) 81 + ->setTransactionType( 82 + PhabricatorProjectImageTransaction::TRANSACTIONTYPE) 82 83 ->setNewValue($new_value); 83 84 84 85 $editor = id(new PhabricatorProjectTransactionEditor())
+1 -25
src/applications/project/editor/PhabricatorProjectTransactionEditor.php
··· 30 30 $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; 31 31 $types[] = PhabricatorTransactions::TYPE_JOIN_POLICY; 32 32 33 - $types[] = PhabricatorProjectTransaction::TYPE_IMAGE; 34 33 $types[] = PhabricatorProjectTransaction::TYPE_ICON; 35 34 $types[] = PhabricatorProjectTransaction::TYPE_COLOR; 36 35 $types[] = PhabricatorProjectTransaction::TYPE_LOCKED; ··· 49 48 PhabricatorApplicationTransaction $xaction) { 50 49 51 50 switch ($xaction->getTransactionType()) { 52 - case PhabricatorProjectTransaction::TYPE_IMAGE: 53 - return $object->getProfileImagePHID(); 54 51 case PhabricatorProjectTransaction::TYPE_ICON: 55 52 return $object->getIcon(); 56 53 case PhabricatorProjectTransaction::TYPE_COLOR: ··· 78 75 PhabricatorApplicationTransaction $xaction) { 79 76 80 77 switch ($xaction->getTransactionType()) { 81 - case PhabricatorProjectTransaction::TYPE_IMAGE: 82 78 case PhabricatorProjectTransaction::TYPE_ICON: 83 79 case PhabricatorProjectTransaction::TYPE_COLOR: 84 80 case PhabricatorProjectTransaction::TYPE_LOCKED: ··· 105 101 PhabricatorApplicationTransaction $xaction) { 106 102 107 103 switch ($xaction->getTransactionType()) { 108 - case PhabricatorProjectTransaction::TYPE_IMAGE: 109 - $object->setProfileImagePHID($xaction->getNewValue()); 110 - return; 111 104 case PhabricatorProjectTransaction::TYPE_ICON: 112 105 $object->setIcon($xaction->getNewValue()); 113 106 return; ··· 150 143 $new = $xaction->getNewValue(); 151 144 152 145 switch ($xaction->getTransactionType()) { 153 - case PhabricatorProjectTransaction::TYPE_IMAGE: 154 146 case PhabricatorProjectTransaction::TYPE_ICON: 155 147 case PhabricatorProjectTransaction::TYPE_COLOR: 156 148 case PhabricatorProjectTransaction::TYPE_LOCKED: ··· 336 328 switch ($xaction->getTransactionType()) { 337 329 case PhabricatorProjectNameTransaction::TRANSACTIONTYPE: 338 330 case PhabricatorProjectStatusTransaction::TRANSACTIONTYPE: 339 - case PhabricatorProjectTransaction::TYPE_IMAGE: 331 + case PhabricatorProjectImageTransaction::TRANSACTIONTYPE: 340 332 case PhabricatorProjectTransaction::TYPE_ICON: 341 333 case PhabricatorProjectTransaction::TYPE_COLOR: 342 334 PhabricatorPolicyFilter::requireCapability( ··· 473 465 474 466 protected function supportsSearch() { 475 467 return true; 476 - } 477 - 478 - protected function extractFilePHIDsFromCustomTransaction( 479 - PhabricatorLiskDAO $object, 480 - PhabricatorApplicationTransaction $xaction) { 481 - 482 - switch ($xaction->getTransactionType()) { 483 - case PhabricatorProjectTransaction::TYPE_IMAGE: 484 - $new = $xaction->getNewValue(); 485 - if ($new) { 486 - return array($new); 487 - } 488 - break; 489 - } 490 - 491 - return parent::extractFilePHIDsFromCustomTransaction($object, $xaction); 492 468 } 493 469 494 470 protected function applyFinalEffects(
+1 -49
src/applications/project/storage/PhabricatorProjectTransaction.php
··· 3 3 final class PhabricatorProjectTransaction 4 4 extends PhabricatorModularTransaction { 5 5 6 - const TYPE_IMAGE = 'project:image'; 7 6 const TYPE_ICON = 'project:icon'; 8 7 const TYPE_COLOR = 'project:color'; 9 8 const TYPE_LOCKED = 'project:locked'; ··· 44 43 $add = array_diff($new, $old); 45 44 $rem = array_diff($old, $new); 46 45 $req_phids = array_merge($add, $rem); 47 - break; 48 - case self::TYPE_IMAGE: 49 - $req_phids[] = $old; 50 - $req_phids[] = $new; 51 46 break; 52 47 } 53 48 ··· 106 101 } 107 102 case self::TYPE_ICON: 108 103 return PhabricatorProjectIconSet::getIconIcon($new); 109 - case self::TYPE_IMAGE: 110 - return 'fa-photo'; 111 104 case self::TYPE_MEMBERS: 112 105 return 'fa-user'; 113 106 } ··· 126 119 '%s created this project.', 127 120 $this->renderHandleLink($author_phid)); 128 121 129 - case self::TYPE_IMAGE: 130 - // TODO: Some day, it would be nice to show the images. 131 - if (!$old) { 132 - return pht( 133 - "%s set this project's image to %s.", 134 - $author_handle, 135 - $this->renderHandleLink($new)); 136 - } else if (!$new) { 137 - return pht( 138 - "%s removed this project's image.", 139 - $author_handle); 140 - } else { 141 - return pht( 142 - "%s updated this project's image from %s to %s.", 143 - $author_handle, 144 - $this->renderHandleLink($old), 145 - $this->renderHandleLink($new)); 146 - } 147 - break; 148 - 149 122 case self::TYPE_ICON: 150 123 $set = new PhabricatorProjectIconSet(); 151 124 ··· 253 226 $new = $this->getNewValue(); 254 227 255 228 switch ($this->getTransactionType()) { 256 - case self::TYPE_IMAGE: 257 - // TODO: Some day, it would be nice to show the images. 258 - if (!$old) { 259 - return pht( 260 - '%s set the image for %s to %s.', 261 - $author_handle, 262 - $object_handle, 263 - $this->renderHandleLink($new)); 264 - } else if (!$new) { 265 - return pht( 266 - '%s removed the image for %s.', 267 - $author_handle, 268 - $object_handle); 269 - } else { 270 - return pht( 271 - '%s updated the image for %s from %s to %s.', 272 - $author_handle, 273 - $object_handle, 274 - $this->renderHandleLink($old), 275 - $this->renderHandleLink($new)); 276 - } 277 229 278 230 case self::TYPE_ICON: 279 231 $set = new PhabricatorProjectIconSet(); ··· 313 265 switch ($this->getTransactionType()) { 314 266 case PhabricatorProjectNameTransaction::TRANSACTIONTYPE: 315 267 case PhabricatorProjectSlugsTransaction::TRANSACTIONTYPE: 316 - case self::TYPE_IMAGE: 268 + case PhabricatorProjectImageTransaction::TRANSACTIONTYPE: 317 269 case self::TYPE_ICON: 318 270 case self::TYPE_COLOR: 319 271 $tags[] = self::MAILTAG_METADATA;
+136
src/applications/project/xaction/PhabricatorProjectImageTransaction.php
··· 1 + <?php 2 + 3 + final class PhabricatorProjectImageTransaction 4 + extends PhabricatorProjectTransactionType { 5 + 6 + const TRANSACTIONTYPE = 'project:image'; 7 + 8 + public function generateOldValue($object) { 9 + return $object->getProfileImagePHID(); 10 + } 11 + 12 + public function applyInternalEffects($object, $value) { 13 + $object->setProfileImagePHID($value); 14 + } 15 + 16 + public function applyExternalEffects($object, $value) { 17 + $old = $this->getOldValue(); 18 + $new = $value; 19 + $all = array(); 20 + if ($old) { 21 + $all[] = $old; 22 + } 23 + if ($new) { 24 + $all[] = $new; 25 + } 26 + 27 + $files = id(new PhabricatorFileQuery()) 28 + ->setViewer($this->getActor()) 29 + ->withPHIDs($all) 30 + ->execute(); 31 + $files = mpull($files, null, 'getPHID'); 32 + 33 + $old_file = idx($files, $old); 34 + if ($old_file) { 35 + $old_file->detachFromObject($object->getPHID()); 36 + } 37 + 38 + $new_file = idx($files, $new); 39 + if ($new_file) { 40 + $new_file->attachToObject($object->getPHID()); 41 + } 42 + } 43 + 44 + public function getTitle() { 45 + $old = $this->getOldValue(); 46 + $new = $this->getNewValue(); 47 + 48 + // TODO: Some day, it would be nice to show the images. 49 + if (!$old) { 50 + return pht( 51 + "%s set this project's image to %s.", 52 + $this->renderAuthor(), 53 + $this->renderNewHandle()); 54 + } else if (!$new) { 55 + return pht( 56 + "%s removed this project's image.", 57 + $this->renderAuthor()); 58 + } else { 59 + return pht( 60 + "%s updated this project's image from %s to %s.", 61 + $this->renderAuthor(), 62 + $this->renderOldHandle(), 63 + $this->renderNewHandle()); 64 + } 65 + } 66 + 67 + public function getTitleForFeed() { 68 + $old = $this->getOldValue(); 69 + $new = $this->getNewValue(); 70 + 71 + // TODO: Some day, it would be nice to show the images. 72 + if (!$old) { 73 + return pht( 74 + '%s set the image for %s to %s.', 75 + $this->renderAuthor(), 76 + $this->renderObject(), 77 + $this->renderNewHandle()); 78 + } else if (!$new) { 79 + return pht( 80 + '%s removed the image for %s.', 81 + $this->renderAuthor(), 82 + $this->renderObject()); 83 + } else { 84 + return pht( 85 + '%s updated the image for %s from %s to %s.', 86 + $this->renderAuthor(), 87 + $this->renderObject(), 88 + $this->renderOldHandle(), 89 + $this->renderNewHandle()); 90 + } 91 + } 92 + 93 + public function getIcon() { 94 + return 'fa-photo'; 95 + } 96 + 97 + public function extractFilePHIDs($object, $value) { 98 + if ($value) { 99 + return array($value); 100 + } 101 + return array(); 102 + } 103 + 104 + public function validateTransactions($object, array $xactions) { 105 + $errors = array(); 106 + $viewer = $this->getActor(); 107 + 108 + foreach ($xactions as $xaction) { 109 + $file_phid = $xaction->getNewValue(); 110 + 111 + // Only validate if file was uploaded 112 + if ($file_phid) { 113 + $file = id(new PhabricatorFileQuery()) 114 + ->setViewer($viewer) 115 + ->withPHIDs(array($file_phid)) 116 + ->executeOne(); 117 + 118 + if (!$file) { 119 + $errors[] = $this->newInvalidError( 120 + pht('"%s" is not a valid file PHID.', 121 + $file_phid)); 122 + } else { 123 + if (!$file->isViewableImage()) { 124 + $mime_type = $file->getMimeType(); 125 + $errors[] = $this->newInvalidError( 126 + pht('File mime type of "%s" is not a valid viewable image.', 127 + $mime_type)); 128 + } 129 + } 130 + } 131 + } 132 + 133 + return $errors; 134 + } 135 + 136 + }
-1
src/applications/project/xaction/PhabricatorProjectSlugsTransaction.php
··· 61 61 count($rem), 62 62 $this->renderSlugList($rem)); 63 63 } 64 - break; 65 64 } 66 65 67 66 public function getTitleForFeed() {