[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/diffusion/query/filecontent/ -> DiffusionFileContentQuery.php (source)

   1  <?php
   2  
   3  /**
   4   * NOTE: this class should only be used where local access to the repository
   5   * is guaranteed and NOT from within the Diffusion application. Diffusion
   6   * should use Conduit method 'diffusion.filecontentquery' to get this sort
   7   * of data.
   8   */
   9  abstract class DiffusionFileContentQuery extends DiffusionQuery {
  10  
  11    private $needsBlame;
  12    private $fileContent;
  13    private $viewer;
  14  
  15    final public static function newFromDiffusionRequest(
  16      DiffusionRequest $request) {
  17      return parent::newQueryObject(__CLASS__, $request);
  18    }
  19  
  20    abstract public function getFileContentFuture();
  21    abstract protected function executeQueryFromFuture(Future $future);
  22  
  23    final public function loadFileContentFromFuture(Future $future) {
  24      $this->fileContent = $this->executeQueryFromFuture($future);
  25  
  26      $repository = $this->getRequest()->getRepository();
  27      $try_encoding = $repository->getDetail('encoding');
  28      if ($try_encoding) {
  29          $this->fileContent->setCorpus(
  30            phutil_utf8_convert(
  31              $this->fileContent->getCorpus(), 'UTF-8', $try_encoding));
  32      }
  33  
  34      return $this->fileContent;
  35    }
  36  
  37    final protected function executeQuery() {
  38      return $this->loadFileContentFromFuture($this->getFileContentFuture());
  39    }
  40  
  41    final public function loadFileContent() {
  42      return $this->executeQuery();
  43    }
  44  
  45    final public function getRawData() {
  46      return $this->fileContent->getCorpus();
  47    }
  48  
  49    /**
  50     * Pretty hairy function. If getNeedsBlame is false, this returns
  51     *
  52     *   ($text_list, array(), array())
  53     *
  54     * Where $text_list is the raw file content with trailing new lines stripped.
  55     *
  56     * If getNeedsBlame is true, this returns
  57     *
  58     *   ($text_list, $line_rev_dict, $blame_dict)
  59     *
  60     * Where $text_list is just the lines of code -- the raw file content will
  61     * contain lots of blame data, $line_rev_dict is a dictionary of line number
  62     * => revision id, and $blame_dict is another complicated data structure.
  63     * In detail, $blame_dict contains [revision id][author] keys, as well
  64     * as [commit id][authorPhid] and [commit id][epoch] keys.
  65     *
  66     * @return ($text_list, $line_rev_dict, $blame_dict)
  67     */
  68    final public function getBlameData() {
  69      $raw_data = preg_replace('/\n$/', '', $this->getRawData());
  70  
  71      $text_list = array();
  72      $line_rev_dict = array();
  73      $blame_dict = array();
  74  
  75      if (!$this->getNeedsBlame()) {
  76        $text_list = explode("\n", $raw_data);
  77      } else if ($raw_data != '') {
  78        $lines = array();
  79        foreach (explode("\n", $raw_data) as $k => $line) {
  80          $lines[$k] = $this->tokenizeLine($line);
  81  
  82          list($rev_id, $author, $text) = $lines[$k];
  83          $text_list[$k] = $text;
  84          $line_rev_dict[$k] = $rev_id;
  85        }
  86  
  87        $line_rev_dict = $this->processRevList($line_rev_dict);
  88  
  89        foreach ($lines as $k => $line) {
  90          list($rev_id, $author, $text) = $line;
  91          $rev_id = $line_rev_dict[$k];
  92  
  93          if (!isset($blame_dict[$rev_id])) {
  94            $blame_dict[$rev_id]['author'] = $author;
  95          }
  96        }
  97  
  98        $repository = $this->getRequest()->getRepository();
  99  
 100        $commits = id(new DiffusionCommitQuery())
 101          ->setViewer($this->getViewer())
 102          ->withDefaultRepository($repository)
 103          ->withIdentifiers(array_unique($line_rev_dict))
 104          ->execute();
 105  
 106        foreach ($commits as $commit) {
 107          $blame_dict[$commit->getCommitIdentifier()]['epoch'] =
 108            $commit->getEpoch();
 109        }
 110  
 111        if ($commits) {
 112          $commits_data = id(new PhabricatorRepositoryCommitData())->loadAllWhere(
 113            'commitID IN (%Ls)',
 114            mpull($commits, 'getID'));
 115  
 116          foreach ($commits_data as $data) {
 117            $author_phid = $data->getCommitDetail('authorPHID');
 118            if (!$author_phid) {
 119              continue;
 120            }
 121            $commit = $commits[$data->getCommitID()];
 122            $commit_identifier = $commit->getCommitIdentifier();
 123            $blame_dict[$commit_identifier]['authorPHID'] = $author_phid;
 124          }
 125        }
 126  
 127     }
 128  
 129      return array($text_list, $line_rev_dict, $blame_dict);
 130    }
 131  
 132    abstract protected function tokenizeLine($line);
 133  
 134    public function setNeedsBlame($needs_blame) {
 135      $this->needsBlame = $needs_blame;
 136      return $this;
 137    }
 138  
 139    public function getNeedsBlame() {
 140      return $this->needsBlame;
 141    }
 142  
 143    public function setViewer(PhabricatorUser $user) {
 144      $this->viewer = $user;
 145      return $this;
 146    }
 147  
 148    public function getViewer() {
 149      return $this->viewer;
 150    }
 151  
 152    protected function processRevList(array $rev_list) {
 153      return $rev_list;
 154    }
 155  }


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