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

Allow EditEngine forms to be marked as "edit" forms

Summary:
Ref T9132. Ref T9908. This attempts to move us forward on answering this question:

> Which form gets used when a user clicks "Edit Task"?

One answer is "the same form that was used to create the task". There are several problems with that:

- The form might not exist anymore.
- The user might not have permission to see it.
- Some of the fields might be hidden, essentially preventing them from being edited.
- We have to store the value somewhere and old tasks won't have a value.
- Any instructions on the form probably don't apply to edits.

One answer is "force the default, full form". That's not as problematic, but it means we have no ability to create limited access users who see fewer fields.

The answer in this diff is:

- Forms can be marked as "edit forms".
- We take the user to the first edit form they have permission to see, from a master list.

This allows you to create several forms like:

- Advanced Edit Form (say, all fields -- visible to administrators).
- Basic Edit Form (say, no policies -- visible to trusted users).
- Noob Edit Form (say, no policies, priorities, or status -- visible to everyone).

Then you can give everyone access to "noob", some people access to "basic", and a few people access to "advanced".

This might only be part of the answer. In particular, you can still //use// any edit form you can see, so we could do these things in the future:

- Give you an option to switch to a different form if you want.
- Save the form the task was created with, and use that form by default.

If we do pursue those, we can fall back to this behavior if there's a problem with them (e.g., original form doesn't exist or wasn't recorded).

There's also no "reorder" UI yet, that'll be coming in the next diff.

I'm also going to try to probably make the "create" and "edit" stuff a little more consistent / less weird in a bit.

Test Plan: Marked various forms as edit forms or not edit forms, made edits, hit permissions errors, etc.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T9132, T9908

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

