public function appendFieldsToPropertyList(PhabricatorCustomFieldInterface $object, PhabricatorUser $viewer, PHUIPropertyListView $view) { $this->readFieldsFromStorage($object); $fields = $this->fields; foreach ($fields as $field) { $field->setViewer($viewer); } // Move all the blocks to the end, regardless of their configuration order, // because it always looks silly to render a block in the middle of a list // of properties. $head = array(); $tail = array(); foreach ($fields as $key => $field) { $style = $field->getStyleForPropertyView(); switch ($style) { case 'property': case 'header': $head[$key] = $field; break; case 'block': $tail[$key] = $field; break; default: throw new Exception(pht("Unknown field property view style '%s'; valid styles are " . "'%s' and '%s'.", $style, 'block', 'property')); } } $fields = $head + $tail; $add_header = null; $phids = array(); foreach ($fields as $key => $field) { $phids[$key] = $field->getRequiredHandlePHIDsForPropertyView(); } $all_phids = array_mergev($phids); if ($all_phids) { $handles = id(new PhabricatorHandleQuery())->setViewer($viewer)->withPHIDs($all_phids)->execute(); } else { $handles = array(); } foreach ($fields as $key => $field) { $field_handles = array_select_keys($handles, $phids[$key]); $label = $field->renderPropertyViewLabel(); $value = $field->renderPropertyViewValue($field_handles); if ($value !== null) { switch ($field->getStyleForPropertyView()) { case 'header': // We want to hide headers if the fields the're assciated with // don't actually produce any visible properties. For example, in a // list like this: // // Header A // Prop A: Value A // Header B // Prop B: Value B // // ...if the "Prop A" field returns `null` when rendering its // property value and we rendered naively, we'd get this: // // Header A // Header B // Prop B: Value B // // This is silly. Instead, we hide "Header A". $add_header = $value; break; case 'property': if ($add_header !== null) { // Add the most recently seen header. $view->addSectionHeader($add_header); $add_header = null; } $view->addProperty($label, $value); break; case 'block': $icon = $field->getIconForPropertyView(); $view->invokeWillRenderEvent(); if ($label !== null) { $view->addSectionHeader($label, $icon); } $view->addTextContent($value); break; } } } }