Differential D17067 Diff 41083 src/applications/differential/conduit/DifferentialConduitAPIMethod.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/differential/conduit/DifferentialConduitAPIMethod.php
| Show First 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | protected function applyFieldEdit( | ||||
| ConduitAPIRequest $request, | ConduitAPIRequest $request, | ||||
| DifferentialRevision $revision, | DifferentialRevision $revision, | ||||
| DifferentialDiff $diff, | DifferentialDiff $diff, | ||||
| array $fields, | array $fields, | ||||
| $message) { | $message) { | ||||
| $viewer = $request->getUser(); | $viewer = $request->getUser(); | ||||
| $field_list = PhabricatorCustomField::getObjectFields( | // We're going to build the body of a "differential.revision.edit" API | ||||
| $revision, | // request, then just call that code directly. | ||||
| DifferentialCustomField::ROLE_COMMITMESSAGEEDIT); | |||||
| $field_list | |||||
| ->setViewer($viewer) | |||||
| ->readFieldsFromStorage($revision); | |||||
| $field_map = mpull($field_list->getFields(), null, 'getFieldKeyForConduit'); | |||||
| $xactions = array(); | $xactions = array(); | ||||
| $xactions[] = array( | |||||
| 'type' => DifferentialRevisionEditEngine::KEY_UPDATE, | |||||
| 'value' => $diff->getPHID(), | |||||
| ); | |||||
| $xactions[] = id(new DifferentialTransaction()) | $field_map = DifferentialCommitMessageField::newEnabledFields($viewer); | ||||
| ->setTransactionType(DifferentialTransaction::TYPE_UPDATE) | |||||
| ->setNewValue($diff->getPHID()); | |||||
| $values = $request->getValue('fields', array()); | $values = $request->getValue('fields', array()); | ||||
| foreach ($values as $key => $value) { | foreach ($values as $key => $value) { | ||||
| $field = idx($field_map, $key); | $field = idx($field_map, $key); | ||||
| if (!$field) { | if (!$field) { | ||||
| // NOTE: We're just ignoring fields we don't know about. This isn't | // NOTE: We're just ignoring fields we don't know about. This isn't | ||||
| // ideal, but the way the workflow currently works involves us getting | // ideal, but the way the workflow currently works involves us getting | ||||
| // several read-only fields, like the revision ID field, which we should | // several read-only fields, like the revision ID field, which we should | ||||
| // just skip. | // just skip. | ||||
| continue; | continue; | ||||
| } | } | ||||
| $role = PhabricatorCustomField::ROLE_APPLICATIONTRANSACTIONS; | |||||
| if (!$field->shouldEnableForRole($role)) { | |||||
| continue; | |||||
| } | |||||
| // TODO: This is fairly similar to PhabricatorCustomField's | |||||
| // buildFieldTransactionsFromRequest() method, but that's currently not | |||||
| // easy to reuse. | |||||
| $transaction_type = $field->getApplicationTransactionType(); | |||||
| $xaction = id(new DifferentialTransaction()) | |||||
| ->setTransactionType($transaction_type); | |||||
| if ($transaction_type == PhabricatorTransactions::TYPE_CUSTOMFIELD) { | |||||
| // For TYPE_CUSTOMFIELD transactions only, we provide the old value | |||||
| // as an input. | |||||
| $old_value = $field->getOldValueForApplicationTransactions(); | |||||
| $xaction->setOldValue($old_value); | |||||
| } | |||||
| // The transaction itself will be validated so this is somewhat | // The transaction itself will be validated so this is somewhat | ||||
| // redundant, but this validator will sometimes give us a better error | // redundant, but this validator will sometimes give us a better error | ||||
| // message or a better reaction to a bad value type. | // message or a better reaction to a bad value type. | ||||
| $field->validateCommitMessageValue($value); | $value = $field->readFieldValueFromConduit($value); | ||||
| $field->readValueFromCommitMessage($value); | |||||
| $xaction | |||||
| ->setNewValue($field->getNewValueForApplicationTransactions()); | |||||
| if ($transaction_type == PhabricatorTransactions::TYPE_CUSTOMFIELD) { | |||||
| // For TYPE_CUSTOMFIELD transactions, add the field key in metadata. | |||||
| $xaction->setMetadataValue('customfield:key', $field->getFieldKey()); | |||||
| } | |||||
| $metadata = $field->getApplicationTransactionMetadata(); | |||||
| foreach ($metadata as $meta_key => $meta_value) { | |||||
| $xaction->setMetadataValue($meta_key, $meta_value); | |||||
| } | |||||
| foreach ($field->getFieldTransactions($value) as $xaction) { | |||||
| $xactions[] = $xaction; | $xactions[] = $xaction; | ||||
| } | } | ||||
| } | |||||
| $message = $request->getValue('message'); | $message = $request->getValue('message'); | ||||
| if (strlen($message)) { | if (strlen($message)) { | ||||
| // This is a little awkward, and should maybe move inside the transaction | // This is a little awkward, and should move elsewhere or be removed. It | ||||
| // editor. It largely exists for legacy reasons. See some discussion in | // largely exists for legacy reasons. See some discussion in T7899. | ||||
| // T7899. | |||||
| $first_line = head(phutil_split_lines($message, false)); | $first_line = head(phutil_split_lines($message, false)); | ||||
| $first_line = id(new PhutilUTF8StringTruncator()) | $first_line = id(new PhutilUTF8StringTruncator()) | ||||
| ->setMaximumBytes(250) | ->setMaximumBytes(250) | ||||
| ->setMaximumGlyphs(80) | ->setMaximumGlyphs(80) | ||||
| ->truncateString($first_line); | ->truncateString($first_line); | ||||
| $diff->setDescription($first_line); | $diff->setDescription($first_line); | ||||
| $diff->save(); | $diff->save(); | ||||
| $xactions[] = id(new DifferentialTransaction()) | $xactions[] = array( | ||||
| ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) | 'type' => PhabricatorCommentEditEngineExtension::EDITKEY, | ||||
| ->attachComment( | 'value' => $message, | ||||
| id(new DifferentialTransactionComment()) | ); | ||||
| ->setContent($message)); | |||||
| } | } | ||||
| $editor = id(new DifferentialTransactionEditor()) | $method = 'differential.revision.edit'; | ||||
| ->setActor($viewer) | $params = array( | ||||
| ->setContentSource($request->newContentSource()) | 'transactions' => $xactions, | ||||
| ->setContinueOnNoEffect(true) | ); | ||||
| ->setContinueOnMissingFields(true); | |||||
| $editor->applyTransactions($revision, $xactions); | if ($revision->getID()) { | ||||
| $params['objectIdentifier'] = $revision->getID(); | |||||
| } | |||||
| return id(new ConduitCall($method, $params, $strict = true)) | |||||
| ->setUser($viewer) | |||||
| ->execute(); | |||||
| } | } | ||||
| protected function loadCustomFieldsForRevisions( | protected function loadCustomFieldsForRevisions( | ||||
| PhabricatorUser $viewer, | PhabricatorUser $viewer, | ||||
| array $revisions) { | array $revisions) { | ||||
| assert_instances_of($revisions, 'DifferentialRevision'); | assert_instances_of($revisions, 'DifferentialRevision'); | ||||
| if (!$revisions) { | if (!$revisions) { | ||||
| ▲ Show 20 Lines • Show All 69 Lines • Show Last 20 Lines | |||||