diff --git a/src/applications/differential/controller/DifferentialRevisionLandController.php b/src/applications/differential/controller/DifferentialRevisionLandController.php index f2d2497a42..0e222370df 100644 --- a/src/applications/differential/controller/DifferentialRevisionLandController.php +++ b/src/applications/differential/controller/DifferentialRevisionLandController.php @@ -1,164 +1,157 @@ revisionID = $data['id']; - $this->strategyClass = $data['strategy']; - } - public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); - - $revision_id = $this->revisionID; + $revision_id = $request->getURIData('id'); + $strategy_class = $request->getURIData('strategy'); $revision = id(new DifferentialRevisionQuery()) ->withIDs(array($revision_id)) ->setViewer($viewer) ->executeOne(); if (!$revision) { return new Aphront404Response(); } - if (is_subclass_of($this->strategyClass, 'DifferentialLandingStrategy')) { - $this->pushStrategy = newv($this->strategyClass, array()); + if (is_subclass_of($strategy_class, 'DifferentialLandingStrategy')) { + $this->pushStrategy = newv($strategy_class, array()); } else { throw new Exception( pht( "Strategy type must be a valid class name and must subclass ". "%s. '%s' is not a subclass of %s", 'DifferentialLandingStrategy', - $this->strategyClass, + $strategy_class, 'DifferentialLandingStrategy')); } if ($request->isDialogFormPost()) { $response = null; $text = ''; try { $response = $this->attemptLand($revision, $request); $title = pht('Success!'); $text = pht('Revision was successfully landed.'); } catch (Exception $ex) { $title = pht('Failed to land revision'); if ($ex instanceof PhutilProxyException) { $text = hsprintf( '%s:
%s
', $ex->getMessage(), $ex->getPreviousException()->getMessage()); } else { $text = phutil_tag('pre', array(), $ex->getMessage()); } $text = id(new PHUIInfoView()) ->appendChild($text); } if ($response instanceof AphrontDialogView) { $dialog = $response; } else { $dialog = id(new AphrontDialogView()) ->setUser($viewer) ->setTitle($title) ->appendChild(phutil_tag('p', array(), $text)) ->addCancelButton('/D'.$revision_id, pht('Done')); } return id(new AphrontDialogResponse())->setDialog($dialog); } $is_disabled = $this->pushStrategy->isActionDisabled( $viewer, $revision, $revision->getRepository()); if ($is_disabled) { if (is_string($is_disabled)) { $explain = $is_disabled; } else { $explain = pht('This action is not currently enabled.'); } $dialog = id(new AphrontDialogView()) ->setUser($viewer) ->setTitle(pht("Can't land revision")) ->appendChild($explain) ->addCancelButton('/D'.$revision_id); return id(new AphrontDialogResponse())->setDialog($dialog); } $prompt = hsprintf('%s

%s', pht( 'This will squash and rebase revision %s, and push it to '. 'the default / master branch.', $revision_id), pht('It is an experimental feature and may not work.')); $dialog = id(new AphrontDialogView()) ->setUser($viewer) ->setTitle(pht('Land Revision %s?', $revision_id)) ->appendChild($prompt) ->setSubmitURI($request->getRequestURI()) ->addSubmitButton(pht('Land it!')) ->addCancelButton('/D'.$revision_id); return id(new AphrontDialogResponse())->setDialog($dialog); } private function attemptLand($revision, $request) { $status = $revision->getStatus(); if ($status != ArcanistDifferentialRevisionStatus::ACCEPTED) { throw new Exception(pht('Only Accepted revisions can be landed.')); } $repository = $revision->getRepository(); if ($repository === null) { throw new Exception(pht('Revision is not attached to a repository.')); } $can_push = PhabricatorPolicyFilter::hasCapability( $request->getUser(), $repository, DiffusionPushCapability::CAPABILITY); if (!$can_push) { throw new Exception( pht('You do not have permission to push to this repository.')); } $lock = $this->lockRepository($repository); try { $response = $this->pushStrategy->processLandRequest( $request, $revision, $repository); } catch (Exception $e) { $lock->unlock(); throw $e; } $lock->unlock(); $looksoon = new ConduitCall( 'diffusion.looksoon', array( 'repositories' => array($repository->getPHID()), )); $looksoon->setUser($request->getUser()); $looksoon->execute(); return $response; } private function lockRepository($repository) { $lock_name = __CLASS__.':'.($repository->getPHID()); $lock = PhabricatorGlobalLock::newLock($lock_name); $lock->lock(); return $lock; } }