diff --git a/src/applications/differential/view/DifferentialRevisionListView.php b/src/applications/differential/view/DifferentialRevisionListView.php --- a/src/applications/differential/view/DifferentialRevisionListView.php +++ b/src/applications/differential/view/DifferentialRevisionListView.php @@ -153,6 +153,13 @@ $revision->getStatusIcon(), $revision->getStatusDisplayName()); + // TODO Is it enough to get $field_list once for the entire list? + $field_list = PhabricatorCustomField::getObjectFields( + $revision, + PhabricatorCustomField::ROLE_LIST); + $field_list + ->appendFieldsToListItem($revision, $this->getViewer(), $item); + $list->addItem($item); } diff --git a/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php b/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php --- a/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php +++ b/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php @@ -297,14 +297,18 @@ EOTEXT )); + $custom_fields_href = PhabricatorEnv::getDoclink( + 'Configuring Custom Fields'); + return array( $this->newOption('maniphest.custom-field-definitions', 'wild', array()) ->setSummary(pht('Custom Maniphest fields.')) ->setDescription( pht( 'Array of custom fields for Maniphest tasks. For details on '. - 'adding custom fields to Maniphest, see "Configuring Custom '. - 'Fields" in the documentation.')) + 'adding custom fields to Maniphest, see **[[ %s | Configuring '. + 'Custom Fields ]]** in the documentation.', + $custom_fields_href)) ->addExample($fields_json, pht('Valid setting')), $this->newOption('maniphest.fields', $custom_field_type, $default_fields) ->setCustomData(id(new ManiphestTask())->getCustomFieldBaseClass()) diff --git a/src/applications/maniphest/view/ManiphestTaskListView.php b/src/applications/maniphest/view/ManiphestTaskListView.php --- a/src/applications/maniphest/view/ManiphestTaskListView.php +++ b/src/applications/maniphest/view/ManiphestTaskListView.php @@ -64,6 +64,13 @@ ->setHeader($task->getTitle()) ->setHref('/T'.$task->getID()); + // TODO Is it enough to get $field_list once for the entire list? + $field_list = PhabricatorCustomField::getObjectFields( + $task, + PhabricatorCustomField::ROLE_LIST); + $field_list + ->appendFieldsToListItem($task, $this->getViewer(), $item); + if ($task->getOwnerPHID()) { $owner = $handles[$task->getOwnerPHID()]; $item->addByline(pht('Assigned: %s', $owner->renderLink())); diff --git a/src/infrastructure/customfield/field/PhabricatorCustomField.php b/src/infrastructure/customfield/field/PhabricatorCustomField.php --- a/src/infrastructure/customfield/field/PhabricatorCustomField.php +++ b/src/infrastructure/customfield/field/PhabricatorCustomField.php @@ -1278,12 +1278,22 @@ * @task list */ public function renderOnListItem(PHUIObjectItemView $view) { + if ($this->proxy) { return $this->proxy->renderOnListItem($view); } throw new PhabricatorCustomFieldImplementationIncompleteException($this); } + /** + * @task list + */ + public function getRequiredHandlePHIDsForListView() { + if ($this->proxy) { + return $this->proxy->getRequiredHandlePHIDsForPropertyView(); + } + return array(); + } /* -( Global Search )------------------------------------------------------ */ diff --git a/src/infrastructure/customfield/field/PhabricatorCustomFieldList.php b/src/infrastructure/customfield/field/PhabricatorCustomFieldList.php --- a/src/infrastructure/customfield/field/PhabricatorCustomFieldList.php +++ b/src/infrastructure/customfield/field/PhabricatorCustomFieldList.php @@ -200,6 +200,23 @@ } } + public function appendFieldsToListItem( + PhabricatorCustomFieldInterface $object, + PhabricatorUser $viewer, + PHUIObjectItemView $view) { + + $this->readFieldsFromStorage($object); + $fields = $this->fields; + + foreach ($fields as $field) { + $field->setViewer($viewer); + } + + foreach ($fields as $key => $field) { + $field->renderOnListItem($view); + } + } + public function buildFieldTransactionsFromRequest( PhabricatorApplicationTransaction $template, AphrontRequest $request) { diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php @@ -286,13 +286,86 @@ return $this->getFieldConfigValue('view', true); } - public function renderPropertyViewValue(array $handles) { + public function shouldAppearInListView() { + return $this->getFieldConfigValue('list', false); + } + + protected function renderValue() { if (!strlen($this->getFieldValue())) { return null; } return $this->getFieldValue(); } + public function renderPropertyViewValue(array $handles) { + return $this->renderValue($handles); + } + + public function getStyleForListItemView() { + return $this->getFieldConfigValue('list'); + } + + public function renderListItemValue() { + return $this->renderValue(); + } + + private function isValue($something) { + // Sometimes renderValue() retuns a PHUISomething, strlen() of which is NULL + // but it has some value. + if (is_object($something)) { + return true; + } + return strlen($something); + } + + public function getListItemValue() { + $style = $this->getStyleForListItemView(); + $value = $this->renderListItemValue(); + if (!$this->isValue($value) || !$style) { + return null; + } + switch ($style) { + case 'icon': + // TODO maybe expose 'list.icon.alt' for hover stuff. + return $this->getFieldConfigValue('list.icon'); + case 'attribute': + case 'byline': + $label = $this->getFieldConfigValue('list.label'); + if (strlen($label)) { + return pht('%s: %s', $label, $value); + } + return $value; + default: + throw new Exception( + pht( + "Unknown field list-item view style '%s'; valid styles are ". + "'%s', '%s'and '%s'.", + $style, + 'icon', + 'attribute', + 'byline')); + } + } + + public function renderOnListItem(PHUIObjectItemView $view) { + $value = $this->getListItemValue(); + if (!$this->isValue($value)) { + return; + } + + switch ($this->getStyleForListItemView()) { + case 'icon': + $view->addIcon($value); + break; + case 'attribute': + $view->addAttribute($value); + break; + case 'byline': + $view->addByline($value); + break; + } + } + public function shouldAppearInApplicationSearch() { return $this->getFieldConfigValue('search', false); } diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldBlueprints.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldBlueprints.php --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldBlueprints.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldBlueprints.php @@ -24,7 +24,7 @@ $new); } - public function renderPropertyViewValue(array $handles) { + protected function renderValue() { $value = $this->getFieldValue(); if (!$value) { return phutil_tag('em', array(), pht('No authorized blueprints.')); diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldBool.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldBool.php --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldBool.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldBool.php @@ -90,7 +90,7 @@ (bool)$this->getFieldValue()); } - public function renderPropertyViewValue(array $handles) { + protected function renderValue() { $value = $this->getFieldValue(); if ($value) { return $this->getString('view.yes', pht('Yes')); diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldCredential.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldCredential.php --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldCredential.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldCredential.php @@ -53,10 +53,10 @@ return array(); } - public function renderPropertyViewValue(array $handles) { + protected function renderValue() { $value = $this->getFieldValue(); if ($value) { - return $handles[$value]->renderLink(); + return $this->getViewer()->renderHandle($value); } return null; } diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php @@ -52,7 +52,7 @@ $this->setFieldValue($value); } - public function renderPropertyViewValue(array $handles) { + protected function renderValue() { $value = $this->getFieldValue(); if (!$value) { return null; diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldHeader.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldHeader.php --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldHeader.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldHeader.php @@ -26,7 +26,7 @@ return 'header'; } - public function renderPropertyViewValue(array $handles) { + protected function renderValue() { return $this->getFieldName(); } diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldLink.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldLink.php --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldLink.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldLink.php @@ -18,7 +18,7 @@ return $indexes; } - public function renderPropertyViewValue(array $handles) { + protected function renderValue() { $value = $this->getFieldValue(); if (!strlen($value)) { diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php @@ -77,15 +77,14 @@ return array(); } - public function renderPropertyViewValue(array $handles) { + protected function renderValue() { $value = $this->getFieldValue(); if (!$value) { return null; } - $handles = mpull($handles, 'renderHovercardLink'); - $handles = phutil_implode_html(', ', $handles); - return $handles; + return $this->getViewer()->renderHandleList($value) + ->setAsInline(true); } public function getRequiredHandlePHIDsForEdit() { diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldRemarkup.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldRemarkup.php --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldRemarkup.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldRemarkup.php @@ -27,7 +27,7 @@ ); } - public function renderPropertyViewValue(array $handles) { + protected function renderValue() { $value = $this->getFieldValue(); if (!strlen($value)) { @@ -42,6 +42,10 @@ return new PHUIRemarkupView($viewer, $value); } + public function shouldAppearInListView() { + return false; + } + public function getApplicationTransactionTitle( PhabricatorApplicationTransaction $xaction) { $author_phid = $xaction->getAuthorPHID(); diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldSelect.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldSelect.php --- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldSelect.php +++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldSelect.php @@ -72,7 +72,7 @@ ->setOptions($this->getOptions()); } - public function renderPropertyViewValue(array $handles) { + protected function renderValue() { if (!strlen($this->getFieldValue())) { return null; }