[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/differential/editor/ -> DifferentialDiffEditor.php (source)

   1  <?php
   2  
   3  final class DifferentialDiffEditor
   4    extends PhabricatorApplicationTransactionEditor {
   5  
   6    private $diffDataDict;
   7    private $lookupRepository = true;
   8  
   9    public function setLookupRepository($bool) {
  10      $this->lookupRepository = $bool;
  11      return $this;
  12    }
  13  
  14    public function getEditorApplicationClass() {
  15      return 'PhabricatorDifferentialApplication';
  16    }
  17  
  18    public function getEditorObjectsDescription() {
  19      return pht('Differential Diffs');
  20    }
  21  
  22    public function getTransactionTypes() {
  23      $types = parent::getTransactionTypes();
  24  
  25      $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
  26      $types[] = DifferentialDiffTransaction::TYPE_DIFF_CREATE;
  27  
  28      return $types;
  29    }
  30  
  31    protected function getCustomTransactionOldValue(
  32      PhabricatorLiskDAO $object,
  33      PhabricatorApplicationTransaction $xaction) {
  34  
  35      switch ($xaction->getTransactionType()) {
  36        case DifferentialDiffTransaction::TYPE_DIFF_CREATE:
  37          return null;
  38      }
  39  
  40      return parent::getCustomTransactionOldValue($object, $xaction);
  41    }
  42  
  43    protected function getCustomTransactionNewValue(
  44      PhabricatorLiskDAO $object,
  45      PhabricatorApplicationTransaction $xaction) {
  46  
  47      switch ($xaction->getTransactionType()) {
  48        case DifferentialDiffTransaction::TYPE_DIFF_CREATE:
  49          $this->diffDataDict = $xaction->getNewValue();
  50          return true;
  51      }
  52  
  53      return parent::getCustomTransactionNewValue($object, $xaction);
  54    }
  55  
  56    protected function applyCustomInternalTransaction(
  57      PhabricatorLiskDAO $object,
  58      PhabricatorApplicationTransaction $xaction) {
  59  
  60      switch ($xaction->getTransactionType()) {
  61        case DifferentialDiffTransaction::TYPE_DIFF_CREATE:
  62          $dict = $this->diffDataDict;
  63          $this->updateDiffFromDict($object, $dict);
  64          return;
  65        case PhabricatorTransactions::TYPE_VIEW_POLICY:
  66          $object->setViewPolicy($xaction->getNewValue());
  67          return;
  68      }
  69  
  70      return parent::applyCustomInternalTransaction($object, $xaction);
  71    }
  72  
  73    protected function applyCustomExternalTransaction(
  74      PhabricatorLiskDAO $object,
  75      PhabricatorApplicationTransaction $xaction) {
  76  
  77      switch ($xaction->getTransactionType()) {
  78        case DifferentialDiffTransaction::TYPE_DIFF_CREATE:
  79        case PhabricatorTransactions::TYPE_VIEW_POLICY:
  80          return;
  81      }
  82  
  83      return parent::applyCustomExternalTransaction($object, $xaction);
  84      }
  85  
  86    protected function applyFinalEffects(
  87      PhabricatorLiskDAO $object,
  88      array $xactions) {
  89  
  90      // If we didn't get an explicit `repositoryPHID` (which means the client
  91      // is old, or couldn't figure out which repository the working copy
  92      // belongs to), apply heuristics to try to figure it out.
  93  
  94      if ($this->lookupRepository && !$object->getRepositoryPHID()) {
  95        $repository = id(new DifferentialRepositoryLookup())
  96          ->setDiff($object)
  97          ->setViewer($this->getActor())
  98          ->lookupRepository();
  99        if ($repository) {
 100          $object->setRepositoryPHID($repository->getPHID());
 101          $object->setRepositoryUUID($repository->getUUID());
 102          $object->save();
 103        }
 104      }
 105  
 106      return $xactions;
 107    }
 108  
 109    /**
 110     * We run Herald as part of transaction validation because Herald can
 111     * block diff creation for Differential diffs. Its important to do this
 112     * separately so no Herald logs are saved; these logs could expose
 113     * information the Herald rules are inteneded to block.
 114     */
 115    protected function validateTransaction(
 116      PhabricatorLiskDAO $object,
 117      $type,
 118      array $xactions) {
 119  
 120      $errors = parent::validateTransaction($object, $type, $xactions);
 121  
 122      foreach ($xactions as $xaction) {
 123        switch ($type) {
 124          case DifferentialDiffTransaction::TYPE_DIFF_CREATE:
 125            $diff = clone $object;
 126            $diff = $this->updateDiffFromDict($diff, $xaction->getNewValue());
 127  
 128            $adapter = $this->buildHeraldAdapter($diff, $xactions);
 129            $adapter->setContentSource($this->getContentSource());
 130            $adapter->setIsNewObject($this->getIsNewObject());
 131  
 132            $engine = new HeraldEngine();
 133  
 134            $rules = $engine->loadRulesForAdapter($adapter);
 135            $rules = mpull($rules, null, 'getID');
 136  
 137            $effects = $engine->applyRules($rules, $adapter);
 138  
 139            $blocking_effect = null;
 140            foreach ($effects as $effect) {
 141              if ($effect->getAction() == HeraldAdapter::ACTION_BLOCK) {
 142                $blocking_effect = $effect;
 143                break;
 144              }
 145            }
 146  
 147            if ($blocking_effect) {
 148              $rule = idx($rules, $effect->getRuleID());
 149              if ($rule && strlen($rule->getName())) {
 150                $rule_name = $rule->getName();
 151              } else {
 152                $rule_name = pht('Unnamed Herald Rule');
 153              }
 154  
 155              $message = $effect->getTarget();
 156              if (!strlen($message)) {
 157                $message = pht('(None.)');
 158              }
 159  
 160              $errors[] = new PhabricatorApplicationTransactionValidationError(
 161                $type,
 162                pht('Rejected by Herald'),
 163                pht(
 164                  "Creation of this diff was rejected by Herald rule %s.\n".
 165                  "  Rule: %s\n".
 166                  "Reason: %s",
 167                  'H'.$effect->getRuleID(),
 168                  $rule_name,
 169                  $message));
 170            }
 171            break;
 172        }
 173      }
 174  
 175      return $errors;
 176    }
 177  
 178  
 179    protected function shouldPublishFeedStory(
 180      PhabricatorLiskDAO $object,
 181      array $xactions) {
 182      return false;
 183    }
 184  
 185    protected function shouldSendMail(
 186      PhabricatorLiskDAO $object,
 187      array $xactions) {
 188      return false;
 189    }
 190  
 191    protected function supportsSearch() {
 192      return false;
 193    }
 194  
 195  /* -(  Herald Integration  )------------------------------------------------- */
 196  
 197    /**
 198     * See @{method:validateTransaction}. The only Herald action is to block
 199     * the creation of Diffs. We thus have to be careful not to save any
 200     * data and do this validation very early.
 201     */
 202    protected function shouldApplyHeraldRules(
 203      PhabricatorLiskDAO $object,
 204      array $xactions) {
 205  
 206      return false;
 207    }
 208  
 209    protected function buildHeraldAdapter(
 210      PhabricatorLiskDAO $object,
 211      array $xactions) {
 212  
 213      $adapter = id(new HeraldDifferentialDiffAdapter())
 214        ->setDiff($object);
 215  
 216      return $adapter;
 217    }
 218  
 219    protected function didApplyHeraldRules(
 220      PhabricatorLiskDAO $object,
 221      HeraldAdapter $adapter,
 222      HeraldTranscript $transcript) {
 223  
 224      $xactions = array();
 225      return $xactions;
 226    }
 227  
 228    private function updateDiffFromDict(DifferentialDiff $diff, $dict) {
 229      $diff
 230        ->setSourcePath(idx($dict, 'sourcePath'))
 231        ->setSourceMachine(idx($dict, 'sourceMachine'))
 232        ->setBranch(idx($dict, 'branch'))
 233        ->setCreationMethod(idx($dict, 'creationMethod'))
 234        ->setAuthorPHID(idx($dict, 'authorPHID', $this->getActor()))
 235        ->setBookmark(idx($dict, 'bookmark'))
 236        ->setRepositoryPHID(idx($dict, 'repositoryPHID'))
 237        ->setRepositoryUUID(idx($dict, 'repositoryUUID'))
 238        ->setSourceControlSystem(idx($dict, 'sourceControlSystem'))
 239        ->setSourceControlPath(idx($dict, 'sourceControlPath'))
 240        ->setSourceControlBaseRevision(idx($dict, 'sourceControlBaseRevision'))
 241        ->setLintStatus(idx($dict, 'lintStatus'))
 242        ->setUnitStatus(idx($dict, 'unitStatus'))
 243        ->setArcanistProjectPHID(idx($dict, 'arcanistProjectPHID'));
 244  
 245      return $diff;
 246    }
 247  }


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