diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 4e001f9964..7a7b02df22 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -1,197 +1,197 @@ array( 'path' => '/res/771b987d/rsrc/css/aphront/dialog-view.css', 'type' => 'css', 'requires' => array( ), ), 'aphront-form-view-css' => array( - 'path' => '/res/51ec6383/rsrc/css/aphront/form-view.css', + 'path' => '/res/75636a53/rsrc/css/aphront/form-view.css', 'type' => 'css', 'requires' => array( ), ), 'aphront-panel-view-css' => array( 'path' => '/res/fe62e634/rsrc/css/aphront/panel-view.css', 'type' => 'css', 'requires' => array( ), ), 'aphront-side-nav-view-css' => array( 'path' => '/res/1a16f19a/rsrc/css/aphront/side-nav-view.css', 'type' => 'css', 'requires' => array( ), ), 'aphront-table-view-css' => array( 'path' => '/res/52b0191f/rsrc/css/aphront/table-view.css', 'type' => 'css', 'requires' => array( ), ), 'aphront-tokenizer-control-css' => array( 'path' => '/res/a3d23074/rsrc/css/aphront/tokenizer.css', 'type' => 'css', 'requires' => array( 0 => 'aphront-typeahead-control-css', ), ), 'aphront-typeahead-control-css' => array( 'path' => '/res/928df9f0/rsrc/css/aphront/typeahead.css', 'type' => 'css', 'requires' => array( ), ), 'phabricator-standard-page-view' => array( 'path' => '/res/0eef6905/rsrc/css/application/base/standard-page-view.css', 'type' => 'css', 'requires' => array( ), ), 'differential-changeset-view-css' => array( 'path' => '/res/658d181a/rsrc/css/application/differential/changeset-view.css', 'type' => 'css', 'requires' => array( ), ), 'differential-core-view-css' => array( 'path' => '/res/f750b85d/rsrc/css/application/differential/core.css', 'type' => 'css', 'requires' => array( ), ), 'differential-table-of-contents-css' => array( 'path' => '/res/ebf6641c/rsrc/css/application/differential/table-of-contents.css', 'type' => 'css', 'requires' => array( ), ), 'phabricator-directory-css' => array( 'path' => '/res/6a000601/rsrc/css/application/directory/phabricator-directory.css', 'type' => 'css', 'requires' => array( ), ), 'phabricator-core-buttons-css' => array( 'path' => '/res/6e348ba4/rsrc/css/core/buttons.css', 'type' => 'css', 'requires' => array( ), ), 'phabricator-core-css' => array( 'path' => '/res/39ce37c2/rsrc/css/core/core.css', 'type' => 'css', 'requires' => array( ), ), 'syntax-highlighting-css' => array( 'path' => '/res/fb673ece/rsrc/css/core/syntax.css', 'type' => 'css', 'requires' => array( ), ), 'javelin-behavior-aphront-basic-tokenizer' => array( 'path' => '/res/8317d761/rsrc/js/application/core/behavior-tokenizer.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), ), 'javelin-behavior-differential-populate' => array( 'path' => '/res/9982573c/rsrc/js/application/differential/behavior-populate.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-lib-dev', ), ), 'javelin-init-dev' => array( 'path' => '/res/c57a9e89/rsrc/js/javelin/init.dev.js', 'type' => 'js', 'requires' => array( ), ), 'javelin-init-prod' => array( 'path' => '/res/f0172c54/rsrc/js/javelin/init.min.js', 'type' => 'js', 'requires' => array( ), ), 'javelin-lib-dev' => array( 'path' => '/res/3e747182/rsrc/js/javelin/javelin.dev.js', 'type' => 'js', 'requires' => array( ), ), 'javelin-lib-prod' => array( 'path' => '/res/9438670e/rsrc/js/javelin/javelin.min.js', 'type' => 'js', 'requires' => array( ), ), 'javelin-typeahead-dev' => array( 'path' => '/res/c81c0f01/rsrc/js/javelin/typeahead.dev.js', 'type' => 'js', 'requires' => array( ), ), 'javelin-typeahead-prod' => array( 'path' => '/res/1da2d984/rsrc/js/javelin/typeahead.min.js', 'type' => 'js', 'requires' => array( ), ), )); diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 0e23449164..4e37c3e090 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1,262 +1,266 @@ array( 'Aphront404Response' => 'aphront/response/404', 'AphrontAjaxResponse' => 'aphront/response/ajax', 'AphrontApplicationConfiguration' => 'aphront/applicationconfiguration', 'AphrontController' => 'aphront/controller', 'AphrontDatabaseConnection' => 'storage/connection/base', 'AphrontDefaultApplicationConfiguration' => 'aphront/default/configuration', 'AphrontDefaultApplicationController' => 'aphront/default/controller', 'AphrontDialogResponse' => 'aphront/response/dialog', 'AphrontDialogView' => 'view/dialog', 'AphrontErrorView' => 'view/form/error', 'AphrontFileResponse' => 'aphront/response/file', 'AphrontFormCheckboxControl' => 'view/form/control/checkbox', 'AphrontFormControl' => 'view/form/control/base', 'AphrontFormFileControl' => 'view/form/control/file', 'AphrontFormMarkupControl' => 'view/form/control/markup', 'AphrontFormSelectControl' => 'view/form/control/select', 'AphrontFormStaticControl' => 'view/form/control/static', 'AphrontFormSubmitControl' => 'view/form/control/submit', 'AphrontFormTextAreaControl' => 'view/form/control/textarea', 'AphrontFormTextControl' => 'view/form/control/text', 'AphrontFormTokenizerControl' => 'view/form/control/tokenizer', 'AphrontFormView' => 'view/form/base', 'AphrontMySQLDatabaseConnection' => 'storage/connection/mysql', 'AphrontNullView' => 'view/null', 'AphrontPageView' => 'view/page/base', 'AphrontPanelView' => 'view/layout/panel', 'AphrontQueryConnectionException' => 'storage/exception/connection', 'AphrontQueryConnectionLostException' => 'storage/exception/connectionlost', 'AphrontQueryCountException' => 'storage/exception/count', 'AphrontQueryException' => 'storage/exception/base', 'AphrontQueryObjectMissingException' => 'storage/exception/objectmissing', 'AphrontQueryParameterException' => 'storage/exception/parameter', 'AphrontQueryRecoverableException' => 'storage/exception/recoverable', 'AphrontRedirectResponse' => 'aphront/response/redirect', 'AphrontRequest' => 'aphront/request', 'AphrontResponse' => 'aphront/response/base', 'AphrontSideNavView' => 'view/layout/sidenav', 'AphrontTableView' => 'view/control/table', 'AphrontURIMapper' => 'aphront/mapper', 'AphrontView' => 'view/base', 'AphrontWebpageResponse' => 'aphront/response/webpage', 'CelerityAPI' => 'infratructure/celerity/api', 'CelerityResourceController' => 'infratructure/celerity/controller', 'CelerityResourceMap' => 'infratructure/celerity/map', 'CelerityStaticResourceResponse' => 'infratructure/celerity/response', 'ConduitAPIMethod' => 'applications/conduit/method/base', 'ConduitAPIRequest' => 'applications/conduit/protocol/request', 'ConduitAPI_conduit_connect_Method' => 'applications/conduit/method/conduit/connect', 'ConduitAPI_differential_creatediff_Method' => 'applications/conduit/method/differential/creatediff', 'ConduitAPI_differential_setdiffproperty_Method' => 'applications/conduit/method/differential/setdiffproperty', 'ConduitAPI_file_upload_Method' => 'applications/conduit/method/file/upload', 'ConduitAPI_user_find_Method' => 'applications/conduit/method/user/find', 'ConduitException' => 'applications/conduit/protocol/exception', 'DifferentialAction' => 'applications/differential/constants/action', 'DifferentialChangeType' => 'applications/differential/constants/changetype', 'DifferentialChangeset' => 'applications/differential/storage/changeset', 'DifferentialChangesetDetailView' => 'applications/differential/view/changesetdetailview', 'DifferentialChangesetListView' => 'applications/differential/view/changesetlistview', 'DifferentialChangesetParser' => 'applications/differential/parser/changeset', 'DifferentialChangesetViewController' => 'applications/differential/controller/changesetview', 'DifferentialController' => 'applications/differential/controller/base', 'DifferentialDAO' => 'applications/differential/storage/base', 'DifferentialDiff' => 'applications/differential/storage/diff', 'DifferentialDiffProperty' => 'applications/differential/storage/diffproperty', 'DifferentialDiffTableOfContentsView' => 'applications/differential/view/difftableofcontents', 'DifferentialDiffViewController' => 'applications/differential/controller/diffview', 'DifferentialHunk' => 'applications/differential/storage/hunk', 'DifferentialLintStatus' => 'applications/differential/constants/lintstatus', 'DifferentialRevision' => 'applications/differential/storage/revision', 'DifferentialRevisionControlSystem' => 'applications/differential/constants/revisioncontrolsystem', 'DifferentialRevisionEditController' => 'applications/differential/controller/revisionedit', 'DifferentialRevisionListController' => 'applications/differential/controller/revisionlist', 'DifferentialRevisionStatus' => 'applications/differential/constants/revisionstatus', 'DifferentialUnitStatus' => 'applications/differential/constants/unitstatus', 'Javelin' => 'infratructure/javelin/api', 'LiskDAO' => 'storage/lisk/dao', 'PhabricatorConduitAPIController' => 'applications/conduit/controller/api', 'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/connectionlog', 'PhabricatorConduitConsoleController' => 'applications/conduit/controller/console', 'PhabricatorConduitController' => 'applications/conduit/controller/base', 'PhabricatorConduitDAO' => 'applications/conduit/storage/base', 'PhabricatorConduitLogController' => 'applications/conduit/controller/log', 'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/methodcalllog', 'PhabricatorController' => 'applications/base/controller/base', 'PhabricatorDirectoryCategory' => 'applications/directory/storage/category', 'PhabricatorDirectoryCategoryDeleteController' => 'applications/directory/controller/categorydelete', 'PhabricatorDirectoryCategoryEditController' => 'applications/directory/controller/categoryedit', 'PhabricatorDirectoryCategoryListController' => 'applications/directory/controller/categorylist', 'PhabricatorDirectoryController' => 'applications/directory/controller/base', 'PhabricatorDirectoryDAO' => 'applications/directory/storage/base', 'PhabricatorDirectoryItem' => 'applications/directory/storage/item', 'PhabricatorDirectoryItemDeleteController' => 'applications/directory/controller/itemdelete', 'PhabricatorDirectoryItemEditController' => 'applications/directory/controller/itemedit', 'PhabricatorDirectoryItemListController' => 'applications/directory/controller/itemlist', 'PhabricatorDirectoryMainController' => 'applications/directory/controller/main', 'PhabricatorFile' => 'applications/files/storage/file', 'PhabricatorFileController' => 'applications/files/controller/base', 'PhabricatorFileDAO' => 'applications/files/storage/base', 'PhabricatorFileListController' => 'applications/files/controller/list', 'PhabricatorFileStorageBlob' => 'applications/files/storage/storageblob', 'PhabricatorFileURI' => 'applications/files/uri', 'PhabricatorFileUploadController' => 'applications/files/controller/upload', 'PhabricatorFileViewController' => 'applications/files/controller/view', 'PhabricatorLiskDAO' => 'applications/base/storage/lisk', 'PhabricatorMetaMTAController' => 'applications/metamta/controller/base', 'PhabricatorMetaMTADAO' => 'applications/metamta/storage/base', 'PhabricatorMetaMTAListController' => 'applications/metamta/controller/list', 'PhabricatorMetaMTAMail' => 'applications/metamta/storage/mail', 'PhabricatorMetaMTASendController' => 'applications/metamta/controller/send', + 'PhabricatorObjectHandle' => 'applications/phid/handle', + 'PhabricatorObjectHandleData' => 'applications/phid/handle/data', 'PhabricatorPHID' => 'applications/phid/storage/phid', 'PhabricatorPHIDAllocateController' => 'applications/phid/controller/allocate', 'PhabricatorPHIDController' => 'applications/phid/controller/base', 'PhabricatorPHIDDAO' => 'applications/phid/storage/base', 'PhabricatorPHIDListController' => 'applications/phid/controller/list', + 'PhabricatorPHIDLookupController' => 'applications/phid/controller/lookup', 'PhabricatorPHIDType' => 'applications/phid/storage/type', 'PhabricatorPHIDTypeEditController' => 'applications/phid/controller/typeedit', 'PhabricatorPHIDTypeListController' => 'applications/phid/controller/typelist', 'PhabricatorPeopleController' => 'applications/people/controller/base', 'PhabricatorPeopleEditController' => 'applications/people/controller/edit', 'PhabricatorPeopleListController' => 'applications/people/controller/list', 'PhabricatorPeopleProfileController' => 'applications/people/controller/profile', 'PhabricatorStandardPageView' => 'view/page/standard', 'PhabricatorTypeaheadCommonDatasourceController' => 'applications/typeahead/controller/common', 'PhabricatorTypeaheadDatasourceController' => 'applications/typeahead/controller/base', 'PhabricatorUser' => 'applications/people/storage/user', 'PhabricatorUserDAO' => 'applications/people/storage/base', ), 'function' => array( '_qsprintf_check_scalar_type' => 'storage/qsprintf', '_qsprintf_check_type' => 'storage/qsprintf', 'celerity_generate_unique_node_id' => 'infratructure/celerity/api', 'celerity_register_resource_map' => 'infratructure/celerity/map', 'javelin_render_tag' => 'infratructure/javelin/markup', 'qsprintf' => 'storage/qsprintf', 'queryfx' => 'storage/queryfx', 'queryfx_all' => 'storage/queryfx', 'queryfx_one' => 'storage/queryfx', 'require_celerity_resource' => 'infratructure/celerity/api', 'vqsprintf' => 'storage/qsprintf', 'vqueryfx' => 'storage/queryfx', 'xsprintf_query' => 'storage/qsprintf', ), 'requires_class' => array( 'Aphront404Response' => 'AphrontResponse', 'AphrontAjaxResponse' => 'AphrontResponse', 'AphrontDefaultApplicationConfiguration' => 'AphrontApplicationConfiguration', 'AphrontDefaultApplicationController' => 'AphrontController', 'AphrontDialogResponse' => 'AphrontResponse', 'AphrontDialogView' => 'AphrontView', 'AphrontErrorView' => 'AphrontView', 'AphrontFileResponse' => 'AphrontResponse', 'AphrontFormCheckboxControl' => 'AphrontFormControl', 'AphrontFormControl' => 'AphrontView', 'AphrontFormFileControl' => 'AphrontFormControl', 'AphrontFormMarkupControl' => 'AphrontFormControl', 'AphrontFormSelectControl' => 'AphrontFormControl', 'AphrontFormStaticControl' => 'AphrontFormControl', 'AphrontFormSubmitControl' => 'AphrontFormControl', 'AphrontFormTextAreaControl' => 'AphrontFormControl', 'AphrontFormTextControl' => 'AphrontFormControl', 'AphrontFormTokenizerControl' => 'AphrontFormControl', 'AphrontFormView' => 'AphrontView', 'AphrontMySQLDatabaseConnection' => 'AphrontDatabaseConnection', 'AphrontNullView' => 'AphrontView', 'AphrontPageView' => 'AphrontView', 'AphrontPanelView' => 'AphrontView', 'AphrontQueryConnectionException' => 'AphrontQueryException', 'AphrontQueryConnectionLostException' => 'AphrontQueryRecoverableException', 'AphrontQueryCountException' => 'AphrontQueryException', 'AphrontQueryObjectMissingException' => 'AphrontQueryException', 'AphrontQueryParameterException' => 'AphrontQueryException', 'AphrontQueryRecoverableException' => 'AphrontQueryException', 'AphrontRedirectResponse' => 'AphrontResponse', 'AphrontSideNavView' => 'AphrontView', 'AphrontTableView' => 'AphrontView', 'AphrontWebpageResponse' => 'AphrontResponse', 'CelerityResourceController' => 'AphrontController', 'ConduitAPI_conduit_connect_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_creatediff_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_setdiffproperty_Method' => 'ConduitAPIMethod', 'ConduitAPI_file_upload_Method' => 'ConduitAPIMethod', 'ConduitAPI_user_find_Method' => 'ConduitAPIMethod', 'DifferentialChangeset' => 'DifferentialDAO', 'DifferentialChangesetDetailView' => 'AphrontView', 'DifferentialChangesetListView' => 'AphrontView', 'DifferentialChangesetViewController' => 'DifferentialController', 'DifferentialController' => 'PhabricatorController', 'DifferentialDAO' => 'PhabricatorLiskDAO', 'DifferentialDiff' => 'DifferentialDAO', 'DifferentialDiffProperty' => 'DifferentialDAO', 'DifferentialDiffTableOfContentsView' => 'AphrontView', 'DifferentialDiffViewController' => 'DifferentialController', 'DifferentialHunk' => 'DifferentialDAO', 'DifferentialRevision' => 'DifferentialDAO', 'DifferentialRevisionEditController' => 'DifferentialController', 'DifferentialRevisionListController' => 'DifferentialController', 'PhabricatorConduitAPIController' => 'PhabricatorConduitController', 'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO', 'PhabricatorConduitConsoleController' => 'PhabricatorConduitController', 'PhabricatorConduitController' => 'PhabricatorController', 'PhabricatorConduitDAO' => 'PhabricatorLiskDAO', 'PhabricatorConduitLogController' => 'PhabricatorConduitController', 'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO', 'PhabricatorController' => 'AphrontController', 'PhabricatorDirectoryCategory' => 'PhabricatorDirectoryDAO', 'PhabricatorDirectoryCategoryDeleteController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryCategoryEditController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryCategoryListController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryController' => 'PhabricatorController', 'PhabricatorDirectoryDAO' => 'PhabricatorLiskDAO', 'PhabricatorDirectoryItem' => 'PhabricatorDirectoryDAO', 'PhabricatorDirectoryItemDeleteController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryItemEditController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryItemListController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryMainController' => 'PhabricatorDirectoryController', 'PhabricatorFile' => 'PhabricatorFileDAO', 'PhabricatorFileController' => 'PhabricatorController', 'PhabricatorFileDAO' => 'PhabricatorLiskDAO', 'PhabricatorFileListController' => 'PhabricatorFileController', 'PhabricatorFileStorageBlob' => 'PhabricatorFileDAO', 'PhabricatorFileUploadController' => 'PhabricatorFileController', 'PhabricatorFileViewController' => 'PhabricatorFileController', 'PhabricatorLiskDAO' => 'LiskDAO', 'PhabricatorMetaMTAController' => 'PhabricatorController', 'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO', 'PhabricatorMetaMTAListController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTAMail' => 'PhabricatorMetaMTADAO', 'PhabricatorMetaMTASendController' => 'PhabricatorMetaMTAController', 'PhabricatorPHID' => 'PhabricatorPHIDDAO', 'PhabricatorPHIDAllocateController' => 'PhabricatorPHIDController', 'PhabricatorPHIDController' => 'PhabricatorController', 'PhabricatorPHIDDAO' => 'PhabricatorLiskDAO', 'PhabricatorPHIDListController' => 'PhabricatorPHIDController', + 'PhabricatorPHIDLookupController' => 'PhabricatorPHIDController', 'PhabricatorPHIDType' => 'PhabricatorPHIDDAO', 'PhabricatorPHIDTypeEditController' => 'PhabricatorPHIDController', 'PhabricatorPHIDTypeListController' => 'PhabricatorPHIDController', 'PhabricatorPeopleController' => 'PhabricatorController', 'PhabricatorPeopleEditController' => 'PhabricatorPeopleController', 'PhabricatorPeopleListController' => 'PhabricatorPeopleController', 'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController', 'PhabricatorStandardPageView' => 'AphrontPageView', 'PhabricatorTypeaheadCommonDatasourceController' => 'PhabricatorTypeaheadDatasourceController', 'PhabricatorTypeaheadDatasourceController' => 'PhabricatorController', 'PhabricatorUser' => 'PhabricatorUserDAO', 'PhabricatorUserDAO' => 'PhabricatorLiskDAO', ), 'requires_interface' => array( ), )); diff --git a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php index faf467307d..c61eec3dc2 100644 --- a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php +++ b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php @@ -1,150 +1,151 @@ array( '$' => 'RepositoryListController', 'new/$' => 'RepositoryEditController', 'edit/(?\d+)/$' => 'RepositoryEditController', 'delete/(?\d+)/$' => 'RepositoryDeleteController', ), '/' => array( '$' => 'PhabricatorDirectoryMainController', ), '/directory/' => array( 'item/$' => 'PhabricatorDirectoryItemListController', 'item/edit/(?:(?\d+)/)?$' => 'PhabricatorDirectoryItemEditController', 'item/delete/(?\d+)/' => 'PhabricatorDirectoryItemDeleteController', 'category/$' => 'PhabricatorDirectoryCategoryListController', 'category/edit/(?:(?\d+)/)?$' => 'PhabricatorDirectoryCategoryEditController', 'category/delete/(?\d+)/' => 'PhabricatorDirectoryCategoryDeleteController', ), '/file/' => array( '$' => 'PhabricatorFileListController', 'upload/$' => 'PhabricatorFileUploadController', '(?info)/(?[^/]+)/' => 'PhabricatorFileViewController', '(?view)/(?[^/]+)/' => 'PhabricatorFileViewController', '(?download)/(?[^/]+)/' => 'PhabricatorFileViewController', ), '/phid/' => array( - '$' => 'PhabricatorPHIDListController', + '$' => 'PhabricatorPHIDLookupController', + 'list/$' => 'PhabricatorPHIDListController', 'type/$' => 'PhabricatorPHIDTypeListController', 'type/edit/(?:(?\d+)/)?$' => 'PhabricatorPHIDTypeEditController', 'new/$' => 'PhabricatorPHIDAllocateController', ), '/people/' => array( '$' => 'PhabricatorPeopleListController', 'edit/(?:(?\w+)/)?$' => 'PhabricatorPeopleEditController', ), '/p/(?\w+)/$' => 'PhabricatorPeopleProfileController', '/conduit/' => array( '$' => 'PhabricatorConduitConsoleController', 'method/(?[^/]+)$' => 'PhabricatorConduitConsoleController', 'log/$' => 'PhabricatorConduitLogController', ), '/api/(?[^/]+)$' => 'PhabricatorConduitAPIController', '/differential/' => array( '$' => 'DifferentialRevisionListController', 'diff/(?\d+)/$' => 'DifferentialDiffViewController', 'changeset/(?\d+)/$' => 'DifferentialChangesetViewController', 'revision/edit/(?:(?\d+)/)?$' => 'DifferentialRevisionEditController', ), '/res/' => array( '(?[a-f0-9]{8})/(?.+\.(?:css|js))$' => 'CelerityResourceController', ), '/typeahead/' => array( 'common/(?\w+)/$' => 'PhabricatorTypeaheadCommonDatasourceController', ), '/mail/' => array( '$' => 'PhabricatorMetaMTAListController', 'send/$' => 'PhabricatorMetaMTASendController', 'view/(?\d+)/$' => 'PhabricatorMetaMTAViewController', ) ); } public function buildRequest() { $request = new AphrontRequest($this->getHost(), $this->getPath()); $request->setRequestData($_GET + $_POST); return $request; } public function handleException(Exception $ex) { $class = phutil_escape_html(get_class($ex)); $message = phutil_escape_html($ex->getMessage()); $content = '
'. '

Unhandled Exception "'.$class.'": '.$message.'

'. ''.phutil_escape_html((string)$ex).''. '
'; $view = new PhabricatorStandardPageView(); $view->appendChild($content); $response = new AphrontWebpageResponse(); $response->setContent($view->render()); return $response; } public function willSendResponse(AphrontResponse $response) { $request = $this->getRequest(); if ($response instanceof AphrontDialogResponse) { if (!$request->isAjax()) { $view = new PhabricatorStandardPageView(); $view->appendChild( '
'. $response->buildResponseString(). '
'); $response = new AphrontWebpageResponse(); $response->setContent($view->render()); return $response; } } return $response; } } diff --git a/src/applications/files/storage/file/PhabricatorFile.php b/src/applications/files/storage/file/PhabricatorFile.php index 37929f2509..9c3a94ce38 100644 --- a/src/applications/files/storage/file/PhabricatorFile.php +++ b/src/applications/files/storage/file/PhabricatorFile.php @@ -1,170 +1,174 @@ true, ) + parent::getConfiguration(); } public function generatePHID() { return PhabricatorPHID::generateNewPHID(self::PHID_TYPE); } public static function newFromPHPUpload($spec, array $params = array()) { if (!$spec) { throw new Exception("No file was uploaded!"); } $err = idx($spec, 'error'); if ($err) { throw new Exception("File upload failed with error '{$err}'."); } $tmp_name = idx($spec, 'tmp_name'); $is_valid = @is_uploaded_file($tmp_name); if (!$is_valid) { throw new Exception("File is not an uploaded file."); } $file_data = Filesystem::readFile($tmp_name); $file_size = idx($spec, 'size'); if (strlen($file_data) != $file_size) { throw new Exception("File size disagrees with uploaded size."); } $file_name = nonempty( idx($params, 'name'), idx($spec, 'name')); $params = array( 'name' => $file_name, ) + $params; return self::newFromFileData($file_data, $params); } public static function newFromFileData($data, array $params = array()) { $file_size = strlen($data); if ($file_size > self::FILE_SIZE_BYTE_LIMIT) { throw new Exception("File is too large to store."); } $file_name = idx($params, 'name'); $file_name = self::normalizeFileName($file_name); $file = new PhabricatorFile(); $file->setName($file_name); $file->setByteSize(strlen($data)); $blob = new PhabricatorFileStorageBlob(); $blob->setData($data); $blob->save(); // TODO: This stuff is almost certainly YAGNI, but we could imagine having // an alternate disk store and gzipping or encrypting things or something // crazy like that and this isn't toooo much extra code. $file->setStorageEngine(self::STORAGE_ENGINE_BLOB); $file->setStorageFormat(self::STORAGE_FORMAT_RAW); $file->setStorageHandle($blob->getID()); try { $tmp = new TempFile(); Filesystem::writeFile($tmp, $data); list($stdout) = execx('file -b --mime %s', $tmp); $file->setMimeType($stdout); } catch (Exception $ex) { // Be robust here since we don't really care that much about mime types. } $file->save(); return $file; } public static function normalizeFileName($file_name) { return preg_replace('/[^a-zA-Z0-9.~_-]/', '_', $file_name); } public function delete() { $this->openTransaction(); switch ($this->getStorageEngine()) { case self::STORAGE_ENGINE_BLOB: $handle = $this->getStorageHandle(); $blob = id(new PhabricatorFileStorageBlob())->load($handle); $blob->delete(); break; default: throw new Exception("Unknown storage engine!"); } $ret = parent::delete(); $this->saveTransaction(); return $ret; } public function loadFileData() { $handle = $this->getStorageHandle(); $data = null; switch ($this->getStorageEngine()) { case self::STORAGE_ENGINE_BLOB: $blob = id(new PhabricatorFileStorageBlob())->load($handle); if (!$blob) { throw new Exception("Failed to load file blob data."); } $data = $blob->getData(); break; default: throw new Exception("Unknown storage engine."); } switch ($this->getStorageFormat()) { case self::STORAGE_FORMAT_RAW: $data = $data; break; default: throw new Exception("Unknown storage format."); } return $data; } + public function getViewURI() { + return PhabricatorFileURI::getViewURIForPHID($this->getPHID()); + } + } diff --git a/src/applications/files/storage/file/__init__.php b/src/applications/files/storage/file/__init__.php index 26394989c8..8328a1bc7b 100644 --- a/src/applications/files/storage/file/__init__.php +++ b/src/applications/files/storage/file/__init__.php @@ -1,19 +1,20 @@ setApplicationName('PHID'); $page->setBaseURI('/phid/'); $page->setTitle(idx($data, 'title')); $page->setTabs( array( - 'phids' => array( + 'lookup' => array( 'href' => '/phid/', - 'name' => 'PHIDs', + 'name' => 'PHID Lookup', + ), + 'phids' => array( + 'href' => '/phid/list/', + 'name' => 'PHID List', ), 'types' => array( 'href' => '/phid/type/', 'name' => 'PHID Types', ), ), idx($data, 'tab')); $page->setGlyph('#'); $page->appendChild($view); $response = new AphrontWebpageResponse(); return $response->setContent($page->render()); } } diff --git a/src/applications/phid/controller/list/PhabricatorPHIDListController.php b/src/applications/phid/controller/list/PhabricatorPHIDListController.php index 33803cc4d0..8e1a0dc569 100644 --- a/src/applications/phid/controller/list/PhabricatorPHIDListController.php +++ b/src/applications/phid/controller/list/PhabricatorPHIDListController.php @@ -1,56 +1,60 @@ loadAllWhere( '1 = 1 ORDER BY id DESC limit 100'); $rows = array(); foreach ($items as $item) { $rows[] = array( phutil_escape_html($item->getPHID()), phutil_escape_html($item->getPHIDType()), phutil_escape_html($item->getOwnerPHID()), phutil_escape_html($item->getParentPHID()), ); } $table = new AphrontTableView($rows); $table->setHeaders( array( 'PHID', 'Type', 'Owner PHID', 'Parent PHID', )); $panel = new AphrontPanelView(); $panel->appendChild($table); $panel->setHeader('PHIDs'); $panel->setCreateButton('Allocate New PHID', '/phid/new/'); - return $this->buildStandardPageResponse($panel, array( - 'title' => 'PHIDs', - 'tab' => 'phids', + return $this->buildStandardPageResponse( + array( + $panel, + ), + array( + 'title' => 'PHIDs', + 'tab' => 'phids', )); } } diff --git a/src/applications/phid/controller/lookup/PhabricatorPHIDLookupController.php b/src/applications/phid/controller/lookup/PhabricatorPHIDLookupController.php new file mode 100644 index 0000000000..0578961e6b --- /dev/null +++ b/src/applications/phid/controller/lookup/PhabricatorPHIDLookupController.php @@ -0,0 +1,111 @@ +getRequest(); + if ($request->isFormPost()) { + $phids = preg_split('/[\s,]+/', $request->getStr('phids')); + $phids = array_filter($phids); + if ($phids) { + $handles = id(new PhabricatorObjectHandleData($phids)) + ->loadHandles(); + + $rows = array(); + foreach ($handles as $handle) { + if ($handle->getURI()) { + $link = phutil_render_tag( + 'a', + array( + 'href' => $handle->getURI(), + ), + phutil_escape_html($handle->getURI())); + } else { + $link = null; + } + + $rows[] = array( + phutil_escape_html($handle->getPHID()), + phutil_escape_html($handle->getType()), + phutil_escape_html($handle->getName()), + phutil_escape_html($handle->getEmail()), + $link, + ); + } + + $table = new AphrontTableView($rows); + $table->setHeaders( + array( + 'PHID', + 'Type', + 'Name', + 'Email', + 'URI', + )); + $table->setColumnClasses( + array( + null, + null, + null, + null, + 'wide', + )); + + $panel = new AphrontPanelView(); + $panel->setHeader('PHID Handles'); + $panel->appendChild($table); + + return $this->buildStandardPageResponse( + $panel, + array( + 'title' => 'PHID Lookup Results', + )); + } + } + + $lookup_form = new AphrontFormView(); + $lookup_form + ->setAction('/phid/') + ->appendChild( + id(new AphrontFormTextAreaControl()) + ->setName('phids') +// ->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT) TODO + ->setCaption('Enter PHIDs separated by spaces or commas.')) + ->appendChild( + id(new AphrontFormSubmitControl()) + ->setValue('Lookup PHIDs')); + + $lookup_panel = new AphrontPanelView(); + $lookup_panel->setHeader('Lookup PHIDs'); + $lookup_panel->appendChild($lookup_form); + $lookup_panel->setWidth(AphrontPanelView::WIDTH_WIDE); + + return $this->buildStandardPageResponse( + array( + $lookup_panel, + ), + array( + 'title' => 'PHID Lookup', + 'tab' => 'lookup', + )); + } + +} diff --git a/src/applications/phid/controller/lookup/__init__.php b/src/applications/phid/controller/lookup/__init__.php new file mode 100644 index 0000000000..b5bb6da8f4 --- /dev/null +++ b/src/applications/phid/controller/lookup/__init__.php @@ -0,0 +1,20 @@ +uri = $uri; + return $this; + } + + public function getURI() { + return $this->uri; + } + + public function setPHID($phid) { + $this->phid = $phid; + return $this; + } + + public function getPHID() { + return $this->phid; + } + + public function setName($name) { + $this->name = $name; + return $this; + } + + public function getName() { + return $this->name; + } + + public function setType($type) { + $this->type = $type; + return $this; + } + + public function getType() { + return $this->type; + } + + public function setEmail($email) { + $this->email = $email; + return $this; + } + + public function getEmail() { + return $this->email; + } + + + +} diff --git a/src/applications/phid/handle/__init__.php b/src/applications/phid/handle/__init__.php new file mode 100644 index 0000000000..e66e9c70a0 --- /dev/null +++ b/src/applications/phid/handle/__init__.php @@ -0,0 +1,10 @@ +phids = $phids; + } + + public function loadHandles() { + + $types = array(); + foreach ($this->phids as $phid) { + $type = $this->lookupType($phid); + $types[$type][] = $phid; + } + + $handles = array(); + + foreach ($types as $type => $phids) { + switch ($type) { + case 'USER': + $class = 'PhabricatorUser'; + PhutilSymbolLoader::loadClass($class); + $object = newv($class, array()); + + $users = $object->loadAllWhere('phid IN (%Ls)', $phids); + $users = mpull($users, null, 'getPHID'); + + foreach ($phids as $phid) { + $handle = new PhabricatorObjectHandle(); + $handle->setPHID($phid); + if (empty($users[$phid])) { + $handle->setType(self::TYPE_UNKNOWN); + $handle->setName('Unknown User'); + } else { + $user = $users[$phid]; + $handle->setType($type); + $handle->setName($user->getUsername()); + $handle->setURI('/p/'.$user->getUsername().'/'); + $handle->setEmail($user->getEmail()); + } + $handles[$phid] = $handle; + } + break; + case 'FILE': + $class = 'PhabricatorFile'; + PhutilSymbolLoader::loadClass($class); + $object = newv($class, array()); + + $files = $object->loadAllWhere('phid IN (%Ls)', $phids); + $files = mpull($files, null, 'getPHID'); + + foreach ($phids as $phid) { + $handle = new PhabricatorObjectHandle(); + $handle->setPHID($phid); + if (empty($files[$phid])) { + $handle->setType(self::TYPE_UNKNOWN); + $handle->setName('Unknown File'); + } else { + $file = $files[$phid]; + $handle->setType($type); + $handle->setName($file->getName()); + $handle->setURI($file->getViewURI()); + } + $handles[$phid] = $handle; + } + break; + default: + foreach ($phids as $phid) { + $handle = new PhabricatorObjectHandle(); + $handle->setType($type); + $handle->setPHID($phid); + $handle->setName('Unknown Object'); + $handles[$phid] = $handle; + } + break; + } + } + + return $handles; + } + + private function lookupType($phid) { + $matches = null; + if (preg_match('/^PHID-([^-]{4})-/', $phid, $matches)) { + return $matches[1]; + } + return self::TYPE_UNKNOWN; + } + +} diff --git a/src/applications/phid/handle/data/__init__.php b/src/applications/phid/handle/data/__init__.php new file mode 100644 index 0000000000..b6578834e2 --- /dev/null +++ b/src/applications/phid/handle/data/__init__.php @@ -0,0 +1,15 @@ +