[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/aphront/configuration/ -> AphrontDefaultApplicationConfiguration.php (source)

   1  <?php
   2  
   3  /**
   4   * NOTE: Do not extend this!
   5   *
   6   * @concrete-extensible
   7   */
   8  class AphrontDefaultApplicationConfiguration
   9    extends AphrontApplicationConfiguration {
  10  
  11    public function __construct() {}
  12  
  13    public function getApplicationName() {
  14      return 'aphront-default';
  15    }
  16  
  17    /**
  18     * @phutil-external-symbol class PhabricatorStartup
  19     */
  20    public function buildRequest() {
  21      $parser = new PhutilQueryStringParser();
  22      $data   = array();
  23  
  24      // If the request has "multipart/form-data" content, we can't use
  25      // PhutilQueryStringParser to parse it, and the raw data supposedly is not
  26      // available anyway (according to the PHP documentation, "php://input" is
  27      // not available for "multipart/form-data" requests). However, it is
  28      // available at least some of the time (see T3673), so double check that
  29      // we aren't trying to parse data we won't be able to parse correctly by
  30      // examining the Content-Type header.
  31      $content_type = idx($_SERVER, 'CONTENT_TYPE');
  32      $is_form_data = preg_match('@^multipart/form-data@i', $content_type);
  33  
  34      $raw_input = PhabricatorStartup::getRawInput();
  35      if (strlen($raw_input) && !$is_form_data) {
  36        $data += $parser->parseQueryString($raw_input);
  37      } else if ($_POST) {
  38        $data += $_POST;
  39      }
  40  
  41      $data += $parser->parseQueryString(idx($_SERVER, 'QUERY_STRING', ''));
  42  
  43      $cookie_prefix = PhabricatorEnv::getEnvConfig('phabricator.cookie-prefix');
  44  
  45      $request = new AphrontRequest($this->getHost(), $this->getPath());
  46      $request->setRequestData($data);
  47      $request->setApplicationConfiguration($this);
  48      $request->setCookiePrefix($cookie_prefix);
  49  
  50      return $request;
  51    }
  52  
  53    public function handleException(Exception $ex) {
  54      $request = $this->getRequest();
  55  
  56      // For Conduit requests, return a Conduit response.
  57      if ($request->isConduit()) {
  58        $response = new ConduitAPIResponse();
  59        $response->setErrorCode(get_class($ex));
  60        $response->setErrorInfo($ex->getMessage());
  61  
  62        return id(new AphrontJSONResponse())
  63          ->setAddJSONShield(false)
  64          ->setContent($response->toDictionary());
  65      }
  66  
  67      // For non-workflow requests, return a Ajax response.
  68      if ($request->isAjax() && !$request->isJavelinWorkflow()) {
  69        // Log these; they don't get shown on the client and can be difficult
  70        // to debug.
  71        phlog($ex);
  72  
  73        $response = new AphrontAjaxResponse();
  74        $response->setError(
  75          array(
  76            'code' => get_class($ex),
  77            'info' => $ex->getMessage(),
  78          ));
  79        return $response;
  80      }
  81  
  82      $user = $request->getUser();
  83      if (!$user) {
  84        // If we hit an exception very early, we won't have a user.
  85        $user = new PhabricatorUser();
  86      }
  87  
  88      if ($ex instanceof PhabricatorSystemActionRateLimitException) {
  89        $dialog = id(new AphrontDialogView())
  90          ->setTitle(pht('Slow Down!'))
  91          ->setUser($user)
  92          ->setErrors(array(pht('You are being rate limited.')))
  93          ->appendParagraph($ex->getMessage())
  94          ->appendParagraph($ex->getRateExplanation())
  95          ->addCancelButton('/', pht('Okaaaaaaaaaaaaaay...'));
  96  
  97        $response = new AphrontDialogResponse();
  98        $response->setDialog($dialog);
  99        return $response;
 100      }
 101  
 102      if ($ex instanceof PhabricatorAuthHighSecurityRequiredException) {
 103  
 104        $form = id(new PhabricatorAuthSessionEngine())->renderHighSecurityForm(
 105          $ex->getFactors(),
 106          $ex->getFactorValidationResults(),
 107          $user,
 108          $request);
 109  
 110        $dialog = id(new AphrontDialogView())
 111          ->setUser($user)
 112          ->setTitle(pht('Entering High Security'))
 113          ->setShortTitle(pht('Security Checkpoint'))
 114          ->setWidth(AphrontDialogView::WIDTH_FORM)
 115          ->addHiddenInput(AphrontRequest::TYPE_HISEC, true)
 116          ->setErrors(
 117            array(
 118              pht(
 119                'You are taking an action which requires you to enter '.
 120                'high security.'),
 121            ))
 122          ->appendParagraph(
 123            pht(
 124              'High security mode helps protect your account from security '.
 125              'threats, like session theft or someone messing with your stuff '.
 126              'while you\'re grabbing a coffee. To enter high security mode, '.
 127              'confirm your credentials.'))
 128          ->appendChild($form->buildLayoutView())
 129          ->appendParagraph(
 130            pht(
 131              'Your account will remain in high security mode for a short '.
 132              'period of time. When you are finished taking sensitive '.
 133              'actions, you should leave high security.'))
 134          ->setSubmitURI($request->getPath())
 135          ->addCancelButton($ex->getCancelURI())
 136          ->addSubmitButton(pht('Enter High Security'));
 137  
 138        foreach ($request->getPassthroughRequestParameters() as $key => $value) {
 139          $dialog->addHiddenInput($key, $value);
 140        }
 141  
 142        $response = new AphrontDialogResponse();
 143        $response->setDialog($dialog);
 144        return $response;
 145      }
 146  
 147      if ($ex instanceof PhabricatorPolicyException) {
 148        if (!$user->isLoggedIn()) {
 149          // If the user isn't logged in, just give them a login form. This is
 150          // probably a generally more useful response than a policy dialog that
 151          // they have to click through to get a login form.
 152          //
 153          // Possibly we should add a header here like "you need to login to see
 154          // the thing you are trying to look at".
 155          $login_controller = new PhabricatorAuthStartController();
 156          $login_controller->setRequest($request);
 157  
 158          $auth_app_class = 'PhabricatorAuthApplication';
 159          $auth_app = PhabricatorApplication::getByClass($auth_app_class);
 160          $login_controller->setCurrentApplication($auth_app);
 161  
 162          return $login_controller->handleRequest($request);
 163        }
 164  
 165        $list = $ex->getMoreInfo();
 166        foreach ($list as $key => $item) {
 167          $list[$key] = phutil_tag('li', array(), $item);
 168        }
 169        if ($list) {
 170          $list = phutil_tag('ul', array(), $list);
 171        }
 172  
 173        $content = array(
 174          phutil_tag(
 175            'div',
 176            array(
 177              'class' => 'aphront-policy-rejection',
 178            ),
 179            $ex->getRejection()),
 180          phutil_tag(
 181            'div',
 182            array(
 183              'class' => 'aphront-capability-details',
 184            ),
 185            pht('Users with the "%s" capability:', $ex->getCapabilityName())),
 186          $list,
 187        );
 188  
 189        $dialog = new AphrontDialogView();
 190        $dialog
 191          ->setTitle($ex->getTitle())
 192          ->setClass('aphront-access-dialog')
 193          ->setUser($user)
 194          ->appendChild($content);
 195  
 196        if ($this->getRequest()->isAjax()) {
 197          $dialog->addCancelButton('/', pht('Close'));
 198        } else {
 199          $dialog->addCancelButton('/', pht('OK'));
 200        }
 201  
 202        $response = new AphrontDialogResponse();
 203        $response->setDialog($dialog);
 204        return $response;
 205      }
 206  
 207      if ($ex instanceof AphrontUsageException) {
 208        $error = new AphrontErrorView();
 209        $error->setTitle($ex->getTitle());
 210        $error->appendChild($ex->getMessage());
 211  
 212        $view = new PhabricatorStandardPageView();
 213        $view->setRequest($this->getRequest());
 214        $view->appendChild($error);
 215  
 216        $response = new AphrontWebpageResponse();
 217        $response->setContent($view->render());
 218        $response->setHTTPResponseCode(500);
 219  
 220        return $response;
 221      }
 222  
 223      // Always log the unhandled exception.
 224      phlog($ex);
 225  
 226      $class    = get_class($ex);
 227      $message  = $ex->getMessage();
 228  
 229      if ($ex instanceof AphrontSchemaQueryException) {
 230        $message .=
 231          "\n\n".
 232          "NOTE: This usually indicates that the MySQL schema has not been ".
 233          "properly upgraded. Run 'bin/storage upgrade' to ensure your ".
 234          "schema is up to date.";
 235      }
 236  
 237      if (PhabricatorEnv::getEnvConfig('phabricator.developer-mode')) {
 238        $trace = id(new AphrontStackTraceView())
 239          ->setUser($user)
 240          ->setTrace($ex->getTrace());
 241      } else {
 242        $trace = null;
 243      }
 244  
 245      $content = phutil_tag(
 246        'div',
 247        array('class' => 'aphront-unhandled-exception'),
 248        array(
 249          phutil_tag('div', array('class' => 'exception-message'), $message),
 250          $trace,
 251        ));
 252  
 253      $dialog = new AphrontDialogView();
 254      $dialog
 255        ->setTitle('Unhandled Exception ("'.$class.'")')
 256        ->setClass('aphront-exception-dialog')
 257        ->setUser($user)
 258        ->appendChild($content);
 259  
 260      if ($this->getRequest()->isAjax()) {
 261        $dialog->addCancelButton('/', 'Close');
 262      }
 263  
 264      $response = new AphrontDialogResponse();
 265      $response->setDialog($dialog);
 266      $response->setHTTPResponseCode(500);
 267  
 268      return $response;
 269    }
 270  
 271    public function willSendResponse(AphrontResponse $response) {
 272      return $response;
 273    }
 274  
 275    public function build404Controller() {
 276      return array(new Phabricator404Controller(), array());
 277    }
 278  
 279    public function buildRedirectController($uri, $external) {
 280      return array(
 281        new PhabricatorRedirectController(),
 282        array(
 283          'uri' => $uri,
 284          'external' => $external,
 285        ),
 286      );
 287    }
 288  
 289  }


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