Path: blob/master/src/applications/differential/conduit/DifferentialConduitAPIMethod.php
12256 views
<?php12abstract class DifferentialConduitAPIMethod extends ConduitAPIMethod {34final public function getApplication() {5return PhabricatorApplication::getByClass(6'PhabricatorDifferentialApplication');7}89protected function buildDiffInfoDictionary(DifferentialDiff $diff) {10$uri = '/differential/diff/'.$diff->getID().'/';11$uri = PhabricatorEnv::getProductionURI($uri);1213return array(14'id' => $diff->getID(),15'phid' => $diff->getPHID(),16'uri' => $uri,17);18}1920protected function buildInlineInfoDictionary(21DifferentialInlineComment $inline,22DifferentialChangeset $changeset = null) {2324$file_path = null;25$diff_id = null;26if ($changeset) {27$file_path = $inline->getIsNewFile()28? $changeset->getFilename()29: $changeset->getOldFile();3031$diff_id = $changeset->getDiffID();32}3334return array(35'id' => $inline->getID(),36'authorPHID' => $inline->getAuthorPHID(),37'filePath' => $file_path,38'isNewFile' => $inline->getIsNewFile(),39'lineNumber' => $inline->getLineNumber(),40'lineLength' => $inline->getLineLength(),41'diffID' => $diff_id,42'content' => $inline->getContent(),43);44}4546protected function applyFieldEdit(47ConduitAPIRequest $request,48DifferentialRevision $revision,49DifferentialDiff $diff,50array $fields,51$message) {5253$viewer = $request->getUser();5455// We're going to build the body of a "differential.revision.edit" API56// request, then just call that code directly.5758$xactions = array();59$xactions[] = array(60'type' => DifferentialRevisionUpdateTransaction::EDITKEY,61'value' => $diff->getPHID(),62);6364$field_map = DifferentialCommitMessageField::newEnabledFields($viewer);65$values = $request->getValue('fields', array());66foreach ($values as $key => $value) {67$field = idx($field_map, $key);68if (!$field) {69// NOTE: We're just ignoring fields we don't know about. This isn't70// ideal, but the way the workflow currently works involves us getting71// several read-only fields, like the revision ID field, which we should72// just skip.73continue;74}7576// The transaction itself will be validated so this is somewhat77// redundant, but this validator will sometimes give us a better error78// message or a better reaction to a bad value type.79$value = $field->readFieldValueFromConduit($value);8081foreach ($field->getFieldTransactions($value) as $xaction) {82$xactions[] = $xaction;83}84}8586$message = $request->getValue('message');87if (strlen($message)) {88// This is a little awkward, and should move elsewhere or be removed. It89// largely exists for legacy reasons. See some discussion in T7899.90$first_line = head(phutil_split_lines($message, false));9192$first_line = id(new PhutilUTF8StringTruncator())93->setMaximumBytes(250)94->setMaximumGlyphs(80)95->truncateString($first_line);9697$diff->setDescription($first_line);98$diff->save();99100$xactions[] = array(101'type' => PhabricatorCommentEditEngineExtension::EDITKEY,102'value' => $message,103);104}105106$method = 'differential.revision.edit';107$params = array(108'transactions' => $xactions,109);110111if ($revision->getID()) {112$params['objectIdentifier'] = $revision->getID();113}114115return id(new ConduitCall($method, $params, $strict = true))116->setUser($viewer)117->execute();118}119120protected function loadCustomFieldsForRevisions(121PhabricatorUser $viewer,122array $revisions) {123assert_instances_of($revisions, 'DifferentialRevision');124125if (!$revisions) {126return array();127}128129$field_lists = array();130foreach ($revisions as $revision) {131$revision_phid = $revision->getPHID();132133$field_list = PhabricatorCustomField::getObjectFields(134$revision,135PhabricatorCustomField::ROLE_CONDUIT);136137$field_list138->setViewer($viewer)139->readFieldsFromObject($revision);140141$field_lists[$revision_phid] = $field_list;142}143144$all_fields = array();145foreach ($field_lists as $field_list) {146foreach ($field_list->getFields() as $field) {147$all_fields[] = $field;148}149}150151id(new PhabricatorCustomFieldStorageQuery())152->addFields($all_fields)153->execute();154155$results = array();156foreach ($field_lists as $revision_phid => $field_list) {157$results[$revision_phid] = array();158foreach ($field_list->getFields() as $field) {159$field_key = $field->getFieldKeyForConduit();160$value = $field->getConduitDictionaryValue();161$results[$revision_phid][$field_key] = $value;162}163}164165// For compatibility, fill in these "custom fields" by querying for them166// efficiently. See T11404 for discussion.167168$legacy_edge_map = array(169'phabricator:projects' =>170PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,171'phabricator:depends-on' =>172DifferentialRevisionDependsOnRevisionEdgeType::EDGECONST,173);174175$query = id(new PhabricatorEdgeQuery())176->withSourcePHIDs(array_keys($results))177->withEdgeTypes($legacy_edge_map);178179$query->execute();180181foreach ($results as $revision_phid => $dict) {182foreach ($legacy_edge_map as $edge_key => $edge_type) {183$phid_list = $query->getDestinationPHIDs(184array($revision_phid),185array($edge_type));186187$results[$revision_phid][$edge_key] = $phid_list;188}189}190191return $results;192}193194}195196197