diff --git a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php index 8f60db7aa8..9117f28bdc 100644 --- a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php +++ b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php @@ -1,637 +1,630 @@ getResourceURIMapRules() + array( - '/(?:(?Pjump)/)?$' => + '/(?:(?Pjump)/)?' => 'PhabricatorDirectoryMainController', '/(?:(?Pfeed)/)' => array( - 'public/$' => 'PhabricatorFeedPublicStreamController', - '(?:(?P[^/]+)/)?$' => + 'public/' => 'PhabricatorFeedPublicStreamController', + '(?:(?P[^/]+)/)?' => 'PhabricatorDirectoryMainController', ), '/directory/' => array( - '(?P\d+)/$' + '(?P\d+)/' => 'PhabricatorDirectoryCategoryViewController', - 'edit/$' + 'edit/' => 'PhabricatorDirectoryEditController', - 'item/edit/(?:(?P\d+)/)?$' + 'item/edit/(?:(?P\d+)/)?' => 'PhabricatorDirectoryItemEditController', 'item/delete/(?P\d+)/' => 'PhabricatorDirectoryItemDeleteController', - 'category/edit/(?:(?P\d+)/)?$' + 'category/edit/(?:(?P\d+)/)?' => 'PhabricatorDirectoryCategoryEditController', 'category/delete/(?P\d+)/' => 'PhabricatorDirectoryCategoryDeleteController', ), '/file/' => array( - '$' => 'PhabricatorFileListController', - 'filter/(?P\w+)/$' => 'PhabricatorFileListController', - 'upload/$' => 'PhabricatorFileUploadController', - 'dropupload/$' => 'PhabricatorFileDropUploadController', - 'delete/(?P\d+)/$' => 'PhabricatorFileDeleteController', + '' => 'PhabricatorFileListController', + 'filter/(?P\w+)/' => 'PhabricatorFileListController', + 'upload/' => 'PhabricatorFileUploadController', + 'dropupload/' => 'PhabricatorFileDropUploadController', + 'delete/(?P\d+)/' => 'PhabricatorFileDeleteController', 'info/(?P[^/]+)/' => 'PhabricatorFileInfoController', - 'data/(?P[^/]+)/(?P[^/]+)/' + 'data/(?P[^/]+)/(?P[^/]+)/.*' => 'PhabricatorFileDataController', // TODO: This is a deprecated version of /data/. Remove it after // old links have had a chance to rot. 'alt/(?P[^/]+)/(?P[^/]+)/' => 'PhabricatorFileDataController', 'macro/' => array( - '$' => 'PhabricatorFileMacroListController', - 'edit/(?:(?P\d+)/)?$' => 'PhabricatorFileMacroEditController', - 'delete/(?P\d+)/$' => 'PhabricatorFileMacroDeleteController', + '' => 'PhabricatorFileMacroListController', + 'edit/(?:(?P\d+)/)?' => 'PhabricatorFileMacroEditController', + 'delete/(?P\d+)/' => 'PhabricatorFileMacroDeleteController', ), - 'proxy/$' => 'PhabricatorFileProxyController', + 'proxy/' => 'PhabricatorFileProxyController', 'xform/(?P[^/]+)/(?P[^/]+)/' => 'PhabricatorFileTransformController', ), '/phid/' => array( - '$' => 'PhabricatorPHIDLookupController', + '' => 'PhabricatorPHIDLookupController', ), '/people/' => array( - '$' => 'PhabricatorPeopleListController', - 'logs/$' => 'PhabricatorPeopleLogsController', - 'edit/(?:(?P\d+)/(?:(?P\w+)/)?)?$' + '' => 'PhabricatorPeopleListController', + 'logs/' => 'PhabricatorPeopleLogsController', + 'edit/(?:(?P\d+)/(?:(?P\w+)/)?)?' => 'PhabricatorPeopleEditController', ), - '/p/(?P\w+)/(?:(?P\w+)/)?$' + '/p/(?P\w+)/(?:(?P\w+)/)?' => 'PhabricatorPeopleProfileController', '/conduit/' => array( - '$' => 'PhabricatorConduitConsoleController', - 'method/(?P[^/]+)/$' => 'PhabricatorConduitConsoleController', - 'log/$' => 'PhabricatorConduitLogController', - 'log/view/(?P[^/]+)/$' => 'PhabricatorConduitLogController', - 'token/$' => 'PhabricatorConduitTokenController', + '' => 'PhabricatorConduitConsoleController', + 'method/(?P[^/]+)/' => 'PhabricatorConduitConsoleController', + 'log/' => 'PhabricatorConduitLogController', + 'log/view/(?P[^/]+)/' => 'PhabricatorConduitLogController', + 'token/' => 'PhabricatorConduitTokenController', ), - '/api/(?P[^/]+)$' => 'PhabricatorConduitAPIController', + '/api/(?P[^/]+)' => 'PhabricatorConduitAPIController', '/D(?P\d+)' => 'DifferentialRevisionViewController', '/differential/' => array( - '$' => 'DifferentialRevisionListController', - 'filter/(?P\w+)/$' => 'DifferentialRevisionListController', - 'stats/(?P\w+)/$' => 'DifferentialRevisionStatsController', + '' => 'DifferentialRevisionListController', + 'filter/(?P\w+)/' => 'DifferentialRevisionListController', + 'stats/(?P\w+)/' => 'DifferentialRevisionStatsController', 'diff/' => array( - '(?P\d+)/$' => 'DifferentialDiffViewController', - 'create/$' => 'DifferentialDiffCreateController', + '(?P\d+)/' => 'DifferentialDiffViewController', + 'create/' => 'DifferentialDiffCreateController', ), - 'changeset/$' => 'DifferentialChangesetViewController', - 'revision/edit/(?:(?P\d+)/)?$' + 'changeset/' => 'DifferentialChangesetViewController', + 'revision/edit/(?:(?P\d+)/)?' => 'DifferentialRevisionEditController', 'comment/' => array( - 'preview/(?P\d+)/$' => 'DifferentialCommentPreviewController', - 'save/$' => 'DifferentialCommentSaveController', + 'preview/(?P\d+)/' => 'DifferentialCommentPreviewController', + 'save/' => 'DifferentialCommentSaveController', 'inline/' => array( - 'preview/(?P\d+)/$' => + 'preview/(?P\d+)/' => 'DifferentialInlineCommentPreviewController', - 'edit/(?P\d+)/$' => 'DifferentialInlineCommentEditController', + 'edit/(?P\d+)/' => 'DifferentialInlineCommentEditController', ), ), - 'subscribe/(?Padd|rem)/(?P\d+)/$' + 'subscribe/(?Padd|rem)/(?P\d+)/' => 'DifferentialSubscribeController', ), '/typeahead/' => array( - 'common/(?P\w+)/$' + 'common/(?P\w+)/' => 'PhabricatorTypeaheadCommonDatasourceController', ), '/mail/' => array( - '$' => 'PhabricatorMetaMTAListController', - 'send/$' => 'PhabricatorMetaMTASendController', - 'view/(?P\d+)/$' => 'PhabricatorMetaMTAViewController', - 'lists/$' => 'PhabricatorMetaMTAMailingListsController', - 'lists/edit/(?:(?P\d+)/)?$' + '' => 'PhabricatorMetaMTAListController', + 'send/' => 'PhabricatorMetaMTASendController', + 'view/(?P\d+)/' => 'PhabricatorMetaMTAViewController', + 'lists/' => 'PhabricatorMetaMTAMailingListsController', + 'lists/edit/(?:(?P\d+)/)?' => 'PhabricatorMetaMTAMailingListEditController', - 'receive/$' => 'PhabricatorMetaMTAReceiveController', - 'received/$' => 'PhabricatorMetaMTAReceivedListController', - 'sendgrid/$' => 'PhabricatorMetaMTASendGridReceiveController', + 'receive/' => 'PhabricatorMetaMTAReceiveController', + 'received/' => 'PhabricatorMetaMTAReceivedListController', + 'sendgrid/' => 'PhabricatorMetaMTASendGridReceiveController', ), '/login/' => array( - '$' => 'PhabricatorLoginController', - 'email/$' => 'PhabricatorEmailLoginController', - 'etoken/(?P\w+)/$' => 'PhabricatorEmailTokenController', - 'refresh/$' => 'PhabricatorRefreshCSRFController', - 'validate/$' => 'PhabricatorLoginValidateController', + '' => 'PhabricatorLoginController', + 'email/' => 'PhabricatorEmailLoginController', + 'etoken/(?P\w+)/' => 'PhabricatorEmailTokenController', + 'refresh/' => 'PhabricatorRefreshCSRFController', + 'validate/' => 'PhabricatorLoginValidateController', ), - '/logout/$' => 'PhabricatorLogoutController', + '/logout/' => 'PhabricatorLogoutController', '/oauth/' => array( '(?P\w+)/' => array( - 'login/$' => 'PhabricatorOAuthLoginController', - 'diagnose/$' => 'PhabricatorOAuthDiagnosticsController', - 'unlink/$' => 'PhabricatorOAuthUnlinkController', + 'login/' => 'PhabricatorOAuthLoginController', + 'diagnose/' => 'PhabricatorOAuthDiagnosticsController', + 'unlink/' => 'PhabricatorOAuthUnlinkController', ), ), '/oauthserver/' => array( 'auth/' => 'PhabricatorOAuthServerAuthController', 'test/' => 'PhabricatorOAuthServerTestController', 'token/' => 'PhabricatorOAuthServerTokenController', 'clientauthorization/' => array( - '$' => 'PhabricatorOAuthClientAuthorizationListController', + '' => 'PhabricatorOAuthClientAuthorizationListController', 'delete/(?P[^/]+)/' => 'PhabricatorOAuthClientAuthorizationDeleteController', 'edit/(?P[^/]+)/' => 'PhabricatorOAuthClientAuthorizationEditController', ), 'client/' => array( - '$' => 'PhabricatorOAuthClientListController', - 'create/$' => 'PhabricatorOAuthClientEditController', - 'delete/(?P[^/]+)/$' => - 'PhabricatorOAuthClientDeleteController', - 'edit/(?P[^/]+)/$' => 'PhabricatorOAuthClientEditController', - 'view/(?P[^/]+)/$' => 'PhabricatorOAuthClientViewController', + '' => 'PhabricatorOAuthClientListController', + 'create/' => 'PhabricatorOAuthClientEditController', + 'delete/(?P[^/]+)/' => 'PhabricatorOAuthClientDeleteController', + 'edit/(?P[^/]+)/' => 'PhabricatorOAuthClientEditController', + 'view/(?P[^/]+)/' => 'PhabricatorOAuthClientViewController', ), ), '/xhprof/' => array( - 'profile/(?P[^/]+)/$' => 'PhabricatorXHProfProfileController', + 'profile/(?P[^/]+)/' => 'PhabricatorXHProfProfileController', ), '/~/' => 'DarkConsoleController', '/settings/' => array( - '(?:page/(?P[^/]+)/)?$' => 'PhabricatorUserSettingsController', + '(?:page/(?P[^/]+)/)?' => 'PhabricatorUserSettingsController', ), '/maniphest/' => array( - '$' => 'ManiphestTaskListController', - 'view/(?P\w+)/$' => 'ManiphestTaskListController', - 'report/(?:(?P\w+)/)?$' => 'ManiphestReportController', - 'batch/$' => 'ManiphestBatchEditController', + '' => 'ManiphestTaskListController', + 'view/(?P\w+)/' => 'ManiphestTaskListController', + 'report/(?:(?P\w+)/)?' => 'ManiphestReportController', + 'batch/' => 'ManiphestBatchEditController', 'task/' => array( - 'create/$' => 'ManiphestTaskEditController', - 'edit/(?P\d+)/$' => 'ManiphestTaskEditController', - 'descriptionchange/(?P\d+)/$' => + 'create/' => 'ManiphestTaskEditController', + 'edit/(?P\d+)/' => 'ManiphestTaskEditController', + 'descriptionchange/(?P\d+)/' => 'ManiphestTaskDescriptionChangeController', - 'descriptiondiff/$' => + 'descriptiondiff/' => 'ManiphestTaskDescriptionDiffController', - 'descriptionpreview/$' => + 'descriptionpreview/' => 'ManiphestTaskDescriptionPreviewController', ), 'transaction/' => array( 'save/' => 'ManiphestTransactionSaveController', - 'preview/(?P\d+)/$' => 'ManiphestTransactionPreviewController', + 'preview/(?P\d+)/' => 'ManiphestTransactionPreviewController', ), - 'export/(?P[^/]+)/$' => 'ManiphestExportController', + 'export/(?P[^/]+)/' => 'ManiphestExportController', ), - '/T(?P\d+)$' => 'ManiphestTaskDetailController', + '/T(?P\d+)' => 'ManiphestTaskDetailController', '/repository/' => array( - '$' => 'PhabricatorRepositoryListController', - 'create/$' => 'PhabricatorRepositoryCreateController', - 'edit/(?P\d+)/(?:(?P\w+)?/)?$' => + '' => 'PhabricatorRepositoryListController', + 'create/' => 'PhabricatorRepositoryCreateController', + 'edit/(?P\d+)/(?:(?P\w+)?/)?' => 'PhabricatorRepositoryEditController', - 'delete/(?P\d+)/$' => 'PhabricatorRepositoryDeleteController', + 'delete/(?P\d+)/' => 'PhabricatorRepositoryDeleteController', 'project/(?P\d+)/' => 'PhabricatorRepositoryArcanistProjectEditController', ), '/search/' => array( - '$' => 'PhabricatorSearchController', - '(?P[^/]+)/$' => 'PhabricatorSearchController', - 'attach/(?P[^/]+)/(?P\w+)/(?:(?P\w+)/)?$' + '' => 'PhabricatorSearchController', + '(?P[^/]+)/' => 'PhabricatorSearchController', + 'attach/(?P[^/]+)/(?P\w+)/(?:(?P\w+)/)?' => 'PhabricatorSearchAttachController', - 'select/(?P\w+)/$' + 'select/(?P\w+)/' => 'PhabricatorSearchSelectController', - 'index/(?P[^/]+)/$' => 'PhabricatorSearchIndexController', + 'index/(?P[^/]+)/' => 'PhabricatorSearchIndexController', ), '/project/' => array( - '$' => 'PhabricatorProjectListController', - 'filter/(?P[^/]+)/$' => 'PhabricatorProjectListController', - 'edit/(?P\d+)/$' => 'PhabricatorProjectProfileEditController', - 'view/(?P\d+)/(?:(?P\w+)/)?$' + '' => 'PhabricatorProjectListController', + 'filter/(?P[^/]+)/' => 'PhabricatorProjectListController', + 'edit/(?P\d+)/' => 'PhabricatorProjectProfileEditController', + 'view/(?P\d+)/(?:(?P\w+)/)?' => 'PhabricatorProjectProfileController', - 'create/$' => 'PhabricatorProjectCreateController', - 'update/(?P\d+)/(?P[^/]+)/$' + 'create/' => 'PhabricatorProjectCreateController', + 'update/(?P\d+)/(?P[^/]+)/' => 'PhabricatorProjectUpdateController', ), - '/r(?P[A-Z]+)(?P[a-z0-9]+)$' + '/r(?P[A-Z]+)(?P[a-z0-9]+)' => 'DiffusionCommitController', '/diffusion/' => array( - '$' => 'DiffusionHomeController', + '' => 'DiffusionHomeController', '(?P[A-Z]+)/' => array( - '$' => 'DiffusionRepositoryController', + '' => 'DiffusionRepositoryController', 'repository/'. - '(?P[^/]+)/'. - '$' + '(?P[^/]+)/' => 'DiffusionRepositoryController', 'change/'. '(?P.*?)'. - '(?:[;](?P[a-z0-9]+))?'. - '$' + '(?:[;](?P[a-z0-9]+))?' => 'DiffusionChangeController', 'history/'. '(?P.*?)'. - '(?:[;](?P[a-z0-9]+))?'. - '$' + '(?:[;](?P[a-z0-9]+))?' => 'DiffusionHistoryController', 'browse/'. '(?P.*?)'. '(?:[;](?P[a-z0-9]+))?'. - '(?:[$](?P\d+(?:-\d+)?))?'. - '$' + '(?:[$](?P\d+(?:-\d+)?))?' => 'DiffusionBrowseController', 'diff/'. '(?P.*?)'. - '(?:[;](?P[a-z0-9]+))?'. - '$' + '(?:[;](?P[a-z0-9]+))?' => 'DiffusionDiffController', 'lastmodified/'. '(?P.*?)'. - '(?:[;](?P[a-z0-9]+))?'. - '$' + '(?:[;](?P[a-z0-9]+))?' => 'DiffusionLastModifiedController', ), 'services/' => array( 'path/' => array( - 'complete/$' => 'DiffusionPathCompleteController', - 'validate/$' => 'DiffusionPathValidateController', + 'complete/' => 'DiffusionPathCompleteController', + 'validate/' => 'DiffusionPathValidateController', ), ), - 'symbol/(?P[^/]+)/$' => 'DiffusionSymbolController', + 'symbol/(?P[^/]+)/' => 'DiffusionSymbolController', ), '/daemon/' => array( - 'task/(?P\d+)/$' => 'PhabricatorWorkerTaskDetailController', - 'task/(?P\d+)/(?P[^/]+)/$' + 'task/(?P\d+)/' => 'PhabricatorWorkerTaskDetailController', + 'task/(?P\d+)/(?P[^/]+)/' => 'PhabricatorWorkerTaskUpdateController', 'log/' => array( - '$' => 'PhabricatorDaemonLogListController', - 'combined/$' => 'PhabricatorDaemonCombinedLogController', - '(?P\d+)/$' => 'PhabricatorDaemonLogViewController', + '' => 'PhabricatorDaemonLogListController', + 'combined/' => 'PhabricatorDaemonCombinedLogController', + '(?P\d+)/' => 'PhabricatorDaemonLogViewController', ), - 'timeline/$' => 'PhabricatorDaemonTimelineConsoleController', - 'timeline/(?P\d+)/$' => 'PhabricatorDaemonTimelineEventController', - '$' => 'PhabricatorDaemonConsoleController', + 'timeline/' => 'PhabricatorDaemonTimelineConsoleController', + 'timeline/(?P\d+)/' => 'PhabricatorDaemonTimelineEventController', + '' => 'PhabricatorDaemonConsoleController', ), '/herald/' => array( - '$' => 'HeraldHomeController', + '' => 'HeraldHomeController', 'view/(?P[^/]+)/' => array( - '$' => 'HeraldHomeController', - '(?Pglobal)/$' => 'HeraldHomeController' + '' => 'HeraldHomeController', + '(?Pglobal)/' => 'HeraldHomeController' ), - 'new/(?:(?P[^/]+)/)?$' => 'HeraldNewController', - 'rule/(?:(?P\d+)/)?$' => 'HeraldRuleController', - 'history/(?P\d+)/$' => 'HeraldRuleEditHistoryController', - 'delete/(?P\d+)/$' => 'HeraldDeleteController', - 'test/$' => 'HeraldTestConsoleController', + 'new/(?:(?P[^/]+)/)?' => 'HeraldNewController', + 'rule/(?:(?P\d+)/)?' => 'HeraldRuleController', + 'history/(?P\d+)/' => 'HeraldRuleEditHistoryController', + 'delete/(?P\d+)/' => 'HeraldDeleteController', + 'test/' => 'HeraldTestConsoleController', 'all/' => array( - '$' => 'HeraldAllRulesController', - 'view/(?P[^/]+)/$' => 'HeraldAllRulesController', + '' => 'HeraldAllRulesController', + 'view/(?P[^/]+)/' => 'HeraldAllRulesController', ), - 'transcript/$' => 'HeraldTranscriptListController', - 'transcript/(?P\d+)/(?:(?P\w+)/)?$' + 'transcript/' => 'HeraldTranscriptListController', + 'transcript/(?P\d+)/(?:(?P\w+)/)?' => 'HeraldTranscriptController', ), '/uiexample/' => array( - '$' => 'PhabricatorUIExampleRenderController', - 'view/(?P[^/]+)/$' => 'PhabricatorUIExampleRenderController', + '' => 'PhabricatorUIExampleRenderController', + 'view/(?P[^/]+)/' => 'PhabricatorUIExampleRenderController', ), '/owners/' => array( - '$' => 'PhabricatorOwnersListController', - 'view/(?P[^/]+)/$' => 'PhabricatorOwnersListController', - 'edit/(?P\d+)/$' => 'PhabricatorOwnersEditController', - 'new/$' => 'PhabricatorOwnersEditController', - 'package/(?P\d+)/$' => 'PhabricatorOwnersDetailController', - 'delete/(?P\d+)/$' => 'PhabricatorOwnersDeleteController', + '' => 'PhabricatorOwnersListController', + 'view/(?P[^/]+)/' => 'PhabricatorOwnersListController', + 'edit/(?P\d+)/' => 'PhabricatorOwnersEditController', + 'new/' => 'PhabricatorOwnersEditController', + 'package/(?P\d+)/' => 'PhabricatorOwnersDetailController', + 'delete/(?P\d+)/' => 'PhabricatorOwnersDeleteController', '(?Prelated|attention)/' => array( - '$' => 'PhabricatorOwnerRelatedListController', - '(?Ppackage|owner)/$' + '' => 'PhabricatorOwnerRelatedListController', + '(?Ppackage|owner)/' => 'PhabricatorOwnerRelatedListController', ), ), '/audit/' => array( - '$' => 'PhabricatorAuditListController', - 'view/(?P[^/]+)/(?:(?P[^/]+)/)?$' + '' => 'PhabricatorAuditListController', + 'view/(?P[^/]+)/(?:(?P[^/]+)/)?' => 'PhabricatorAuditListController', - 'addcomment/$' => 'PhabricatorAuditAddCommentController', - 'preview/(?P\d+)/$' => 'PhabricatorAuditPreviewController', + 'addcomment/' => 'PhabricatorAuditAddCommentController', + 'preview/(?P\d+)/' => 'PhabricatorAuditPreviewController', ), '/xhpast/' => array( - '$' => 'PhabricatorXHPASTViewRunController', - 'view/(?P\d+)/$' + '' => 'PhabricatorXHPASTViewRunController', + 'view/(?P\d+)/' => 'PhabricatorXHPASTViewFrameController', - 'frameset/(?P\d+)/$' + 'frameset/(?P\d+)/' => 'PhabricatorXHPASTViewFramesetController', - 'input/(?P\d+)/$' + 'input/(?P\d+)/' => 'PhabricatorXHPASTViewInputController', - 'tree/(?P\d+)/$' + 'tree/(?P\d+)/' => 'PhabricatorXHPASTViewTreeController', - 'stream/(?P\d+)/$' + 'stream/(?P\d+)/' => 'PhabricatorXHPASTViewStreamController', ), - '/status/$' => 'PhabricatorStatusController', + '/status/' => 'PhabricatorStatusController', '/paste/' => array( - '$' => 'PhabricatorPasteListController', - 'filter/(?P\w+)/$' => 'PhabricatorPasteListController', + '' => 'PhabricatorPasteListController', + 'filter/(?P\w+)/' => 'PhabricatorPasteListController', ), - '/P(?P\d+)$' => 'PhabricatorPasteViewController', + '/P(?P\d+)' => 'PhabricatorPasteViewController', '/help/' => array( - 'keyboardshortcut/$' => 'PhabricatorHelpKeyboardShortcutController', + 'keyboardshortcut/' => 'PhabricatorHelpKeyboardShortcutController', ), '/countdown/' => array( - '$' + '' => 'PhabricatorCountdownListController', - '(?P\d+)/$' + '(?P\d+)/' => 'PhabricatorCountdownViewController', - 'edit/(?:(?P\d+)/)?$' + 'edit/(?:(?P\d+)/)?' => 'PhabricatorCountdownEditController', - 'delete/(?P\d+)/$' + 'delete/(?P\d+)/' => 'PhabricatorCountdownDeleteController' ), - '/V(?P\d+)$' => 'PhabricatorSlowvotePollController', + '/V(?P\d+)' => 'PhabricatorSlowvotePollController', '/vote/' => array( - '(?:view/(?P\w+)/)?$' => 'PhabricatorSlowvoteListController', - 'create/' => 'PhabricatorSlowvoteCreateController', + '(?:view/(?P\w+)/)?' => 'PhabricatorSlowvoteListController', + 'create/' => 'PhabricatorSlowvoteCreateController', ), // Match "/w/" with slug "/". - '/w(?P/)$' => 'PhrictionDocumentController', + '/w(?P/)' => 'PhrictionDocumentController', // Match "/w/x/y/z/" with slug "x/y/z/". - '/w/(?P.+/)$' => 'PhrictionDocumentController', + '/w/(?P.+/)' => 'PhrictionDocumentController', '/phriction/' => array( - '$' => 'PhrictionListController', - 'list/(?P[^/]+)/$' => 'PhrictionListController', + '' => 'PhrictionListController', + 'list/(?P[^/]+)/' => 'PhrictionListController', - 'history(?P/)$' => 'PhrictionHistoryController', - 'history/(?P.+/)$' => 'PhrictionHistoryController', + 'history(?P/)' => 'PhrictionHistoryController', + 'history/(?P.+/)' => 'PhrictionHistoryController', - 'edit/(?:(?P\d+)/)?$' => 'PhrictionEditController', - 'delete/(?P\d+)/$' => 'PhrictionDeleteController', + 'edit/(?:(?P\d+)/)?' => 'PhrictionEditController', + 'delete/(?P\d+)/' => 'PhrictionDeleteController', - 'preview/$' => 'PhrictionDocumentPreviewController', - 'diff/(?P\d+)/$' => 'PhrictionDiffController', + 'preview/' => 'PhrictionDocumentPreviewController', + 'diff/(?P\d+)/' => 'PhrictionDiffController', ), '/calendar/' => array( - '$' => 'PhabricatorCalendarBrowseController', + '' => 'PhabricatorCalendarBrowseController', ), '/drydock/' => array( - '$' => 'DrydockResourceListController', - 'resource/$' => 'DrydockResourceListController', - 'resource/allocate/$' => 'DrydockResourceAllocateController', + '' => 'DrydockResourceListController', + 'resource/' => 'DrydockResourceListController', + 'resource/allocate/' => 'DrydockResourceAllocateController', 'host/' => array( - '$' => 'DrydockHostListController', - 'edit/$' => 'DrydockHostEditController', - 'edit/(?P\d+)/$' => 'DrydockhostEditController', + '' => 'DrydockHostListController', + 'edit/' => 'DrydockHostEditController', + 'edit/(?P\d+)/' => 'DrydockhostEditController', ), - 'lease/$' => 'DrydockLeaseListController', + 'lease/' => 'DrydockLeaseListController', ), '/chatlog/' => array( - '$' => + '' => 'PhabricatorChatLogChannelListController', - 'channel/(?P[^/]+)/$' => + 'channel/(?P[^/]+)/' => 'PhabricatorChatLogChannelLogController', ), ); } protected function getResourceURIMapRules() { return array( '/res/' => array( - '(?Ppkg/)?(?P[a-f0-9]{8})/(?P.+\.(?:css|js))$' + '(?Ppkg/)?(?P[a-f0-9]{8})/(?P.+\.(?: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 '
'. '
Stack Trace
'. $table->render(). '
'; } } diff --git a/src/aphront/mapper/AphrontURIMapper.php b/src/aphront/mapper/AphrontURIMapper.php index 8376b87a3a..bdda98bdf6 100644 --- a/src/aphront/mapper/AphrontURIMapper.php +++ b/src/aphront/mapper/AphrontURIMapper.php @@ -1,68 +1,68 @@ map = $map; } final public function mapPath($path) { $map = $this->map; foreach ($map as $rule => $value) { list($controller, $data) = $this->tryRule($rule, $value, $path); if ($controller) { foreach ($data as $k => $v) { if (is_numeric($k)) { unset($data[$k]); } } return array($controller, $data); } } return array(null, null); } final private function tryRule($rule, $value, $path) { $match = null; - if (!preg_match('#^'.$rule.'#', $path, $match)) { + $pattern = '#^'.$rule.(is_array($value) ? '' : '$').'#'; + if (!preg_match($pattern, $path, $match)) { return array(null, null); } if (!is_array($value)) { return array($value, $match); } $path = substr($path, strlen($match[0])); foreach ($value as $srule => $sval) { list($controller, $data) = $this->tryRule($srule, $sval, $path); if ($controller) { return array($controller, $data + $match); } } return array(null, null); } }