[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/differential/conduit/ -> DifferentialQueryConduitAPIMethod.php (source)

   1  <?php
   2  
   3  final class DifferentialQueryConduitAPIMethod
   4    extends DifferentialConduitAPIMethod {
   5  
   6    public function getAPIMethodName() {
   7      return 'differential.query';
   8    }
   9  
  10    public function getMethodDescription() {
  11      return 'Query Differential revisions which match certain criteria.';
  12    }
  13  
  14    public function defineParamTypes() {
  15      $hash_types = ArcanistDifferentialRevisionHash::getTypes();
  16      $hash_const = $this->formatStringConstants($hash_types);
  17  
  18      $status_types = array(
  19        DifferentialRevisionQuery::STATUS_ANY,
  20        DifferentialRevisionQuery::STATUS_OPEN,
  21        DifferentialRevisionQuery::STATUS_ACCEPTED,
  22        DifferentialRevisionQuery::STATUS_CLOSED,
  23      );
  24      $status_const = $this->formatStringConstants($status_types);
  25  
  26      $order_types = array(
  27        DifferentialRevisionQuery::ORDER_MODIFIED,
  28        DifferentialRevisionQuery::ORDER_CREATED,
  29      );
  30      $order_const = $this->formatStringConstants($order_types);
  31  
  32      return array(
  33        'authors'           => 'optional list<phid>',
  34        'ccs'               => 'optional list<phid>',
  35        'reviewers'         => 'optional list<phid>',
  36        'paths'             => 'optional list<pair<callsign, path>>',
  37        'commitHashes'      => 'optional list<pair<'.$hash_const.', string>>',
  38        'status'            => 'optional '.$status_const,
  39        'order'             => 'optional '.$order_const,
  40        'limit'             => 'optional uint',
  41        'offset'            => 'optional uint',
  42        'ids'               => 'optional list<uint>',
  43        'phids'             => 'optional list<phid>',
  44        'subscribers'       => 'optional list<phid>',
  45        'responsibleUsers'  => 'optional list<phid>',
  46        'branches'          => 'optional list<string>',
  47        'arcanistProjects'  => 'optional list<string>',
  48      );
  49    }
  50  
  51    public function defineReturnType() {
  52      return 'list<dict>';
  53    }
  54  
  55    public function defineErrorTypes() {
  56      return array(
  57        'ERR-INVALID-PARAMETER' => 'Missing or malformed parameter.',
  58      );
  59    }
  60  
  61    protected function execute(ConduitAPIRequest $request) {
  62      $authors            = $request->getValue('authors');
  63      $ccs                = $request->getValue('ccs');
  64      $reviewers          = $request->getValue('reviewers');
  65      $status             = $request->getValue('status');
  66      $order              = $request->getValue('order');
  67      $path_pairs         = $request->getValue('paths');
  68      $commit_hashes      = $request->getValue('commitHashes');
  69      $limit              = $request->getValue('limit');
  70      $offset             = $request->getValue('offset');
  71      $ids                = $request->getValue('ids');
  72      $phids              = $request->getValue('phids');
  73      $subscribers        = $request->getValue('subscribers');
  74      $responsible_users  = $request->getValue('responsibleUsers');
  75      $branches           = $request->getValue('branches');
  76      $arc_projects       = $request->getValue('arcanistProjects');
  77  
  78      $query = id(new DifferentialRevisionQuery())
  79        ->setViewer($request->getUser());
  80  
  81      if ($authors) {
  82        $query->withAuthors($authors);
  83      }
  84      if ($ccs) {
  85        $query->withCCs($ccs);
  86      }
  87      if ($reviewers) {
  88        $query->withReviewers($reviewers);
  89      }
  90  
  91      if ($path_pairs) {
  92        $paths = array();
  93        foreach ($path_pairs as $pair) {
  94          list($callsign, $path) = $pair;
  95          $paths[] = $path;
  96        }
  97  
  98        $path_map = id(new DiffusionPathIDQuery($paths))->loadPathIDs();
  99        if (count($path_map) != count($paths)) {
 100          $unknown_paths = array();
 101          foreach ($paths as $p) {
 102            if (!idx($path_map, $p)) {
 103              $unknown_paths[] = $p;
 104            }
 105          }
 106          throw id(new ConduitException('ERR-INVALID-PARAMETER'))
 107            ->setErrorDescription(
 108              'Unknown paths: '.implode(', ', $unknown_paths));
 109        }
 110  
 111        $repos = array();
 112        foreach ($path_pairs as $pair) {
 113          list($callsign, $path) = $pair;
 114          if (!idx($repos, $callsign)) {
 115            $repos[$callsign] = id(new PhabricatorRepositoryQuery())
 116              ->setViewer($request->getUser())
 117              ->withCallsigns(array($callsign))
 118              ->executeOne();
 119  
 120            if (!$repos[$callsign]) {
 121              throw id(new ConduitException('ERR-INVALID-PARAMETER'))
 122                ->setErrorDescription(
 123                  'Unknown repo callsign: '.$callsign);
 124            }
 125          }
 126          $repo = $repos[$callsign];
 127  
 128          $query->withPath($repo->getID(), idx($path_map, $path));
 129        }
 130      }
 131  
 132      if ($commit_hashes) {
 133        $hash_types = ArcanistDifferentialRevisionHash::getTypes();
 134        foreach ($commit_hashes as $info) {
 135          list($type, $hash) = $info;
 136          if (empty($type) ||
 137              !in_array($type, $hash_types) ||
 138              empty($hash)) {
 139                throw new ConduitException('ERR-INVALID-PARAMETER');
 140          }
 141        }
 142        $query->withCommitHashes($commit_hashes);
 143      }
 144  
 145      if ($status) {
 146        $query->withStatus($status);
 147      }
 148      if ($order) {
 149        $query->setOrder($order);
 150      }
 151      if ($limit) {
 152        $query->setLimit($limit);
 153      }
 154      if ($offset) {
 155        $query->setOffset($offset);
 156      }
 157      if ($ids) {
 158        $query->withIDs($ids);
 159      }
 160      if ($phids) {
 161        $query->withPHIDs($phids);
 162      }
 163      if ($responsible_users) {
 164        $query->withResponsibleUsers($responsible_users);
 165      }
 166      if ($subscribers) {
 167        $query->withCCs($subscribers);
 168      }
 169      if ($branches) {
 170        $query->withBranches($branches);
 171      }
 172      if ($arc_projects) {
 173        // This is sort of special-cased, but don't make arc do an extra round
 174        // trip.
 175        $projects = id(new PhabricatorRepositoryArcanistProject())
 176          ->loadAllWhere(
 177            'name in (%Ls)',
 178            $arc_projects);
 179        if (!$projects) {
 180          return array();
 181        }
 182  
 183        $query->withArcanistProjectPHIDs(mpull($projects, 'getPHID'));
 184      }
 185  
 186      $query->needRelationships(true);
 187      $query->needCommitPHIDs(true);
 188      $query->needDiffIDs(true);
 189      $query->needActiveDiffs(true);
 190      $query->needHashes(true);
 191  
 192      $revisions = $query->execute();
 193  
 194      $field_data = $this->loadCustomFieldsForRevisions(
 195        $request->getUser(),
 196        $revisions);
 197  
 198      $results = array();
 199      foreach ($revisions as $revision) {
 200        $diff = $revision->getActiveDiff();
 201        if (!$diff) {
 202          continue;
 203        }
 204  
 205        $id = $revision->getID();
 206        $phid = $revision->getPHID();
 207  
 208        $result = array(
 209          'id'                  => $id,
 210          'phid'                => $phid,
 211          'title'               => $revision->getTitle(),
 212          'uri'                 => PhabricatorEnv::getProductionURI('/D'.$id),
 213          'dateCreated'         => $revision->getDateCreated(),
 214          'dateModified'        => $revision->getDateModified(),
 215          'authorPHID'          => $revision->getAuthorPHID(),
 216          'status'              => $revision->getStatus(),
 217          'statusName'          =>
 218            ArcanistDifferentialRevisionStatus::getNameForRevisionStatus(
 219              $revision->getStatus()),
 220          'branch'              => $diff->getBranch(),
 221          'summary'             => $revision->getSummary(),
 222          'testPlan'            => $revision->getTestPlan(),
 223          'lineCount'           => $revision->getLineCount(),
 224          'activeDiffPHID'      => $diff->getPHID(),
 225          'diffs'               => $revision->getDiffIDs(),
 226          'commits'             => $revision->getCommitPHIDs(),
 227          'reviewers'           => array_values($revision->getReviewers()),
 228          'ccs'                 => array_values($revision->getCCPHIDs()),
 229          'hashes'              => $revision->getHashes(),
 230          'auxiliary'           => idx($field_data, $phid, array()),
 231          'arcanistProjectPHID' => $diff->getArcanistProjectPHID(),
 232          'repositoryPHID'      => $diff->getRepositoryPHID(),
 233        );
 234  
 235        // TODO: This is a hacky way to put permissions on this field until we
 236        // have first-class support, see T838.
 237        if ($revision->getAuthorPHID() == $request->getUser()->getPHID()) {
 238          $result['sourcePath'] = $diff->getSourcePath();
 239        }
 240  
 241        $results[] = $result;
 242      }
 243  
 244      return $results;
 245    }
 246  
 247  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1