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

Use EditEngine, not CustomFields, to define Dashboard Panel edit behavior

Summary:
Depends on D20371. Ref T13272. Dashboard panels use CustomField to specify editable panel behavior. This is an older approach which was largely or entirely obsoleted by EditEngine.

Throw away all the CustomField edit stuff. Convert the "text" panel to EditEngine to prove this at least mostly works.

This breaks "query" panels and "tab" panels (they'll still work fine, but they can't be meaningfully edited). I'll restore those in a future change.

Test Plan: Created and edited a "text" panel.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13272

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

+67 -356
+4 -14
src/__phutil_library_map__.php
··· 2927 2927 'PhabricatorDashboardObjectInstallWorkflow' => 'applications/dashboard/install/PhabricatorDashboardObjectInstallWorkflow.php', 2928 2928 'PhabricatorDashboardPanel' => 'applications/dashboard/storage/PhabricatorDashboardPanel.php', 2929 2929 'PhabricatorDashboardPanelArchiveController' => 'applications/dashboard/controller/panel/PhabricatorDashboardPanelArchiveController.php', 2930 - 'PhabricatorDashboardPanelCoreCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelCoreCustomField.php', 2931 - 'PhabricatorDashboardPanelCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelCustomField.php', 2932 2930 'PhabricatorDashboardPanelDatasource' => 'applications/dashboard/typeahead/PhabricatorDashboardPanelDatasource.php', 2933 2931 'PhabricatorDashboardPanelEditConduitAPIMethod' => 'applications/dashboard/conduit/PhabricatorDashboardPanelEditConduitAPIMethod.php', 2934 2932 'PhabricatorDashboardPanelEditController' => 'applications/dashboard/controller/panel/PhabricatorDashboardPanelEditController.php', ··· 2938 2936 'PhabricatorDashboardPanelNameTransaction' => 'applications/dashboard/xaction/panel/PhabricatorDashboardPanelNameTransaction.php', 2939 2937 'PhabricatorDashboardPanelNgrams' => 'applications/dashboard/storage/PhabricatorDashboardPanelNgrams.php', 2940 2938 'PhabricatorDashboardPanelPHIDType' => 'applications/dashboard/phid/PhabricatorDashboardPanelPHIDType.php', 2939 + 'PhabricatorDashboardPanelPropertyTransaction' => 'applications/dashboard/xaction/panel/PhabricatorDashboardPanelPropertyTransaction.php', 2941 2940 'PhabricatorDashboardPanelQuery' => 'applications/dashboard/query/PhabricatorDashboardPanelQuery.php', 2942 2941 'PhabricatorDashboardPanelRenderController' => 'applications/dashboard/controller/panel/PhabricatorDashboardPanelRenderController.php', 2943 2942 'PhabricatorDashboardPanelRenderingEngine' => 'applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php', 2944 - 'PhabricatorDashboardPanelSearchApplicationCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelSearchApplicationCustomField.php', 2945 2943 'PhabricatorDashboardPanelSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardPanelSearchEngine.php', 2946 - 'PhabricatorDashboardPanelSearchQueryCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelSearchQueryCustomField.php', 2947 2944 'PhabricatorDashboardPanelStatusTransaction' => 'applications/dashboard/xaction/panel/PhabricatorDashboardPanelStatusTransaction.php', 2948 - 'PhabricatorDashboardPanelTabsCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelTabsCustomField.php', 2949 2945 'PhabricatorDashboardPanelTransaction' => 'applications/dashboard/storage/PhabricatorDashboardPanelTransaction.php', 2950 2946 'PhabricatorDashboardPanelTransactionEditor' => 'applications/dashboard/editor/PhabricatorDashboardPanelTransactionEditor.php', 2951 2947 'PhabricatorDashboardPanelTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardPanelTransactionQuery.php', ··· 2985 2981 'PhabricatorDashboardSchemaSpec' => 'applications/dashboard/storage/PhabricatorDashboardSchemaSpec.php', 2986 2982 'PhabricatorDashboardSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardSearchEngine.php', 2987 2983 'PhabricatorDashboardTabsPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php', 2984 + 'PhabricatorDashboardTextPanelTextTransaction' => 'applications/dashboard/xaction/panel/PhabricatorDashboardTextPanelTextTransaction.php', 2988 2985 'PhabricatorDashboardTextPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardTextPanelType.php', 2989 2986 'PhabricatorDashboardTransaction' => 'applications/dashboard/storage/PhabricatorDashboardTransaction.php', 2990 2987 'PhabricatorDashboardTransactionEditor' => 'applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php', ··· 8899 8896 'PhabricatorDashboardDAO', 8900 8897 'PhabricatorApplicationTransactionInterface', 8901 8898 'PhabricatorPolicyInterface', 8902 - 'PhabricatorCustomFieldInterface', 8903 8899 'PhabricatorFlaggableInterface', 8904 8900 'PhabricatorDestructibleInterface', 8905 8901 'PhabricatorNgramsInterface', 8906 8902 ), 8907 8903 'PhabricatorDashboardPanelArchiveController' => 'PhabricatorDashboardController', 8908 - 'PhabricatorDashboardPanelCoreCustomField' => array( 8909 - 'PhabricatorDashboardPanelCustomField', 8910 - 'PhabricatorStandardCustomFieldInterface', 8911 - ), 8912 - 'PhabricatorDashboardPanelCustomField' => 'PhabricatorCustomField', 8913 8904 'PhabricatorDashboardPanelDatasource' => 'PhabricatorTypeaheadDatasource', 8914 8905 'PhabricatorDashboardPanelEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod', 8915 8906 'PhabricatorDashboardPanelEditController' => 'PhabricatorDashboardController', ··· 8919 8910 'PhabricatorDashboardPanelNameTransaction' => 'PhabricatorDashboardPanelTransactionType', 8920 8911 'PhabricatorDashboardPanelNgrams' => 'PhabricatorSearchNgrams', 8921 8912 'PhabricatorDashboardPanelPHIDType' => 'PhabricatorPHIDType', 8913 + 'PhabricatorDashboardPanelPropertyTransaction' => 'PhabricatorDashboardPanelTransactionType', 8922 8914 'PhabricatorDashboardPanelQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 8923 8915 'PhabricatorDashboardPanelRenderController' => 'PhabricatorDashboardController', 8924 8916 'PhabricatorDashboardPanelRenderingEngine' => 'Phobject', 8925 - 'PhabricatorDashboardPanelSearchApplicationCustomField' => 'PhabricatorStandardCustomField', 8926 8917 'PhabricatorDashboardPanelSearchEngine' => 'PhabricatorApplicationSearchEngine', 8927 - 'PhabricatorDashboardPanelSearchQueryCustomField' => 'PhabricatorStandardCustomField', 8928 8918 'PhabricatorDashboardPanelStatusTransaction' => 'PhabricatorDashboardPanelTransactionType', 8929 - 'PhabricatorDashboardPanelTabsCustomField' => 'PhabricatorStandardCustomField', 8930 8919 'PhabricatorDashboardPanelTransaction' => 'PhabricatorModularTransaction', 8931 8920 'PhabricatorDashboardPanelTransactionEditor' => 'PhabricatorApplicationTransactionEditor', 8932 8921 'PhabricatorDashboardPanelTransactionQuery' => 'PhabricatorApplicationTransactionQuery', ··· 8971 8960 'PhabricatorDashboardSchemaSpec' => 'PhabricatorConfigSchemaSpec', 8972 8961 'PhabricatorDashboardSearchEngine' => 'PhabricatorApplicationSearchEngine', 8973 8962 'PhabricatorDashboardTabsPanelType' => 'PhabricatorDashboardPanelType', 8963 + 'PhabricatorDashboardTextPanelTextTransaction' => 'PhabricatorDashboardPanelPropertyTransaction', 8974 8964 'PhabricatorDashboardTextPanelType' => 'PhabricatorDashboardPanelType', 8975 8965 'PhabricatorDashboardTransaction' => 'PhabricatorApplicationTransaction', 8976 8966 'PhabricatorDashboardTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
-47
src/applications/dashboard/customfield/PhabricatorDashboardPanelCoreCustomField.php
··· 1 - <?php 2 - 3 - final class PhabricatorDashboardPanelCoreCustomField 4 - extends PhabricatorDashboardPanelCustomField 5 - implements PhabricatorStandardCustomFieldInterface { 6 - 7 - public function getStandardCustomFieldNamespace() { 8 - return 'dashboard:core'; 9 - } 10 - 11 - public function createFields($object) { 12 - if (!$object->getPanelType()) { 13 - return array(); 14 - } 15 - 16 - $impl = $object->requireImplementation(); 17 - $specs = $impl->getFieldSpecifications(); 18 - return PhabricatorStandardCustomField::buildStandardFields($this, $specs); 19 - } 20 - 21 - public function shouldUseStorage() { 22 - return false; 23 - } 24 - 25 - public function readValueFromObject(PhabricatorCustomFieldInterface $object) { 26 - $key = $this->getProxy()->getRawStandardFieldKey(); 27 - $this->setValueFromStorage($object->getProperty($key)); 28 - $this->didSetValueFromStorage(); 29 - } 30 - 31 - public function applyApplicationTransactionInternalEffects( 32 - PhabricatorApplicationTransaction $xaction) { 33 - $object = $this->getObject(); 34 - $key = $this->getProxy()->getRawStandardFieldKey(); 35 - 36 - $this->setValueFromApplicationTransactions($xaction->getNewValue()); 37 - $value = $this->getValueForStorage(); 38 - 39 - $object->setProperty($key, $value); 40 - } 41 - 42 - public function applyApplicationTransactionExternalEffects( 43 - PhabricatorApplicationTransaction $xaction) { 44 - return; 45 - } 46 - 47 - }
-4
src/applications/dashboard/customfield/PhabricatorDashboardPanelCustomField.php
··· 1 - <?php 2 - 3 - abstract class PhabricatorDashboardPanelCustomField 4 - extends PhabricatorCustomField {}
-53
src/applications/dashboard/customfield/PhabricatorDashboardPanelSearchApplicationCustomField.php
··· 1 - <?php 2 - 3 - final class PhabricatorDashboardPanelSearchApplicationCustomField 4 - extends PhabricatorStandardCustomField { 5 - 6 - public function getFieldType() { 7 - return 'search.application'; 8 - } 9 - 10 - public function shouldAppearInApplicationSearch() { 11 - return false; 12 - } 13 - 14 - public function renderEditControl(array $handles) { 15 - $engines = id(new PhutilClassMapQuery()) 16 - ->setAncestorClass('PhabricatorApplicationSearchEngine') 17 - ->setFilterMethod('canUseInPanelContext') 18 - ->execute(); 19 - 20 - $all_apps = id(new PhabricatorApplicationQuery()) 21 - ->setViewer($this->getViewer()) 22 - ->withUnlisted(false) 23 - ->withInstalled(true) 24 - ->execute(); 25 - foreach ($engines as $index => $engine) { 26 - if (!isset($all_apps[$engine->getApplicationClassName()])) { 27 - unset($engines[$index]); 28 - continue; 29 - } 30 - } 31 - 32 - $options = array(); 33 - 34 - $value = $this->getFieldValue(); 35 - if (strlen($value) && empty($engines[$value])) { 36 - $options[$value] = $value; 37 - } 38 - 39 - $engines = msort($engines, 'getResultTypeDescription'); 40 - foreach ($engines as $class_name => $engine) { 41 - $options[$class_name] = $engine->getResultTypeDescription(); 42 - } 43 - 44 - return id(new AphrontFormSelectControl()) 45 - ->setID($this->getFieldControlID()) 46 - ->setLabel($this->getFieldName()) 47 - ->setCaption($this->getCaption()) 48 - ->setName($this->getFieldKey()) 49 - ->setValue($this->getFieldValue()) 50 - ->setOptions($options); 51 - } 52 - 53 - }
-68
src/applications/dashboard/customfield/PhabricatorDashboardPanelSearchQueryCustomField.php
··· 1 - <?php 2 - 3 - final class PhabricatorDashboardPanelSearchQueryCustomField 4 - extends PhabricatorStandardCustomField { 5 - 6 - public function getFieldType() { 7 - return 'search.query'; 8 - } 9 - 10 - public function shouldAppearInApplicationSearch() { 11 - return false; 12 - } 13 - 14 - public function renderEditControl(array $handles) { 15 - $engines = id(new PhutilClassMapQuery()) 16 - ->setAncestorClass('PhabricatorApplicationSearchEngine') 17 - ->setFilterMethod('canUseInPanelContext') 18 - ->execute(); 19 - 20 - $value = $this->getFieldValue(); 21 - 22 - $queries = array(); 23 - $seen = false; 24 - foreach ($engines as $engine_class => $engine) { 25 - $engine->setViewer($this->getViewer()); 26 - $engine_queries = $engine->loadEnabledNamedQueries(); 27 - $query_map = mpull($engine_queries, 'getQueryName', 'getQueryKey'); 28 - asort($query_map); 29 - 30 - foreach ($query_map as $key => $name) { 31 - $queries[$engine_class][] = array('key' => $key, 'name' => $name); 32 - if ($key == $value) { 33 - $seen = true; 34 - } 35 - } 36 - } 37 - 38 - if (strlen($value) && !$seen) { 39 - $name = pht('Custom Query ("%s")', $value); 40 - } else { 41 - $name = pht('(None)'); 42 - } 43 - 44 - $options = array($value => $name); 45 - 46 - $app_control_key = $this->getFieldConfigValue('control.application'); 47 - Javelin::initBehavior( 48 - 'dashboard-query-panel-select', 49 - array( 50 - 'applicationID' => $this->getFieldControlID($app_control_key), 51 - 'queryID' => $this->getFieldControlID(), 52 - 'options' => $queries, 53 - 'value' => array( 54 - 'key' => strlen($value) ? $value : null, 55 - 'name' => $name, 56 - ), 57 - )); 58 - 59 - return id(new AphrontFormSelectControl()) 60 - ->setID($this->getFieldControlID()) 61 - ->setLabel($this->getFieldName()) 62 - ->setCaption($this->getCaption()) 63 - ->setName($this->getFieldKey()) 64 - ->setValue($this->getFieldValue()) 65 - ->setOptions($options); 66 - } 67 - 68 - }
-114
src/applications/dashboard/customfield/PhabricatorDashboardPanelTabsCustomField.php
··· 1 - <?php 2 - 3 - final class PhabricatorDashboardPanelTabsCustomField 4 - extends PhabricatorStandardCustomField { 5 - 6 - public function getFieldType() { 7 - return 'dashboard.tabs'; 8 - } 9 - 10 - public function shouldAppearInApplicationSearch() { 11 - return false; 12 - } 13 - 14 - public function readValueFromRequest(AphrontRequest $request) { 15 - $value = array(); 16 - 17 - $names = $request->getArr($this->getFieldKey().'_name'); 18 - $panel_ids = $request->getArr($this->getFieldKey().'_panelID'); 19 - $panels = array(); 20 - foreach ($panel_ids as $panel_id) { 21 - $panels[] = $panel_id[0]; 22 - } 23 - foreach ($names as $idx => $name) { 24 - $panel_id = idx($panels, $idx); 25 - if (strlen($name) && $panel_id) { 26 - $value[] = array( 27 - 'name' => $name, 28 - 'panelID' => $panel_id, 29 - ); 30 - } 31 - } 32 - 33 - $this->setFieldValue($value); 34 - } 35 - 36 - public function getApplicationTransactionTitle( 37 - PhabricatorApplicationTransaction $xaction) { 38 - $author_phid = $xaction->getAuthorPHID(); 39 - $old = $xaction->getOldValue(); 40 - $new = $xaction->getNewValue(); 41 - 42 - $new_tabs = array(); 43 - if ($new) { 44 - foreach ($new as $new_tab) { 45 - $new_tabs[] = $new_tab['name']; 46 - } 47 - $new_tabs = implode(' | ', $new_tabs); 48 - } 49 - 50 - $old_tabs = array(); 51 - if ($old) { 52 - foreach ($old as $old_tab) { 53 - $old_tabs[] = $old_tab['name']; 54 - } 55 - $old_tabs = implode(' | ', $old_tabs); 56 - } 57 - 58 - if (!$old) { 59 - // In case someone makes a tab panel with no tabs. 60 - if ($new) { 61 - return pht( 62 - '%s set the tabs to "%s".', 63 - $xaction->renderHandleLink($author_phid), 64 - $new_tabs); 65 - } 66 - } else if (!$new) { 67 - return pht( 68 - '%s removed tabs.', 69 - $xaction->renderHandleLink($author_phid)); 70 - } else { 71 - return pht( 72 - '%s changed the tabs from "%s" to "%s".', 73 - $xaction->renderHandleLink($author_phid), 74 - $old_tabs, 75 - $new_tabs); 76 - } 77 - } 78 - 79 - public function renderEditControl(array $handles) { 80 - // NOTE: This includes archived panels so we don't mutate the tabs 81 - // when saving a tab panel that includes archived panels. This whole UI is 82 - // hopefully temporary anyway. 83 - 84 - $value = $this->getFieldValue(); 85 - if (!is_array($value)) { 86 - $value = array(); 87 - } 88 - 89 - $out = array(); 90 - for ($ii = 1; $ii <= 6; $ii++) { 91 - $tab = idx($value, ($ii - 1), array()); 92 - $panel = idx($tab, 'panelID', null); 93 - $panel_id = array(); 94 - if ($panel) { 95 - $panel_id[] = $panel; 96 - } 97 - $out[] = id(new AphrontFormTextControl()) 98 - ->setName($this->getFieldKey().'_name[]') 99 - ->setValue(idx($tab, 'name')) 100 - ->setLabel(pht('Tab %d Name', $ii)); 101 - 102 - $out[] = id(new AphrontFormTokenizerControl()) 103 - ->setUser($this->getViewer()) 104 - ->setDatasource(new PhabricatorDashboardPanelDatasource()) 105 - ->setName($this->getFieldKey().'_panelID[]') 106 - ->setValue($panel_id) 107 - ->setLimit(1) 108 - ->setLabel(pht('Tab %d Panel', $ii)); 109 - } 110 - 111 - return $out; 112 - } 113 - 114 - }
+9 -2
src/applications/dashboard/editor/PhabricatorDashboardPanelEditEngine.php
··· 98 98 return $dashboard->getURI(); 99 99 } 100 100 101 - return parent::getEffectiveObjectDoneURI($object); 101 + return parent::getEffectiveObjectEditDoneURI($object); 102 102 } 103 103 104 104 protected function getObjectEditTitleText($object) { ··· 138 138 } 139 139 140 140 protected function buildCustomEditFields($object) { 141 - return array( 141 + $fields = array( 142 142 id(new PhabricatorTextEditField()) 143 143 ->setKey('name') 144 144 ->setLabel(pht('Name')) ··· 150 150 ->setIsRequired(true) 151 151 ->setValue($object->getName()), 152 152 ); 153 + 154 + $panel_fields = $object->getEditEngineFields(); 155 + foreach ($panel_fields as $panel_field) { 156 + $fields[] = $panel_field; 157 + } 158 + 159 + return $fields; 153 160 } 154 161 155 162 }
+7 -1
src/applications/dashboard/paneltype/PhabricatorDashboardPanelType.php
··· 5 5 abstract public function getPanelTypeKey(); 6 6 abstract public function getPanelTypeName(); 7 7 abstract public function getPanelTypeDescription(); 8 - abstract public function getFieldSpecifications(); 9 8 abstract public function getIcon(); 10 9 11 10 abstract public function renderPanelContent( ··· 52 51 ->setUniqueMethod('getPanelTypeKey') 53 52 ->execute(); 54 53 } 54 + 55 + final public function getEditEngineFields(PhabricatorDashboardPanel $panel) { 56 + return $this->newEditEngineFields($panel); 57 + } 58 + 59 + abstract protected function newEditEngineFields( 60 + PhabricatorDashboardPanel $panel); 55 61 56 62 }
+3 -17
src/applications/dashboard/paneltype/PhabricatorDashboardQueryPanelType.php
··· 21 21 'revisions you need to review.'); 22 22 } 23 23 24 - public function getFieldSpecifications() { 25 - return array( 26 - 'class' => array( 27 - 'name' => pht('Search For'), 28 - 'type' => 'search.application', 29 - ), 30 - 'key' => array( 31 - 'name' => pht('Query'), 32 - 'type' => 'search.query', 33 - 'control.application' => 'class', 34 - ), 35 - 'limit' => array( 36 - 'name' => pht('Limit'), 37 - 'caption' => pht('Leave this blank for the default number of items.'), 38 - 'type' => 'text', 39 - ), 40 - ); 24 + protected function newEditEngineFields(PhabricatorDashboardPanel $panel) { 25 + // TODO: Restore this using EditEngine instead of CustomField. 26 + return array(); 41 27 } 42 28 43 29 public function initializeFieldsFromRequest(
+3 -7
src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php
··· 19 19 return pht('Use tabs to switch between several other panels.'); 20 20 } 21 21 22 - public function getFieldSpecifications() { 23 - return array( 24 - 'config' => array( 25 - 'name' => pht('Tabs'), 26 - 'type' => 'dashboard.tabs', 27 - ), 28 - ); 22 + protected function newEditEngineFields(PhabricatorDashboardPanel $panel) { 23 + // TODO: Restore this using EditEngine instead of CustomField. 24 + return array(); 29 25 } 30 26 31 27 public function shouldRenderAsync() {
+7 -5
src/applications/dashboard/paneltype/PhabricatorDashboardTextPanelType.php
··· 21 21 'context.'); 22 22 } 23 23 24 - public function getFieldSpecifications() { 24 + protected function newEditEngineFields(PhabricatorDashboardPanel $panel) { 25 25 return array( 26 - 'text' => array( 27 - 'name' => pht('Text'), 28 - 'type' => 'remarkup', 29 - ), 26 + id(new PhabricatorRemarkupEditField()) 27 + ->setKey('text') 28 + ->setLabel(pht('Text')) 29 + ->setTransactionType( 30 + PhabricatorDashboardTextPanelTextTransaction::TRANSACTIONTYPE) 31 + ->setValue($panel->getProperty('text', '')), 30 32 ); 31 33 } 32 34
+4 -24
src/applications/dashboard/storage/PhabricatorDashboardPanel.php
··· 8 8 implements 9 9 PhabricatorApplicationTransactionInterface, 10 10 PhabricatorPolicyInterface, 11 - PhabricatorCustomFieldInterface, 12 11 PhabricatorFlaggableInterface, 13 12 PhabricatorDestructibleInterface, 14 13 PhabricatorNgramsInterface { ··· 20 19 protected $authorPHID; 21 20 protected $isArchived = 0; 22 21 protected $properties = array(); 23 - 24 - private $customFields = self::ATTACHABLE; 25 22 26 23 public static function initializeNewPanel(PhabricatorUser $actor) { 27 24 return id(new PhabricatorDashboardPanel()) ··· 105 102 return $impl; 106 103 } 107 104 105 + public function getEditEngineFields() { 106 + return $this->requireImplementation()->getEditEngineFields($this); 107 + } 108 + 108 109 109 110 /* -( PhabricatorApplicationTransactionInterface )------------------------- */ 110 111 ··· 139 140 140 141 public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { 141 142 return false; 142 - } 143 - 144 - 145 - /* -( PhabricatorCustomFieldInterface )------------------------------------ */ 146 - 147 - 148 - public function getCustomFieldSpecificationForRole($role) { 149 - return array(); 150 - } 151 - 152 - public function getCustomFieldBaseClass() { 153 - return 'PhabricatorDashboardPanelCustomField'; 154 - } 155 - 156 - public function getCustomFields() { 157 - return $this->assertAttached($this->customFields); 158 - } 159 - 160 - public function attachCustomFields(PhabricatorCustomFieldAttachment $fields) { 161 - $this->customFields = $fields; 162 - return $this; 163 143 } 164 144 165 145
+18
src/applications/dashboard/xaction/panel/PhabricatorDashboardPanelPropertyTransaction.php
··· 1 + <?php 2 + 3 + abstract class PhabricatorDashboardPanelPropertyTransaction 4 + extends PhabricatorDashboardPanelTransactionType { 5 + 6 + abstract protected function getPropertyKey(); 7 + 8 + public function generateOldValue($object) { 9 + $property_key = $this->getPropertyKey(); 10 + return $object->getProperty($property_key); 11 + } 12 + 13 + public function applyInternalEffects($object, $value) { 14 + $property_key = $this->getPropertyKey(); 15 + $object->setProperty($property_key, $value); 16 + } 17 + 18 + }
+12
src/applications/dashboard/xaction/panel/PhabricatorDashboardTextPanelTextTransaction.php
··· 1 + <?php 2 + 3 + final class PhabricatorDashboardTextPanelTextTransaction 4 + extends PhabricatorDashboardPanelPropertyTransaction { 5 + 6 + const TRANSACTIONTYPE = 'text.text'; 7 + 8 + protected function getPropertyKey() { 9 + return 'text'; 10 + } 11 + 12 + }