Path: blob/master/src/applications/differential/conduit/DifferentialGetCommitMessageConduitAPIMethod.php
12256 views
<?php12final class DifferentialGetCommitMessageConduitAPIMethod3extends DifferentialConduitAPIMethod {45public function getAPIMethodName() {6return 'differential.getcommitmessage';7}89public function getMethodDescription() {10return pht('Retrieve Differential commit messages or message templates.');11}1213protected function defineParamTypes() {14$edit_types = array('edit', 'create');1516return array(17'revision_id' => 'optional revision_id',18'fields' => 'optional dict<string, wild>',19'edit' => 'optional '.$this->formatStringConstants($edit_types),20);21}2223protected function defineReturnType() {24return 'nonempty string';25}2627protected function defineErrorTypes() {28return array(29'ERR_NOT_FOUND' => pht('Revision was not found.'),30);31}3233protected function execute(ConduitAPIRequest $request) {34$id = $request->getValue('revision_id');35$viewer = $request->getUser();3637if ($id) {38$revision = id(new DifferentialRevisionQuery())39->withIDs(array($id))40->setViewer($viewer)41->needReviewers(true)42->needActiveDiffs(true)43->executeOne();44if (!$revision) {45throw new ConduitException('ERR_NOT_FOUND');46}47} else {48$revision = DifferentialRevision::initializeNewRevision($viewer);49}5051// There are three modes here: "edit", "create", and "read" (which has52// no value for the "edit" parameter).5354// In edit or create mode, we hide read-only fields. In create mode, we55// show "Field:" templates for some fields even if they are empty.56$edit_mode = $request->getValue('edit');5758$is_any_edit = $edit_mode !== null && (bool)strlen($edit_mode);59$is_create = ($edit_mode == 'create');6061$field_list = DifferentialCommitMessageField::newEnabledFields($viewer);6263$custom_storage = $this->loadCustomFieldStorage($viewer, $revision);64foreach ($field_list as $field) {65$field->setCustomFieldStorage($custom_storage);66}6768// If we're editing the message, remove fields like "Conflicts" and69// "git-svn-id" which should not be presented to the user for editing.70if ($is_any_edit) {71foreach ($field_list as $field_key => $field) {72if (!$field->isFieldEditable()) {73unset($field_list[$field_key]);74}75}76}7778$overrides = $request->getValue('fields', array());7980$value_map = array();81foreach ($field_list as $field_key => $field) {82if (array_key_exists($field_key, $overrides)) {83$field_value = $overrides[$field_key];84} else {85$field_value = $field->readFieldValueFromObject($revision);86}8788// We're calling this method on the value no matter where we got it89// from, so we hit the same validation logic for values which came over90// the wire and which we generated.91$field_value = $field->readFieldValueFromConduit($field_value);9293$value_map[$field_key] = $field_value;94}9596$key_title = DifferentialTitleCommitMessageField::FIELDKEY;9798$commit_message = array();99foreach ($field_list as $field_key => $field) {100$label = $field->getFieldName();101$wire_value = $value_map[$field_key];102$value = $field->renderFieldValue($wire_value);103104$is_template = ($is_create && $field->isTemplateField());105106if (!is_string($value) && !is_null($value)) {107throw new Exception(108pht(109'Commit message field "%s" was expected to render a string or '.110'null value, but rendered a "%s" instead.',111$field->getFieldKey(),112gettype($value)));113}114115$is_title = ($field_key == $key_title);116117if ($value === null || !strlen($value)) {118if ($is_template) {119$commit_message[] = $label.': ';120}121} else {122if ($is_title) {123$commit_message[] = $value;124} else {125$value = str_replace(126array("\r\n", "\r"),127array("\n", "\n"),128$value);129if (strpos($value, "\n") !== false || substr($value, 0, 2) === ' ') {130$commit_message[] = "{$label}:\n{$value}";131} else {132$commit_message[] = "{$label}: {$value}";133}134}135}136}137138return implode("\n\n", $commit_message);139}140141private function loadCustomFieldStorage(142PhabricatorUser $viewer,143DifferentialRevision $revision) {144145$custom_field_list = PhabricatorCustomField::getObjectFields(146$revision,147PhabricatorCustomField::ROLE_STORAGE);148149$custom_field_list150->setViewer($viewer)151->readFieldsFromStorage($revision);152153$custom_field_map = array();154foreach ($custom_field_list->getFields() as $custom_field) {155if (!$custom_field->shouldUseStorage()) {156continue;157}158$custom_field_key = $custom_field->getFieldKey();159$custom_field_value = $custom_field->getValueForStorage();160$custom_field_map[$custom_field_key] = $custom_field_value;161}162163return $custom_field_map;164}165166167}168169170