mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-25 06:50:55 +01:00
Partially move Releeph custom fields to PhabricatorCustomField
Summary: Fixes T3661. Ref T3718. This makes Releeph custom fields extend PhabricatorCustomField so we can start moving over other pieces of infrastructure (rendering, storage, etc) to run through the same pathways. It's roughly the minimum amount of work required to be able to move forward. NOTE: This removes per-project custom field selectors. Fields are now configured for an entire install. My understanding is that Facebook does not use this feature, and modern field infrastructure has moved away from selectors. Test Plan: Viewed and edited projects, branches, and requests in Releeph. Grepped for removed config. Grepped for `field_selector`. Reviewers: btrahan Reviewed By: btrahan CC: LegNeato, aran Maniphest Tasks: T3661, T3718 Differential Revision: https://secure.phabricator.com/D6750
This commit is contained in:
parent
ca0115b361
commit
74de24909b
24 changed files with 121 additions and 63 deletions
|
@ -4141,7 +4141,11 @@ phutil_register_library_map(array(
|
||||||
'ReleephDiffSizeFieldSpecification' => 'ReleephFieldSpecification',
|
'ReleephDiffSizeFieldSpecification' => 'ReleephFieldSpecification',
|
||||||
'ReleephEvent' => 'ReleephDAO',
|
'ReleephEvent' => 'ReleephDAO',
|
||||||
'ReleephFieldParseException' => 'Exception',
|
'ReleephFieldParseException' => 'Exception',
|
||||||
'ReleephFieldSpecification' => 'PhabricatorMarkupInterface',
|
'ReleephFieldSpecification' =>
|
||||||
|
array(
|
||||||
|
0 => 'PhabricatorCustomField',
|
||||||
|
1 => 'PhabricatorMarkupInterface',
|
||||||
|
),
|
||||||
'ReleephFieldSpecificationIncompleteException' => 'Exception',
|
'ReleephFieldSpecificationIncompleteException' => 'Exception',
|
||||||
'ReleephIntentFieldSpecification' => 'ReleephFieldSpecification',
|
'ReleephIntentFieldSpecification' => 'ReleephFieldSpecification',
|
||||||
'ReleephLevelFieldSpecification' => 'ReleephFieldSpecification',
|
'ReleephLevelFieldSpecification' => 'ReleephFieldSpecification',
|
||||||
|
|
|
@ -12,6 +12,37 @@ final class PhabricatorApplicationReleephConfigOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getOptions() {
|
public function getOptions() {
|
||||||
|
|
||||||
|
$default_fields = array(
|
||||||
|
new ReleephCommitMessageFieldSpecification(),
|
||||||
|
new ReleephSummaryFieldSpecification(),
|
||||||
|
new ReleephReasonFieldSpecification(),
|
||||||
|
new ReleephAuthorFieldSpecification(),
|
||||||
|
new ReleephRevisionFieldSpecification(),
|
||||||
|
new ReleephRequestorFieldSpecification(),
|
||||||
|
new ReleephSeverityFieldSpecification(),
|
||||||
|
new ReleephOriginalCommitFieldSpecification(),
|
||||||
|
new ReleephDiffMessageFieldSpecification(),
|
||||||
|
new ReleephStatusFieldSpecification(),
|
||||||
|
new ReleephIntentFieldSpecification(),
|
||||||
|
new ReleephBranchCommitFieldSpecification(),
|
||||||
|
new ReleephDiffSizeFieldSpecification(),
|
||||||
|
new ReleephDiffChurnFieldSpecification(),
|
||||||
|
);
|
||||||
|
|
||||||
|
$default = array();
|
||||||
|
foreach ($default_fields as $default_field) {
|
||||||
|
$default[$default_field->getFieldKey()] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($default as $key => $enabled) {
|
||||||
|
$default[$key] = array(
|
||||||
|
'disabled' => !$enabled,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$custom_field_type = 'custom:PhabricatorCustomFieldConfigOptionType';
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
$this->newOption('releeph.installed', 'bool', false)
|
$this->newOption('releeph.installed', 'bool', false)
|
||||||
->setSummary(pht('Enable the Releeph application.'))
|
->setSummary(pht('Enable the Releeph application.'))
|
||||||
|
@ -26,16 +57,8 @@ final class PhabricatorApplicationReleephConfigOptions
|
||||||
"set of alpha testers at Facebook. For the time being you are ".
|
"set of alpha testers at Facebook. For the time being you are ".
|
||||||
"strongly discouraged from relying on Releeph being at all ".
|
"strongly discouraged from relying on Releeph being at all ".
|
||||||
"stable.")),
|
"stable.")),
|
||||||
$this->newOption(
|
$this->newOption('releeph.fields', $custom_field_type, $default)
|
||||||
'releeph.field-selector',
|
->setCustomData('ReleephFieldSpecification'),
|
||||||
'class',
|
|
||||||
'ReleephDefaultFieldSelector')
|
|
||||||
->setBaseClass('ReleephFieldSelector')
|
|
||||||
->setSummary(pht('Field selector class'))
|
|
||||||
->setDescription(
|
|
||||||
pht(
|
|
||||||
"Control which fields are available when making a new Releeph ".
|
|
||||||
"request, and which are then shown in the Releeph UI.")),
|
|
||||||
$this->newOption(
|
$this->newOption(
|
||||||
'releeph.user-view',
|
'releeph.user-view',
|
||||||
'class',
|
'class',
|
||||||
|
|
|
@ -31,9 +31,6 @@ final class ReleephProjectEditController extends ReleephProjectController {
|
||||||
$test_paths = $this->getReleephProject()->getDetail('testPaths', array());
|
$test_paths = $this->getReleephProject()->getDetail('testPaths', array());
|
||||||
}
|
}
|
||||||
|
|
||||||
$field_selector = $request->getStr('fieldSelector',
|
|
||||||
get_class($this->getReleephProject()->getReleephFieldSelector()));
|
|
||||||
|
|
||||||
$release_counter = $request->getInt(
|
$release_counter = $request->getInt(
|
||||||
'releaseCounter',
|
'releaseCounter',
|
||||||
$this->getReleephProject()->getCurrentReleaseNumber());
|
$this->getReleephProject()->getCurrentReleaseNumber());
|
||||||
|
@ -82,7 +79,6 @@ final class ReleephProjectEditController extends ReleephProjectController {
|
||||||
->setTrunkBranch($trunk_branch)
|
->setTrunkBranch($trunk_branch)
|
||||||
->setDetail('pushers', $pusher_phids)
|
->setDetail('pushers', $pusher_phids)
|
||||||
->setDetail('pick_failure_instructions', $pick_failure_instructions)
|
->setDetail('pick_failure_instructions', $pick_failure_instructions)
|
||||||
->setDetail('field_selector', $field_selector)
|
|
||||||
->setDetail('branchTemplate', $branch_template)
|
->setDetail('branchTemplate', $branch_template)
|
||||||
->setDetail('commitWithAuthor', $commit_author)
|
->setDetail('commitWithAuthor', $commit_author)
|
||||||
->setDetail('testPaths', $test_paths);
|
->setDetail('testPaths', $test_paths);
|
||||||
|
@ -214,32 +210,6 @@ final class ReleephProjectEditController extends ReleephProjectController {
|
||||||
->setDatasource('/typeahead/common/users/')
|
->setDatasource('/typeahead/common/users/')
|
||||||
->setValue($pusher_tokens));
|
->setValue($pusher_tokens));
|
||||||
|
|
||||||
$field_selector_options = array();
|
|
||||||
$field_selector_symbols = id(new PhutilSymbolLoader())
|
|
||||||
->setType('class')
|
|
||||||
->setConcreteOnly(true)
|
|
||||||
->setAncestorClass('ReleephFieldSelector')
|
|
||||||
->selectAndLoadSymbols();
|
|
||||||
foreach ($field_selector_symbols as $symbol) {
|
|
||||||
$selector_name = $symbol['name'];
|
|
||||||
$field_selector_options[$selector_name] = $selector_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
$field_selector_blurb = pht(
|
|
||||||
"If you you have additional information to render about Releeph ".
|
|
||||||
"requests, or want to re-arrange the UI, implement a ".
|
|
||||||
"<tt>ReleephFieldSelector</tt> and select it here.");
|
|
||||||
|
|
||||||
$fields_inset = id(new AphrontFormInsetView())
|
|
||||||
->setTitle(pht('Fields'))
|
|
||||||
->appendChild($field_selector_blurb)
|
|
||||||
->appendChild(
|
|
||||||
id(new AphrontFormSelectControl())
|
|
||||||
->setLabel(pht('Selector'))
|
|
||||||
->setName('fieldSelector')
|
|
||||||
->setValue($field_selector)
|
|
||||||
->setOptions($field_selector_options));
|
|
||||||
|
|
||||||
$commit_author_inset = $this->buildCommitAuthorInset($commit_author);
|
$commit_author_inset = $this->buildCommitAuthorInset($commit_author);
|
||||||
|
|
||||||
// Build the Template inset
|
// Build the Template inset
|
||||||
|
@ -276,7 +246,6 @@ final class ReleephProjectEditController extends ReleephProjectController {
|
||||||
->setUser($request->getUser())
|
->setUser($request->getUser())
|
||||||
->appendChild($basic_inset)
|
->appendChild($basic_inset)
|
||||||
->appendChild($pushers_inset)
|
->appendChild($pushers_inset)
|
||||||
->appendChild($fields_inset)
|
|
||||||
->appendChild($commit_author_inset)
|
->appendChild($commit_author_inset)
|
||||||
->appendChild($template_inset);
|
->appendChild($template_inset);
|
||||||
|
|
||||||
|
|
|
@ -246,7 +246,7 @@ final class ReleephRequestEditController extends ReleephProjectController {
|
||||||
// Fields
|
// Fields
|
||||||
foreach ($fields as $field) {
|
foreach ($fields as $field) {
|
||||||
if ($field->isEditable()) {
|
if ($field->isEditable()) {
|
||||||
$control = $field->renderEditControl($request);
|
$control = $field->renderReleephEditControl($request);
|
||||||
$form->appendChild($control);
|
$form->appendChild($control);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,10 @@ final class ReleephAuthorFieldSpecification
|
||||||
|
|
||||||
private static $authorMap = array();
|
private static $authorMap = array();
|
||||||
|
|
||||||
|
public function getFieldKey() {
|
||||||
|
return 'author';
|
||||||
|
}
|
||||||
|
|
||||||
public function bulkLoad(array $releeph_requests) {
|
public function bulkLoad(array $releeph_requests) {
|
||||||
foreach ($releeph_requests as $releeph_request) {
|
foreach ($releeph_requests as $releeph_request) {
|
||||||
$commit = $releeph_request->loadPhabricatorRepositoryCommit();
|
$commit = $releeph_request->loadPhabricatorRepositoryCommit();
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
final class ReleephBranchCommitFieldSpecification
|
final class ReleephBranchCommitFieldSpecification
|
||||||
extends ReleephFieldSpecification {
|
extends ReleephFieldSpecification {
|
||||||
|
|
||||||
|
public function getFieldKey() {
|
||||||
|
return 'commit';
|
||||||
|
}
|
||||||
|
|
||||||
public function getName() {
|
public function getName() {
|
||||||
return 'Commit';
|
return 'Commit';
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
final class ReleephCommitMessageFieldSpecification
|
final class ReleephCommitMessageFieldSpecification
|
||||||
extends ReleephFieldSpecification {
|
extends ReleephFieldSpecification {
|
||||||
|
|
||||||
|
public function getFieldKey() {
|
||||||
|
return 'commit:apply';
|
||||||
|
}
|
||||||
|
|
||||||
public function getName() {
|
public function getName() {
|
||||||
return '__only_for_commit_message!';
|
return '__only_for_commit_message!';
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,10 @@ final class ReleephDiffChurnFieldSpecification
|
||||||
const UPDATES_WEIGHT = 10;
|
const UPDATES_WEIGHT = 10;
|
||||||
const MAX_POINTS = 100;
|
const MAX_POINTS = 100;
|
||||||
|
|
||||||
|
public function getFieldKey() {
|
||||||
|
return 'churn';
|
||||||
|
}
|
||||||
|
|
||||||
public function getName() {
|
public function getName() {
|
||||||
return 'Churn';
|
return 'Churn';
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
final class ReleephDiffMessageFieldSpecification
|
final class ReleephDiffMessageFieldSpecification
|
||||||
extends ReleephFieldSpecification {
|
extends ReleephFieldSpecification {
|
||||||
|
|
||||||
|
public function getFieldKey() {
|
||||||
|
return 'commit:message';
|
||||||
|
}
|
||||||
|
|
||||||
public function getName() {
|
public function getName() {
|
||||||
return 'Message';
|
return 'Message';
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,10 @@ final class ReleephDiffSizeFieldSpecification
|
||||||
const PATHS_WEIGHT = 30;
|
const PATHS_WEIGHT = 30;
|
||||||
const MAX_POINTS = 1000;
|
const MAX_POINTS = 1000;
|
||||||
|
|
||||||
|
public function getFieldKey() {
|
||||||
|
return 'commit:size';
|
||||||
|
}
|
||||||
|
|
||||||
public function getName() {
|
public function getName() {
|
||||||
return 'Size';
|
return 'Size';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
abstract class ReleephFieldSpecification
|
abstract class ReleephFieldSpecification
|
||||||
|
extends PhabricatorCustomField
|
||||||
implements PhabricatorMarkupInterface {
|
implements PhabricatorMarkupInterface {
|
||||||
|
|
||||||
abstract public function getName();
|
abstract public function getName();
|
||||||
|
@ -83,7 +84,7 @@ abstract class ReleephFieldSpecification
|
||||||
|
|
||||||
/* -( Edit View )---------------------------------------------------------- */
|
/* -( Edit View )---------------------------------------------------------- */
|
||||||
|
|
||||||
public function renderEditControl(AphrontRequest $request) {
|
public function renderReleephEditControl(AphrontRequest $request) {
|
||||||
throw new ReleephFieldSpecificationIncompleteException($this);
|
throw new ReleephFieldSpecificationIncompleteException($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
final class ReleephIntentFieldSpecification
|
final class ReleephIntentFieldSpecification
|
||||||
extends ReleephFieldSpecification {
|
extends ReleephFieldSpecification {
|
||||||
|
|
||||||
|
public function getFieldKey() {
|
||||||
|
return 'intent';
|
||||||
|
}
|
||||||
|
|
||||||
public function getName() {
|
public function getName() {
|
||||||
return 'Intent';
|
return 'Intent';
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ abstract class ReleephLevelFieldSpecification
|
||||||
return $this->getNameForLevel($level);
|
return $this->getNameForLevel($level);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function renderEditControl(AphrontRequest $request) {
|
public function renderReleephEditControl(AphrontRequest $request) {
|
||||||
$control_name = $this->getRequiredStorageKey();
|
$control_name = $this->getRequiredStorageKey();
|
||||||
$all_levels = $this->getLevels();
|
$all_levels = $this->getLevels();
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
final class ReleephOriginalCommitFieldSpecification
|
final class ReleephOriginalCommitFieldSpecification
|
||||||
extends ReleephFieldSpecification {
|
extends ReleephFieldSpecification {
|
||||||
|
|
||||||
|
public function getFieldKey() {
|
||||||
|
return 'commit:name';
|
||||||
|
}
|
||||||
|
|
||||||
public function getName() {
|
public function getName() {
|
||||||
return 'Commit';
|
return 'Commit';
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
final class ReleephReasonFieldSpecification
|
final class ReleephReasonFieldSpecification
|
||||||
extends ReleephFieldSpecification {
|
extends ReleephFieldSpecification {
|
||||||
|
|
||||||
|
public function getFieldKey() {
|
||||||
|
return 'reason';
|
||||||
|
}
|
||||||
|
|
||||||
public function getName() {
|
public function getName() {
|
||||||
return 'Reason';
|
return 'Reason';
|
||||||
}
|
}
|
||||||
|
@ -31,7 +35,7 @@ final class ReleephReasonFieldSpecification
|
||||||
|
|
||||||
private $error = true;
|
private $error = true;
|
||||||
|
|
||||||
public function renderEditControl(AphrontRequest $request) {
|
public function renderReleephEditControl(AphrontRequest $request) {
|
||||||
$reason = $request->getStr('reason', $this->getValue());
|
$reason = $request->getStr('reason', $this->getValue());
|
||||||
return id(new AphrontFormTextAreaControl())
|
return id(new AphrontFormTextAreaControl())
|
||||||
->setLabel('Reason')
|
->setLabel('Reason')
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
final class ReleephRequestorFieldSpecification
|
final class ReleephRequestorFieldSpecification
|
||||||
extends ReleephFieldSpecification {
|
extends ReleephFieldSpecification {
|
||||||
|
|
||||||
|
public function getFieldKey() {
|
||||||
|
return 'requestor';
|
||||||
|
}
|
||||||
|
|
||||||
public function bulkLoad(array $releeph_requests) {
|
public function bulkLoad(array $releeph_requests) {
|
||||||
$phids = mpull($releeph_requests, 'getRequestUserPHID');
|
$phids = mpull($releeph_requests, 'getRequestUserPHID');
|
||||||
ReleephUserView::getNewInstance()
|
ReleephUserView::getNewInstance()
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
final class ReleephRevisionFieldSpecification
|
final class ReleephRevisionFieldSpecification
|
||||||
extends ReleephFieldSpecification {
|
extends ReleephFieldSpecification {
|
||||||
|
|
||||||
|
public function getFieldKey() {
|
||||||
|
return 'revision';
|
||||||
|
}
|
||||||
|
|
||||||
public function getName() {
|
public function getName() {
|
||||||
return 'Revision';
|
return 'Revision';
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,10 @@ final class ReleephRiskFieldSpecification
|
||||||
'HIGH' => 'This is pretty risky, but is also very important.',
|
'HIGH' => 'This is pretty risky, but is also very important.',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public function getFieldKey() {
|
||||||
|
return 'risk';
|
||||||
|
}
|
||||||
|
|
||||||
public function getName() {
|
public function getName() {
|
||||||
return 'Riskiness';
|
return 'Riskiness';
|
||||||
}
|
}
|
||||||
|
@ -23,7 +27,7 @@ final class ReleephRiskFieldSpecification
|
||||||
|
|
||||||
private $error = true;
|
private $error = true;
|
||||||
|
|
||||||
public function renderEditControl(AphrontRequest $request) {
|
public function renderReleephEditControl(AphrontRequest $request) {
|
||||||
$value = $request->getStr('risk', $this->getValue());
|
$value = $request->getStr('risk', $this->getValue());
|
||||||
$buttons = id(new AphrontFormRadioButtonControl())
|
$buttons = id(new AphrontFormRadioButtonControl())
|
||||||
->setLabel('Riskiness')
|
->setLabel('Riskiness')
|
||||||
|
|
|
@ -6,6 +6,10 @@ final class ReleephSeverityFieldSpecification
|
||||||
const HOTFIX = 'HOTFIX';
|
const HOTFIX = 'HOTFIX';
|
||||||
const RELEASE = 'RELEASE';
|
const RELEASE = 'RELEASE';
|
||||||
|
|
||||||
|
public function getFieldKey() {
|
||||||
|
return 'severity';
|
||||||
|
}
|
||||||
|
|
||||||
public function getName() {
|
public function getName() {
|
||||||
return 'Severity';
|
return 'Severity';
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
final class ReleephStatusFieldSpecification
|
final class ReleephStatusFieldSpecification
|
||||||
extends ReleephFieldSpecification {
|
extends ReleephFieldSpecification {
|
||||||
|
|
||||||
|
public function getFieldKey() {
|
||||||
|
return 'status';
|
||||||
|
}
|
||||||
|
|
||||||
public function getName() {
|
public function getName() {
|
||||||
return 'Status';
|
return 'Status';
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,10 @@ final class ReleephSummaryFieldSpecification
|
||||||
|
|
||||||
const MAX_SUMMARY_LENGTH = 60;
|
const MAX_SUMMARY_LENGTH = 60;
|
||||||
|
|
||||||
|
public function getFieldKey() {
|
||||||
|
return 'summary';
|
||||||
|
}
|
||||||
|
|
||||||
public function getName() {
|
public function getName() {
|
||||||
return 'Summary';
|
return 'Summary';
|
||||||
}
|
}
|
||||||
|
@ -15,7 +19,7 @@ final class ReleephSummaryFieldSpecification
|
||||||
|
|
||||||
private $error = false;
|
private $error = false;
|
||||||
|
|
||||||
public function renderEditControl(AphrontRequest $request) {
|
public function renderReleephEditControl(AphrontRequest $request) {
|
||||||
$summary = $request->getStr('summary', $this->getValue());
|
$summary = $request->getStr('summary', $this->getValue());
|
||||||
return id(new AphrontFormTextControl())
|
return id(new AphrontFormTextControl())
|
||||||
->setLabel('Summary')
|
->setLabel('Summary')
|
||||||
|
|
|
@ -141,17 +141,7 @@ final class ReleephProject extends ReleephDAO
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getReleephFieldSelector() {
|
public function getReleephFieldSelector() {
|
||||||
$class = $this->getDetail('field_selector');
|
return new ReleephDefaultFieldSelector();
|
||||||
if (!$class) {
|
|
||||||
$key = 'releeph.field-selector';
|
|
||||||
$class = PhabricatorEnv::getEnvConfig($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($class) {
|
|
||||||
return newv($class, array());
|
|
||||||
} else {
|
|
||||||
return new ReleephDefaultFieldSelector();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,9 +3,18 @@
|
||||||
final class PhabricatorCustomFieldImplementationIncompleteException
|
final class PhabricatorCustomFieldImplementationIncompleteException
|
||||||
extends Exception {
|
extends Exception {
|
||||||
|
|
||||||
public function __construct(PhabricatorCustomField $field) {
|
public function __construct(
|
||||||
$key = $field->getFieldKey();
|
PhabricatorCustomField $field,
|
||||||
$name = $field->getFieldName();
|
$field_key_is_incomplete = false) {
|
||||||
|
|
||||||
|
if ($field_key_is_incomplete) {
|
||||||
|
$key = pht('<incomplete key>');
|
||||||
|
$name = pht('<incomplete name>');
|
||||||
|
} else {
|
||||||
|
$key = $field->getFieldKey();
|
||||||
|
$name = $field->getFieldName();
|
||||||
|
}
|
||||||
|
|
||||||
$class = get_class($field);
|
$class = get_class($field);
|
||||||
|
|
||||||
parent::__construct(
|
parent::__construct(
|
||||||
|
|
|
@ -154,7 +154,9 @@ abstract class PhabricatorCustomField {
|
||||||
if ($this->proxy) {
|
if ($this->proxy) {
|
||||||
return $this->proxy->getFieldKey();
|
return $this->proxy->getFieldKey();
|
||||||
}
|
}
|
||||||
throw new PhabricatorCustomFieldImplementationIncompleteException($this);
|
throw new PhabricatorCustomFieldImplementationIncompleteException(
|
||||||
|
$this,
|
||||||
|
$field_key_is_incomplete = true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue