.+\.(?:css|js))$'
=> 'CelerityResourceController',
),
);
}
public function buildRequest() {
$request = new AphrontRequest($this->getHost(), $this->getPath());
$request->setRequestData($_GET + $_POST);
$request->setApplicationConfiguration($this);
return $request;
}
public function handleException(Exception $ex) {
// Always log the unhandled exception.
phlog($ex);
$class = phutil_escape_html(get_class($ex));
$message = phutil_escape_html($ex->getMessage());
if (PhabricatorEnv::getEnvConfig('phabricator.show-stack-traces')) {
$trace = $this->renderStackTrace($ex->getTrace());
} else {
$trace = null;
}
$content =
''.
'
'.$message.'
'.
$trace.
'
';
$user = $this->getRequest()->getUser();
if (!$user) {
// If we hit an exception very early, we won't have a user.
$user = new PhabricatorUser();
}
$dialog = new AphrontDialogView();
$dialog
->setTitle('Unhandled Exception ("'.$class.'")')
->setClass('aphront-exception-dialog')
->setUser($user)
->appendChild($content);
if ($this->getRequest()->isAjax()) {
$dialog->addCancelButton('/', 'Close');
}
$response = new AphrontDialogResponse();
$response->setDialog($dialog);
return $response;
}
public function willSendResponse(AphrontResponse $response) {
$request = $this->getRequest();
$response->setRequest($request);
if ($response instanceof AphrontDialogResponse) {
if (!$request->isAjax()) {
$view = new PhabricatorStandardPageView();
$view->setRequest($request);
$view->appendChild(
''.
$response->buildResponseString().
'
');
$response = new AphrontWebpageResponse();
$response->setContent($view->render());
return $response;
} else {
return id(new AphrontAjaxResponse())
->setContent(array(
'dialog' => $response->buildResponseString(),
));
}
} else if ($response instanceof AphrontRedirectResponse) {
if ($request->isAjax()) {
return id(new AphrontAjaxResponse())
->setContent(
array(
'redirect' => $response->getURI(),
));
}
}
return $response;
}
public function build404Controller() {
return array(new Phabricator404Controller($this->getRequest()), array());
}
public function buildRedirectController($uri) {
return array(
new PhabricatorRedirectController($this->getRequest()),
array(
'uri' => $uri,
));
}
private function renderStackTrace($trace) {
$libraries = PhutilBootloader::getInstance()->getAllLibraries();
// TODO: Make this configurable?
$host = 'https://secure.phabricator.com';
$browse = array(
'arcanist' =>
$host.'/diffusion/ARC/browse/origin:master/src/',
'phutil' =>
$host.'/diffusion/PHU/browse/origin:master/src/',
'phabricator' =>
$host.'/diffusion/P/browse/origin:master/src/',
);
$rows = array();
$depth = count($trace);
foreach ($trace as $part) {
$lib = null;
$file = idx($part, 'file');
$relative = $file;
foreach ($libraries as $library) {
$root = phutil_get_library_root($library);
if (Filesystem::isDescendant($file, $root)) {
$lib = $library;
$relative = Filesystem::readablePath($file, $root);
break;
}
}
$where = '';
if (isset($part['class'])) {
$where .= $part['class'].'::';
}
if (isset($part['function'])) {
$where .= $part['function'].'()';
}
if ($file) {
if (isset($browse[$lib])) {
$file_name = phutil_render_tag(
'a',
array(
'href' => $browse[$lib].$relative.'$'.$part['line'],
'title' => $file,
'target' => '_blank',
),
phutil_escape_html($relative));
} else {
$file_name = phutil_render_tag(
'span',
array(
'title' => $file,
),
phutil_escape_html($relative));
}
$file_name = $file_name.' : '.(int)$part['line'];
} else {
$file_name = '(Internal)';
}
$rows[] = array(
$depth--,
phutil_escape_html($lib),
$file_name,
phutil_escape_html($where),
);
}
$table = new AphrontTableView($rows);
$table->setHeaders(
array(
'Depth',
'Library',
'File',
'Where',
));
$table->setColumnClasses(
array(
'n',
'',
'',
'wide',
));
return
''.
''.
$table->render().
'
';
}
}
diff --git a/src/applications/repository/parser/default/PhabricatorRepositoryDefaultCommitMessageDetailParser.php b/src/applications/repository/parser/default/PhabricatorRepositoryDefaultCommitMessageDetailParser.php
index c8f36d686b..c0e0b86933 100644
--- a/src/applications/repository/parser/default/PhabricatorRepositoryDefaultCommitMessageDetailParser.php
+++ b/src/applications/repository/parser/default/PhabricatorRepositoryDefaultCommitMessageDetailParser.php
@@ -1,85 +1,85 @@
getCommit();
$data = $this->getCommitData();
$details = nonempty($data->getCommitDetails(), array());
$message = $data->getCommitMessage();
$author_name = $data->getAuthorName();
// TODO: Some day, it would be good to drive all of this via
// DifferentialFieldSpecification configuration directly.
$match = null;
if (preg_match(
'/^\s*Differential Revision:\s*(\S+)\s*$/mi',
$message,
$match)) {
// NOTE: We now accept ONLY full URIs because if we accept numeric IDs
// then anyone importing the Phabricator repository will have their
// first few thousand revisions marked committed. This does mean that
// some older revisions won't re-parse correctly, but that shouldn't
- // really affect anyone. If necesary, an install can extend the parser
+ // really affect anyone. If necessary, an install can extend the parser
// and restore the older, more-liberal parsing fairly easily.
$id = DifferentialRevisionIDFieldSpecification::parseRevisionIDFromURI(
$match[1]);
if ($id) {
$details['differential.revisionID'] = $id;
$revision = id(new DifferentialRevision())->load($id);
if ($revision) {
$details['differential.revisionPHID'] = $revision->getPHID();
}
}
}
if (preg_match(
'/^\s*Reviewed By:\s*(\S+)\s*$/mi',
$message,
$match)) {
$details['reviewerName'] = $match[1];
$reviewer_phid = $this->resolveUserPHID($details['reviewerName']);
if ($reviewer_phid) {
$details['reviewerPHID'] = $reviewer_phid;
} else {
unset($details['reviewerPHID']);
}
} else {
unset($details['reviewerName']);
unset($details['reviewerPHID']);
}
$author_phid = $this->resolveUserPHID($author_name);
if ($author_phid) {
$details['authorPHID'] = $author_phid;
} else {
unset($details['authorPHID']);
}
$data->setCommitDetails($details);
}
}