+297 -84
+2
src/__phutil_library_map__.php
··· 2135 2135 'PhabricatorEditEngineConfigurationEditController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationEditController.php', 2136 2136 'PhabricatorEditEngineConfigurationEditEngine' => 'applications/transactions/editor/PhabricatorEditEngineConfigurationEditEngine.php', 2137 2137 'PhabricatorEditEngineConfigurationEditor' => 'applications/transactions/editor/PhabricatorEditEngineConfigurationEditor.php', 2138 + 'PhabricatorEditEngineConfigurationIsEditController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationIsEditController.php', 2138 2139 'PhabricatorEditEngineConfigurationListController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationListController.php', 2139 2140 'PhabricatorEditEngineConfigurationLockController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationLockController.php', 2140 2141 'PhabricatorEditEngineConfigurationPHIDType' => 'applications/transactions/phid/PhabricatorEditEngineConfigurationPHIDType.php', ··· 6263 6264 'PhabricatorEditEngineConfigurationEditController' => 'PhabricatorEditEngineController', 6264 6265 'PhabricatorEditEngineConfigurationEditEngine' => 'PhabricatorEditEngine', 6265 6266 'PhabricatorEditEngineConfigurationEditor' => 'PhabricatorApplicationTransactionEditor', 6267 + 'PhabricatorEditEngineConfigurationIsEditController' => 'PhabricatorEditEngineController', 6266 6268 'PhabricatorEditEngineConfigurationListController' => 'PhabricatorEditEngineController', 6267 6269 'PhabricatorEditEngineConfigurationLockController' => 'PhabricatorEditEngineController', 6268 6270 'PhabricatorEditEngineConfigurationPHIDType' => 'PhabricatorPHIDType',
+2
src/applications/transactions/application/PhabricatorTransactionsApplication.php
··· 53 53 'PhabricatorEditEngineConfigurationLockController', 54 54 'defaultcreate/(?P<key>[^/]+)/' => 55 55 'PhabricatorEditEngineConfigurationDefaultCreateController', 56 + 'defaultedit/(?P<key>[^/]+)/' => 57 + 'PhabricatorEditEngineConfigurationIsEditController', 56 58 'disable/(?P<key>[^/]+)/' => 57 59 'PhabricatorEditEngineConfigurationDisableController', 58 60 ),
+60
src/applications/transactions/controller/PhabricatorEditEngineConfigurationIsEditController.php
··· 1 + <?php 2 + 3 + final class PhabricatorEditEngineConfigurationIsEditController 4 + extends PhabricatorEditEngineController { 5 + 6 + public function handleRequest(AphrontRequest $request) { 7 + $viewer = $this->getViewer(); 8 + 9 + $config = $this->loadConfigForEdit(); 10 + if (!$config) { 11 + return id(new Aphront404Response()); 12 + } 13 + 14 + $engine_key = $config->getEngineKey(); 15 + $key = $config->getIdentifier(); 16 + $cancel_uri = "/transactions/editengine/{$engine_key}/view/{$key}/"; 17 + 18 + $type = PhabricatorEditEngineConfigurationTransaction::TYPE_ISEDIT; 19 + 20 + if ($request->isFormPost()) { 21 + $xactions = array(); 22 + 23 + $xactions[] = id(new PhabricatorEditEngineConfigurationTransaction()) 24 + ->setTransactionType($type) 25 + ->setNewValue(!$config->getIsEdit()); 26 + 27 + $editor = id(new PhabricatorEditEngineConfigurationEditor()) 28 + ->setActor($viewer) 29 + ->setContentSourceFromRequest($request) 30 + ->setContinueOnMissingFields(true) 31 + ->setContinueOnNoEffect(true); 32 + 33 + $editor->applyTransactions($config, $xactions); 34 + 35 + return id(new AphrontRedirectResponse()) 36 + ->setURI($cancel_uri); 37 + } 38 + 39 + if ($config->getIsEdit()) { 40 + $title = pht('Unmark as Edit Form'); 41 + $body = pht( 42 + 'Unmark this form as an edit form? It will no longer be able to be '. 43 + 'used to edit objects.'); 44 + $button = pht('Unmark Form'); 45 + } else { 46 + $title = pht('Mark as Edit Form'); 47 + $body = pht( 48 + 'Mark this form as an edit form? Users who can view it will be able '. 49 + 'to use it to edit objects.'); 50 + $button = pht('Mark Form'); 51 + } 52 + 53 + return $this->newDialog() 54 + ->setTitle($title) 55 + ->appendParagraph($body) 56 + ->addSubmitButton($button) 57 + ->addCancelbutton($cancel_uri); 58 + } 59 + 60 + }
+18
src/applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php
··· 177 177 ->setWorkflow(true) 178 178 ->setDisabled(!$can_edit)); 179 179 180 + if ($config->getIsEdit()) { 181 + $isedit_name = pht('Unmark as "Edit" Form'); 182 + $isedit_icon = 'fa-minus'; 183 + } else { 184 + $isedit_name = pht('Mark as "Edit" Form'); 185 + $isedit_icon = 'fa-plus'; 186 + } 187 + 188 + $isedit_uri = "{$base_uri}/defaultedit/{$form_key}/"; 189 + 190 + $view->addAction( 191 + id(new PhabricatorActionView()) 192 + ->setName($isedit_name) 193 + ->setIcon($isedit_icon) 194 + ->setHref($isedit_uri) 195 + ->setWorkflow(true) 196 + ->setDisabled(!$can_edit)); 197 + 180 198 return $view; 181 199 } 182 200
+145 -83
src/applications/transactions/editengine/PhabricatorEditEngine.php
··· 198 198 return $this->editEngineConfiguration; 199 199 } 200 200 201 - 202 - /** 203 - * Load the default configuration, ignoring customization in the database 204 - * (which means we implicitly ignore policies). 205 - * 206 - * This is used from places like Conduit, where the fields available in the 207 - * API should not be affected by configuration changes. 208 - * 209 - * @return PhabricatorEditEngineConfiguration Default configuration, ignoring 210 - * customization. 211 - */ 212 - private function loadDefaultEditEngineConfiguration() { 213 - return $this->loadEditEngineConfigurationWithOptions( 214 - self::EDITENGINECONFIG_DEFAULT, 215 - true); 201 + private function newConfigurationQuery() { 202 + return id(new PhabricatorEditEngineConfigurationQuery()) 203 + ->setViewer($this->getViewer()) 204 + ->withEngineKeys(array($this->getEngineKey())); 216 205 } 217 206 207 + private function loadEditEngineConfigurationWithQuery( 208 + PhabricatorEditEngineConfigurationQuery $query, 209 + $sort_method) { 218 210 219 - /** 220 - * Load a named configuration, respecting database customization and policies. 221 - * 222 - * @param string Configuration key, or null to load the default. 223 - * @return PhabricatorEditEngineConfiguration Default configuration, 224 - * respecting customization. 225 - */ 226 - private function loadEditEngineConfiguration($key) { 227 - if (!strlen($key)) { 228 - $key = self::EDITENGINECONFIG_DEFAULT; 211 + if ($sort_method) { 212 + $results = $query->execute(); 213 + $results = msort($results, $sort_method); 214 + $result = head($results); 215 + } else { 216 + $result = $query->executeOne(); 229 217 } 230 218 231 - return $this->loadEditEngineConfigurationWithOptions( 232 - $key, 233 - false); 219 + if (!$result) { 220 + return null; 221 + } 222 + 223 + $this->editEngineConfiguration = $result; 224 + return $result; 234 225 } 235 226 236 - private function loadEditEngineConfigurationWithOptions( 237 - $key, 238 - $ignore_database) { 239 - $viewer = $this->getViewer(); 227 + private function loadEditEngineConfigurationWithIdentifier($identifier) { 228 + $query = $this->newConfigurationQuery() 229 + ->withIdentifiers(array($identifier)); 230 + 231 + return $this->loadEditEngineConfigurationWithQuery($query, null); 232 + } 233 + 234 + private function loadDefaultConfiguration() { 235 + $query = $this->newConfigurationQuery() 236 + ->withIdentifiers( 237 + array( 238 + self::EDITENGINECONFIG_DEFAULT, 239 + )) 240 + ->withIgnoreDatabaseConfigurations(true); 241 + 242 + return $this->loadEditEngineConfigurationWithQuery($query, null); 243 + } 240 244 241 - $config = id(new PhabricatorEditEngineConfigurationQuery()) 242 - ->setViewer($viewer) 243 - ->withEngineKeys(array($this->getEngineKey())) 244 - ->withIdentifiers(array($key)) 245 - ->withIgnoreDatabaseConfigurations($ignore_database) 246 - ->executeOne(); 247 - if (!$config) { 248 - return null; 249 - } 245 + private function loadDefaultCreateConfiguration() { 246 + $query = $this->newConfigurationQuery() 247 + ->withIsDefault(true) 248 + ->withIsDisabled(false); 249 + 250 + return $this->loadEditEngineConfigurationWithQuery( 251 + $query, 252 + 'getCreateSortKey'); 253 + } 250 254 251 - $this->editEngineConfiguration = $config; 255 + private function loadDefaultEditConfiguration() { 256 + $query = $this->newConfigurationQuery() 257 + ->withIsEdit(true) 258 + ->withIsDisabled(false); 252 259 253 - return $config; 260 + return $this->loadEditEngineConfigurationWithQuery( 261 + $query, 262 + 'getEditSortKey'); 254 263 } 255 264 256 265 final public function getBuiltinEngineConfigurations() { ··· 278 287 if (!$first->getBuiltinKey()) { 279 288 $first 280 289 ->setBuiltinKey(self::EDITENGINECONFIG_DEFAULT) 281 - ->setIsDefault(true); 290 + ->setIsDefault(true) 291 + ->setIsEdit(true); 282 292 283 293 if (!strlen($first->getName())) { 284 294 $first->setName($this->getObjectCreateShortText()); ··· 648 658 break; 649 659 } 650 660 651 - if ($use_default) { 652 - $config = $this->loadDefaultEditEngineConfiguration(); 653 - } else { 654 - $form_key = $request->getURIData('formKey'); 655 - $config = $this->loadEditEngineConfiguration($form_key); 656 - } 657 - 658 - if (!$config) { 659 - return new Aphront404Response(); 660 - } 661 + $id = $request->getURIData('id'); 661 662 662 - $id = $request->getURIData('id'); 663 663 if ($id) { 664 664 $this->setIsCreate(false); 665 665 $object = $this->newObjectFromID($id, $capabilities); ··· 679 679 680 680 $this->validateObject($object); 681 681 682 + if ($use_default) { 683 + $config = $this->loadDefaultConfiguration(); 684 + if (!$config) { 685 + return new Aphront404Response(); 686 + } 687 + } else { 688 + $form_key = $request->getURIData('formKey'); 689 + if (strlen($form_key)) { 690 + $config = $this->loadEditEngineConfigurationWithIdentifier($form_key); 691 + 692 + if (!$config) { 693 + return new Aphront404Response(); 694 + } 695 + 696 + if ($id && !$config->getIsEdit()) { 697 + return $this->buildNotEditFormRespose($object, $config); 698 + } 699 + } else { 700 + if ($id) { 701 + $config = $this->loadDefaultEditConfiguration(); 702 + if (!$config) { 703 + return $this->buildNoEditResponse($object); 704 + } 705 + } else { 706 + $config = $this->loadDefaultCreateConfiguration(); 707 + if (!$config) { 708 + return $this->buildNoCreateResponse($object); 709 + } 710 + } 711 + } 712 + } 713 + 714 + if ($config->getIsDisabled()) { 715 + return $this->buildFormDisabledResponse($object, $config); 716 + } 717 + 682 718 switch ($action) { 683 719 case 'parameters': 684 720 return $this->buildParametersResponse($object); ··· 1032 1068 } 1033 1069 1034 1070 final public function buildEditEngineCommentView($object) { 1035 - $config = $this->loadDefaultEditEngineConfiguration(); 1071 + $config = $this->loadDefaultConfiguration(); 1036 1072 1037 1073 $viewer = $this->getViewer(); 1038 1074 $object_phid = $object->getPHID(); ··· 1146 1182 } 1147 1183 1148 1184 1149 - private function buildNoDefaultResponse($object) { 1185 + private function buildError($object, $title, $body) { 1150 1186 $cancel_uri = $this->getObjectCreateCancelURI($object); 1151 1187 1152 1188 return $this->getController() 1153 1189 ->newDialog() 1154 - ->setTitle(pht('No Default Create Forms')) 1155 - ->appendParagraph( 1156 - pht( 1157 - 'This application is not configured with any visible, enabled '. 1158 - 'forms for creating objects.')) 1190 + ->setTitle($title) 1191 + ->appendParagraph($body) 1159 1192 ->addCancelButton($cancel_uri); 1160 1193 } 1161 1194 1162 - private function buildNoCreateResponse($object) { 1163 - $cancel_uri = $this->getObjectCreateCancelURI($object); 1164 1195 1165 - return $this->getController() 1166 - ->newDialog() 1167 - ->setTitle(pht('No Create Permission')) 1168 - ->appendParagraph( 1169 - pht( 1170 - 'You do not have permission to create these objects.')) 1171 - ->addCancelButton($cancel_uri); 1196 + private function buildNoDefaultResponse($object) { 1197 + return $this->buildError( 1198 + $object, 1199 + pht('No Default Create Forms'), 1200 + pht( 1201 + 'This application is not configured with any forms for creating '. 1202 + 'objects that are visible to you and enabled.')); 1203 + } 1204 + 1205 + private function buildNoCreateResponse($object) { 1206 + return $this->buildError( 1207 + $object, 1208 + pht('No Create Permission'), 1209 + pht('You do not have permission to create these objects.')); 1172 1210 } 1173 1211 1174 1212 private function buildNoManageResponse($object) { 1175 - $cancel_uri = $this->getObjectCreateCancelURI($object); 1213 + return $this->buildError( 1214 + $object, 1215 + pht('No Manage Permission'), 1216 + pht( 1217 + 'You do not have permission to configure forms for this '. 1218 + 'application.')); 1219 + } 1220 + 1221 + private function buildNoEditResponse($object) { 1222 + return $this->buildError( 1223 + $object, 1224 + pht('No Edit Forms'), 1225 + pht( 1226 + 'You do not have access to any forms which are enabled and marked '. 1227 + 'as edit forms.')); 1228 + } 1229 + 1230 + private function buildNotEditFormRespose($object, $config) { 1231 + return $this->buildError( 1232 + $object, 1233 + pht('Not an Edit Form'), 1234 + pht( 1235 + 'This form ("%s") is not marked as an edit form, so '. 1236 + 'it can not be used to edit objects.', 1237 + $config->getName())); 1238 + } 1176 1239 1177 - return $this->getController() 1178 - ->newDialog() 1179 - ->setTitle(pht('No Manage Permission')) 1180 - ->appendParagraph( 1181 - pht( 1182 - 'You do not have permission to configure forms for this '. 1183 - 'application.')) 1184 - ->addCancelButton($cancel_uri); 1240 + private function buildDisabledFormResponse($object, $config) { 1241 + return $this->buildError( 1242 + $object, 1243 + pht('Form Disabled'), 1244 + pht( 1245 + 'This form ("%s") has been disabled, so it can not be used.', 1246 + $config->getName())); 1185 1247 } 1186 1248 1187 1249 private function buildCommentResponse($object) { ··· 1198 1260 return new Aphront400Response(); 1199 1261 } 1200 1262 1201 - $config = $this->loadDefaultEditEngineConfiguration(); 1263 + $config = $this->loadDefaultConfiguration(); 1202 1264 $fields = $this->buildEditFields($object); 1203 1265 1204 1266 $is_preview = $request->isPreviewRequest(); ··· 1328 1390 final public function buildConduitResponse(ConduitAPIRequest $request) { 1329 1391 $viewer = $this->getViewer(); 1330 1392 1331 - $config = $this->loadDefaultEditEngineConfiguration(); 1393 + $config = $this->loadDefaultConfiguration(); 1332 1394 if (!$config) { 1333 1395 throw new Exception( 1334 1396 pht( ··· 1476 1538 } 1477 1539 1478 1540 public function getConduitEditTypes() { 1479 - $config = $this->loadDefaultEditEngineConfiguration(); 1541 + $config = $this->loadDefaultConfiguration(); 1480 1542 if (!$config) { 1481 1543 return array(); 1482 1544 }
+8
src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditor.php
··· 23 23 $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS; 24 24 $types[] = 25 25 PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE; 26 + $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_ISEDIT; 26 27 $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE; 27 28 28 29 ··· 75 76 return $object->getFieldLocks(); 76 77 case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE: 77 78 return (int)$object->getIsDefault(); 79 + case PhabricatorEditEngineConfigurationTransaction::TYPE_ISEDIT: 80 + return (int)$object->getIsEdit(); 78 81 case PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE: 79 82 return (int)$object->getIsDisabled(); 80 83 } ··· 92 95 case PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS: 93 96 return $xaction->getNewValue(); 94 97 case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE: 98 + case PhabricatorEditEngineConfigurationTransaction::TYPE_ISEDIT: 95 99 case PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE: 96 100 return (int)$xaction->getNewValue(); 97 101 } ··· 121 125 case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE: 122 126 $object->setIsDefault($xaction->getNewValue()); 123 127 return; 128 + case PhabricatorEditEngineConfigurationTransaction::TYPE_ISEDIT: 129 + $object->setIsEdit($xaction->getNewValue()); 130 + return; 124 131 case PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE: 125 132 $object->setIsDisabled($xaction->getNewValue()); 126 133 return; ··· 138 145 case PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE; 139 146 case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER; 140 147 case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT: 148 + case PhabricatorEditEngineConfigurationTransaction::TYPE_ISEDIT: 141 149 case PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS: 142 150 case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE: 143 151 case PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE:
+14
src/applications/transactions/query/PhabricatorEditEngineConfigurationQuery.php
··· 9 9 private $builtinKeys; 10 10 private $identifiers; 11 11 private $default; 12 + private $isEdit; 12 13 private $disabled; 13 14 private $ignoreDatabaseConfigurations; 14 15 ··· 39 40 40 41 public function withIsDefault($default) { 41 42 $this->default = $default; 43 + return $this; 44 + } 45 + 46 + public function withIsEdit($edit) { 47 + $this->isEdit = $edit; 42 48 return $this; 43 49 } 44 50 ··· 143 149 if ($this->default !== null) { 144 150 foreach ($page as $key => $config) { 145 151 if ($config->getIsDefault() != $this->default) { 152 + unset($page[$key]); 153 + } 154 + } 155 + } 156 + 157 + if ($this->isEdit !== null) { 158 + foreach ($page as $key => $config) { 159 + if ($config->getIsEdit() != $this->isEdit) { 146 160 unset($page[$key]); 147 161 } 148 162 }
+37 -1
src/applications/transactions/query/PhabricatorEditEngineConfigurationSearchEngine.php
··· 33 33 34 34 protected function buildQueryFromParameters(array $map) { 35 35 $query = $this->newQuery(); 36 + 37 + $is_create = $map['isCreate']; 38 + if ($is_create !== null) { 39 + $query->withIsDefault($is_create); 40 + } 41 + 42 + $is_edit = $map['isEdit']; 43 + if ($is_edit !== null) { 44 + $query->withIsEdit($is_edit); 45 + } 46 + 36 47 return $query; 37 48 } 38 49 39 50 protected function buildCustomSearchFields() { 40 - return array(); 51 + return array( 52 + id(new PhabricatorSearchThreeStateField()) 53 + ->setLabel(pht('Create')) 54 + ->setKey('isCreate') 55 + ->setOptions( 56 + pht('Show All'), 57 + pht('Hide Create Forms'), 58 + pht('Show Only Create Forms')), 59 + id(new PhabricatorSearchThreeStateField()) 60 + ->setLabel(pht('Edit')) 61 + ->setKey('isEdit') 62 + ->setOptions( 63 + pht('Show All'), 64 + pht('Hide Edit Forms'), 65 + pht('Show Only Edit Forms')), 66 + ); 41 67 } 42 68 43 69 protected function getDefaultFieldOrder() { ··· 51 77 protected function getBuiltinQueryNames() { 52 78 $names = array( 53 79 'all' => pht('All Forms'), 80 + 'create' => pht('Create Forms'), 81 + 'modify' => pht('Edit Forms'), 54 82 ); 55 83 56 84 return $names; ··· 63 91 switch ($query_key) { 64 92 case 'all': 65 93 return $query; 94 + case 'create': 95 + return $query->setParameter('isCreate', true); 96 + case 'modify': 97 + return $query->setParameter('isEdit', true); 66 98 } 67 99 68 100 return parent::buildSavedQueryFromBuiltin($query_key); ··· 94 126 95 127 if ($config->getIsDefault()) { 96 128 $item->addIcon('fa-plus', pht('Default')); 129 + } 130 + 131 + if ($config->getIsEdit()) { 132 + $item->addIcon('fa-pencil', pht('Edit Form')); 97 133 } 98 134 99 135 if ($config->getIsDisabled()) {
+11
src/applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php
··· 9 9 const TYPE_DEFAULT = 'editengine.config.default'; 10 10 const TYPE_LOCKS = 'editengine.config.locks'; 11 11 const TYPE_DEFAULTCREATE = 'editengine.config.default.create'; 12 + const TYPE_ISEDIT = 'editengine.config.isedit'; 12 13 const TYPE_DISABLE = 'editengine.config.disable'; 13 14 14 15 public function getApplicationName() { ··· 70 71 } else { 71 72 return pht( 72 73 '%s removed this form from the "Create" menu.', 74 + $this->renderHandleLink($author_phid)); 75 + } 76 + case self::TYPE_ISEDIT: 77 + if ($new) { 78 + return pht( 79 + '%s marked this form as an edit form.', 80 + $this->renderHandleLink($author_phid)); 81 + } else { 82 + return pht( 83 + '%s unmarked this form as an edit form.', 73 84 $this->renderHandleLink($author_phid)); 74 85 } 75 86 case self::TYPE_DISABLE: