diff --git a/externals/skins/oblivious/css/oblivious.css b/externals/skins/oblivious/css/oblivious.css
index cad5d6cf9a..044d478aab 100644
--- a/externals/skins/oblivious/css/oblivious.css
+++ b/externals/skins/oblivious/css/oblivious.css
@@ -29,19 +29,18 @@ html {
.oblivious-content {
padding-top: 3%;
margin-left: 22%;
- max-width: 600px;
+ max-width: 800px;
}
a {
- color: #222222;
+ color: #2980b9;
text-decoration: none;
}
a:hover {
- color: #a00000;
+ text-decoration: underline;
}
-
h1 {
font-size: 24px;
font-weight: normal;
@@ -50,37 +49,24 @@ h1 {
h2 {
font-size: 22px;
font-weight: bold;
+ margin-bottom: 8px;
}
.phame-post {
margin: 0 0 2em;
}
+.phame-post-title {
+ font-size: 28px;
+}
+
.phame-post-date {
font-size: 12px;
- margin: .25em 0 1em;
+ margin: .25em 0 2em;
}
-.phame-post {
- line-height: 1.6em;
-}
-
-.phame-post p {
- margin: 0 0 1em;
-}
-
-.phame-post tt {
- color: #333333;
- background: #ebebeb;
- padding: 0 .25em;
- white-space: pre-wrap;
-}
-
-.phame-post .remarkup-code-block pre {
- overflow: auto;
- padding: 10px 10px;
- border: 1px solid #dfdfdf;
- background-color: #f8f8f8;
+.oblivious-content .phabricator-remarkup ul.remarkup-list {
+ margin-left: 0;
}
.fb-comments,
diff --git a/externals/skins/oblivious/header.php b/externals/skins/oblivious/header.php
index c3e7a4d60f..0ea9f331c7 100644
--- a/externals/skins/oblivious/header.php
+++ b/externals/skins/oblivious/header.php
@@ -13,6 +13,6 @@
echo _e($blog->getName());
?>
-
diff --git a/resources/celerity/map.php b/resources/celerity/map.php
index fe97bdc236..91b57e9f5d 100644
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -7,7 +7,7 @@
*/
return array(
'names' => array(
- 'core.pkg.css' => '15e557bc',
+ 'core.pkg.css' => 'e94665e4',
'core.pkg.js' => '47dc9ebb',
'darkconsole.pkg.js' => 'e7393ebb',
'differential.pkg.css' => '2de124c9',
@@ -25,8 +25,8 @@ return array(
'rsrc/css/aphront/notification.css' => '9c279160',
'rsrc/css/aphront/panel-view.css' => '8427b78d',
'rsrc/css/aphront/phabricator-nav-view.css' => 'a24cb589',
- 'rsrc/css/aphront/table-view.css' => '61543e7a',
- 'rsrc/css/aphront/tokenizer.css' => '04875312',
+ 'rsrc/css/aphront/table-view.css' => '6d01d468',
+ 'rsrc/css/aphront/tokenizer.css' => '056da01b',
'rsrc/css/aphront/tooltip.css' => '7672b60f',
'rsrc/css/aphront/typeahead-browse.css' => 'd8581d2c',
'rsrc/css/aphront/typeahead.css' => '0e403212',
@@ -36,7 +36,7 @@ return array(
'rsrc/css/application/base/notification-menu.css' => 'f31c0bde',
'rsrc/css/application/base/phabricator-application-launch-view.css' => '95351601',
'rsrc/css/application/base/phui-theme.css' => '6b451f24',
- 'rsrc/css/application/base/standard-page-view.css' => '1f53d056',
+ 'rsrc/css/application/base/standard-page-view.css' => 'a1096ed4',
'rsrc/css/application/calendar/calendar-icon.css' => 'c69aa59f',
'rsrc/css/application/chatlog/chatlog.css' => 'd295b020',
'rsrc/css/application/conduit/conduit-api.css' => '7bc725c4',
@@ -100,17 +100,17 @@ return array(
'rsrc/css/application/releeph/releeph-request-differential-create-dialog.css' => '8d8b92cd',
'rsrc/css/application/releeph/releeph-request-typeahead.css' => '667a48ae',
'rsrc/css/application/search/search-results.css' => '7dea472c',
- 'rsrc/css/application/slowvote/slowvote.css' => '475b4bd2',
+ 'rsrc/css/application/slowvote/slowvote.css' => 'da0afb1b',
'rsrc/css/application/tokens/tokens.css' => '3d0f239e',
'rsrc/css/application/uiexample/example.css' => '528b19de',
- 'rsrc/css/core/core.css' => 'a76cefc9',
- 'rsrc/css/core/remarkup.css' => '8d341238',
+ 'rsrc/css/core/core.css' => '78e8d7ea',
+ 'rsrc/css/core/remarkup.css' => '2193fc05',
'rsrc/css/core/syntax.css' => '9fd11da8',
'rsrc/css/core/z-index.css' => '57ddcaa2',
- 'rsrc/css/diviner/diviner-shared.css' => '5a337049',
+ 'rsrc/css/diviner/diviner-shared.css' => 'aa3656aa',
+ 'rsrc/css/font/font-aleo.css' => 'b61d3062',
'rsrc/css/font/font-awesome.css' => 'd2fc4e8d',
'rsrc/css/font/font-lato.css' => '5ab1a46a',
- 'rsrc/css/font/font-roboto-slab.css' => 'f24a53cb',
'rsrc/css/font/phui-font-icon-base.css' => 'ecbbb4c2',
'rsrc/css/layout/phabricator-filetree-view.css' => 'fccf9f82',
'rsrc/css/layout/phabricator-hovercard-view.css' => '1239cd52',
@@ -126,16 +126,17 @@ return array(
'rsrc/css/phui/phui-box.css' => 'a5bb366d',
'rsrc/css/phui/phui-button.css' => '16020a60',
'rsrc/css/phui/phui-crumbs-view.css' => 'd842f867',
- 'rsrc/css/phui/phui-document.css' => '0267054b',
+ 'rsrc/css/phui/phui-document-pro.css' => '4f2b42e3',
+ 'rsrc/css/phui/phui-document.css' => '9fa715d2',
'rsrc/css/phui/phui-feed-story.css' => 'b7b26d23',
- 'rsrc/css/phui/phui-fontkit.css' => 'cb8ae7ad',
+ 'rsrc/css/phui/phui-fontkit.css' => 'c9d63950',
'rsrc/css/phui/phui-form-view.css' => '621b21c5',
'rsrc/css/phui/phui-form.css' => 'afdb2c6e',
'rsrc/css/phui/phui-header-view.css' => '55bb32dd',
'rsrc/css/phui/phui-icon.css' => 'b0a6b1b6',
'rsrc/css/phui/phui-image-mask.css' => '5a8b09c8',
'rsrc/css/phui/phui-info-panel.css' => '27ea50a1',
- 'rsrc/css/phui/phui-info-view.css' => '5b16bac6',
+ 'rsrc/css/phui/phui-info-view.css' => '6d7c3509',
'rsrc/css/phui/phui-list.css' => '125599df',
'rsrc/css/phui/phui-object-box.css' => '407eaf5a',
'rsrc/css/phui/phui-object-item-list-view.css' => '26c30d3f',
@@ -145,7 +146,7 @@ return array(
'rsrc/css/phui/phui-remarkup-preview.css' => '867f85b3',
'rsrc/css/phui/phui-spacing.css' => '042804d6',
'rsrc/css/phui/phui-status.css' => '888cedb8',
- 'rsrc/css/phui/phui-tag-view.css' => '402691cc',
+ 'rsrc/css/phui/phui-tag-view.css' => 'e60e227b',
'rsrc/css/phui/phui-text.css' => 'cf019f54',
'rsrc/css/phui/phui-timeline-view.css' => '2efceff8',
'rsrc/css/phui/phui-two-column-view.css' => '39ecafb1',
@@ -156,6 +157,14 @@ return array(
'rsrc/css/sprite-menu.css' => '9dd65b92',
'rsrc/css/sprite-projects.css' => 'e5ad842a',
'rsrc/css/sprite-tokens.css' => '4f399012',
+ 'rsrc/externals/font/aleo/aleo-bold.eot' => 'd3d3bed7',
+ 'rsrc/externals/font/aleo/aleo-bold.ttf' => '4b08bef0',
+ 'rsrc/externals/font/aleo/aleo-bold.woff' => '93b513a1',
+ 'rsrc/externals/font/aleo/aleo-bold.woff2' => '75fbf322',
+ 'rsrc/externals/font/aleo/aleo-regular.eot' => 'a4e29e2f',
+ 'rsrc/externals/font/aleo/aleo-regular.ttf' => '751e7479',
+ 'rsrc/externals/font/aleo/aleo-regular.woff' => 'c3744be9',
+ 'rsrc/externals/font/aleo/aleo-regular.woff2' => '851aa0ee',
'rsrc/externals/font/fontawesome/fontawesome-webfont.eot' => '7d5a4653',
'rsrc/externals/font/fontawesome/fontawesome-webfont.ttf' => '531835e8',
'rsrc/externals/font/fontawesome/fontawesome-webfont.woff' => '427fe363',
@@ -176,10 +185,6 @@ return array(
'rsrc/externals/font/lato/lato-regular.ttf' => 'e270165b',
'rsrc/externals/font/lato/lato-regular.woff' => '13d39fe2',
'rsrc/externals/font/lato/lato-regular.woff2' => '57a9f742',
- 'rsrc/externals/font/robotoslab/robotoslab-regular.eot' => 'eaefe21c',
- 'rsrc/externals/font/robotoslab/robotoslab-regular.ttf' => '4bfef7d5',
- 'rsrc/externals/font/robotoslab/robotoslab-regular.woff' => '7f0552f9',
- 'rsrc/externals/font/robotoslab/robotoslab-regular.woff2' => '23bdd43c',
'rsrc/externals/javelin/core/Event.js' => '85ea0626',
'rsrc/externals/javelin/core/Stratcom.js' => '6c53634d',
'rsrc/externals/javelin/core/__tests__/event-stop-and-kill.js' => '717554e4',
@@ -448,7 +453,7 @@ return array(
'rsrc/js/core/behavior-device.js' => 'a205cf28',
'rsrc/js/core/behavior-drag-and-drop-textarea.js' => '6d49590e',
'rsrc/js/core/behavior-error-log.js' => '6882e80a',
- 'rsrc/js/core/behavior-fancy-datepicker.js' => '665cf6ac',
+ 'rsrc/js/core/behavior-fancy-datepicker.js' => '8ae55229',
'rsrc/js/core/behavior-file-tree.js' => '88236f00',
'rsrc/js/core/behavior-form.js' => '5c54cbf3',
'rsrc/js/core/behavior-gesture.js' => '3ab51e2c',
@@ -493,8 +498,8 @@ return array(
'aphront-list-filter-view-css' => '5d6f0526',
'aphront-multi-column-view-css' => 'fd18389d',
'aphront-panel-view-css' => '8427b78d',
- 'aphront-table-view-css' => '61543e7a',
- 'aphront-tokenizer-control-css' => '04875312',
+ 'aphront-table-view-css' => '6d01d468',
+ 'aphront-tokenizer-control-css' => '056da01b',
'aphront-tooltip-css' => '7672b60f',
'aphront-typeahead-control-css' => '0e403212',
'auth-css' => '0877ed6e',
@@ -523,10 +528,10 @@ return array(
'diffusion-icons-css' => '2941baf1',
'diffusion-readme-css' => '2106ea08',
'diffusion-source-css' => '075ba788',
- 'diviner-shared-css' => '5a337049',
+ 'diviner-shared-css' => 'aa3656aa',
+ 'font-aleo' => 'b61d3062',
'font-fontawesome' => 'd2fc4e8d',
'font-lato' => '5ab1a46a',
- 'font-roboto-slab' => 'f24a53cb',
'global-drag-and-drop-css' => '697324ad',
'harbormaster-css' => 'b0758ca5',
'herald-css' => '826075fa',
@@ -581,7 +586,7 @@ return array(
'javelin-behavior-durable-column' => 'c72aa091',
'javelin-behavior-error-log' => '6882e80a',
'javelin-behavior-event-all-day' => '38dcf3c8',
- 'javelin-behavior-fancy-datepicker' => '665cf6ac',
+ 'javelin-behavior-fancy-datepicker' => '8ae55229',
'javelin-behavior-global-drag-and-drop' => 'c8e57404',
'javelin-behavior-herald-rule-editor' => '7ebaeed3',
'javelin-behavior-high-security-warning' => 'a464fe03',
@@ -713,7 +718,7 @@ return array(
'phabricator-busy' => '59a7976a',
'phabricator-chatlog-css' => 'd295b020',
'phabricator-content-source-view-css' => '4b8b05d4',
- 'phabricator-core-css' => 'a76cefc9',
+ 'phabricator-core-css' => '78e8d7ea',
'phabricator-countdown-css' => 'e7544472',
'phabricator-dashboard-css' => 'eb458607',
'phabricator-drag-and-drop-file-upload' => 'ad10aeac',
@@ -735,13 +740,13 @@ return array(
'phabricator-object-selector-css' => '85ee8ce6',
'phabricator-phtize' => 'd254d646',
'phabricator-prefab' => '6920d200',
- 'phabricator-remarkup-css' => '8d341238',
+ 'phabricator-remarkup-css' => '2193fc05',
'phabricator-search-results-css' => '7dea472c',
'phabricator-shaped-request' => '7cbe244b',
'phabricator-side-menu-view-css' => 'bec2458e',
- 'phabricator-slowvote-css' => '475b4bd2',
+ 'phabricator-slowvote-css' => 'da0afb1b',
'phabricator-source-code-view-css' => 'cbeef983',
- 'phabricator-standard-page-view' => '1f53d056',
+ 'phabricator-standard-page-view' => 'a1096ed4',
'phabricator-textareautils' => '5c93c52c',
'phabricator-title' => 'df5e11d2',
'phabricator-tooltip' => '1d298e3a',
@@ -775,17 +780,18 @@ return array(
'phui-calendar-list-css' => 'c1c7f338',
'phui-calendar-month-css' => '476be7e0',
'phui-crumbs-view-css' => 'd842f867',
- 'phui-document-view-css' => '0267054b',
+ 'phui-document-view-css' => '9fa715d2',
+ 'phui-document-view-pro-css' => '4f2b42e3',
'phui-feed-story-css' => 'b7b26d23',
'phui-font-icon-base-css' => 'ecbbb4c2',
- 'phui-fontkit-css' => 'cb8ae7ad',
+ 'phui-fontkit-css' => 'c9d63950',
'phui-form-css' => 'afdb2c6e',
'phui-form-view-css' => '621b21c5',
'phui-header-view-css' => '55bb32dd',
'phui-icon-view-css' => 'b0a6b1b6',
'phui-image-mask-css' => '5a8b09c8',
'phui-info-panel-css' => '27ea50a1',
- 'phui-info-view-css' => '5b16bac6',
+ 'phui-info-view-css' => '6d7c3509',
'phui-inline-comment-view-css' => '0fdb3667',
'phui-list-view-css' => '125599df',
'phui-object-box-css' => '407eaf5a',
@@ -796,7 +802,7 @@ return array(
'phui-remarkup-preview-css' => '867f85b3',
'phui-spacing-css' => '042804d6',
'phui-status-list-view-css' => '888cedb8',
- 'phui-tag-view-css' => '402691cc',
+ 'phui-tag-view-css' => 'e60e227b',
'phui-text-css' => 'cf019f54',
'phui-theme-css' => '6b451f24',
'phui-timeline-view-css' => '2efceff8',
@@ -861,14 +867,14 @@ return array(
'javelin-stratcom',
'phabricator-prefab',
),
- '04875312' => array(
- 'aphront-typeahead-control-css',
- 'phui-tag-view-css',
- ),
'05270951' => array(
'javelin-util',
'javelin-magical-init',
),
+ '056da01b' => array(
+ 'aphront-typeahead-control-css',
+ 'phui-tag-view-css',
+ ),
'065227cc' => array(
'javelin-behavior',
'javelin-dom',
@@ -1288,13 +1294,6 @@ return array(
'javelin-vector',
'differential-inline-comment-editor',
),
- '665cf6ac' => array(
- 'javelin-behavior',
- 'javelin-util',
- 'javelin-dom',
- 'javelin-stratcom',
- 'javelin-vector',
- ),
'6882e80a' => array(
'javelin-dom',
),
@@ -1494,6 +1493,13 @@ return array(
'javelin-install',
'javelin-dom',
),
+ '8ae55229' => array(
+ 'javelin-behavior',
+ 'javelin-util',
+ 'javelin-dom',
+ 'javelin-stratcom',
+ 'javelin-vector',
+ ),
'8b3fd187' => array(
'javelin-install',
'javelin-util',
@@ -1711,6 +1717,9 @@ return array(
'javelin-dom',
'javelin-util',
),
+ 'b61d3062' => array(
+ 'phui-fontkit-css',
+ ),
'b6993408' => array(
'javelin-behavior',
'javelin-stratcom',
@@ -1946,9 +1955,6 @@ return array(
'javelin-workflow',
'javelin-json',
),
- 'f24a53cb' => array(
- 'phui-fontkit-css',
- ),
'f36e01af' => array(
'javelin-behavior',
'javelin-behavior-device',
diff --git a/resources/sql/autopatches/20151030.harbormaster.initiator.sql b/resources/sql/autopatches/20151030.harbormaster.initiator.sql
new file mode 100644
index 0000000000..f8ba3f6757
--- /dev/null
+++ b/resources/sql/autopatches/20151030.harbormaster.initiator.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_build
+ ADD COLUMN initiatorPHID VARBINARY(64);
diff --git a/resources/sql/autopatches/20151106.phame.post.mailkey.1.sql b/resources/sql/autopatches/20151106.phame.post.mailkey.1.sql
new file mode 100644
index 0000000000..3e4846d909
--- /dev/null
+++ b/resources/sql/autopatches/20151106.phame.post.mailkey.1.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_phame.phame_post
+ ADD mailKey binary(20) NOT NULL;
diff --git a/resources/sql/autopatches/20151106.phame.post.mailkey.2.php b/resources/sql/autopatches/20151106.phame.post.mailkey.2.php
new file mode 100644
index 0000000000..5c9942665d
--- /dev/null
+++ b/resources/sql/autopatches/20151106.phame.post.mailkey.2.php
@@ -0,0 +1,18 @@
+establishConnection('w');
+$iterator = new LiskMigrationIterator($table);
+foreach ($iterator as $post) {
+ $id = $post->getID();
+
+ echo pht('Adding mail key for Post %d...', $id);
+ echo "\n";
+
+ queryfx(
+ $conn_w,
+ 'UPDATE %T SET mailKey = %s WHERE id = %d',
+ $table->getTableName(),
+ Filesystem::readRandomCharacters(20),
+ $id);
+}
diff --git a/scripts/symbols/import_repository_symbols.php b/scripts/symbols/import_repository_symbols.php
index 2ac2b3c8a9..c8dabc8508 100755
--- a/scripts/symbols/import_repository_symbols.php
+++ b/scripts/symbols/import_repository_symbols.php
@@ -102,7 +102,7 @@ function commit_symbols(
$repository->getPHID());
}
- echo pht('Loading %s symbols...', new PhutilNumber(count($sql))), "\n";
+ echo pht('Loading %s symbols...', phutil_count($sql)), "\n";
foreach (array_chunk($sql, 128) as $chunk) {
queryfx(
$conn_w,
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index 398d212913..aaacc2cde4 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -135,6 +135,7 @@ phutil_register_library_map(array(
'AphrontFormView' => 'view/form/AphrontFormView.php',
'AphrontGlyphBarView' => 'view/widget/bars/AphrontGlyphBarView.php',
'AphrontHTMLResponse' => 'aphront/response/AphrontHTMLResponse.php',
+ 'AphrontHTTPParameterType' => 'aphront/httpparametertype/AphrontHTTPParameterType.php',
'AphrontHTTPProxyResponse' => 'aphront/response/AphrontHTTPProxyResponse.php',
'AphrontHTTPSink' => 'aphront/sink/AphrontHTTPSink.php',
'AphrontHTTPSinkTestCase' => 'aphront/sink/__tests__/AphrontHTTPSinkTestCase.php',
@@ -149,10 +150,13 @@ phutil_register_library_map(array(
'AphrontMultiColumnView' => 'view/layout/AphrontMultiColumnView.php',
'AphrontMySQLDatabaseConnectionTestCase' => 'infrastructure/storage/__tests__/AphrontMySQLDatabaseConnectionTestCase.php',
'AphrontNullView' => 'view/AphrontNullView.php',
+ 'AphrontPHIDHTTPParameterType' => 'aphront/httpparametertype/AphrontPHIDHTTPParameterType.php',
+ 'AphrontPHIDListHTTPParameterType' => 'aphront/httpparametertype/AphrontPHIDListHTTPParameterType.php',
'AphrontPHPHTTPSink' => 'aphront/sink/AphrontPHPHTTPSink.php',
'AphrontPageView' => 'view/page/AphrontPageView.php',
'AphrontPlainTextResponse' => 'aphront/response/AphrontPlainTextResponse.php',
'AphrontProgressBarView' => 'view/widget/bars/AphrontProgressBarView.php',
+ 'AphrontProjectListHTTPParameterType' => 'aphront/httpparametertype/AphrontProjectListHTTPParameterType.php',
'AphrontProxyResponse' => 'aphront/response/AphrontProxyResponse.php',
'AphrontRedirectResponse' => 'aphront/response/AphrontRedirectResponse.php',
'AphrontRedirectResponseTestCase' => 'aphront/response/__tests__/AphrontRedirectResponseTestCase.php',
@@ -164,15 +168,19 @@ phutil_register_library_map(array(
'AphrontResponseProducerInterface' => 'aphront/interface/AphrontResponseProducerInterface.php',
'AphrontRoutingMap' => 'aphront/site/AphrontRoutingMap.php',
'AphrontRoutingResult' => 'aphront/site/AphrontRoutingResult.php',
+ 'AphrontSelectHTTPParameterType' => 'aphront/httpparametertype/AphrontSelectHTTPParameterType.php',
'AphrontSideNavFilterView' => 'view/layout/AphrontSideNavFilterView.php',
'AphrontSite' => 'aphront/site/AphrontSite.php',
'AphrontStackTraceView' => 'view/widget/AphrontStackTraceView.php',
'AphrontStandaloneHTMLResponse' => 'aphront/response/AphrontStandaloneHTMLResponse.php',
+ 'AphrontStringHTTPParameterType' => 'aphront/httpparametertype/AphrontStringHTTPParameterType.php',
+ 'AphrontStringListHTTPParameterType' => 'aphront/httpparametertype/AphrontStringListHTTPParameterType.php',
'AphrontTableView' => 'view/control/AphrontTableView.php',
'AphrontTagView' => 'view/AphrontTagView.php',
'AphrontTokenizerTemplateView' => 'view/control/AphrontTokenizerTemplateView.php',
'AphrontTypeaheadTemplateView' => 'view/control/AphrontTypeaheadTemplateView.php',
'AphrontUnhandledExceptionResponse' => 'aphront/response/AphrontUnhandledExceptionResponse.php',
+ 'AphrontUserListHTTPParameterType' => 'aphront/httpparametertype/AphrontUserListHTTPParameterType.php',
'AphrontView' => 'view/AphrontView.php',
'AphrontWebpageResponse' => 'aphront/response/AphrontWebpageResponse.php',
'ArcanistConduitAPIMethod' => 'applications/arcanist/conduit/ArcanistConduitAPIMethod.php',
@@ -1403,6 +1411,7 @@ phutil_register_library_map(array(
'PHUI' => 'view/phui/PHUI.php',
'PHUIActionPanelExample' => 'applications/uiexample/examples/PHUIActionPanelExample.php',
'PHUIActionPanelView' => 'view/phui/PHUIActionPanelView.php',
+ 'PHUIApplicationMenuView' => 'view/layout/PHUIApplicationMenuView.php',
'PHUIBadgeBoxView' => 'view/phui/PHUIBadgeBoxView.php',
'PHUIBadgeExample' => 'applications/uiexample/examples/PHUIBadgeExample.php',
'PHUIBadgeMiniView' => 'view/phui/PHUIBadgeMiniView.php',
@@ -1433,6 +1442,7 @@ phutil_register_library_map(array(
'PHUIDiffTwoUpInlineCommentRowScaffold' => 'infrastructure/diff/view/PHUIDiffTwoUpInlineCommentRowScaffold.php',
'PHUIDocumentExample' => 'applications/uiexample/examples/PHUIDocumentExample.php',
'PHUIDocumentView' => 'view/phui/PHUIDocumentView.php',
+ 'PHUIDocumentViewPro' => 'view/phui/PHUIDocumentViewPro.php',
'PHUIFeedStoryExample' => 'applications/uiexample/examples/PHUIFeedStoryExample.php',
'PHUIFeedStoryView' => 'view/phui/PHUIFeedStoryView.php',
'PHUIFormDividerControl' => 'view/form/control/PHUIFormDividerControl.php',
@@ -1528,6 +1538,7 @@ phutil_register_library_map(array(
'PasteCreateMailReceiver' => 'applications/paste/mail/PasteCreateMailReceiver.php',
'PasteDefaultEditCapability' => 'applications/paste/capability/PasteDefaultEditCapability.php',
'PasteDefaultViewCapability' => 'applications/paste/capability/PasteDefaultViewCapability.php',
+ 'PasteEditConduitAPIMethod' => 'applications/paste/conduit/PasteEditConduitAPIMethod.php',
'PasteEmbedView' => 'applications/paste/view/PasteEmbedView.php',
'PasteInfoConduitAPIMethod' => 'applications/paste/conduit/PasteInfoConduitAPIMethod.php',
'PasteMailReceiver' => 'applications/paste/mail/PasteMailReceiver.php',
@@ -1568,6 +1579,9 @@ phutil_register_library_map(array(
'PhabricatorApplicationDatasource' => 'applications/meta/typeahead/PhabricatorApplicationDatasource.php',
'PhabricatorApplicationDetailViewController' => 'applications/meta/controller/PhabricatorApplicationDetailViewController.php',
'PhabricatorApplicationEditController' => 'applications/meta/controller/PhabricatorApplicationEditController.php',
+ 'PhabricatorApplicationEditEngine' => 'applications/transactions/editengine/PhabricatorApplicationEditEngine.php',
+ 'PhabricatorApplicationEditEngineAPIMethod' => 'applications/transactions/editengine/PhabricatorApplicationEditEngineAPIMethod.php',
+ 'PhabricatorApplicationEditHTTPParameterHelpView' => 'applications/transactions/view/PhabricatorApplicationEditHTTPParameterHelpView.php',
'PhabricatorApplicationEmailCommandsController' => 'applications/meta/controller/PhabricatorApplicationEmailCommandsController.php',
'PhabricatorApplicationLaunchView' => 'applications/meta/view/PhabricatorApplicationLaunchView.php',
'PhabricatorApplicationPanelController' => 'applications/meta/controller/PhabricatorApplicationPanelController.php',
@@ -1840,7 +1854,6 @@ phutil_register_library_map(array(
'PhabricatorCommonPasswords' => 'applications/auth/constants/PhabricatorCommonPasswords.php',
'PhabricatorConduitAPIController' => 'applications/conduit/controller/PhabricatorConduitAPIController.php',
'PhabricatorConduitApplication' => 'applications/conduit/application/PhabricatorConduitApplication.php',
- 'PhabricatorConduitCertificateSettingsPanel' => 'applications/settings/panel/PhabricatorConduitCertificateSettingsPanel.php',
'PhabricatorConduitCertificateToken' => 'applications/conduit/storage/PhabricatorConduitCertificateToken.php',
'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/PhabricatorConduitConnectionLog.php',
'PhabricatorConduitConsoleController' => 'applications/conduit/controller/PhabricatorConduitConsoleController.php',
@@ -1884,6 +1897,7 @@ phutil_register_library_map(array(
'PhabricatorConfigEntryQuery' => 'applications/config/query/PhabricatorConfigEntryQuery.php',
'PhabricatorConfigFileSource' => 'infrastructure/env/PhabricatorConfigFileSource.php',
'PhabricatorConfigGroupController' => 'applications/config/controller/PhabricatorConfigGroupController.php',
+ 'PhabricatorConfigHTTPParameterTypesModule' => 'applications/config/module/PhabricatorConfigHTTPParameterTypesModule.php',
'PhabricatorConfigHistoryController' => 'applications/config/controller/PhabricatorConfigHistoryController.php',
'PhabricatorConfigIgnoreController' => 'applications/config/controller/PhabricatorConfigIgnoreController.php',
'PhabricatorConfigIssueListController' => 'applications/config/controller/PhabricatorConfigIssueListController.php',
@@ -2061,6 +2075,7 @@ phutil_register_library_map(array(
'PhabricatorDataCacheSpec' => 'applications/cache/spec/PhabricatorDataCacheSpec.php',
'PhabricatorDataNotAttachedException' => 'infrastructure/storage/lisk/PhabricatorDataNotAttachedException.php',
'PhabricatorDatabaseSetupCheck' => 'applications/config/check/PhabricatorDatabaseSetupCheck.php',
+ 'PhabricatorDatasourceEditField' => 'applications/transactions/editfield/PhabricatorDatasourceEditField.php',
'PhabricatorDateTimeSettingsPanel' => 'applications/settings/panel/PhabricatorDateTimeSettingsPanel.php',
'PhabricatorDebugController' => 'applications/system/controller/PhabricatorDebugController.php',
'PhabricatorDefaultRequestExceptionHandler' => 'aphront/handler/PhabricatorDefaultRequestExceptionHandler.php',
@@ -2089,12 +2104,15 @@ phutil_register_library_map(array(
'PhabricatorEdgeConfig' => 'infrastructure/edges/constants/PhabricatorEdgeConfig.php',
'PhabricatorEdgeConstants' => 'infrastructure/edges/constants/PhabricatorEdgeConstants.php',
'PhabricatorEdgeCycleException' => 'infrastructure/edges/exception/PhabricatorEdgeCycleException.php',
+ 'PhabricatorEdgeEditType' => 'applications/transactions/edittype/PhabricatorEdgeEditType.php',
'PhabricatorEdgeEditor' => 'infrastructure/edges/editor/PhabricatorEdgeEditor.php',
'PhabricatorEdgeGraph' => 'infrastructure/edges/util/PhabricatorEdgeGraph.php',
'PhabricatorEdgeQuery' => 'infrastructure/edges/query/PhabricatorEdgeQuery.php',
'PhabricatorEdgeTestCase' => 'infrastructure/edges/__tests__/PhabricatorEdgeTestCase.php',
'PhabricatorEdgeType' => 'infrastructure/edges/type/PhabricatorEdgeType.php',
'PhabricatorEdgeTypeTestCase' => 'infrastructure/edges/type/__tests__/PhabricatorEdgeTypeTestCase.php',
+ 'PhabricatorEditField' => 'applications/transactions/editfield/PhabricatorEditField.php',
+ 'PhabricatorEditType' => 'applications/transactions/edittype/PhabricatorEditType.php',
'PhabricatorEditor' => 'infrastructure/PhabricatorEditor.php',
'PhabricatorElasticSearchEngine' => 'applications/search/engine/PhabricatorElasticSearchEngine.php',
'PhabricatorElasticSearchSetupCheck' => 'applications/config/check/PhabricatorElasticSearchSetupCheck.php',
@@ -2241,6 +2259,7 @@ phutil_register_library_map(array(
'PhabricatorGlobalLock' => 'infrastructure/util/PhabricatorGlobalLock.php',
'PhabricatorGlobalUploadTargetView' => 'applications/files/view/PhabricatorGlobalUploadTargetView.php',
'PhabricatorGoogleAuthProvider' => 'applications/auth/provider/PhabricatorGoogleAuthProvider.php',
+ 'PhabricatorHTTPParameterTypeTableView' => 'applications/config/view/PhabricatorHTTPParameterTypeTableView.php',
'PhabricatorHandleList' => 'applications/phid/handle/pool/PhabricatorHandleList.php',
'PhabricatorHandleObjectSelectorDataView' => 'applications/phid/handle/view/PhabricatorHandleObjectSelectorDataView.php',
'PhabricatorHandlePool' => 'applications/phid/handle/pool/PhabricatorHandlePool.php',
@@ -2532,6 +2551,7 @@ phutil_register_library_map(array(
'PhabricatorPHID' => 'applications/phid/storage/PhabricatorPHID.php',
'PhabricatorPHIDConstants' => 'applications/phid/PhabricatorPHIDConstants.php',
'PhabricatorPHIDInterface' => 'applications/phid/interface/PhabricatorPHIDInterface.php',
+ 'PhabricatorPHIDResolver' => 'applications/phid/resolver/PhabricatorPHIDResolver.php',
'PhabricatorPHIDType' => 'applications/phid/type/PhabricatorPHIDType.php',
'PhabricatorPHIDTypeTestCase' => 'applications/phid/type/__tests__/PhabricatorPHIDTypeTestCase.php',
'PhabricatorPHPASTApplication' => 'applications/phpast/application/PhabricatorPHPASTApplication.php',
@@ -2552,6 +2572,7 @@ phutil_register_library_map(array(
'PhabricatorPasteController' => 'applications/paste/controller/PhabricatorPasteController.php',
'PhabricatorPasteDAO' => 'applications/paste/storage/PhabricatorPasteDAO.php',
'PhabricatorPasteEditController' => 'applications/paste/controller/PhabricatorPasteEditController.php',
+ 'PhabricatorPasteEditEngine' => 'applications/paste/editor/PhabricatorPasteEditEngine.php',
'PhabricatorPasteEditor' => 'applications/paste/editor/PhabricatorPasteEditor.php',
'PhabricatorPasteListController' => 'applications/paste/controller/PhabricatorPasteListController.php',
'PhabricatorPastePastePHIDType' => 'applications/paste/phid/PhabricatorPastePastePHIDType.php',
@@ -2622,8 +2643,11 @@ phutil_register_library_map(array(
'PhabricatorPhurlApplication' => 'applications/phurl/application/PhabricatorPhurlApplication.php',
'PhabricatorPhurlController' => 'applications/phurl/controller/PhabricatorPhurlController.php',
'PhabricatorPhurlDAO' => 'applications/phurl/storage/PhabricatorPhurlDAO.php',
+ 'PhabricatorPhurlLinkRemarkupRule' => 'applications/phurl/remarkup/PhabricatorPhurlLinkRemarkupRule.php',
+ 'PhabricatorPhurlRemarkupRule' => 'applications/phurl/remarkup/PhabricatorPhurlRemarkupRule.php',
'PhabricatorPhurlSchemaSpec' => 'applications/phurl/storage/PhabricatorPhurlSchemaSpec.php',
'PhabricatorPhurlURL' => 'applications/phurl/storage/PhabricatorPhurlURL.php',
+ 'PhabricatorPhurlURLAccessController' => 'applications/phurl/controller/PhabricatorPhurlURLAccessController.php',
'PhabricatorPhurlURLEditController' => 'applications/phurl/controller/PhabricatorPhurlURLEditController.php',
'PhabricatorPhurlURLEditor' => 'applications/phurl/editor/PhabricatorPhurlURLEditor.php',
'PhabricatorPhurlURLListController' => 'applications/phurl/controller/PhabricatorPhurlURLListController.php',
@@ -2651,6 +2675,7 @@ phutil_register_library_map(array(
'PhabricatorPolicyDAO' => 'applications/policy/storage/PhabricatorPolicyDAO.php',
'PhabricatorPolicyDataTestCase' => 'applications/policy/__tests__/PhabricatorPolicyDataTestCase.php',
'PhabricatorPolicyEditController' => 'applications/policy/controller/PhabricatorPolicyEditController.php',
+ 'PhabricatorPolicyEditField' => 'applications/transactions/editfield/PhabricatorPolicyEditField.php',
'PhabricatorPolicyException' => 'applications/policy/exception/PhabricatorPolicyException.php',
'PhabricatorPolicyExplainController' => 'applications/policy/controller/PhabricatorPolicyExplainController.php',
'PhabricatorPolicyFilter' => 'applications/policy/filter/PhabricatorPolicyFilter.php',
@@ -2718,6 +2743,7 @@ phutil_register_library_map(array(
'PhabricatorProjectObjectHasProjectEdgeType' => 'applications/project/edge/PhabricatorProjectObjectHasProjectEdgeType.php',
'PhabricatorProjectOrUserDatasource' => 'applications/project/typeahead/PhabricatorProjectOrUserDatasource.php',
'PhabricatorProjectOrUserFunctionDatasource' => 'applications/project/typeahead/PhabricatorProjectOrUserFunctionDatasource.php',
+ 'PhabricatorProjectPHIDResolver' => 'applications/phid/resolver/PhabricatorProjectPHIDResolver.php',
'PhabricatorProjectProfileController' => 'applications/project/controller/PhabricatorProjectProfileController.php',
'PhabricatorProjectProjectHasMemberEdgeType' => 'applications/project/edge/PhabricatorProjectProjectHasMemberEdgeType.php',
'PhabricatorProjectProjectHasObjectEdgeType' => 'applications/project/edge/PhabricatorProjectProjectHasObjectEdgeType.php',
@@ -2740,6 +2766,7 @@ phutil_register_library_map(array(
'PhabricatorProjectUserFunctionDatasource' => 'applications/project/typeahead/PhabricatorProjectUserFunctionDatasource.php',
'PhabricatorProjectViewController' => 'applications/project/controller/PhabricatorProjectViewController.php',
'PhabricatorProjectWatchController' => 'applications/project/controller/PhabricatorProjectWatchController.php',
+ 'PhabricatorProjectsEditField' => 'applications/transactions/editfield/PhabricatorProjectsEditField.php',
'PhabricatorProjectsPolicyRule' => 'applications/policy/rule/PhabricatorProjectsPolicyRule.php',
'PhabricatorProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorProtocolAdapter.php',
'PhabricatorPygmentSetupCheck' => 'applications/config/check/PhabricatorPygmentSetupCheck.php',
@@ -2914,6 +2941,7 @@ phutil_register_library_map(array(
'PhabricatorSearchWorker' => 'applications/search/worker/PhabricatorSearchWorker.php',
'PhabricatorSecurityConfigOptions' => 'applications/config/option/PhabricatorSecurityConfigOptions.php',
'PhabricatorSecuritySetupCheck' => 'applications/config/check/PhabricatorSecuritySetupCheck.php',
+ 'PhabricatorSelectEditField' => 'applications/transactions/editfield/PhabricatorSelectEditField.php',
'PhabricatorSendGridConfigOptions' => 'applications/config/option/PhabricatorSendGridConfigOptions.php',
'PhabricatorSessionsSettingsPanel' => 'applications/settings/panel/PhabricatorSessionsSettingsPanel.php',
'PhabricatorSettingsAddEmailAction' => 'applications/settings/action/PhabricatorSettingsAddEmailAction.php',
@@ -2926,6 +2954,7 @@ phutil_register_library_map(array(
'PhabricatorSetupIssue' => 'applications/config/issue/PhabricatorSetupIssue.php',
'PhabricatorSetupIssueUIExample' => 'applications/uiexample/examples/PhabricatorSetupIssueUIExample.php',
'PhabricatorSetupIssueView' => 'applications/config/view/PhabricatorSetupIssueView.php',
+ 'PhabricatorSimpleEditType' => 'applications/transactions/edittype/PhabricatorSimpleEditType.php',
'PhabricatorSite' => 'aphront/site/PhabricatorSite.php',
'PhabricatorSlowvoteApplication' => 'applications/slowvote/application/PhabricatorSlowvoteApplication.php',
'PhabricatorSlowvoteChoice' => 'applications/slowvote/storage/PhabricatorSlowvoteChoice.php',
@@ -2954,6 +2983,7 @@ phutil_register_library_map(array(
'PhabricatorSlugTestCase' => 'infrastructure/util/__tests__/PhabricatorSlugTestCase.php',
'PhabricatorSortTableUIExample' => 'applications/uiexample/examples/PhabricatorSortTableUIExample.php',
'PhabricatorSourceCodeView' => 'view/layout/PhabricatorSourceCodeView.php',
+ 'PhabricatorSpaceEditField' => 'applications/transactions/editfield/PhabricatorSpaceEditField.php',
'PhabricatorSpacesApplication' => 'applications/spaces/application/PhabricatorSpacesApplication.php',
'PhabricatorSpacesArchiveController' => 'applications/spaces/controller/PhabricatorSpacesArchiveController.php',
'PhabricatorSpacesCapabilityCreateSpaces' => 'applications/spaces/capability/PhabricatorSpacesCapabilityCreateSpaces.php',
@@ -3017,6 +3047,7 @@ phutil_register_library_map(array(
'PhabricatorStreamingProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorStreamingProtocolAdapter.php',
'PhabricatorSubscribableInterface' => 'applications/subscriptions/interface/PhabricatorSubscribableInterface.php',
'PhabricatorSubscribedToObjectEdgeType' => 'applications/transactions/edges/PhabricatorSubscribedToObjectEdgeType.php',
+ 'PhabricatorSubscribersEditField' => 'applications/transactions/editfield/PhabricatorSubscribersEditField.php',
'PhabricatorSubscribersQuery' => 'applications/subscriptions/query/PhabricatorSubscribersQuery.php',
'PhabricatorSubscriptionTriggerClock' => 'infrastructure/daemon/workers/clock/PhabricatorSubscriptionTriggerClock.php',
'PhabricatorSubscriptionsAddSelfHeraldAction' => 'applications/subscriptions/herald/PhabricatorSubscriptionsAddSelfHeraldAction.php',
@@ -3060,6 +3091,8 @@ phutil_register_library_map(array(
'PhabricatorTestNoCycleEdgeType' => 'applications/transactions/edges/PhabricatorTestNoCycleEdgeType.php',
'PhabricatorTestStorageEngine' => 'applications/files/engine/PhabricatorTestStorageEngine.php',
'PhabricatorTestWorker' => 'infrastructure/daemon/workers/__tests__/PhabricatorTestWorker.php',
+ 'PhabricatorTextAreaEditField' => 'applications/transactions/editfield/PhabricatorTextAreaEditField.php',
+ 'PhabricatorTextEditField' => 'applications/transactions/editfield/PhabricatorTextEditField.php',
'PhabricatorTime' => 'infrastructure/time/PhabricatorTime.php',
'PhabricatorTimeGuard' => 'infrastructure/time/PhabricatorTimeGuard.php',
'PhabricatorTimeTestCase' => 'infrastructure/time/__tests__/PhabricatorTimeTestCase.php',
@@ -3081,6 +3114,7 @@ phutil_register_library_map(array(
'PhabricatorTokenReceiverQuery' => 'applications/tokens/query/PhabricatorTokenReceiverQuery.php',
'PhabricatorTokenTokenPHIDType' => 'applications/tokens/phid/PhabricatorTokenTokenPHIDType.php',
'PhabricatorTokenUIEventListener' => 'applications/tokens/event/PhabricatorTokenUIEventListener.php',
+ 'PhabricatorTokenizerEditField' => 'applications/transactions/editfield/PhabricatorTokenizerEditField.php',
'PhabricatorTokensApplication' => 'applications/tokens/application/PhabricatorTokensApplication.php',
'PhabricatorTokensSettingsPanel' => 'applications/settings/panel/PhabricatorTokensSettingsPanel.php',
'PhabricatorTooltipUIExample' => 'applications/uiexample/examples/PhabricatorTooltipUIExample.php',
@@ -3128,6 +3162,7 @@ phutil_register_library_map(array(
'PhabricatorUserEmailTestCase' => 'applications/people/storage/__tests__/PhabricatorUserEmailTestCase.php',
'PhabricatorUserLog' => 'applications/people/storage/PhabricatorUserLog.php',
'PhabricatorUserLogView' => 'applications/people/view/PhabricatorUserLogView.php',
+ 'PhabricatorUserPHIDResolver' => 'applications/phid/resolver/PhabricatorUserPHIDResolver.php',
'PhabricatorUserPreferences' => 'applications/settings/storage/PhabricatorUserPreferences.php',
'PhabricatorUserProfile' => 'applications/people/storage/PhabricatorUserProfile.php',
'PhabricatorUserProfileEditor' => 'applications/people/editor/PhabricatorUserProfileEditor.php',
@@ -3140,6 +3175,7 @@ phutil_register_library_map(array(
'PhabricatorUserTestCase' => 'applications/people/storage/__tests__/PhabricatorUserTestCase.php',
'PhabricatorUserTitleField' => 'applications/people/customfield/PhabricatorUserTitleField.php',
'PhabricatorUserTransaction' => 'applications/people/storage/PhabricatorUserTransaction.php',
+ 'PhabricatorUsersEditField' => 'applications/transactions/editfield/PhabricatorUsersEditField.php',
'PhabricatorUsersPolicyRule' => 'applications/policy/rule/PhabricatorUsersPolicyRule.php',
'PhabricatorUsersSearchField' => 'applications/people/searchfield/PhabricatorUsersSearchField.php',
'PhabricatorVCSResponse' => 'applications/repository/response/PhabricatorVCSResponse.php',
@@ -3211,6 +3247,7 @@ phutil_register_library_map(array(
'PhameBasicBlogSkin' => 'applications/phame/skins/PhameBasicBlogSkin.php',
'PhameBasicTemplateBlogSkin' => 'applications/phame/skins/PhameBasicTemplateBlogSkin.php',
'PhameBlog' => 'applications/phame/storage/PhameBlog.php',
+ 'PhameBlogController' => 'applications/phame/controller/blog/PhameBlogController.php',
'PhameBlogDeleteController' => 'applications/phame/controller/blog/PhameBlogDeleteController.php',
'PhameBlogEditController' => 'applications/phame/controller/blog/PhameBlogEditController.php',
'PhameBlogEditor' => 'applications/phame/editor/PhameBlogEditor.php',
@@ -3229,6 +3266,7 @@ phutil_register_library_map(array(
'PhameCreatePostConduitAPIMethod' => 'applications/phame/conduit/PhameCreatePostConduitAPIMethod.php',
'PhameDAO' => 'applications/phame/storage/PhameDAO.php',
'PhamePost' => 'applications/phame/storage/PhamePost.php',
+ 'PhamePostController' => 'applications/phame/controller/post/PhamePostController.php',
'PhamePostDeleteController' => 'applications/phame/controller/post/PhamePostDeleteController.php',
'PhamePostEditController' => 'applications/phame/controller/post/PhamePostEditController.php',
'PhamePostEditor' => 'applications/phame/editor/PhamePostEditor.php',
@@ -3239,6 +3277,7 @@ phutil_register_library_map(array(
'PhamePostPreviewController' => 'applications/phame/controller/post/PhamePostPreviewController.php',
'PhamePostPublishController' => 'applications/phame/controller/post/PhamePostPublishController.php',
'PhamePostQuery' => 'applications/phame/query/PhamePostQuery.php',
+ 'PhamePostReplyHandler' => 'applications/phame/mail/PhamePostReplyHandler.php',
'PhamePostSearchEngine' => 'applications/phame/query/PhamePostSearchEngine.php',
'PhamePostTransaction' => 'applications/phame/storage/PhamePostTransaction.php',
'PhamePostTransactionQuery' => 'applications/phame/query/PhamePostTransactionQuery.php',
@@ -3848,6 +3887,7 @@ phutil_register_library_map(array(
'AphrontFormView' => 'AphrontView',
'AphrontGlyphBarView' => 'AphrontBarView',
'AphrontHTMLResponse' => 'AphrontResponse',
+ 'AphrontHTTPParameterType' => 'Phobject',
'AphrontHTTPProxyResponse' => 'AphrontResponse',
'AphrontHTTPSink' => 'Phobject',
'AphrontHTTPSinkTestCase' => 'PhabricatorTestCase',
@@ -3862,10 +3902,13 @@ phutil_register_library_map(array(
'AphrontMultiColumnView' => 'AphrontView',
'AphrontMySQLDatabaseConnectionTestCase' => 'PhabricatorTestCase',
'AphrontNullView' => 'AphrontView',
+ 'AphrontPHIDHTTPParameterType' => 'AphrontHTTPParameterType',
+ 'AphrontPHIDListHTTPParameterType' => 'AphrontHTTPParameterType',
'AphrontPHPHTTPSink' => 'AphrontHTTPSink',
'AphrontPageView' => 'AphrontView',
'AphrontPlainTextResponse' => 'AphrontResponse',
'AphrontProgressBarView' => 'AphrontBarView',
+ 'AphrontProjectListHTTPParameterType' => 'AphrontHTTPParameterType',
'AphrontProxyResponse' => array(
'AphrontResponse',
'AphrontResponseProducerInterface',
@@ -3879,15 +3922,19 @@ phutil_register_library_map(array(
'AphrontResponse' => 'Phobject',
'AphrontRoutingMap' => 'Phobject',
'AphrontRoutingResult' => 'Phobject',
+ 'AphrontSelectHTTPParameterType' => 'AphrontHTTPParameterType',
'AphrontSideNavFilterView' => 'AphrontView',
'AphrontSite' => 'Phobject',
'AphrontStackTraceView' => 'AphrontView',
'AphrontStandaloneHTMLResponse' => 'AphrontHTMLResponse',
+ 'AphrontStringHTTPParameterType' => 'AphrontHTTPParameterType',
+ 'AphrontStringListHTTPParameterType' => 'AphrontHTTPParameterType',
'AphrontTableView' => 'AphrontView',
'AphrontTagView' => 'AphrontView',
'AphrontTokenizerTemplateView' => 'AphrontView',
'AphrontTypeaheadTemplateView' => 'AphrontView',
'AphrontUnhandledExceptionResponse' => 'AphrontStandaloneHTMLResponse',
+ 'AphrontUserListHTTPParameterType' => 'AphrontHTTPParameterType',
'AphrontView' => array(
'Phobject',
'PhutilSafeHTMLProducerInterface',
@@ -5308,6 +5355,7 @@ phutil_register_library_map(array(
'PHUI' => 'Phobject',
'PHUIActionPanelExample' => 'PhabricatorUIExample',
'PHUIActionPanelView' => 'AphrontTagView',
+ 'PHUIApplicationMenuView' => 'Phobject',
'PHUIBadgeBoxView' => 'AphrontTagView',
'PHUIBadgeExample' => 'PhabricatorUIExample',
'PHUIBadgeMiniView' => 'AphrontTagView',
@@ -5338,6 +5386,7 @@ phutil_register_library_map(array(
'PHUIDiffTwoUpInlineCommentRowScaffold' => 'PHUIDiffInlineCommentRowScaffold',
'PHUIDocumentExample' => 'PhabricatorUIExample',
'PHUIDocumentView' => 'AphrontTagView',
+ 'PHUIDocumentViewPro' => 'AphrontTagView',
'PHUIFeedStoryExample' => 'PhabricatorUIExample',
'PHUIFeedStoryView' => 'AphrontView',
'PHUIFormDividerControl' => 'AphrontFormControl',
@@ -5441,6 +5490,7 @@ phutil_register_library_map(array(
'PasteCreateMailReceiver' => 'PhabricatorMailReceiver',
'PasteDefaultEditCapability' => 'PhabricatorPolicyCapability',
'PasteDefaultViewCapability' => 'PhabricatorPolicyCapability',
+ 'PasteEditConduitAPIMethod' => 'PhabricatorApplicationEditEngineAPIMethod',
'PasteEmbedView' => 'AphrontView',
'PasteInfoConduitAPIMethod' => 'PasteConduitAPIMethod',
'PasteMailReceiver' => 'PhabricatorObjectMailReceiver',
@@ -5484,6 +5534,9 @@ phutil_register_library_map(array(
'PhabricatorApplicationDatasource' => 'PhabricatorTypeaheadDatasource',
'PhabricatorApplicationDetailViewController' => 'PhabricatorApplicationsController',
'PhabricatorApplicationEditController' => 'PhabricatorApplicationsController',
+ 'PhabricatorApplicationEditEngine' => 'Phobject',
+ 'PhabricatorApplicationEditEngineAPIMethod' => 'ConduitAPIMethod',
+ 'PhabricatorApplicationEditHTTPParameterHelpView' => 'AphrontView',
'PhabricatorApplicationEmailCommandsController' => 'PhabricatorApplicationsController',
'PhabricatorApplicationLaunchView' => 'AphrontTagView',
'PhabricatorApplicationPanelController' => 'PhabricatorApplicationsController',
@@ -5812,7 +5865,6 @@ phutil_register_library_map(array(
'PhabricatorCommonPasswords' => 'Phobject',
'PhabricatorConduitAPIController' => 'PhabricatorConduitController',
'PhabricatorConduitApplication' => 'PhabricatorApplication',
- 'PhabricatorConduitCertificateSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorConduitCertificateToken' => 'PhabricatorConduitDAO',
'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO',
'PhabricatorConduitConsoleController' => 'PhabricatorConduitController',
@@ -5866,6 +5918,7 @@ phutil_register_library_map(array(
'PhabricatorConfigEntryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorConfigFileSource' => 'PhabricatorConfigProxySource',
'PhabricatorConfigGroupController' => 'PhabricatorConfigController',
+ 'PhabricatorConfigHTTPParameterTypesModule' => 'PhabricatorConfigModule',
'PhabricatorConfigHistoryController' => 'PhabricatorConfigController',
'PhabricatorConfigIgnoreController' => 'PhabricatorConfigController',
'PhabricatorConfigIssueListController' => 'PhabricatorConfigController',
@@ -6075,6 +6128,7 @@ phutil_register_library_map(array(
'PhabricatorDataCacheSpec' => 'PhabricatorCacheSpec',
'PhabricatorDataNotAttachedException' => 'Exception',
'PhabricatorDatabaseSetupCheck' => 'PhabricatorSetupCheck',
+ 'PhabricatorDatasourceEditField' => 'PhabricatorTokenizerEditField',
'PhabricatorDateTimeSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorDebugController' => 'PhabricatorController',
'PhabricatorDefaultRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler',
@@ -6102,12 +6156,15 @@ phutil_register_library_map(array(
'PhabricatorEdgeConfig' => 'PhabricatorEdgeConstants',
'PhabricatorEdgeConstants' => 'Phobject',
'PhabricatorEdgeCycleException' => 'Exception',
+ 'PhabricatorEdgeEditType' => 'PhabricatorEditType',
'PhabricatorEdgeEditor' => 'Phobject',
'PhabricatorEdgeGraph' => 'AbstractDirectedGraph',
'PhabricatorEdgeQuery' => 'PhabricatorQuery',
'PhabricatorEdgeTestCase' => 'PhabricatorTestCase',
'PhabricatorEdgeType' => 'Phobject',
'PhabricatorEdgeTypeTestCase' => 'PhabricatorTestCase',
+ 'PhabricatorEditField' => 'Phobject',
+ 'PhabricatorEditType' => 'Phobject',
'PhabricatorEditor' => 'Phobject',
'PhabricatorElasticSearchEngine' => 'PhabricatorSearchEngine',
'PhabricatorElasticSearchSetupCheck' => 'PhabricatorSetupCheck',
@@ -6285,6 +6342,7 @@ phutil_register_library_map(array(
'PhabricatorGlobalLock' => 'PhutilLock',
'PhabricatorGlobalUploadTargetView' => 'AphrontView',
'PhabricatorGoogleAuthProvider' => 'PhabricatorOAuth2AuthProvider',
+ 'PhabricatorHTTPParameterTypeTableView' => 'AphrontView',
'PhabricatorHandleList' => array(
'Phobject',
'Iterator',
@@ -6611,6 +6669,7 @@ phutil_register_library_map(array(
'PhabricatorPHDConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorPHID' => 'Phobject',
'PhabricatorPHIDConstants' => 'Phobject',
+ 'PhabricatorPHIDResolver' => 'Phobject',
'PhabricatorPHIDType' => 'Phobject',
'PhabricatorPHIDTypeTestCase' => 'PhutilTestCase',
'PhabricatorPHPASTApplication' => 'PhabricatorApplication',
@@ -6642,6 +6701,7 @@ phutil_register_library_map(array(
'PhabricatorPasteController' => 'PhabricatorController',
'PhabricatorPasteDAO' => 'PhabricatorLiskDAO',
'PhabricatorPasteEditController' => 'PhabricatorPasteController',
+ 'PhabricatorPasteEditEngine' => 'PhabricatorApplicationEditEngine',
'PhabricatorPasteEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorPasteListController' => 'PhabricatorPasteController',
'PhabricatorPastePastePHIDType' => 'PhabricatorPHIDType',
@@ -6712,6 +6772,8 @@ phutil_register_library_map(array(
'PhabricatorPhurlApplication' => 'PhabricatorApplication',
'PhabricatorPhurlController' => 'PhabricatorController',
'PhabricatorPhurlDAO' => 'PhabricatorLiskDAO',
+ 'PhabricatorPhurlLinkRemarkupRule' => 'PhutilRemarkupRule',
+ 'PhabricatorPhurlRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'PhabricatorPhurlSchemaSpec' => 'PhabricatorConfigSchemaSpec',
'PhabricatorPhurlURL' => array(
'PhabricatorPhurlDAO',
@@ -6725,6 +6787,7 @@ phutil_register_library_map(array(
'PhabricatorFlaggableInterface',
'PhabricatorSpacesInterface',
),
+ 'PhabricatorPhurlURLAccessController' => 'PhabricatorPhurlController',
'PhabricatorPhurlURLEditController' => 'PhabricatorPhurlController',
'PhabricatorPhurlURLEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorPhurlURLListController' => 'PhabricatorPhurlController',
@@ -6756,6 +6819,7 @@ phutil_register_library_map(array(
'PhabricatorPolicyDAO' => 'PhabricatorLiskDAO',
'PhabricatorPolicyDataTestCase' => 'PhabricatorTestCase',
'PhabricatorPolicyEditController' => 'PhabricatorPolicyController',
+ 'PhabricatorPolicyEditField' => 'PhabricatorEditField',
'PhabricatorPolicyException' => 'Exception',
'PhabricatorPolicyExplainController' => 'PhabricatorPolicyController',
'PhabricatorPolicyFilter' => 'Phobject',
@@ -6845,6 +6909,7 @@ phutil_register_library_map(array(
'PhabricatorProjectObjectHasProjectEdgeType' => 'PhabricatorEdgeType',
'PhabricatorProjectOrUserDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'PhabricatorProjectOrUserFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
+ 'PhabricatorProjectPHIDResolver' => 'PhabricatorPHIDResolver',
'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
'PhabricatorProjectProjectHasMemberEdgeType' => 'PhabricatorEdgeType',
'PhabricatorProjectProjectHasObjectEdgeType' => 'PhabricatorEdgeType',
@@ -6870,6 +6935,7 @@ phutil_register_library_map(array(
'PhabricatorProjectUserFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'PhabricatorProjectViewController' => 'PhabricatorProjectController',
'PhabricatorProjectWatchController' => 'PhabricatorProjectController',
+ 'PhabricatorProjectsEditField' => 'PhabricatorTokenizerEditField',
'PhabricatorProjectsPolicyRule' => 'PhabricatorPolicyRule',
'PhabricatorProtocolAdapter' => 'Phobject',
'PhabricatorPygmentSetupCheck' => 'PhabricatorSetupCheck',
@@ -7084,6 +7150,7 @@ phutil_register_library_map(array(
'PhabricatorSearchWorker' => 'PhabricatorWorker',
'PhabricatorSecurityConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorSecuritySetupCheck' => 'PhabricatorSetupCheck',
+ 'PhabricatorSelectEditField' => 'PhabricatorEditField',
'PhabricatorSendGridConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorSessionsSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsAddEmailAction' => 'PhabricatorSystemAction',
@@ -7096,6 +7163,7 @@ phutil_register_library_map(array(
'PhabricatorSetupIssue' => 'Phobject',
'PhabricatorSetupIssueUIExample' => 'PhabricatorUIExample',
'PhabricatorSetupIssueView' => 'AphrontView',
+ 'PhabricatorSimpleEditType' => 'PhabricatorEditType',
'PhabricatorSite' => 'AphrontSite',
'PhabricatorSlowvoteApplication' => 'PhabricatorApplication',
'PhabricatorSlowvoteChoice' => 'PhabricatorSlowvoteDAO',
@@ -7134,6 +7202,7 @@ phutil_register_library_map(array(
'PhabricatorSlugTestCase' => 'PhabricatorTestCase',
'PhabricatorSortTableUIExample' => 'PhabricatorUIExample',
'PhabricatorSourceCodeView' => 'AphrontView',
+ 'PhabricatorSpaceEditField' => 'PhabricatorEditField',
'PhabricatorSpacesApplication' => 'PhabricatorApplication',
'PhabricatorSpacesArchiveController' => 'PhabricatorSpacesController',
'PhabricatorSpacesCapabilityCreateSpaces' => 'PhabricatorPolicyCapability',
@@ -7178,7 +7247,10 @@ phutil_register_library_map(array(
'PhabricatorStandardCustomFieldText' => 'PhabricatorStandardCustomField',
'PhabricatorStandardCustomFieldTokenizer' => 'PhabricatorStandardCustomFieldPHIDs',
'PhabricatorStandardCustomFieldUsers' => 'PhabricatorStandardCustomFieldTokenizer',
- 'PhabricatorStandardPageView' => 'PhabricatorBarePageView',
+ 'PhabricatorStandardPageView' => array(
+ 'PhabricatorBarePageView',
+ 'AphrontResponseProducerInterface',
+ ),
'PhabricatorStandardSelectCustomFieldDatasource' => 'PhabricatorTypeaheadDatasource',
'PhabricatorStatusController' => 'PhabricatorController',
'PhabricatorStatusUIExample' => 'PhabricatorUIExample',
@@ -7200,6 +7272,7 @@ phutil_register_library_map(array(
'PhabricatorStorageSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorStreamingProtocolAdapter' => 'PhabricatorProtocolAdapter',
'PhabricatorSubscribedToObjectEdgeType' => 'PhabricatorEdgeType',
+ 'PhabricatorSubscribersEditField' => 'PhabricatorTokenizerEditField',
'PhabricatorSubscribersQuery' => 'PhabricatorQuery',
'PhabricatorSubscriptionTriggerClock' => 'PhabricatorTriggerClock',
'PhabricatorSubscriptionsAddSelfHeraldAction' => 'PhabricatorSubscriptionsHeraldAction',
@@ -7243,6 +7316,8 @@ phutil_register_library_map(array(
'PhabricatorTestNoCycleEdgeType' => 'PhabricatorEdgeType',
'PhabricatorTestStorageEngine' => 'PhabricatorFileStorageEngine',
'PhabricatorTestWorker' => 'PhabricatorWorker',
+ 'PhabricatorTextAreaEditField' => 'PhabricatorEditField',
+ 'PhabricatorTextEditField' => 'PhabricatorEditField',
'PhabricatorTime' => 'Phobject',
'PhabricatorTimeGuard' => 'Phobject',
'PhabricatorTimeTestCase' => 'PhabricatorTestCase',
@@ -7269,6 +7344,7 @@ phutil_register_library_map(array(
'PhabricatorTokenReceiverQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorTokenTokenPHIDType' => 'PhabricatorPHIDType',
'PhabricatorTokenUIEventListener' => 'PhabricatorEventListener',
+ 'PhabricatorTokenizerEditField' => 'PhabricatorEditField',
'PhabricatorTokensApplication' => 'PhabricatorApplication',
'PhabricatorTokensSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorTooltipUIExample' => 'PhabricatorUIExample',
@@ -7331,6 +7407,7 @@ phutil_register_library_map(array(
'PhabricatorPolicyInterface',
),
'PhabricatorUserLogView' => 'AphrontView',
+ 'PhabricatorUserPHIDResolver' => 'PhabricatorPHIDResolver',
'PhabricatorUserPreferences' => 'PhabricatorUserDAO',
'PhabricatorUserProfile' => 'PhabricatorUserDAO',
'PhabricatorUserProfileEditor' => 'PhabricatorApplicationTransactionEditor',
@@ -7343,6 +7420,7 @@ phutil_register_library_map(array(
'PhabricatorUserTestCase' => 'PhabricatorTestCase',
'PhabricatorUserTitleField' => 'PhabricatorUserCustomField',
'PhabricatorUserTransaction' => 'PhabricatorApplicationTransaction',
+ 'PhabricatorUsersEditField' => 'PhabricatorTokenizerEditField',
'PhabricatorUsersPolicyRule' => 'PhabricatorPolicyRule',
'PhabricatorUsersSearchField' => 'PhabricatorSearchTokenizerField',
'PhabricatorVCSResponse' => 'AphrontResponse',
@@ -7432,18 +7510,19 @@ phutil_register_library_map(array(
'PhabricatorProjectInterface',
'PhabricatorApplicationTransactionInterface',
),
- 'PhameBlogDeleteController' => 'PhameController',
- 'PhameBlogEditController' => 'PhameController',
+ 'PhameBlogController' => 'PhameController',
+ 'PhameBlogDeleteController' => 'PhameBlogController',
+ 'PhameBlogEditController' => 'PhameBlogController',
'PhameBlogEditor' => 'PhabricatorApplicationTransactionEditor',
- 'PhameBlogFeedController' => 'PhameController',
- 'PhameBlogListController' => 'PhameController',
- 'PhameBlogLiveController' => 'PhameController',
+ 'PhameBlogFeedController' => 'PhameBlogController',
+ 'PhameBlogListController' => 'PhameBlogController',
+ 'PhameBlogLiveController' => 'PhameBlogController',
'PhameBlogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhameBlogSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhameBlogSite' => 'PhameSite',
'PhameBlogSkin' => 'PhabricatorController',
'PhameBlogTransaction' => 'PhabricatorApplicationTransaction',
- 'PhameBlogViewController' => 'PhameController',
+ 'PhameBlogViewController' => 'PhameBlogController',
'PhameCelerityResources' => 'CelerityResources',
'PhameConduitAPIMethod' => 'ConduitAPIMethod',
'PhameController' => 'PhabricatorController',
@@ -7459,22 +7538,24 @@ phutil_register_library_map(array(
'PhabricatorSubscribableInterface',
'PhabricatorTokenReceiverInterface',
),
- 'PhamePostDeleteController' => 'PhameController',
- 'PhamePostEditController' => 'PhameController',
+ 'PhamePostController' => 'PhameController',
+ 'PhamePostDeleteController' => 'PhamePostController',
+ 'PhamePostEditController' => 'PhamePostController',
'PhamePostEditor' => 'PhabricatorApplicationTransactionEditor',
- 'PhamePostFramedController' => 'PhameController',
- 'PhamePostListController' => 'PhameController',
- 'PhamePostNewController' => 'PhameController',
- 'PhamePostNotLiveController' => 'PhameController',
- 'PhamePostPreviewController' => 'PhameController',
- 'PhamePostPublishController' => 'PhameController',
+ 'PhamePostFramedController' => 'PhamePostController',
+ 'PhamePostListController' => 'PhamePostController',
+ 'PhamePostNewController' => 'PhamePostController',
+ 'PhamePostNotLiveController' => 'PhamePostController',
+ 'PhamePostPreviewController' => 'PhamePostController',
+ 'PhamePostPublishController' => 'PhamePostController',
'PhamePostQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+ 'PhamePostReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
'PhamePostSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhamePostTransaction' => 'PhabricatorApplicationTransaction',
'PhamePostTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
- 'PhamePostUnpublishController' => 'PhameController',
+ 'PhamePostUnpublishController' => 'PhamePostController',
'PhamePostView' => 'AphrontView',
- 'PhamePostViewController' => 'PhameController',
+ 'PhamePostViewController' => 'PhamePostController',
'PhameQueryConduitAPIMethod' => 'PhameConduitAPIMethod',
'PhameQueryPostsConduitAPIMethod' => 'PhameConduitAPIMethod',
'PhameResourceController' => 'CelerityResourceController',
diff --git a/src/aphront/httpparametertype/AphrontHTTPParameterType.php b/src/aphront/httpparametertype/AphrontHTTPParameterType.php
new file mode 100644
index 0000000000..995556a6b9
--- /dev/null
+++ b/src/aphront/httpparametertype/AphrontHTTPParameterType.php
@@ -0,0 +1,309 @@
+viewer = $viewer;
+ return $this;
+ }
+
+
+ /**
+ * Get the current viewer.
+ *
+ * @return PhabricatorUser Current viewer.
+ * @task read
+ */
+ final public function getViewer() {
+ if (!$this->viewer) {
+ throw new PhutilInvalidStateException('setViewer');
+ }
+ return $this->viewer;
+ }
+
+
+ /**
+ * Test if a value is present in a request.
+ *
+ * @param AphrontRequest The incoming request.
+ * @param string The key to examine.
+ * @return bool True if a readable value is present in the request.
+ * @task read
+ */
+ final public function getExists(AphrontRequest $request, $key) {
+ return $this->getParameterExists($request, $key);
+ }
+
+
+ /**
+ * Read a value from a request.
+ *
+ * If the value is not present, a default value is returned (usually `null`).
+ * Use @{method:getExists} to test if a value is present.
+ *
+ * @param AphrontRequest The incoming request.
+ * @param string The key to examine.
+ * @return wild Value, or default if value is not present.
+ * @task read
+ */
+ final public function getValue(AphrontRequest $request, $key) {
+
+ if (!$this->getExists($request, $key)) {
+ return $this->getParameterDefault();
+ }
+
+ return $this->getParameterValue($request, $key);
+ }
+
+
+ /**
+ * Get the default value for this parameter type.
+ *
+ * @return wild Default value for this type.
+ * @task read
+ */
+ final public function getDefaultValue() {
+ return $this->getParameterDefault();
+ }
+
+
+/* -( Information About the Type )----------------------------------------- */
+
+
+ /**
+ * Get a short name for this type, like `string` or `list
`.
+ *
+ * @return string Short type name.
+ * @task info
+ */
+ final public function getTypeName() {
+ return $this->getParameterTypeName();
+ }
+
+
+ /**
+ * Get a list of human-readable descriptions of acceptable formats for this
+ * type.
+ *
+ * For example, a type might return strings like these:
+ *
+ * > Any positive integer.
+ * > A comma-separated list of PHIDs.
+ *
+ * This is used to explain to users how to specify a type when generating
+ * documentation.
+ *
+ * @return list Human-readable list of acceptable formats.
+ * @task info
+ */
+ final public function getFormatDescriptions() {
+ return $this->getParameterFormatDescriptions();
+ }
+
+
+ /**
+ * Get a list of human-readable examples of how to format this type as an
+ * HTTP GET parameter.
+ *
+ * For example, a type might return strings like these:
+ *
+ * > v=123
+ * > v[]=1&v[]=2
+ *
+ * This is used to show users how to specify parameters of this type in
+ * generated documentation.
+ *
+ * @return list Human-readable list of format examples.
+ * @task info
+ */
+ final public function getExamples() {
+ return $this->getParameterExamples();
+ }
+
+
+/* -( Utilities )---------------------------------------------------------- */
+
+
+ /**
+ * Call another type's existence check.
+ *
+ * This method allows a type to reuse the exitence behavior of a different
+ * type. For example, a "list of users" type may have the same basic
+ * existence check that a simpler "list of strings" type has, and can just
+ * call the simpler type to reuse its behavior.
+ *
+ * @param AphrontHTTPParameterType The other type.
+ * @param AphrontRequest Incoming request.
+ * @param string Key to examine.
+ * @return bool True if the parameter exists.
+ * @task util
+ */
+ final protected function getExistsWithType(
+ AphrontHTTPParameterType $type,
+ AphrontRequest $request,
+ $key) {
+
+ $type->setViewer($this->getViewer());
+
+ return $type->getParameterExists($request, $key);
+ }
+
+
+ /**
+ * Call another type's value parser.
+ *
+ * This method allows a type to reuse the parsing behavior of a different
+ * type. For example, a "list of users" type may start by running the same
+ * basic parsing that a simpler "list of strings" type does.
+ *
+ * @param AphrontHTTPParameterType The other type.
+ * @param AphrontRequest Incoming request.
+ * @param string Key to examine.
+ * @return wild Parsed value.
+ * @task util
+ */
+ final protected function getValueWithType(
+ AphrontHTTPParameterType $type,
+ AphrontRequest $request,
+ $key) {
+
+ $type->setViewer($this->getViewer());
+
+ return $type->getValue($request, $key);
+ }
+
+
+ /**
+ * Get a list of all available parameter types.
+ *
+ * @return list List of all available types.
+ * @task util
+ */
+ final public static function getAllTypes() {
+ return id(new PhutilClassMapQuery())
+ ->setAncestorClass(__CLASS__)
+ ->setUniqueMethod('getTypeName')
+ ->setSortMethod('getTypeName')
+ ->execute();
+ }
+
+
+/* -( Implementation )----------------------------------------------------- */
+
+
+ /**
+ * Test if a parameter exists in a request.
+ *
+ * See @{method:getExists}. By default, this method tests if the key is
+ * present in the request.
+ *
+ * To call another type's behavior in order to perform this check, use
+ * @{method:getExistsWithType}.
+ *
+ * @param AphrontRequest The incoming request.
+ * @param string The key to examine.
+ * @return bool True if a readable value is present in the request.
+ * @task impl
+ */
+ protected function getParameterExists(AphrontRequest $request, $key) {
+ return $request->getExists($key);
+ }
+
+
+ /**
+ * Parse a value from a request.
+ *
+ * See @{method:getValue}. This method will //only// be called if this type
+ * has already asserted that the value exists with
+ * @{method:getParameterExists}.
+ *
+ * To call another type's behavior in order to parse a value, use
+ * @{method:getValueWithType}.
+ *
+ * @param AphrontRequest The incoming request.
+ * @param string The key to examine.
+ * @return wild Parsed value.
+ * @task impl
+ */
+ abstract protected function getParameterValue(AphrontRequest $request, $key);
+
+
+ /**
+ * Return a simple type name string, like "string" or "list".
+ *
+ * See @{method:getTypeName}.
+ *
+ * @return string Short type name.
+ * @task impl
+ */
+ abstract protected function getParameterTypeName();
+
+
+ /**
+ * Return a human-readable list of format descriptions.
+ *
+ * See @{method:getFormatDescriptions}.
+ *
+ * @return list Human-readable list of acceptable formats.
+ * @task impl
+ */
+ abstract protected function getParameterFormatDescriptions();
+
+
+ /**
+ * Return a human-readable list of examples.
+ *
+ * See @{method:getExamples}.
+ *
+ * @return list Human-readable list of format examples.
+ * @task impl
+ */
+ abstract protected function getParameterExamples();
+
+
+ /**
+ * Return the default value for this parameter type.
+ *
+ * See @{method:getDefaultValue}. If unspecified, the default is `null`.
+ *
+ * @return wild Default value.
+ * @task impl
+ */
+ protected function getParameterDefault() {
+ return null;
+ }
+
+}
diff --git a/src/aphront/httpparametertype/AphrontPHIDHTTPParameterType.php b/src/aphront/httpparametertype/AphrontPHIDHTTPParameterType.php
new file mode 100644
index 0000000000..645510bc98
--- /dev/null
+++ b/src/aphront/httpparametertype/AphrontPHIDHTTPParameterType.php
@@ -0,0 +1,26 @@
+getStr($key);
+ }
+
+ protected function getParameterTypeName() {
+ return 'phid';
+ }
+
+ protected function getParameterFormatDescriptions() {
+ return array(
+ pht('A single object PHID.'),
+ );
+ }
+
+ protected function getParameterExamples() {
+ return array(
+ 'v=PHID-XXXX-1111',
+ );
+ }
+
+}
diff --git a/src/aphront/httpparametertype/AphrontPHIDListHTTPParameterType.php b/src/aphront/httpparametertype/AphrontPHIDListHTTPParameterType.php
new file mode 100644
index 0000000000..e61bfb0f77
--- /dev/null
+++ b/src/aphront/httpparametertype/AphrontPHIDListHTTPParameterType.php
@@ -0,0 +1,30 @@
+getValueWithType($type, $request, $key);
+ }
+
+ protected function getParameterTypeName() {
+ return 'list';
+ }
+
+ protected function getParameterFormatDescriptions() {
+ return array(
+ pht('Comma-separated list of PHIDs.'),
+ pht('List of PHIDs, as array.'),
+ );
+ }
+
+ protected function getParameterExamples() {
+ return array(
+ 'v=PHID-XXXX-1111',
+ 'v=PHID-XXXX-1111,PHID-XXXX-2222',
+ 'v[]=PHID-XXXX-1111&v[]=PHID-XXXX-2222',
+ );
+ }
+
+}
diff --git a/src/aphront/httpparametertype/AphrontProjectListHTTPParameterType.php b/src/aphront/httpparametertype/AphrontProjectListHTTPParameterType.php
new file mode 100644
index 0000000000..fd7e0db5cd
--- /dev/null
+++ b/src/aphront/httpparametertype/AphrontProjectListHTTPParameterType.php
@@ -0,0 +1,42 @@
+getValueWithType($type, $request, $key);
+
+ return id(new PhabricatorProjectPHIDResolver())
+ ->setViewer($this->getViewer())
+ ->resolvePHIDs($list);
+ }
+
+ protected function getParameterTypeName() {
+ return 'list';
+ }
+
+ protected function getParameterFormatDescriptions() {
+ return array(
+ pht('Comma-separated list of project PHIDs.'),
+ pht('List of project PHIDs, as array.'),
+ pht('Comma-separated list of project hashtags.'),
+ pht('List of project hashtags, as array.'),
+ pht('Mixture of hashtags and PHIDs.'),
+ );
+ }
+
+ protected function getParameterExamples() {
+ return array(
+ 'v=PHID-PROJ-1111',
+ 'v=PHID-PROJ-1111,PHID-PROJ-2222',
+ 'v=hashtag',
+ 'v=frontend,backend',
+ 'v[]=PHID-PROJ-1111&v[]=PHID-PROJ-2222',
+ 'v[]=frontend&v[]=backend',
+ 'v=PHID-PROJ-1111,frontend',
+ 'v[]=PHID-PROJ-1111&v[]=backend',
+ );
+ }
+
+}
diff --git a/src/aphront/httpparametertype/AphrontSelectHTTPParameterType.php b/src/aphront/httpparametertype/AphrontSelectHTTPParameterType.php
new file mode 100644
index 0000000000..017900666c
--- /dev/null
+++ b/src/aphront/httpparametertype/AphrontSelectHTTPParameterType.php
@@ -0,0 +1,26 @@
+getStr($key);
+ }
+
+ protected function getParameterTypeName() {
+ return 'select';
+ }
+
+ protected function getParameterFormatDescriptions() {
+ return array(
+ pht('A single value from the allowed set.'),
+ );
+ }
+
+ protected function getParameterExamples() {
+ return array(
+ 'v=value',
+ );
+ }
+
+}
diff --git a/src/aphront/httpparametertype/AphrontStringHTTPParameterType.php b/src/aphront/httpparametertype/AphrontStringHTTPParameterType.php
new file mode 100644
index 0000000000..ebcc21cb1e
--- /dev/null
+++ b/src/aphront/httpparametertype/AphrontStringHTTPParameterType.php
@@ -0,0 +1,27 @@
+getStr($key);
+ }
+
+ protected function getParameterTypeName() {
+ return 'string';
+ }
+
+ protected function getParameterFormatDescriptions() {
+ return array(
+ pht('A URL-encoded string.'),
+ );
+ }
+
+ protected function getParameterExamples() {
+ return array(
+ 'v=simple',
+ 'v=properly%20escaped%20text',
+ );
+ }
+
+}
diff --git a/src/aphront/httpparametertype/AphrontStringListHTTPParameterType.php b/src/aphront/httpparametertype/AphrontStringListHTTPParameterType.php
new file mode 100644
index 0000000000..5c34dbc248
--- /dev/null
+++ b/src/aphront/httpparametertype/AphrontStringListHTTPParameterType.php
@@ -0,0 +1,38 @@
+getArr($key, null);
+
+ if ($list === null) {
+ $list = $request->getStrList($key);
+ }
+
+ return $list;
+ }
+
+ protected function getParameterDefault() {
+ return array();
+ }
+
+ protected function getParameterTypeName() {
+ return 'list';
+ }
+
+ protected function getParameterFormatDescriptions() {
+ return array(
+ pht('Comma-separated list of strings.'),
+ pht('List of strings, as array.'),
+ );
+ }
+
+ protected function getParameterExamples() {
+ return array(
+ 'v=cat,dog,pig',
+ 'v[]=cat&v[]=dog',
+ );
+ }
+
+}
diff --git a/src/aphront/httpparametertype/AphrontUserListHTTPParameterType.php b/src/aphront/httpparametertype/AphrontUserListHTTPParameterType.php
new file mode 100644
index 0000000000..3254542115
--- /dev/null
+++ b/src/aphront/httpparametertype/AphrontUserListHTTPParameterType.php
@@ -0,0 +1,42 @@
+getValueWithType($type, $request, $key);
+
+ return id(new PhabricatorUserPHIDResolver())
+ ->setViewer($this->getViewer())
+ ->resolvePHIDs($list);
+ }
+
+ protected function getParameterTypeName() {
+ return 'list';
+ }
+
+ protected function getParameterFormatDescriptions() {
+ return array(
+ pht('Comma-separated list of user PHIDs.'),
+ pht('List of user PHIDs, as array.'),
+ pht('Comma-separated list of usernames.'),
+ pht('List of usernames, as array.'),
+ pht('Mixture of usernames and PHIDs.'),
+ );
+ }
+
+ protected function getParameterExamples() {
+ return array(
+ 'v=PHID-USER-1111',
+ 'v=PHID-USER-1111,PHID-USER-2222',
+ 'v=username',
+ 'v=alincoln,htaft',
+ 'v[]=PHID-USER-1111&v[]=PHID-USER-2222',
+ 'v[]=htaft&v[]=alincoln',
+ 'v=PHID-USER-1111,alincoln',
+ 'v[]=PHID-USER-1111&v[]=htaft',
+ );
+ }
+
+}
diff --git a/src/applications/almanac/phid/AlmanacBindingPHIDType.php b/src/applications/almanac/phid/AlmanacBindingPHIDType.php
index d8fcb510fb..db469690cd 100644
--- a/src/applications/almanac/phid/AlmanacBindingPHIDType.php
+++ b/src/applications/almanac/phid/AlmanacBindingPHIDType.php
@@ -12,6 +12,10 @@ final class AlmanacBindingPHIDType extends PhabricatorPHIDType {
return new AlmanacBinding();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorAlmanacApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/almanac/phid/AlmanacDevicePHIDType.php b/src/applications/almanac/phid/AlmanacDevicePHIDType.php
index 8a1bb36a90..26c88a7a86 100644
--- a/src/applications/almanac/phid/AlmanacDevicePHIDType.php
+++ b/src/applications/almanac/phid/AlmanacDevicePHIDType.php
@@ -12,6 +12,10 @@ final class AlmanacDevicePHIDType extends PhabricatorPHIDType {
return new AlmanacDevice();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorAlmanacApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/almanac/phid/AlmanacInterfacePHIDType.php b/src/applications/almanac/phid/AlmanacInterfacePHIDType.php
index 67f9b1664a..581e86e3be 100644
--- a/src/applications/almanac/phid/AlmanacInterfacePHIDType.php
+++ b/src/applications/almanac/phid/AlmanacInterfacePHIDType.php
@@ -12,6 +12,10 @@ final class AlmanacInterfacePHIDType extends PhabricatorPHIDType {
return new AlmanacInterface();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorAlmanacApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/almanac/phid/AlmanacNetworkPHIDType.php b/src/applications/almanac/phid/AlmanacNetworkPHIDType.php
index e27efa5cd8..2264ce0e5f 100644
--- a/src/applications/almanac/phid/AlmanacNetworkPHIDType.php
+++ b/src/applications/almanac/phid/AlmanacNetworkPHIDType.php
@@ -12,6 +12,10 @@ final class AlmanacNetworkPHIDType extends PhabricatorPHIDType {
return new AlmanacNetwork();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorAlmanacApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/almanac/phid/AlmanacServicePHIDType.php b/src/applications/almanac/phid/AlmanacServicePHIDType.php
index c64e089ce6..a64a229e94 100644
--- a/src/applications/almanac/phid/AlmanacServicePHIDType.php
+++ b/src/applications/almanac/phid/AlmanacServicePHIDType.php
@@ -12,6 +12,10 @@ final class AlmanacServicePHIDType extends PhabricatorPHIDType {
return new AlmanacService();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorAlmanacApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/auth/controller/PhabricatorAuthController.php b/src/applications/auth/controller/PhabricatorAuthController.php
index db1c8c6da4..76161e6c77 100644
--- a/src/applications/auth/controller/PhabricatorAuthController.php
+++ b/src/applications/auth/controller/PhabricatorAuthController.php
@@ -2,18 +2,6 @@
abstract class PhabricatorAuthController extends PhabricatorController {
- public function buildStandardPageResponse($view, array $data) {
- $page = $this->buildStandardPageView();
-
- $page->setApplicationName(pht('Login'));
- $page->setBaseURI('/login/');
- $page->setTitle(idx($data, 'title'));
- $page->appendChild($view);
-
- $response = new AphrontWebpageResponse();
- return $response->setContent($page->render());
- }
-
protected function renderErrorPage($title, array $messages) {
$view = new PHUIInfoView();
$view->setTitle($title);
diff --git a/src/applications/auth/controller/config/PhabricatorAuthListController.php b/src/applications/auth/controller/config/PhabricatorAuthListController.php
index 5be803b895..71aac9e185 100644
--- a/src/applications/auth/controller/config/PhabricatorAuthListController.php
+++ b/src/applications/auth/controller/config/PhabricatorAuthListController.php
@@ -109,7 +109,7 @@ final class PhabricatorAuthListController
'only users with a verified email address at one of these %s '.
'allowed domain(s) will be able to register an account: %s',
$domains_link,
- new PhutilNumber(count($domains_value)),
+ phutil_count($domains_value),
phutil_tag('strong', array(), implode(', ', $domains_value)));
} else {
$issues[] = pht(
diff --git a/src/applications/auth/management/PhabricatorAuthManagementRefreshWorkflow.php b/src/applications/auth/management/PhabricatorAuthManagementRefreshWorkflow.php
index 23c0a109cb..fb82d55439 100644
--- a/src/applications/auth/management/PhabricatorAuthManagementRefreshWorkflow.php
+++ b/src/applications/auth/management/PhabricatorAuthManagementRefreshWorkflow.php
@@ -78,7 +78,7 @@ final class PhabricatorAuthManagementRefreshWorkflow
"%s\n",
pht(
'Found %s account(s) to refresh.',
- new PhutilNumber(count($accounts))));
+ phutil_count($accounts)));
}
$providers = PhabricatorAuthProvider::getAllEnabledProviders();
diff --git a/src/applications/auth/phid/PhabricatorAuthAuthFactorPHIDType.php b/src/applications/auth/phid/PhabricatorAuthAuthFactorPHIDType.php
index ca21397fb6..2819c84572 100644
--- a/src/applications/auth/phid/PhabricatorAuthAuthFactorPHIDType.php
+++ b/src/applications/auth/phid/PhabricatorAuthAuthFactorPHIDType.php
@@ -12,6 +12,10 @@ final class PhabricatorAuthAuthFactorPHIDType extends PhabricatorPHIDType {
return new PhabricatorAuthFactorConfig();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorAuthApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/auth/phid/PhabricatorAuthAuthProviderPHIDType.php b/src/applications/auth/phid/PhabricatorAuthAuthProviderPHIDType.php
index b271183f5c..e91b66e647 100644
--- a/src/applications/auth/phid/PhabricatorAuthAuthProviderPHIDType.php
+++ b/src/applications/auth/phid/PhabricatorAuthAuthProviderPHIDType.php
@@ -12,6 +12,10 @@ final class PhabricatorAuthAuthProviderPHIDType extends PhabricatorPHIDType {
return new PhabricatorAuthProviderConfig();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorAuthApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/auth/phid/PhabricatorAuthInvitePHIDType.php b/src/applications/auth/phid/PhabricatorAuthInvitePHIDType.php
index 0f1b205763..b633e10eab 100644
--- a/src/applications/auth/phid/PhabricatorAuthInvitePHIDType.php
+++ b/src/applications/auth/phid/PhabricatorAuthInvitePHIDType.php
@@ -12,6 +12,10 @@ final class PhabricatorAuthInvitePHIDType extends PhabricatorPHIDType {
return new PhabricatorAuthInvite();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorAuthApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php
index f499bea5c9..080062a2d9 100644
--- a/src/applications/base/PhabricatorApplication.php
+++ b/src/applications/base/PhabricatorApplication.php
@@ -635,4 +635,8 @@ abstract class PhabricatorApplication
return array();
}
+ protected function getEditRoutePattern($base) {
+ return $base.'(?:(?P[0-9]\d*)/)?(?:(?Pparameters)/)?';
+ }
+
}
diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php
index 9dcfa62fa2..e10b4b2802 100644
--- a/src/applications/base/controller/PhabricatorController.php
+++ b/src/applications/base/controller/PhabricatorController.php
@@ -3,7 +3,6 @@
abstract class PhabricatorController extends AphrontController {
private $handles;
- private $extraQuicksandConfig = array();
public function shouldRequireLogin() {
return true;
@@ -62,15 +61,6 @@ abstract class PhabricatorController extends AphrontController {
return false;
}
- public function addExtraQuicksandConfig($config) {
- $this->extraQuicksandConfig += $config;
- return $this;
- }
-
- private function getExtraQuicksandConfig() {
- return $this->extraQuicksandConfig;
- }
-
public function willBeginExecution() {
$request = $this->getRequest();
@@ -285,32 +275,6 @@ abstract class PhabricatorController extends AphrontController {
}
}
- public function buildStandardPageView() {
- $view = new PhabricatorStandardPageView();
- $view->setRequest($this->getRequest());
- $view->setController($this);
- return $view;
- }
-
- public function buildStandardPageResponse($view, array $data) {
- $page = $this->buildStandardPageView();
- $page->appendChild($view);
- return $this->buildPageResponse($page);
- }
-
- private function buildPageResponse($page) {
- if ($this->getRequest()->isQuicksand()) {
- $response = id(new AphrontAjaxResponse())
- ->setContent($page->renderForQuicksand(
- $this->getExtraQuicksandConfig()));
- } else {
- $response = id(new AphrontWebpageResponse())
- ->setContent($page->render());
- }
-
- return $response;
- }
-
public function getApplicationURI($path = '') {
if (!$this->getCurrentApplication()) {
throw new Exception(pht('No application!'));
@@ -318,58 +282,6 @@ abstract class PhabricatorController extends AphrontController {
return $this->getCurrentApplication()->getApplicationURI($path);
}
- public function buildApplicationPage($view, array $options) {
- $page = $this->buildStandardPageView();
-
- $title = PhabricatorEnv::getEnvConfig('phabricator.serious-business') ?
- 'Phabricator' :
- pht('Bacon Ice Cream for Breakfast');
-
- $application = $this->getCurrentApplication();
- $page->setTitle(idx($options, 'title', $title));
- if ($application) {
- $page->setApplicationName($application->getName());
- if ($application->getTitleGlyph()) {
- $page->setGlyph($application->getTitleGlyph());
- }
- }
-
- if (!($view instanceof AphrontSideNavFilterView)) {
- $nav = new AphrontSideNavFilterView();
- $nav->appendChild($view);
- $view = $nav;
- }
-
- $user = $this->getRequest()->getUser();
- $view->setUser($user);
-
- $page->appendChild($view);
-
- $object_phids = idx($options, 'pageObjects', array());
- if ($object_phids) {
- $page->appendPageObjects($object_phids);
- foreach ($object_phids as $object_phid) {
- PhabricatorFeedStoryNotification::updateObjectNotificationViews(
- $user,
- $object_phid);
- }
- }
-
- if (idx($options, 'device', true)) {
- $page->setDeviceReady(true);
- }
-
- $page->setShowFooter(idx($options, 'showFooter', true));
- $page->setShowChrome(idx($options, 'chrome', true));
-
- $application_menu = $this->buildApplicationMenu();
- if ($application_menu) {
- $page->setApplicationMenu($application_menu);
- }
-
- return $this->buildPageResponse($page);
- }
-
public function willSendResponse(AphrontResponse $response) {
$request = $this->getRequest();
@@ -532,6 +444,36 @@ abstract class PhabricatorController extends AphrontController {
->setSubmitURI($submit_uri);
}
+ public function newPage() {
+ $page = id(new PhabricatorStandardPageView())
+ ->setRequest($this->getRequest())
+ ->setController($this)
+ ->setDeviceReady(true);
+
+ $application = $this->getCurrentApplication();
+ if ($application) {
+ $page->setApplicationName($application->getName());
+ if ($application->getTitleGlyph()) {
+ $page->setGlyph($application->getTitleGlyph());
+ }
+ }
+
+ $viewer = $this->getRequest()->getUser();
+ if ($viewer) {
+ $page->setUser($viewer);
+ }
+
+ // TODO: Remove after removing callsites to addExtraQuicksandConfig().
+ $page->addQuicksandConfig($this->extraQuicksandConfig);
+
+ return $page;
+ }
+
+ public function newApplicationMenu() {
+ return id(new PHUIApplicationMenuView())
+ ->setViewer($this->getRequest()->getUser());
+ }
+
protected function buildTransactionTimeline(
PhabricatorApplicationTransactionInterface $object,
PhabricatorApplicationTransactionQuery $query,
@@ -579,4 +521,89 @@ abstract class PhabricatorController extends AphrontController {
return $timeline;
}
+
+ public function buildApplicationCrumbsForEditEngine() {
+ // TODO: This is kind of gross, I'm bascially just making this public so
+ // I can use it in EditEngine. We could do this without making it public
+ // by using controller delegation, or make it properly public.
+ return $this->buildApplicationCrumbs();
+ }
+
+
+/* -( Deprecated )--------------------------------------------------------- */
+
+
+ /**
+ * DEPRECATED.
+ */
+ private $extraQuicksandConfig = array();
+
+
+ /**
+ * DEPRECATED. Use @{method:newPage} and call addQuicksandConfig().
+ */
+ public function addExtraQuicksandConfig($config) {
+ // TODO: When this method is removed,
+ $this->extraQuicksandConfig += $config;
+ return $this;
+ }
+
+
+ /**
+ * DEPRECATED. Use @{method:newPage}.
+ */
+ public function buildStandardPageView() {
+ return $this->newPage();
+ }
+
+
+ /**
+ * DEPRECATED. Use @{method:newPage}.
+ */
+ public function buildStandardPageResponse($view, array $data) {
+ $page = $this->buildStandardPageView();
+ $page->appendChild($view);
+ return $page->produceAphrontResponse();
+ }
+
+
+ /**
+ * DEPRECATED. Use @{method:newPage}.
+ */
+ public function buildApplicationPage($view, array $options) {
+ $page = $this->newPage();
+
+ $title = PhabricatorEnv::getEnvConfig('phabricator.serious-business') ?
+ 'Phabricator' :
+ pht('Bacon Ice Cream for Breakfast');
+
+ $page->setTitle(idx($options, 'title', $title));
+
+ if (idx($options, 'class')) {
+ $page->addClass($options['class']);
+ }
+
+ if (!($view instanceof AphrontSideNavFilterView)) {
+ $nav = new AphrontSideNavFilterView();
+ $nav->appendChild($view);
+ $view = $nav;
+ }
+
+ $page->appendChild($view);
+
+ $object_phids = idx($options, 'pageObjects', array());
+ if ($object_phids) {
+ $page->setPageObjectPHIDs($object_phids);
+ }
+
+ if (!idx($options, 'device', true)) {
+ $page->setDeviceReady(false);
+ }
+
+ $page->setShowFooter(idx($options, 'showFooter', true));
+ $page->setShowChrome(idx($options, 'chrome', true));
+
+ return $page->produceAphrontResponse();
+ }
+
}
diff --git a/src/applications/calendar/phid/PhabricatorCalendarEventPHIDType.php b/src/applications/calendar/phid/PhabricatorCalendarEventPHIDType.php
index 7acc968f21..d37be2ef32 100644
--- a/src/applications/calendar/phid/PhabricatorCalendarEventPHIDType.php
+++ b/src/applications/calendar/phid/PhabricatorCalendarEventPHIDType.php
@@ -8,14 +8,14 @@ final class PhabricatorCalendarEventPHIDType extends PhabricatorPHIDType {
return pht('Event');
}
- public function getPHIDTypeApplicationClass() {
- return 'PhabricatorCalendarApplication';
- }
-
public function newObject() {
return new PhabricatorCalendarEvent();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorCalendarApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/celerity/management/CelerityManagementMapWorkflow.php b/src/applications/celerity/management/CelerityManagementMapWorkflow.php
index 525a079f53..e838de58f4 100644
--- a/src/applications/celerity/management/CelerityManagementMapWorkflow.php
+++ b/src/applications/celerity/management/CelerityManagementMapWorkflow.php
@@ -18,7 +18,7 @@ final class CelerityManagementMapWorkflow
$this->log(
pht(
'Rebuilding %d resource source(s).',
- new PhutilNumber(count($resources_map))));
+ phutil_count($resources_map)));
foreach ($resources_map as $name => $resources) {
$this->rebuildResources($resources);
diff --git a/src/applications/celerity/postprocessor/CelerityDefaultPostprocessor.php b/src/applications/celerity/postprocessor/CelerityDefaultPostprocessor.php
index 368d6406f3..7c230d9869 100644
--- a/src/applications/celerity/postprocessor/CelerityDefaultPostprocessor.php
+++ b/src/applications/celerity/postprocessor/CelerityDefaultPostprocessor.php
@@ -172,11 +172,11 @@ final class CelerityDefaultPostprocessor
'sh-pinkbackground' => '#fbeaf8',
// Shade Grey
- 'sh-lightgreyborder' => '#d8d8d8',
+ 'sh-lightgreyborder' => '#e3e4e8',
'sh-greyborder' => '#b2b2b2',
'sh-greyicon' => '#757575',
'sh-greytext' => '#555555',
- 'sh-greybackground' => '#e7e7e7',
+ 'sh-greybackground' => '#edeef2',
// Shade Disabled
'sh-lightdisabledborder' => '#e5e5e5',
diff --git a/src/applications/config/check/PhabricatorDaemonsSetupCheck.php b/src/applications/config/check/PhabricatorDaemonsSetupCheck.php
index 3b4b335134..a89590cc18 100644
--- a/src/applications/config/check/PhabricatorDaemonsSetupCheck.php
+++ b/src/applications/config/check/PhabricatorDaemonsSetupCheck.php
@@ -115,7 +115,7 @@ final class PhabricatorDaemonsSetupCheck extends PhabricatorSetupCheck {
$list_section = array(
pht(
'The configurations differ in the following %s way(s):',
- new PhutilNumber(count($issues))),
+ phutil_count($issues)),
phutil_tag(
'ul',
array(),
diff --git a/src/applications/config/check/PhabricatorPathSetupCheck.php b/src/applications/config/check/PhabricatorPathSetupCheck.php
index 618c81abb9..9f5502e215 100644
--- a/src/applications/config/check/PhabricatorPathSetupCheck.php
+++ b/src/applications/config/check/PhabricatorPathSetupCheck.php
@@ -111,7 +111,7 @@ final class PhabricatorPathSetupCheck extends PhabricatorSetupCheck {
$this
->newIssue('config.PATH.'.$digest)
- ->setName(pht('$PATH Component Unusable'))
+ ->setName(pht('%s Component Unusable', '$PATH'))
->setSummary(
pht(
'A component of the configured PATH can not be used by '.
diff --git a/src/applications/config/module/PhabricatorConfigHTTPParameterTypesModule.php b/src/applications/config/module/PhabricatorConfigHTTPParameterTypesModule.php
new file mode 100644
index 0000000000..66a44c8c83
--- /dev/null
+++ b/src/applications/config/module/PhabricatorConfigHTTPParameterTypesModule.php
@@ -0,0 +1,27 @@
+getViewer();
+
+ $types = AphrontHTTPParameterType::getAllTypes();
+
+ $table = id(new PhabricatorHTTPParameterTypeTableView())
+ ->setHTTPParameterTypes($types);
+
+ return id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('HTTP Parameter Types'))
+ ->setTable($table);
+ }
+
+}
diff --git a/src/applications/config/phid/PhabricatorConfigConfigPHIDType.php b/src/applications/config/phid/PhabricatorConfigConfigPHIDType.php
index 161b1e42f4..95c543427f 100644
--- a/src/applications/config/phid/PhabricatorConfigConfigPHIDType.php
+++ b/src/applications/config/phid/PhabricatorConfigConfigPHIDType.php
@@ -12,6 +12,10 @@ final class PhabricatorConfigConfigPHIDType extends PhabricatorPHIDType {
return new PhabricatorConfigEntry();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorConfigApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/config/view/PhabricatorHTTPParameterTypeTableView.php b/src/applications/config/view/PhabricatorHTTPParameterTypeTableView.php
new file mode 100644
index 0000000000..25e944a9fd
--- /dev/null
+++ b/src/applications/config/view/PhabricatorHTTPParameterTypeTableView.php
@@ -0,0 +1,56 @@
+types = $types;
+ return $this;
+ }
+
+ public function getHTTPParameterTypes() {
+ return $this->types;
+ }
+
+ public function render() {
+ $types = $this->getHTTPParameterTypes();
+ $types = mpull($types, null, 'getTypeName');
+
+ $br = phutil_tag('br');
+
+ $rows = array();
+ foreach ($types as $name => $type) {
+ $formats = $type->getFormatDescriptions();
+ $formats = phutil_implode_html($br, $formats);
+
+ $examples = $type->getExamples();
+ $examples = phutil_implode_html($br, $examples);
+
+ $rows[] = array(
+ $name,
+ $formats,
+ $examples,
+ );
+ }
+
+ $table = id(new AphrontTableView($rows))
+ ->setHeaders(
+ array(
+ pht('Type'),
+ pht('Formats'),
+ pht('Examples'),
+ ))
+ ->setColumnClasses(
+ array(
+ 'pri top',
+ 'top',
+ 'wide top prewrap',
+ ));
+
+ return $table;
+ }
+
+}
diff --git a/src/applications/config/view/PhabricatorSetupIssueView.php b/src/applications/config/view/PhabricatorSetupIssueView.php
index 7ece4f865c..cb8859bb86 100644
--- a/src/applications/config/view/PhabricatorSetupIssueView.php
+++ b/src/applications/config/view/PhabricatorSetupIssueView.php
@@ -387,7 +387,7 @@ final class PhabricatorSetupIssueView extends AphrontView {
array(),
pht(
'PHP also loaded these %s configuration file(s):',
- new PhutilNumber(count($more_loc))));
+ phutil_count($more_loc)));
$info[] = phutil_tag(
'pre',
array(),
diff --git a/src/applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php b/src/applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php
index c7ea1405cd..d5f3267a06 100644
--- a/src/applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php
+++ b/src/applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php
@@ -29,14 +29,13 @@ final class ConpherenceUpdateThreadConduitAPIMethod
protected function defineErrorTypes() {
return array(
'ERR_USAGE_NO_ROOM_ID' => pht(
- 'You must specify a room id or room phid to query transactions '.
- 'from.'),
+ 'You must specify a room ID or room PHID to query transactions from.'),
'ERR_USAGE_ROOM_NOT_FOUND' => pht(
- 'room does not exist or logged in user can not see it.'),
+ 'Room does not exist or logged in user can not see it.'),
'ERR_USAGE_ONLY_SELF_REMOVE' => pht(
'Only a user can remove themselves from a room.'),
'ERR_USAGE_NO_UPDATES' => pht(
- 'You must specify data that actually updates the conpherence.'),
+ 'You must specify data that actually updates the Conpherence.'),
);
}
diff --git a/src/applications/conpherence/controller/ConpherenceUpdateController.php b/src/applications/conpherence/controller/ConpherenceUpdateController.php
index 6012c81437..1ab0923fc4 100644
--- a/src/applications/conpherence/controller/ConpherenceUpdateController.php
+++ b/src/applications/conpherence/controller/ConpherenceUpdateController.php
@@ -325,8 +325,7 @@ final class ConpherenceUpdateController
$remove_person = $request->getStr('remove_person');
$participants = $conpherence->getParticipants();
- $message = pht(
- 'Are you sure you want to leave this room?');
+ $message = pht('Are you sure you want to leave this room?');
$test_conpherence = clone $conpherence;
$test_conpherence->attachParticipants(array());
if (!PhabricatorPolicyFilter::hasCapability(
@@ -334,17 +333,14 @@ final class ConpherenceUpdateController
$test_conpherence,
PhabricatorPolicyCapability::CAN_VIEW)) {
if (count($participants) == 1) {
- $message .= pht(
- ' The room will be inaccessible forever and ever.');
+ $message .= ' '.pht('The room will be inaccessible forever and ever.');
} else {
- $message .= pht(
- ' Someone else in the room can add you back later.');
+ $message .= ' '.pht('Someone else in the room can add you back later.');
}
}
$body = phutil_tag(
'p',
- array(
- ),
+ array(),
$message);
require_celerity_resource('conpherence-update-css');
diff --git a/src/applications/conpherence/storage/ConpherenceTransaction.php b/src/applications/conpherence/storage/ConpherenceTransaction.php
index ba49cdf9b4..062b9e4a9f 100644
--- a/src/applications/conpherence/storage/ConpherenceTransaction.php
+++ b/src/applications/conpherence/storage/ConpherenceTransaction.php
@@ -77,14 +77,14 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
count($rem));
} else if ($add) {
$title = pht(
- '%s added %d files(s).',
+ '%s added %s files(s).',
$this->renderHandleLink($author_phid),
- count($add));
+ phutil_count($add));
} else {
$title = pht(
- '%s removed %d file(s).',
+ '%s removed %s file(s).',
$this->renderHandleLink($author_phid),
- count($rem));
+ phutil_count($rem));
}
return $title;
break;
diff --git a/src/applications/countdown/phid/PhabricatorCountdownCountdownPHIDType.php b/src/applications/countdown/phid/PhabricatorCountdownCountdownPHIDType.php
index 852c5889ed..573d89c843 100644
--- a/src/applications/countdown/phid/PhabricatorCountdownCountdownPHIDType.php
+++ b/src/applications/countdown/phid/PhabricatorCountdownCountdownPHIDType.php
@@ -12,6 +12,10 @@ final class PhabricatorCountdownCountdownPHIDType extends PhabricatorPHIDType {
return new PhabricatorCountdown();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorCountdownApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php b/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php
index 1cfa2499b2..a2beba3cd2 100644
--- a/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php
+++ b/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php
@@ -226,7 +226,9 @@ abstract class PhabricatorDaemonManagementWorkflow
// Retry without sudo
$console->writeOut(
"%s\n",
- pht('sudo command failed. Starting daemon as current user.'));
+ pht(
+ '%s command failed. Starting daemon as current user.',
+ 'sudo'));
$this->executeDaemonLaunchCommand(
$command,
$daemon_script_dir,
@@ -265,8 +267,9 @@ abstract class PhabricatorDaemonManagementWorkflow
if (preg_match('/sudo: a password is required/', $stderr)) {
throw new Exception(
pht(
- 'sudo exited with a zero exit code, but emitted output '.
- 'consistent with failure under OSX.'));
+ '%s exited with a zero exit code, but emitted output '.
+ 'consistent with failure under OSX.',
+ 'sudo'));
}
}
}
diff --git a/src/applications/dashboard/phid/PhabricatorDashboardDashboardPHIDType.php b/src/applications/dashboard/phid/PhabricatorDashboardDashboardPHIDType.php
index e097dc161d..1450e2aa68 100644
--- a/src/applications/dashboard/phid/PhabricatorDashboardDashboardPHIDType.php
+++ b/src/applications/dashboard/phid/PhabricatorDashboardDashboardPHIDType.php
@@ -12,6 +12,10 @@ final class PhabricatorDashboardDashboardPHIDType extends PhabricatorPHIDType {
return new PhabricatorDashboard();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorDashboardApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/dashboard/phid/PhabricatorDashboardPanelPHIDType.php b/src/applications/dashboard/phid/PhabricatorDashboardPanelPHIDType.php
index c4aec82b8e..49a5091412 100644
--- a/src/applications/dashboard/phid/PhabricatorDashboardPanelPHIDType.php
+++ b/src/applications/dashboard/phid/PhabricatorDashboardPanelPHIDType.php
@@ -12,6 +12,10 @@ final class PhabricatorDashboardPanelPHIDType extends PhabricatorPHIDType {
return new PhabricatorDashboardPanel();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorDashboardApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/differential/customfield/DifferentialJIRAIssuesField.php b/src/applications/differential/customfield/DifferentialJIRAIssuesField.php
index 046539d0da..e40e34f4ad 100644
--- a/src/applications/differential/customfield/DifferentialJIRAIssuesField.php
+++ b/src/applications/differential/customfield/DifferentialJIRAIssuesField.php
@@ -218,21 +218,21 @@ final class DifferentialJIRAIssuesField
return pht(
'%s updated JIRA issue(s): added %d %s; removed %d %s.',
$xaction->renderHandleLink($author_phid),
- new PhutilNumber(count($add)),
+ phutil_count($add),
implode(', ', $add),
- new PhutilNumber(count($rem)),
+ phutil_count($rem),
implode(', ', $rem));
} else if ($add) {
return pht(
'%s added %d JIRA issue(s): %s.',
$xaction->renderHandleLink($author_phid),
- new PhutilNumber(count($add)),
+ phutil_count($add),
implode(', ', $add));
} else if ($rem) {
return pht(
'%s removed %d JIRA issue(s): %s.',
$xaction->renderHandleLink($author_phid),
- new PhutilNumber(count($rem)),
+ phutil_count($rem),
implode(', ', $rem));
}
diff --git a/src/applications/differential/customfield/DifferentialUnitField.php b/src/applications/differential/customfield/DifferentialUnitField.php
index 3883baba86..17973be7a6 100644
--- a/src/applications/differential/customfield/DifferentialUnitField.php
+++ b/src/applications/differential/customfield/DifferentialUnitField.php
@@ -125,7 +125,7 @@ final class DifferentialUnitField
)) + $groups;
foreach ($groups as $result => $group) {
- $count = new PhutilNumber(count($group));
+ $count = phutil_count($group);
switch ($result) {
case ArcanistUnitTestResult::RESULT_PASS:
$note[] = pht('%s Passed Test(s)', $count);
diff --git a/src/applications/differential/herald/DifferentialReviewersHeraldAction.php b/src/applications/differential/herald/DifferentialReviewersHeraldAction.php
index c568537f7c..5293af4311 100644
--- a/src/applications/differential/herald/DifferentialReviewersHeraldAction.php
+++ b/src/applications/differential/herald/DifferentialReviewersHeraldAction.php
@@ -135,12 +135,12 @@ abstract class DifferentialReviewersHeraldAction
case self::DO_ADD_REVIEWERS:
return pht(
'Added %s reviewer(s): %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
case self::DO_ADD_BLOCKING_REVIEWERS:
return pht(
'Added %s blocking reviewer(s): %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
}
}
diff --git a/src/applications/differential/mail/DifferentialCreateMailReceiver.php b/src/applications/differential/mail/DifferentialCreateMailReceiver.php
index c3198d3642..f5d9dc59f7 100644
--- a/src/applications/differential/mail/DifferentialCreateMailReceiver.php
+++ b/src/applications/differential/mail/DifferentialCreateMailReceiver.php
@@ -81,14 +81,14 @@ final class DifferentialCreateMailReceiver extends PhabricatorMailReceiver {
} else {
$subject = pht(
'Diff creation failed; see body for %s error(s).',
- new PhutilNumber(count($errors)));
+ phutil_count($errors));
}
$body = new PhabricatorMetaMTAMailBody();
$body->addRawSection($subject);
if (count($diffs)) {
$text_body = '';
$html_body = array();
- $body_label = pht('%s DIFF LINK(S)', new PhutilNumber(count($diffs)));
+ $body_label = pht('%s DIFF LINK(S)', phutil_count($diffs));
foreach ($diffs as $filename => $diff_uri) {
$text_body .= $filename.': '.$diff_uri."\n";
$html_body[] = phutil_tag(
@@ -105,7 +105,7 @@ final class DifferentialCreateMailReceiver extends PhabricatorMailReceiver {
if (count($errors)) {
$body_section = new PhabricatorMetaMTAMailSection();
- $body_label = pht('%s ERROR(S)', new PhutilNumber(count($errors)));
+ $body_label = pht('%s ERROR(S)', phutil_count($errors));
foreach ($errors as $error) {
$body_section->addFragment($error);
}
diff --git a/src/applications/differential/phid/DifferentialDiffPHIDType.php b/src/applications/differential/phid/DifferentialDiffPHIDType.php
index 887397d57f..746da368c7 100644
--- a/src/applications/differential/phid/DifferentialDiffPHIDType.php
+++ b/src/applications/differential/phid/DifferentialDiffPHIDType.php
@@ -12,6 +12,10 @@ final class DifferentialDiffPHIDType extends PhabricatorPHIDType {
return new DifferentialDiff();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorDifferentialApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/differential/phid/DifferentialRevisionPHIDType.php b/src/applications/differential/phid/DifferentialRevisionPHIDType.php
index a46dc71c65..b22c8b05cb 100644
--- a/src/applications/differential/phid/DifferentialRevisionPHIDType.php
+++ b/src/applications/differential/phid/DifferentialRevisionPHIDType.php
@@ -8,14 +8,14 @@ final class DifferentialRevisionPHIDType extends PhabricatorPHIDType {
return pht('Differential Revision');
}
- public function getPHIDTypeApplicationClass() {
- return 'PhabricatorDifferentialApplication';
- }
-
public function newObject() {
return new DifferentialRevision();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorDifferentialApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/diffusion/herald/DiffusionAuditorsHeraldAction.php b/src/applications/diffusion/herald/DiffusionAuditorsHeraldAction.php
index 32830cb673..a7dbdde682 100644
--- a/src/applications/diffusion/herald/DiffusionAuditorsHeraldAction.php
+++ b/src/applications/diffusion/herald/DiffusionAuditorsHeraldAction.php
@@ -68,7 +68,7 @@ abstract class DiffusionAuditorsHeraldAction
case self::DO_ADD_AUDITORS:
return pht(
'Added %s auditor(s): %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
}
}
diff --git a/src/applications/diviner/atomizer/DivinerPHPAtomizer.php b/src/applications/diviner/atomizer/DivinerPHPAtomizer.php
index c22cb4bcc3..36616897f2 100644
--- a/src/applications/diviner/atomizer/DivinerPHPAtomizer.php
+++ b/src/applications/diviner/atomizer/DivinerPHPAtomizer.php
@@ -152,8 +152,8 @@ final class DivinerPHPAtomizer extends DivinerAtomizer {
$atom->addWarning(
pht(
'This call takes %s parameter(s), but only %s are documented.',
- new PhutilNumber(count($params)),
- new PhutilNumber(count($docs))));
+ phutil_count($params),
+ phutil_count($docs)));
}
}
diff --git a/src/applications/diviner/controller/DivinerAtomController.php b/src/applications/diviner/controller/DivinerAtomController.php
index ecde1218f3..05bb80c16a 100644
--- a/src/applications/diviner/controller/DivinerAtomController.php
+++ b/src/applications/diviner/controller/DivinerAtomController.php
@@ -58,13 +58,7 @@ final class DivinerAtomController extends DivinerController {
$crumbs->addTextCrumb($atom_short_title);
$header = id(new PHUIHeaderView())
- ->setHeader($this->renderFullSignature($symbol))
- ->addTag(
- id(new PHUITagView())
- ->setType(PHUITagView::TYPE_STATE)
- ->setBackgroundColor(PHUITagView::COLOR_BLUE)
- ->setName(DivinerAtom::getAtomTypeNameString(
- $atom ? $atom->getType() : $symbol->getType())));
+ ->setHeader($this->renderFullSignature($symbol));
$properties = new PHUIPropertyListView();
@@ -78,11 +72,11 @@ final class DivinerAtomController extends DivinerController {
$prop_list = new PHUIPropertyGroupView();
$prop_list->addPropertyList($properties);
- $document = id(new PHUIDocumentView())
+ $document = id(new PHUIDocumentViewPro())
->setBook($book->getTitle(), $group_name)
->setHeader($header)
->addClass('diviner-view')
- ->appendChild($prop_list);
+ ->setPropertyList($prop_list);
if ($atom) {
$this->buildDefined($properties, $symbol);
@@ -163,10 +157,6 @@ final class DivinerAtomController extends DivinerController {
->setHeader($spec['title']));
$task_methods = idx($methods_by_task, $spec['name'], array());
- $inner_box = id(new PHUIBoxView())
- ->addPadding(PHUI::PADDING_LARGE_LEFT)
- ->addPadding(PHUI::PADDING_LARGE_RIGHT)
- ->addPadding(PHUI::PADDING_LARGE_BOTTOM);
$box_content = array();
if ($task_methods) {
@@ -198,7 +188,7 @@ final class DivinerAtomController extends DivinerController {
$box_content = phutil_tag('em', array(), $no_methods);
}
- $inner_box->appendChild($box_content);
+ $inner_box = phutil_tag_div('diviner-task-items', $box_content);
$section->addContent($inner_box);
}
$document->appendChild($section);
@@ -246,7 +236,7 @@ final class DivinerAtomController extends DivinerController {
->setHref('#'.$key));
}
- $document->setSideNav($side, PHUIDocumentView::NAV_TOP);
+ $document->setToc($side);
}
return $this->buildApplicationPage(
@@ -256,6 +246,7 @@ final class DivinerAtomController extends DivinerController {
),
array(
'title' => $symbol->getTitle(),
+ 'class' => 'pro-white-background',
));
}
@@ -629,7 +620,7 @@ final class DivinerAtomController extends DivinerController {
$content = phutil_tag(
'div',
array(
- 'class' => 'phabricator-remarkup',
+ 'class' => 'phabricator-remarkup diviner-remarkup-section',
),
$content);
} else {
@@ -668,8 +659,6 @@ final class DivinerAtomController extends DivinerController {
if (($impl !== $parent) || $out) {
$where = id(new PHUIBoxView())
- ->addPadding(PHUI::PADDING_MEDIUM_LEFT)
- ->addPadding(PHUI::PADDING_MEDIUM_RIGHT)
->addClass('diviner-method-implementation-header')
->appendChild($impl->getName());
$doc = array($where, $doc);
diff --git a/src/applications/diviner/controller/DivinerBookController.php b/src/applications/diviner/controller/DivinerBookController.php
index ae4b81aa01..2731823588 100644
--- a/src/applications/diviner/controller/DivinerBookController.php
+++ b/src/applications/diviner/controller/DivinerBookController.php
@@ -53,7 +53,7 @@ final class DivinerBookController extends DivinerController {
->setName($book->getRepository()->getMonogram()));
}
- $document = new PHUIDocumentView();
+ $document = new PHUIDocumentViewPro();
$document->setHeader($header);
$document->addClass('diviner-view');
@@ -111,6 +111,7 @@ final class DivinerBookController extends DivinerController {
),
array(
'title' => $book->getTitle(),
+ 'class' => 'pro-white-background',
));
}
diff --git a/src/applications/diviner/controller/DivinerMainController.php b/src/applications/diviner/controller/DivinerMainController.php
index b2233463c0..a68d900d8a 100644
--- a/src/applications/diviner/controller/DivinerMainController.php
+++ b/src/applications/diviner/controller/DivinerMainController.php
@@ -30,7 +30,7 @@ final class DivinerMainController extends DivinerController {
->setHeader(pht('Documentation Books'))
->addActionLink($query_button);
- $document = new PHUIDocumentView();
+ $document = new PHUIDocumentViewPro();
$document->setHeader($header);
$document->addClass('diviner-view');
@@ -45,10 +45,7 @@ final class DivinerMainController extends DivinerController {
$list[] = $item;
}
$list = id(new PHUIBoxView())
- ->addPadding(PHUI::PADDING_LARGE_LEFT)
- ->addPadding(PHUI::PADDING_LARGE_RIGHT)
- ->addPadding(PHUI::PADDING_SMALL_TOP)
- ->addPadding(PHUI::PADDING_SMALL_BOTTOM)
+ ->addPadding(PHUI::PADDING_MEDIUM_TOP)
->appendChild($list);
$document->appendChild($list);
@@ -82,7 +79,7 @@ final class DivinerMainController extends DivinerController {
),
array(
'title' => pht('Documentation Books'),
- 'fonts' => true,
+ 'class' => 'pro-white-background',
));
}
}
diff --git a/src/applications/diviner/publisher/DivinerPublisher.php b/src/applications/diviner/publisher/DivinerPublisher.php
index 401a1a331f..e5dcf695db 100644
--- a/src/applications/diviner/publisher/DivinerPublisher.php
+++ b/src/applications/diviner/publisher/DivinerPublisher.php
@@ -140,14 +140,14 @@ abstract class DivinerPublisher extends Phobject {
"%s\n",
pht(
'Deleting %s document(s).',
- new PhutilNumber(count($deleted))));
+ phutil_count($deleted)));
$this->deleteDocumentsByHash($deleted);
$console->writeOut(
"%s\n",
pht(
'Creating %s document(s).',
- new PhutilNumber(count($created))));
+ phutil_count($created)));
$this->createDocumentsByHash($created);
}
diff --git a/src/applications/diviner/view/DivinerSectionView.php b/src/applications/diviner/view/DivinerSectionView.php
index f12fb01fab..cc02d9d8b8 100644
--- a/src/applications/diviner/view/DivinerSectionView.php
+++ b/src/applications/diviner/view/DivinerSectionView.php
@@ -30,12 +30,10 @@ final class DivinerSectionView extends AphrontTagView {
$header = id(new PHUIHeaderView())
->setBleedHeader(true)
+ ->addClass('diviner-section-header')
->setHeader($this->header);
- $content = id(new PHUIBoxView())
- ->addPadding(PHUI::PADDING_LARGE_LEFT)
- ->addPadding(PHUI::PADDING_LARGE_RIGHT)
- ->appendChild($this->content);
+ $content = phutil_tag_div('diviner-section-content', $this->content);
return array($header, $content);
}
diff --git a/src/applications/diviner/workflow/DivinerGenerateWorkflow.php b/src/applications/diviner/workflow/DivinerGenerateWorkflow.php
index d448de69c0..ad671bbbea 100644
--- a/src/applications/diviner/workflow/DivinerGenerateWorkflow.php
+++ b/src/applications/diviner/workflow/DivinerGenerateWorkflow.php
@@ -69,7 +69,7 @@ final class DivinerGenerateWorkflow extends DivinerWorkflow {
'.book',
'--book '));
} else {
- $this->log(pht('Found %s book(s).', new PhutilNumber(count($books))));
+ $this->log(pht('Found %s book(s).', phutil_count($books)));
}
}
@@ -224,26 +224,26 @@ final class DivinerGenerateWorkflow extends DivinerWorkflow {
$this->log(
pht(
'Found %s file(s) in project.',
- new PhutilNumber(count($file_hashes))));
+ phutil_count($file_hashes)));
$this->deleteDeadAtoms($file_hashes);
$atomize = $this->getFilesToAtomize($file_hashes);
$this->log(
pht(
'Found %s unatomized, uncached file(s).',
- new PhutilNumber(count($atomize))));
+ phutil_count($atomize)));
$file_atomizers = $this->getAtomizersForFiles($atomize);
$this->log(
pht(
'Found %s file(s) to atomize.',
- new PhutilNumber(count($file_atomizers))));
+ phutil_count($file_atomizers)));
$futures = $this->buildAtomizerFutures($file_atomizers);
$this->log(
pht(
'Atomizing %s file(s).',
- new PhutilNumber(count($file_atomizers))));
+ phutil_count($file_atomizers)));
if ($futures) {
$this->resolveAtomizerFutures($futures, $file_hashes);
@@ -452,7 +452,7 @@ final class DivinerGenerateWorkflow extends DivinerWorkflow {
$this->log(
pht(
'Found %s obsolete atom(s) in graph.',
- new PhutilNumber(count($del_atoms))));
+ phutil_count($del_atoms)));
foreach ($del_atoms as $nhash => $shash) {
$atom_cache->deleteSymbol($nhash);
@@ -466,7 +466,7 @@ final class DivinerGenerateWorkflow extends DivinerWorkflow {
$this->log(
pht(
'Found %s new atom(s) in graph.',
- new PhutilNumber(count($new_atoms))));
+ phutil_count($new_atoms)));
foreach ($new_atoms as $nhash => $ignored) {
$shash = $this->computeSymbolHash($nhash);
@@ -505,7 +505,7 @@ final class DivinerGenerateWorkflow extends DivinerWorkflow {
$this->log(
pht(
'Found %s affected atoms.',
- new PhutilNumber(count($dirty_nhashes))));
+ phutil_count($dirty_nhashes)));
foreach ($dirty_nhashes as $nhash => $ignored) {
$atom_cache->addGraph($nhash, $this->computeGraphHash($nhash));
diff --git a/src/applications/doorkeeper/option/PhabricatorAsanaConfigOptions.php b/src/applications/doorkeeper/option/PhabricatorAsanaConfigOptions.php
index f0cdb5a819..e7f2ef85de 100644
--- a/src/applications/doorkeeper/option/PhabricatorAsanaConfigOptions.php
+++ b/src/applications/doorkeeper/option/PhabricatorAsanaConfigOptions.php
@@ -96,8 +96,11 @@ final class PhabricatorAsanaConfigOptions
}
$out = array();
- $out[] = pht('| Workspace ID | Workspace Name |');
- $out[] = '| ------------ | -------------- |';
+ $out[] = sprintf(
+ '| %s | %s |',
+ pht('Workspace ID'),
+ pht('Workspace Name'));
+ $out[] = '| ------------ | -------------- |';
foreach ($workspaces as $workspace) {
$out[] = sprintf('| `%s` | `%s` |', $workspace['id'], $workspace['name']);
}
diff --git a/src/applications/drydock/phid/DrydockAuthorizationPHIDType.php b/src/applications/drydock/phid/DrydockAuthorizationPHIDType.php
index e518149945..058ccff6a9 100644
--- a/src/applications/drydock/phid/DrydockAuthorizationPHIDType.php
+++ b/src/applications/drydock/phid/DrydockAuthorizationPHIDType.php
@@ -12,6 +12,10 @@ final class DrydockAuthorizationPHIDType extends PhabricatorPHIDType {
return new DrydockAuthorization();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorDrydockApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/drydock/phid/DrydockBlueprintPHIDType.php b/src/applications/drydock/phid/DrydockBlueprintPHIDType.php
index e63f1294a7..ef286cf5f1 100644
--- a/src/applications/drydock/phid/DrydockBlueprintPHIDType.php
+++ b/src/applications/drydock/phid/DrydockBlueprintPHIDType.php
@@ -8,10 +8,6 @@ final class DrydockBlueprintPHIDType extends PhabricatorPHIDType {
return pht('Blueprint');
}
- public function getPHIDTypeApplicationClass() {
- return 'PhabricatorDrydockApplication';
- }
-
public function getTypeIcon() {
return 'fa-map-o';
}
@@ -20,6 +16,10 @@ final class DrydockBlueprintPHIDType extends PhabricatorPHIDType {
return new DrydockBlueprint();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorDrydockApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/drydock/phid/DrydockLeasePHIDType.php b/src/applications/drydock/phid/DrydockLeasePHIDType.php
index fc921cee3a..faa751b0f1 100644
--- a/src/applications/drydock/phid/DrydockLeasePHIDType.php
+++ b/src/applications/drydock/phid/DrydockLeasePHIDType.php
@@ -8,10 +8,6 @@ final class DrydockLeasePHIDType extends PhabricatorPHIDType {
return pht('Drydock Lease');
}
- public function getPHIDTypeApplicationClass() {
- return 'PhabricatorDrydockApplication';
- }
-
public function getTypeIcon() {
return 'fa-link';
}
@@ -20,6 +16,10 @@ final class DrydockLeasePHIDType extends PhabricatorPHIDType {
return new DrydockLease();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorDrydockApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/drydock/phid/DrydockRepositoryOperationPHIDType.php b/src/applications/drydock/phid/DrydockRepositoryOperationPHIDType.php
index d21efd8a86..0926f92388 100644
--- a/src/applications/drydock/phid/DrydockRepositoryOperationPHIDType.php
+++ b/src/applications/drydock/phid/DrydockRepositoryOperationPHIDType.php
@@ -12,6 +12,10 @@ final class DrydockRepositoryOperationPHIDType extends PhabricatorPHIDType {
return new DrydockRepositoryOperation();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorDrydockApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/drydock/phid/DrydockResourcePHIDType.php b/src/applications/drydock/phid/DrydockResourcePHIDType.php
index 966cf35abe..a36647964d 100644
--- a/src/applications/drydock/phid/DrydockResourcePHIDType.php
+++ b/src/applications/drydock/phid/DrydockResourcePHIDType.php
@@ -8,10 +8,6 @@ final class DrydockResourcePHIDType extends PhabricatorPHIDType {
return pht('Drydock Resource');
}
- public function getPHIDTypeApplicationClass() {
- return 'PhabricatorDrydockApplication';
- }
-
public function getTypeIcon() {
return 'fa-map';
}
@@ -20,6 +16,10 @@ final class DrydockResourcePHIDType extends PhabricatorPHIDType {
return new DrydockResource();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorDrydockApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/feed/controller/PhabricatorFeedController.php b/src/applications/feed/controller/PhabricatorFeedController.php
index ce7a9afe76..6e4d353518 100644
--- a/src/applications/feed/controller/PhabricatorFeedController.php
+++ b/src/applications/feed/controller/PhabricatorFeedController.php
@@ -2,26 +2,6 @@
abstract class PhabricatorFeedController extends PhabricatorController {
- public function buildStandardPageResponse($view, array $data) {
- $page = $this->buildStandardPageView();
-
- $page->setApplicationName(pht('Feed'));
- $page->setBaseURI('/feed/');
- $page->setTitle(idx($data, 'title'));
- $page->setGlyph("\xE2\x88\x9E");
- $page->appendChild($view);
-
- $response = new AphrontWebpageResponse();
-
- if (!empty($data['public'])) {
- $page->setFrameable(true);
- $page->setShowChrome(false);
- $response->setFrameable(true);
- }
-
- return $response->setContent($page->render());
- }
-
protected function buildSideNavView() {
$user = $this->getRequest()->getUser();
diff --git a/src/applications/files/phid/PhabricatorFileFilePHIDType.php b/src/applications/files/phid/PhabricatorFileFilePHIDType.php
index 7b74065535..c847c7f1a5 100644
--- a/src/applications/files/phid/PhabricatorFileFilePHIDType.php
+++ b/src/applications/files/phid/PhabricatorFileFilePHIDType.php
@@ -12,6 +12,10 @@ final class PhabricatorFileFilePHIDType extends PhabricatorPHIDType {
return new PhabricatorFile();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorFilesApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/files/storage/PhabricatorFile.php b/src/applications/files/storage/PhabricatorFile.php
index 4ca26fc03b..f0a5f228e3 100644
--- a/src/applications/files/storage/PhabricatorFile.php
+++ b/src/applications/files/storage/PhabricatorFile.php
@@ -557,7 +557,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
'Failed to fetch remote URI "%s" after following %s redirect(s) '.
'(%s): %s',
$uri,
- new PhutilNumber(count($redirects)),
+ phutil_count($redirects),
implode(' > ', array_keys($redirects)),
$ex->getMessage()),
$ex);
diff --git a/src/applications/fund/phid/FundBackerPHIDType.php b/src/applications/fund/phid/FundBackerPHIDType.php
index f5f1258334..3feff6364a 100644
--- a/src/applications/fund/phid/FundBackerPHIDType.php
+++ b/src/applications/fund/phid/FundBackerPHIDType.php
@@ -12,6 +12,10 @@ final class FundBackerPHIDType extends PhabricatorPHIDType {
return new FundInitiative();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorFundApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/harbormaster/conduit/HarbormasterSendMessageConduitAPIMethod.php b/src/applications/harbormaster/conduit/HarbormasterSendMessageConduitAPIMethod.php
index 3a2d808239..6d68b0a8b6 100644
--- a/src/applications/harbormaster/conduit/HarbormasterSendMessageConduitAPIMethod.php
+++ b/src/applications/harbormaster/conduit/HarbormasterSendMessageConduitAPIMethod.php
@@ -37,7 +37,7 @@ final class HarbormasterSendMessageConduitAPIMethod
$unit_spec = HarbormasterBuildUnitMessage::getParameterSpec();
foreach ($unit_spec as $key => $parameter) {
$type = idx($parameter, 'type');
- $type = str_replace('|', pht(' or '), $type);
+ $type = str_replace('|', ' '.pht('or').' ', $type);
$description = idx($parameter, 'description');
$rows[] = "| `{$key}` | //{$type}// | {$description} |";
}
@@ -61,7 +61,7 @@ final class HarbormasterSendMessageConduitAPIMethod
$lint_spec = HarbormasterBuildLintMessage::getParameterSpec();
foreach ($lint_spec as $key => $parameter) {
$type = idx($parameter, 'type');
- $type = str_replace('|', pht(' or '), $type);
+ $type = str_replace('|', ' '.pht('or').' ', $type);
$description = idx($parameter, 'description');
$rows[] = "| `{$key}` | //{$type}// | {$description} |";
}
diff --git a/src/applications/harbormaster/controller/HarbormasterBuildViewController.php b/src/applications/harbormaster/controller/HarbormasterBuildViewController.php
index 1d655bb2e0..363a05776e 100644
--- a/src/applications/harbormaster/controller/HarbormasterBuildViewController.php
+++ b/src/applications/harbormaster/controller/HarbormasterBuildViewController.php
@@ -377,7 +377,7 @@ final class HarbormasterBuildViewController
array(
pht(
'%s empty logs are hidden.',
- new PhutilNumber(count($empty_logs))),
+ phutil_count($empty_logs)),
' ',
javelin_tag(
'a',
diff --git a/src/applications/harbormaster/controller/HarbormasterPlanRunController.php b/src/applications/harbormaster/controller/HarbormasterPlanRunController.php
index 6655fd6806..fb664dc084 100644
--- a/src/applications/harbormaster/controller/HarbormasterPlanRunController.php
+++ b/src/applications/harbormaster/controller/HarbormasterPlanRunController.php
@@ -59,7 +59,7 @@ final class HarbormasterPlanRunController extends HarbormasterController {
if (!$errors) {
$buildable->save();
- $buildable->applyPlan($plan, array());
+ $buildable->applyPlan($plan, array(), $viewer->getPHID());
$buildable_uri = '/B'.$buildable->getID();
return id(new AphrontRedirectResponse())->setURI($buildable_uri);
diff --git a/src/applications/harbormaster/controller/HarbormasterStepEditController.php b/src/applications/harbormaster/controller/HarbormasterStepEditController.php
index 37bef5f411..f15a3235b9 100644
--- a/src/applications/harbormaster/controller/HarbormasterStepEditController.php
+++ b/src/applications/harbormaster/controller/HarbormasterStepEditController.php
@@ -231,7 +231,10 @@ final class HarbormasterStepEditController extends HarbormasterController {
'The following variables can be used in most fields. '.
'To reference a variable, use `%s` in a field.',
'${name}');
- $rows[] = pht('| Variable | Description |');
+ $rows[] = sprintf(
+ '| %s | %s |',
+ pht('Variable'),
+ pht('Description'));
$rows[] = '|---|---|';
foreach ($variables as $name => $description) {
$rows[] = '| `'.$name.'` | '.$description.' |';
diff --git a/src/applications/harbormaster/engine/HarbormasterBuildRequest.php b/src/applications/harbormaster/engine/HarbormasterBuildRequest.php
index 1874f08b27..71721fdaf2 100644
--- a/src/applications/harbormaster/engine/HarbormasterBuildRequest.php
+++ b/src/applications/harbormaster/engine/HarbormasterBuildRequest.php
@@ -14,6 +14,7 @@
final class HarbormasterBuildRequest extends Phobject {
private $buildPlanPHID;
+ private $initiatorPHID;
private $buildParameters = array();
public function setBuildPlanPHID($build_plan_phid) {
@@ -34,4 +35,13 @@ final class HarbormasterBuildRequest extends Phobject {
return $this->buildParameters;
}
+ public function setInitiatorPHID($phid) {
+ $this->initiatorPHID = $phid;
+ return $this;
+ }
+
+ public function getInitiatorPHID() {
+ return $this->initiatorPHID;
+ }
+
}
diff --git a/src/applications/harbormaster/engine/HarbormasterTargetEngine.php b/src/applications/harbormaster/engine/HarbormasterTargetEngine.php
index b201891b6b..d9efb8b9fd 100644
--- a/src/applications/harbormaster/engine/HarbormasterTargetEngine.php
+++ b/src/applications/harbormaster/engine/HarbormasterTargetEngine.php
@@ -6,7 +6,7 @@ final class HarbormasterTargetEngine extends Phobject {
private $object;
private $autoTargetKeys;
- public function setViewer($viewer) {
+ public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
return $this;
}
@@ -163,6 +163,10 @@ final class HarbormasterTargetEngine extends Phobject {
array $step_map) {
$viewer = $this->getViewer();
+ $initiator_phid = null;
+ if (!$viewer->isOmnipotent()) {
+ $initiator_phid = $viewer->getPHID();
+ }
$plan_map = mgroup($step_map, 'getBuildPlanPHID');
$builds = id(new HarbormasterBuildQuery())
@@ -206,7 +210,7 @@ final class HarbormasterTargetEngine extends Phobject {
// resource and "own" it, so we don't try to handle this, but may need
// to be more careful here if use of autotargets expands.
- $build = $buildable->applyPlan($plan, array());
+ $build = $buildable->applyPlan($plan, array(), $initiator_phid);
PhabricatorWorker::setRunAllTasksInProcess(false);
} catch (Exception $ex) {
PhabricatorWorker::setRunAllTasksInProcess(false);
diff --git a/src/applications/harbormaster/herald/HarbormasterRunBuildPlansHeraldAction.php b/src/applications/harbormaster/herald/HarbormasterRunBuildPlansHeraldAction.php
index db75b36d2f..76bdf9ccc3 100644
--- a/src/applications/harbormaster/herald/HarbormasterRunBuildPlansHeraldAction.php
+++ b/src/applications/harbormaster/herald/HarbormasterRunBuildPlansHeraldAction.php
@@ -16,7 +16,7 @@ final class HarbormasterRunBuildPlansHeraldAction
return ($adapter instanceof HarbormasterBuildableAdapterInterface);
}
- protected function applyBuilds(array $phids) {
+ protected function applyBuilds(array $phids, HeraldRule $rule) {
$adapter = $this->getAdapter();
$allowed_types = array(
@@ -32,7 +32,8 @@ final class HarbormasterRunBuildPlansHeraldAction
foreach ($phids as $phid) {
$request = id(new HarbormasterBuildRequest())
- ->setBuildPlanPHID($phid);
+ ->setBuildPlanPHID($phid)
+ ->setInitiatorPHID($rule->getPHID());
$adapter->queueHarbormasterBuildRequest($request);
}
@@ -54,7 +55,7 @@ final class HarbormasterRunBuildPlansHeraldAction
case self::DO_BUILD:
return pht(
'Started %s build(s): %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
}
}
@@ -68,7 +69,7 @@ final class HarbormasterRunBuildPlansHeraldAction
}
public function applyEffect($object, HeraldEffect $effect) {
- return $this->applyBuilds($effect->getTarget());
+ return $this->applyBuilds($effect->getTarget(), $effect->getRule());
}
public function getHeraldActionStandardType() {
diff --git a/src/applications/harbormaster/management/HarbormasterManagementBuildWorkflow.php b/src/applications/harbormaster/management/HarbormasterManagementBuildWorkflow.php
index 7110d98d6e..6fd3cf2ffd 100644
--- a/src/applications/harbormaster/management/HarbormasterManagementBuildWorkflow.php
+++ b/src/applications/harbormaster/management/HarbormasterManagementBuildWorkflow.php
@@ -98,7 +98,12 @@ final class HarbormasterManagementBuildWorkflow
PhabricatorWorker::setRunAllTasksInProcess(true);
}
- $buildable->applyPlan($plan, array());
+ if ($viewer->isOmnipotent()) {
+ $initiator = id(new PhabricatorHarbormasterApplication())->getPHID();
+ } else {
+ $initiator = $viewer->getPHID();
+ }
+ $buildable->applyPlan($plan, array(), $initiator);
$console->writeOut("%s\n", pht('Done.'));
diff --git a/src/applications/harbormaster/phid/HarbormasterBuildArtifactPHIDType.php b/src/applications/harbormaster/phid/HarbormasterBuildArtifactPHIDType.php
index 5c3eb992f7..29256afd96 100644
--- a/src/applications/harbormaster/phid/HarbormasterBuildArtifactPHIDType.php
+++ b/src/applications/harbormaster/phid/HarbormasterBuildArtifactPHIDType.php
@@ -12,6 +12,10 @@ final class HarbormasterBuildArtifactPHIDType extends PhabricatorPHIDType {
return new HarbormasterBuildArtifact();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorHarbormasterApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/harbormaster/phid/HarbormasterBuildLogPHIDType.php b/src/applications/harbormaster/phid/HarbormasterBuildLogPHIDType.php
index 5e2705a40a..c0fba81c43 100644
--- a/src/applications/harbormaster/phid/HarbormasterBuildLogPHIDType.php
+++ b/src/applications/harbormaster/phid/HarbormasterBuildLogPHIDType.php
@@ -12,6 +12,10 @@ final class HarbormasterBuildLogPHIDType extends PhabricatorPHIDType {
return new HarbormasterBuildLog();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorHarbormasterApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/harbormaster/phid/HarbormasterBuildPHIDType.php b/src/applications/harbormaster/phid/HarbormasterBuildPHIDType.php
index 5669df4ee9..27551f13a8 100644
--- a/src/applications/harbormaster/phid/HarbormasterBuildPHIDType.php
+++ b/src/applications/harbormaster/phid/HarbormasterBuildPHIDType.php
@@ -12,6 +12,10 @@ final class HarbormasterBuildPHIDType extends PhabricatorPHIDType {
return new HarbormasterBuild();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorHarbormasterApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/harbormaster/phid/HarbormasterBuildPlanPHIDType.php b/src/applications/harbormaster/phid/HarbormasterBuildPlanPHIDType.php
index d2a733630a..86aacfb8d3 100644
--- a/src/applications/harbormaster/phid/HarbormasterBuildPlanPHIDType.php
+++ b/src/applications/harbormaster/phid/HarbormasterBuildPlanPHIDType.php
@@ -16,6 +16,10 @@ final class HarbormasterBuildPlanPHIDType extends PhabricatorPHIDType {
return new HarbormasterBuildPlan();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorHarbormasterApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/harbormaster/phid/HarbormasterBuildStepPHIDType.php b/src/applications/harbormaster/phid/HarbormasterBuildStepPHIDType.php
index c3427fe46f..63e9bc6a12 100644
--- a/src/applications/harbormaster/phid/HarbormasterBuildStepPHIDType.php
+++ b/src/applications/harbormaster/phid/HarbormasterBuildStepPHIDType.php
@@ -12,6 +12,10 @@ final class HarbormasterBuildStepPHIDType extends PhabricatorPHIDType {
return new HarbormasterBuildStep();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorHarbormasterApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/harbormaster/phid/HarbormasterBuildTargetPHIDType.php b/src/applications/harbormaster/phid/HarbormasterBuildTargetPHIDType.php
index e16db13ccb..b20d6dc0a4 100644
--- a/src/applications/harbormaster/phid/HarbormasterBuildTargetPHIDType.php
+++ b/src/applications/harbormaster/phid/HarbormasterBuildTargetPHIDType.php
@@ -12,6 +12,10 @@ final class HarbormasterBuildTargetPHIDType extends PhabricatorPHIDType {
return new HarbormasterBuildTarget();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorHarbormasterApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/harbormaster/phid/HarbormasterBuildablePHIDType.php b/src/applications/harbormaster/phid/HarbormasterBuildablePHIDType.php
index 8c854efdf6..c6ccabf515 100644
--- a/src/applications/harbormaster/phid/HarbormasterBuildablePHIDType.php
+++ b/src/applications/harbormaster/phid/HarbormasterBuildablePHIDType.php
@@ -12,6 +12,10 @@ final class HarbormasterBuildablePHIDType extends PhabricatorPHIDType {
return new HarbormasterBuildable();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorHarbormasterApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/harbormaster/storage/HarbormasterBuildable.php b/src/applications/harbormaster/storage/HarbormasterBuildable.php
index e74471e879..3a7df73f52 100644
--- a/src/applications/harbormaster/storage/HarbormasterBuildable.php
+++ b/src/applications/harbormaster/storage/HarbormasterBuildable.php
@@ -154,11 +154,14 @@ final class HarbormasterBuildable extends HarbormasterDAO
}
$parameters = $request->getBuildParameters();
- $buildable->applyPlan($plan, $parameters);
+ $buildable->applyPlan($plan, $parameters, $request->getInitiatorPHID());
}
}
- public function applyPlan(HarbormasterBuildPlan $plan, array $parameters) {
+ public function applyPlan(
+ HarbormasterBuildPlan $plan,
+ array $parameters,
+ $initiator_phid) {
$viewer = PhabricatorUser::getOmnipotentUser();
$build = HarbormasterBuild::initializeNewBuild($viewer)
@@ -166,6 +169,9 @@ final class HarbormasterBuildable extends HarbormasterDAO
->setBuildPlanPHID($plan->getPHID())
->setBuildParameters($parameters)
->setBuildStatus(HarbormasterBuild::STATUS_PENDING);
+ if ($initiator_phid) {
+ $build->setInitiatorPHID($initiator_phid);
+ }
$auto_key = $plan->getPlanAutoKey();
if ($auto_key) {
diff --git a/src/applications/harbormaster/storage/build/HarbormasterBuild.php b/src/applications/harbormaster/storage/build/HarbormasterBuild.php
index 154681d93f..c96d0c2710 100644
--- a/src/applications/harbormaster/storage/build/HarbormasterBuild.php
+++ b/src/applications/harbormaster/storage/build/HarbormasterBuild.php
@@ -10,6 +10,7 @@ final class HarbormasterBuild extends HarbormasterDAO
protected $buildStatus;
protected $buildGeneration;
protected $buildParameters = array();
+ protected $initiatorPHID;
protected $planAutoKey;
private $buildable = self::ATTACHABLE;
@@ -164,6 +165,7 @@ final class HarbormasterBuild extends HarbormasterDAO
'buildStatus' => 'text32',
'buildGeneration' => 'uint32',
'planAutoKey' => 'text32?',
+ 'initiatorPHID' => 'phid?',
),
self::CONFIG_KEY_SCHEMA => array(
'key_buildable' => array(
@@ -260,6 +262,7 @@ final class HarbormasterBuild extends HarbormasterDAO
'repository.uri' => null,
'step.timestamp' => null,
'build.id' => null,
+ 'initiator.phid' => null,
);
foreach ($this->getBuildParameters() as $key => $value) {
@@ -275,6 +278,7 @@ final class HarbormasterBuild extends HarbormasterDAO
$results['step.timestamp'] = time();
$results['build.id'] = $this->getID();
+ $results['initiator.phid'] = $this->getInitiatorPHID();
return $results;
}
@@ -289,6 +293,9 @@ final class HarbormasterBuild extends HarbormasterDAO
'step.timestamp' => pht('The current UNIX timestamp.'),
'build.id' => pht('The ID of the current build.'),
'target.phid' => pht('The PHID of the current build target.'),
+ 'initiator.phid' => pht(
+ 'The PHID of the user or Object that initiated the build, '.
+ 'if applicable.'),
);
foreach ($objects as $object) {
diff --git a/src/applications/help/controller/PhabricatorHelpController.php b/src/applications/help/controller/PhabricatorHelpController.php
index 247175c3ec..d51618b545 100644
--- a/src/applications/help/controller/PhabricatorHelpController.php
+++ b/src/applications/help/controller/PhabricatorHelpController.php
@@ -1,18 +1,3 @@
buildStandardPageView();
-
- $page->setApplicationName(pht('Help'));
- $page->setBaseURI('/help/');
- $page->setTitle(idx($data, 'title'));
- $page->setGlyph('?');
- $page->appendChild($view);
-
- $response = new AphrontWebpageResponse();
- return $response->setContent($page->render());
- }
-
-}
+abstract class PhabricatorHelpController extends PhabricatorController {}
diff --git a/src/applications/herald/action/HeraldAction.php b/src/applications/herald/action/HeraldAction.php
index f4217cd4db..6b076fbddf 100644
--- a/src/applications/herald/action/HeraldAction.php
+++ b/src/applications/herald/action/HeraldAction.php
@@ -346,22 +346,22 @@ abstract class HeraldAction extends Phobject {
case self::DO_STANDARD_NO_EFFECT:
return pht(
'This action has no effect on %s target(s): %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
case self::DO_STANDARD_INVALID:
return pht(
'%s target(s) are invalid or of the wrong type: %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
case self::DO_STANDARD_UNLOADABLE:
return pht(
'%s target(s) could not be loaded: %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
case self::DO_STANDARD_PERMISSION:
return pht(
'%s target(s) do not have permission to see this object: %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
case self::DO_STANDARD_INVALID_ACTION:
return pht(
diff --git a/src/applications/herald/controller/HeraldController.php b/src/applications/herald/controller/HeraldController.php
index b363232ca5..b3ba2f17c3 100644
--- a/src/applications/herald/controller/HeraldController.php
+++ b/src/applications/herald/controller/HeraldController.php
@@ -2,20 +2,6 @@
abstract class HeraldController extends PhabricatorController {
- public function buildStandardPageResponse($view, array $data) {
- $page = $this->buildStandardPageView();
-
- $page->setApplicationName(pht('Herald'));
- $page->setBaseURI('/herald/');
- $page->setTitle(idx($data, 'title'));
- $page->setGlyph("\xE2\x98\xBF");
-
- $page->appendChild($view);
-
- $response = new AphrontWebpageResponse();
- return $response->setContent($page->render());
- }
-
public function buildApplicationMenu() {
return $this->buildSideNavView(true)->getMenu();
}
diff --git a/src/applications/herald/phid/HeraldRulePHIDType.php b/src/applications/herald/phid/HeraldRulePHIDType.php
index 4820eee62b..f8d5c25db4 100644
--- a/src/applications/herald/phid/HeraldRulePHIDType.php
+++ b/src/applications/herald/phid/HeraldRulePHIDType.php
@@ -12,6 +12,10 @@ final class HeraldRulePHIDType extends PhabricatorPHIDType {
return new HeraldRule();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorHeraldApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/home/controller/PhabricatorHomeController.php b/src/applications/home/controller/PhabricatorHomeController.php
index 024807b74b..334a34e99b 100644
--- a/src/applications/home/controller/PhabricatorHomeController.php
+++ b/src/applications/home/controller/PhabricatorHomeController.php
@@ -2,19 +2,6 @@
abstract class PhabricatorHomeController extends PhabricatorController {
- public function buildStandardPageResponse($view, array $data) {
- $page = $this->buildStandardPageView();
-
- $page->setBaseURI('/');
- $page->setTitle(idx($data, 'title'));
-
- $page->setGlyph("\xE2\x9A\x92");
- $page->appendChild($view);
-
- $response = new AphrontWebpageResponse();
- return $response->setContent($page->render());
- }
-
public function buildNav() {
$user = $this->getRequest()->getUser();
diff --git a/src/applications/legalpad/controller/LegalpadDocumentSignController.php b/src/applications/legalpad/controller/LegalpadDocumentSignController.php
index 40697eef30..b9c43e377b 100644
--- a/src/applications/legalpad/controller/LegalpadDocumentSignController.php
+++ b/src/applications/legalpad/controller/LegalpadDocumentSignController.php
@@ -253,7 +253,7 @@ final class LegalpadDocumentSignController extends LegalpadController {
->setIcon(
id(new PHUIIconView())
->setIconFont('fa-pencil'))
- ->setText(pht('Manage Document'))
+ ->setText(pht('Manage'))
->setHref($manage_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
@@ -278,7 +278,7 @@ final class LegalpadDocumentSignController extends LegalpadController {
$preamble_box->addPropertyList($preamble);
}
- $content = id(new PHUIDocumentView())
+ $content = id(new PHUIDocumentViewPro())
->addClass('legalpad')
->setHeader($header)
->appendChild(
@@ -288,6 +288,7 @@ final class LegalpadDocumentSignController extends LegalpadController {
$document_markup,
));
+ $signature_box = null;
if (!$has_signed) {
$error_view = null;
if ($errors) {
@@ -301,23 +302,21 @@ final class LegalpadDocumentSignController extends LegalpadController {
$field_errors);
switch ($document->getSignatureType()) {
- case LegalpadDocument::SIGNATURE_TYPE_NONE:
- $subheader = null;
+ default:
break;
case LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL:
case LegalpadDocument::SIGNATURE_TYPE_CORPORATION:
- $subheader = id(new PHUIHeaderView())
- ->setHeader(pht('Agree and Sign Document'))
- ->setBleedHeader(true);
+ $box = id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Agree and Sign Document'))
+ ->setForm($signature_form);
+ if ($error_view) {
+ $box->setInfoView($error_view);
+ }
+ $signature_box = phutil_tag_div('phui-document-view-pro-box', $box);
break;
}
- $content->appendChild(
- array(
- $subheader,
- $error_view,
- $signature_form,
- ));
+
}
$crumbs = $this->buildApplicationCrumbs();
@@ -328,9 +327,11 @@ final class LegalpadDocumentSignController extends LegalpadController {
array(
$crumbs,
$content,
+ $signature_box,
),
array(
'title' => $title,
+ 'class' => 'pro-white-background',
'pageObjects' => array($document->getPHID()),
));
}
diff --git a/src/applications/legalpad/herald/LegalpadRequireSignatureHeraldAction.php b/src/applications/legalpad/herald/LegalpadRequireSignatureHeraldAction.php
index 22d41449ad..7ff69d37d5 100644
--- a/src/applications/legalpad/herald/LegalpadRequireSignatureHeraldAction.php
+++ b/src/applications/legalpad/herald/LegalpadRequireSignatureHeraldAction.php
@@ -95,12 +95,12 @@ final class LegalpadRequireSignatureHeraldAction
case self::DO_SIGNED:
return pht(
'%s document(s) are already signed: %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
case self::DO_REQUIRED:
return pht(
'Required %s signature(s): %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
}
}
diff --git a/src/applications/legalpad/phid/PhabricatorLegalpadDocumentPHIDType.php b/src/applications/legalpad/phid/PhabricatorLegalpadDocumentPHIDType.php
index 5b1a4a9833..39c744f271 100644
--- a/src/applications/legalpad/phid/PhabricatorLegalpadDocumentPHIDType.php
+++ b/src/applications/legalpad/phid/PhabricatorLegalpadDocumentPHIDType.php
@@ -16,6 +16,10 @@ final class PhabricatorLegalpadDocumentPHIDType extends PhabricatorPHIDType {
return new LegalpadDocument();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorLegalpadApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/maniphest/phid/ManiphestTaskPHIDType.php b/src/applications/maniphest/phid/ManiphestTaskPHIDType.php
index 719b4a8446..3b3c4a203f 100644
--- a/src/applications/maniphest/phid/ManiphestTaskPHIDType.php
+++ b/src/applications/maniphest/phid/ManiphestTaskPHIDType.php
@@ -8,14 +8,14 @@ final class ManiphestTaskPHIDType extends PhabricatorPHIDType {
return pht('Maniphest Task');
}
- public function getPHIDTypeApplicationClass() {
- return 'PhabricatorManiphestApplication';
- }
-
public function newObject() {
return new ManiphestTask();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorManiphestApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/maniphest/storage/ManiphestTransaction.php b/src/applications/maniphest/storage/ManiphestTransaction.php
index a05cf1ab13..0456673a10 100644
--- a/src/applications/maniphest/storage/ManiphestTransaction.php
+++ b/src/applications/maniphest/storage/ManiphestTransaction.php
@@ -546,23 +546,23 @@ final class ManiphestTransaction
$removed = array_diff($old, $new);
if ($added && !$removed) {
return pht(
- '%s attached %d file(s): %s.',
+ '%s attached %s file(s): %s.',
$this->renderHandleLink($author_phid),
- count($added),
+ phutil_count($added),
$this->renderHandleList($added));
} else if ($removed && !$added) {
return pht(
- '%s detached %d file(s): %s.',
+ '%s detached %s file(s): %s.',
$this->renderHandleLink($author_phid),
- count($removed),
+ phutil_count($removed),
$this->renderHandleList($removed));
} else {
return pht(
- '%s changed file(s), attached %d: %s; detached %d: %s.',
+ '%s changed file(s), attached %s: %s; detached %s: %s.',
$this->renderHandleLink($author_phid),
- count($added),
+ phutil_count($added),
$this->renderHandleList($added),
- count($removed),
+ phutil_count($removed),
$this->renderHandleList($removed));
}
@@ -585,9 +585,9 @@ final class ManiphestTransaction
case self::TYPE_MERGED_FROM:
return pht(
- '%s merged %d task(s): %s.',
+ '%s merged %s task(s): %s.',
$this->renderHandleLink($author_phid),
- count($new),
+ phutil_count($new),
$this->renderHandleList($new));
break;
diff --git a/src/applications/maniphest/view/ManiphestTaskResultListView.php b/src/applications/maniphest/view/ManiphestTaskResultListView.php
index cd05d7f7f7..52f4a3b2d6 100644
--- a/src/applications/maniphest/view/ManiphestTaskResultListView.php
+++ b/src/applications/maniphest/view/ManiphestTaskResultListView.php
@@ -82,7 +82,7 @@ final class ManiphestTaskResultListView extends ManiphestView {
$header = id(new PHUIHeaderView())
->addSigil('task-group')
->setMetadata(array('priority' => head($list)->getPriority()))
- ->setHeader(pht('%s (%s)', $group, new PhutilNumber(count($list))));
+ ->setHeader(pht('%s (%s)', $group, phutil_count($list)));
$lists[] = id(new PHUIObjectBoxView())
->setHeader($header)
diff --git a/src/applications/meta/controller/PhabricatorApplicationEmailCommandsController.php b/src/applications/meta/controller/PhabricatorApplicationEmailCommandsController.php
index 23ac83ac92..63f2d256e1 100644
--- a/src/applications/meta/controller/PhabricatorApplicationEmailCommandsController.php
+++ b/src/applications/meta/controller/PhabricatorApplicationEmailCommandsController.php
@@ -115,6 +115,7 @@ final class PhabricatorApplicationEmailCommandsController
$crumbs = $this->buildApplicationCrumbs();
$this->addApplicationCrumb($crumbs, $selected);
$crumbs->addTextCrumb($title);
+ $crumbs->setBorder(true);
$content_box = PhabricatorMarkupEngine::renderOneObject(
id(new PhabricatorMarkupOneOff())->setContent($content),
@@ -134,7 +135,7 @@ final class PhabricatorApplicationEmailCommandsController
$header = id(new PHUIHeaderView())
->setHeader($title);
- $document = id(new PHUIDocumentView())
+ $document = id(new PHUIDocumentViewPro())
->setHeader($header)
->appendChild($info_view)
->appendChild($content_box);
@@ -146,6 +147,7 @@ final class PhabricatorApplicationEmailCommandsController
),
array(
'title' => $title,
+ 'class' => 'pro-white-background',
));
}
diff --git a/src/applications/meta/phid/PhabricatorApplicationApplicationPHIDType.php b/src/applications/meta/phid/PhabricatorApplicationApplicationPHIDType.php
index aa2b21b967..d0b1f763a4 100644
--- a/src/applications/meta/phid/PhabricatorApplicationApplicationPHIDType.php
+++ b/src/applications/meta/phid/PhabricatorApplicationApplicationPHIDType.php
@@ -17,6 +17,10 @@ final class PhabricatorApplicationApplicationPHIDType
return null;
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorApplicationsApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/metamta/herald/PhabricatorMetaMTAEmailHeraldAction.php b/src/applications/metamta/herald/PhabricatorMetaMTAEmailHeraldAction.php
index ec7036ebe0..2b29fe2443 100644
--- a/src/applications/metamta/herald/PhabricatorMetaMTAEmailHeraldAction.php
+++ b/src/applications/metamta/herald/PhabricatorMetaMTAEmailHeraldAction.php
@@ -75,13 +75,13 @@ abstract class PhabricatorMetaMTAEmailHeraldAction
case self::DO_SEND:
return pht(
'Queued email to be delivered to %s target(s): %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
case self::DO_FORCE:
return pht(
'Queued email to be delivered to %s target(s), ignoring their '.
'notification preferences: %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
}
}
diff --git a/src/applications/metamta/phid/PhabricatorMetaMTAMailPHIDType.php b/src/applications/metamta/phid/PhabricatorMetaMTAMailPHIDType.php
index 7117b50f8e..1436038fae 100644
--- a/src/applications/metamta/phid/PhabricatorMetaMTAMailPHIDType.php
+++ b/src/applications/metamta/phid/PhabricatorMetaMTAMailPHIDType.php
@@ -8,14 +8,14 @@ final class PhabricatorMetaMTAMailPHIDType extends PhabricatorPHIDType {
return pht('MetaMTA Mail');
}
- public function getPHIDTypeApplicationClass() {
- return 'PhabricatorMetaMTAApplication';
- }
-
public function newObject() {
return new PhabricatorMetaMTAMail();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorMetaMTAApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/multimeter/controller/MultimeterSampleController.php b/src/applications/multimeter/controller/MultimeterSampleController.php
index a62d10ef30..f9a36b37d1 100644
--- a/src/applications/multimeter/controller/MultimeterSampleController.php
+++ b/src/applications/multimeter/controller/MultimeterSampleController.php
@@ -90,7 +90,7 @@ final class MultimeterSampleController extends MultimeterController {
$events_col = $this->renderGroupingLink(
$group,
'id',
- pht('%s Events', new PhutilNumber($row['N'])));
+ pht('%s Event(s)', new PhutilNumber($row['N'])));
}
if (isset($group['request'])) {
diff --git a/src/applications/notification/controller/PhabricatorNotificationController.php b/src/applications/notification/controller/PhabricatorNotificationController.php
index 576625eab8..11e60c17f8 100644
--- a/src/applications/notification/controller/PhabricatorNotificationController.php
+++ b/src/applications/notification/controller/PhabricatorNotificationController.php
@@ -1,21 +1,4 @@
buildStandardPageView();
-
- $page->setApplicationName(pht('Notification'));
- $page->setBaseURI('/notification/');
- $page->setTitle(idx($data, 'title'));
- $page->setGlyph('!');
- $page->appendChild($view);
-
- $response = new AphrontWebpageResponse();
- return $response->setContent($page->render());
-
- }
-
-}
+ extends PhabricatorController {}
diff --git a/src/applications/nuance/phid/NuanceItemPHIDType.php b/src/applications/nuance/phid/NuanceItemPHIDType.php
index e1068cc50d..f401c63594 100644
--- a/src/applications/nuance/phid/NuanceItemPHIDType.php
+++ b/src/applications/nuance/phid/NuanceItemPHIDType.php
@@ -12,6 +12,10 @@ final class NuanceItemPHIDType extends PhabricatorPHIDType {
return new NuanceItem();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorNuanceApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/nuance/phid/NuanceQueuePHIDType.php b/src/applications/nuance/phid/NuanceQueuePHIDType.php
index 13bcfa5d20..b51812320d 100644
--- a/src/applications/nuance/phid/NuanceQueuePHIDType.php
+++ b/src/applications/nuance/phid/NuanceQueuePHIDType.php
@@ -12,6 +12,10 @@ final class NuanceQueuePHIDType extends PhabricatorPHIDType {
return new NuanceQueue();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorNuanceApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/nuance/phid/NuanceRequestorPHIDType.php b/src/applications/nuance/phid/NuanceRequestorPHIDType.php
index 2cf06bbb10..a2442d3b48 100644
--- a/src/applications/nuance/phid/NuanceRequestorPHIDType.php
+++ b/src/applications/nuance/phid/NuanceRequestorPHIDType.php
@@ -12,6 +12,10 @@ final class NuanceRequestorPHIDType extends PhabricatorPHIDType {
return new NuanceRequestor();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorNuanceApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/nuance/phid/NuanceSourcePHIDType.php b/src/applications/nuance/phid/NuanceSourcePHIDType.php
index d259fe48a9..774939bf29 100644
--- a/src/applications/nuance/phid/NuanceSourcePHIDType.php
+++ b/src/applications/nuance/phid/NuanceSourcePHIDType.php
@@ -12,6 +12,10 @@ final class NuanceSourcePHIDType extends PhabricatorPHIDType {
return new NuanceSource();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorNuanceApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/oauthserver/phid/PhabricatorOAuthServerClientAuthorizationPHIDType.php b/src/applications/oauthserver/phid/PhabricatorOAuthServerClientAuthorizationPHIDType.php
index e3ff50a6f7..b2fc1554fd 100644
--- a/src/applications/oauthserver/phid/PhabricatorOAuthServerClientAuthorizationPHIDType.php
+++ b/src/applications/oauthserver/phid/PhabricatorOAuthServerClientAuthorizationPHIDType.php
@@ -13,6 +13,10 @@ final class PhabricatorOAuthServerClientAuthorizationPHIDType
return new PhabricatorOAuthClientAuthorization();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorOAuthServerApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/oauthserver/phid/PhabricatorOAuthServerClientPHIDType.php b/src/applications/oauthserver/phid/PhabricatorOAuthServerClientPHIDType.php
index 81b8fdacde..a4d8834b96 100644
--- a/src/applications/oauthserver/phid/PhabricatorOAuthServerClientPHIDType.php
+++ b/src/applications/oauthserver/phid/PhabricatorOAuthServerClientPHIDType.php
@@ -12,6 +12,10 @@ final class PhabricatorOAuthServerClientPHIDType extends PhabricatorPHIDType {
return new PhabricatorOAuthServerClient();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorOAuthServerApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/owners/phid/PhabricatorOwnersPackagePHIDType.php b/src/applications/owners/phid/PhabricatorOwnersPackagePHIDType.php
index b2492b0bef..fa667d4dcb 100644
--- a/src/applications/owners/phid/PhabricatorOwnersPackagePHIDType.php
+++ b/src/applications/owners/phid/PhabricatorOwnersPackagePHIDType.php
@@ -16,6 +16,10 @@ final class PhabricatorOwnersPackagePHIDType extends PhabricatorPHIDType {
return new PhabricatorOwnersPackage();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorOwnersApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/paste/application/PhabricatorPasteApplication.php b/src/applications/paste/application/PhabricatorPasteApplication.php
index 7fe3ec41e7..e066d4cd9d 100644
--- a/src/applications/paste/application/PhabricatorPasteApplication.php
+++ b/src/applications/paste/application/PhabricatorPasteApplication.php
@@ -39,7 +39,7 @@ final class PhabricatorPasteApplication extends PhabricatorApplication {
'/paste/' => array(
'(query/(?P[^/]+)/)?' => 'PhabricatorPasteListController',
'create/' => 'PhabricatorPasteEditController',
- 'edit/(?P[1-9]\d*)/' => 'PhabricatorPasteEditController',
+ $this->getEditRoutePattern('edit/') => 'PhabricatorPasteEditController',
'raw/(?P[1-9]\d*)/' => 'PhabricatorPasteRawController',
'comment/(?P[1-9]\d*)/' => 'PhabricatorPasteCommentController',
),
diff --git a/src/applications/paste/conduit/PasteCreateConduitAPIMethod.php b/src/applications/paste/conduit/PasteCreateConduitAPIMethod.php
index 379f5b6e8d..d5ce021f13 100644
--- a/src/applications/paste/conduit/PasteCreateConduitAPIMethod.php
+++ b/src/applications/paste/conduit/PasteCreateConduitAPIMethod.php
@@ -44,16 +44,11 @@ final class PasteCreateConduitAPIMethod extends PasteConduitAPIMethod {
$paste = PhabricatorPaste::initializeNewPaste($viewer);
- $file = PhabricatorPasteEditor::initializeFileForPaste(
- $viewer,
- $title,
- $content);
-
$xactions = array();
$xactions[] = id(new PhabricatorPasteTransaction())
->setTransactionType(PhabricatorPasteTransaction::TYPE_CONTENT)
- ->setNewValue($file->getPHID());
+ ->setNewValue($content);
$xactions[] = id(new PhabricatorPasteTransaction())
->setTransactionType(PhabricatorPasteTransaction::TYPE_TITLE)
diff --git a/src/applications/paste/conduit/PasteEditConduitAPIMethod.php b/src/applications/paste/conduit/PasteEditConduitAPIMethod.php
new file mode 100644
index 0000000000..c02fb940e8
--- /dev/null
+++ b/src/applications/paste/conduit/PasteEditConduitAPIMethod.php
@@ -0,0 +1,19 @@
+getRequest()->getUser();
-
- $nav = new AphrontSideNavFilterView();
- $nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
-
- if ($for_app) {
- $nav->addFilter('create', pht('Create Paste'));
- }
-
- id(new PhabricatorPasteSearchEngine())
- ->setViewer($user)
- ->addNavigationItems($nav->getMenu());
-
- $nav->selectFilter(null);
-
- return $nav;
- }
-
public function buildApplicationMenu() {
- return $this->buildSideNavView(true)->getMenu();
- }
-
- protected function buildApplicationCrumbs() {
- $crumbs = parent::buildApplicationCrumbs();
-
- $crumbs->addAction(
- id(new PHUIListItemView())
- ->setName(pht('Create Paste'))
- ->setHref($this->getApplicationURI('create/'))
- ->setIcon('fa-plus-square'));
-
- return $crumbs;
+ return $this->newApplicationMenu()
+ ->setSearchEngine(new PhabricatorPasteSearchEngine());
}
public function buildSourceCodeView(
diff --git a/src/applications/paste/controller/PhabricatorPasteEditController.php b/src/applications/paste/controller/PhabricatorPasteEditController.php
index 19b394c18a..c9ee5a289e 100644
--- a/src/applications/paste/controller/PhabricatorPasteEditController.php
+++ b/src/applications/paste/controller/PhabricatorPasteEditController.php
@@ -3,248 +3,9 @@
final class PhabricatorPasteEditController extends PhabricatorPasteController {
public function handleRequest(AphrontRequest $request) {
- $viewer = $request->getViewer();
- $id = $request->getURIData('id');
-
- $parent = null;
- $parent_id = null;
- if (!$id) {
- $is_create = true;
-
- $paste = PhabricatorPaste::initializeNewPaste($viewer);
-
- $parent_id = $request->getStr('parent');
- if ($parent_id) {
- // NOTE: If the Paste is forked from a paste which the user no longer
- // has permission to see, we still let them edit it.
- $parent = id(new PhabricatorPasteQuery())
- ->setViewer($viewer)
- ->withIDs(array($parent_id))
- ->needContent(true)
- ->needRawContent(true)
- ->execute();
- $parent = head($parent);
-
- if ($parent) {
- $paste->setParentPHID($parent->getPHID());
- $paste->setViewPolicy($parent->getViewPolicy());
- }
- }
-
- $paste->setAuthorPHID($viewer->getPHID());
- $paste->attachRawContent('');
- } else {
- $is_create = false;
-
- $paste = id(new PhabricatorPasteQuery())
- ->setViewer($viewer)
- ->requireCapabilities(
- array(
- PhabricatorPolicyCapability::CAN_VIEW,
- PhabricatorPolicyCapability::CAN_EDIT,
- ))
- ->withIDs(array($id))
- ->needRawContent(true)
- ->executeOne();
- if (!$paste) {
- return new Aphront404Response();
- }
- }
-
- $v_space = $paste->getSpacePHID();
- if ($is_create && $parent) {
- $v_title = pht('Fork of %s', $parent->getFullName());
- $v_language = $parent->getLanguage();
- $v_text = $parent->getRawContent();
- $v_space = $parent->getSpacePHID();
- } else {
- $v_title = $paste->getTitle();
- $v_language = $paste->getLanguage();
- $v_text = $paste->getRawContent();
- }
- $v_view_policy = $paste->getViewPolicy();
- $v_edit_policy = $paste->getEditPolicy();
- $v_status = $paste->getStatus();
-
- if ($is_create) {
- $v_projects = array();
- } else {
- $v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs(
- $paste->getPHID(),
- PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
- $v_projects = array_reverse($v_projects);
- }
-
- $validation_exception = null;
- if ($request->isFormPost()) {
- $xactions = array();
-
- $v_text = $request->getStr('text');
- $v_title = $request->getStr('title');
- $v_language = $request->getStr('language');
- $v_view_policy = $request->getStr('can_view');
- $v_edit_policy = $request->getStr('can_edit');
- $v_projects = $request->getArr('projects');
- $v_space = $request->getStr('spacePHID');
- $v_status = $request->getStr('status');
-
- // NOTE: The author is the only editor and can always view the paste,
- // so it's impossible for them to choose an invalid policy.
-
- if ($is_create || ($v_text !== $paste->getRawContent())) {
- $file = PhabricatorPasteEditor::initializeFileForPaste(
- $viewer,
- $v_title,
- $v_text);
-
- $xactions[] = id(new PhabricatorPasteTransaction())
- ->setTransactionType(PhabricatorPasteTransaction::TYPE_CONTENT)
- ->setNewValue($file->getPHID());
- }
-
- $xactions[] = id(new PhabricatorPasteTransaction())
- ->setTransactionType(PhabricatorPasteTransaction::TYPE_TITLE)
- ->setNewValue($v_title);
- $xactions[] = id(new PhabricatorPasteTransaction())
- ->setTransactionType(PhabricatorPasteTransaction::TYPE_LANGUAGE)
- ->setNewValue($v_language);
- $xactions[] = id(new PhabricatorPasteTransaction())
- ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
- ->setNewValue($v_view_policy);
- $xactions[] = id(new PhabricatorPasteTransaction())
- ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)
- ->setNewValue($v_edit_policy);
- $xactions[] = id(new PhabricatorPasteTransaction())
- ->setTransactionType(PhabricatorTransactions::TYPE_SPACE)
- ->setNewValue($v_space);
- $xactions[] = id(new PhabricatorPasteTransaction())
- ->setTransactionType(PhabricatorPasteTransaction::TYPE_STATUS)
- ->setNewValue($v_status);
-
- $proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
- $xactions[] = id(new PhabricatorPasteTransaction())
- ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
- ->setMetadataValue('edge:type', $proj_edge_type)
- ->setNewValue(array('=' => array_fuse($v_projects)));
-
- $editor = id(new PhabricatorPasteEditor())
- ->setActor($viewer)
- ->setContentSourceFromRequest($request)
- ->setContinueOnNoEffect(true);
-
- try {
- $xactions = $editor->applyTransactions($paste, $xactions);
- return id(new AphrontRedirectResponse())->setURI($paste->getURI());
- } catch (PhabricatorApplicationTransactionValidationException $ex) {
- $validation_exception = $ex;
- }
- }
-
- $form = new AphrontFormView();
-
- $langs = array(
- '' => pht('(Detect From Filename in Title)'),
- ) + PhabricatorEnv::getEnvConfig('pygments.dropdown-choices');
-
- $form
- ->setUser($viewer)
- ->addHiddenInput('parent', $parent_id)
- ->appendChild(
- id(new AphrontFormTextControl())
- ->setLabel(pht('Title'))
- ->setValue($v_title)
- ->setName('title'))
- ->appendChild(
- id(new AphrontFormSelectControl())
- ->setLabel(pht('Language'))
- ->setName('language')
- ->setValue($v_language)
- ->setOptions($langs));
-
- $policies = id(new PhabricatorPolicyQuery())
- ->setViewer($viewer)
- ->setObject($paste)
- ->execute();
-
- $form->appendChild(
- id(new AphrontFormPolicyControl())
- ->setUser($viewer)
- ->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
- ->setPolicyObject($paste)
- ->setPolicies($policies)
- ->setValue($v_view_policy)
- ->setSpacePHID($v_space)
- ->setName('can_view'));
-
- $form->appendChild(
- id(new AphrontFormPolicyControl())
- ->setUser($viewer)
- ->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
- ->setPolicyObject($paste)
- ->setPolicies($policies)
- ->setValue($v_edit_policy)
- ->setName('can_edit'));
-
- $form->appendChild(
- id(new AphrontFormSelectControl())
- ->setLabel(pht('Status'))
- ->setName('status')
- ->setValue($v_status)
- ->setOptions($paste->getStatusNameMap()));
-
- $form->appendControl(
- id(new AphrontFormTokenizerControl())
- ->setLabel(pht('Projects'))
- ->setName('projects')
- ->setValue($v_projects)
- ->setDatasource(new PhabricatorProjectDatasource()));
-
- $form
- ->appendChild(
- id(new AphrontFormTextAreaControl())
- ->setLabel(pht('Text'))
- ->setValue($v_text)
- ->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
- ->setCustomClass('PhabricatorMonospaced')
- ->setName('text'));
-
- $submit = new AphrontFormSubmitControl();
-
- if (!$is_create) {
- $submit->addCancelButton($paste->getURI());
- $submit->setValue(pht('Save Paste'));
- $title = pht('Edit %s', $paste->getFullName());
- $short = pht('Edit');
- } else {
- $submit->setValue(pht('Create Paste'));
- $title = pht('Create New Paste');
- $short = pht('Create');
- }
-
- $form->appendChild($submit);
-
- $form_box = id(new PHUIObjectBoxView())
- ->setHeaderText($title)
- ->setForm($form);
-
- if ($validation_exception) {
- $form_box->setValidationException($validation_exception);
- }
-
- $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView());
- if (!$is_create) {
- $crumbs->addTextCrumb('P'.$paste->getID(), '/P'.$paste->getID());
- }
- $crumbs->addTextCrumb($short);
-
- return $this->buildApplicationPage(
- array(
- $crumbs,
- $form_box,
- ),
- array(
- 'title' => $title,
- ));
+ return id(new PhabricatorPasteEditEngine())
+ ->setController($this)
+ ->buildResponse();
}
}
diff --git a/src/applications/paste/controller/PhabricatorPasteListController.php b/src/applications/paste/controller/PhabricatorPasteListController.php
index 2092443ffc..e867b4e773 100644
--- a/src/applications/paste/controller/PhabricatorPasteListController.php
+++ b/src/applications/paste/controller/PhabricatorPasteListController.php
@@ -7,15 +7,21 @@ final class PhabricatorPasteListController extends PhabricatorPasteController {
}
public function handleRequest(AphrontRequest $request) {
- $querykey = $request->getURIData('queryKey');
-
- $controller = id(new PhabricatorApplicationSearchController())
- ->setQueryKey($querykey)
- ->setSearchEngine(new PhabricatorPasteSearchEngine())
- ->setNavigation($this->buildSideNavView());
-
- return $this->delegateToController($controller);
+ return id(new PhabricatorPasteSearchEngine())
+ ->setController($this)
+ ->buildResponse();
}
+ protected function buildApplicationCrumbs() {
+ $crumbs = parent::buildApplicationCrumbs();
+
+ $crumbs->addAction(
+ id(new PHUIListItemView())
+ ->setName(pht('Create Paste'))
+ ->setHref($this->getApplicationURI('edit/'))
+ ->setIcon('fa-plus-square'));
+
+ return $crumbs;
+ }
}
diff --git a/src/applications/paste/controller/PhabricatorPasteViewController.php b/src/applications/paste/controller/PhabricatorPasteViewController.php
index 46239e7fca..43a7058f59 100644
--- a/src/applications/paste/controller/PhabricatorPasteViewController.php
+++ b/src/applications/paste/controller/PhabricatorPasteViewController.php
@@ -66,7 +66,7 @@ final class PhabricatorPasteViewController extends PhabricatorPasteController {
),
$source_code);
- $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView())
+ $crumbs = $this->buildApplicationCrumbs()
->addTextCrumb('P'.$paste->getID(), '/P'.$paste->getID());
$timeline = $this->buildTransactionTimeline(
@@ -89,18 +89,20 @@ final class PhabricatorPasteViewController extends PhabricatorPasteController {
->setAction($this->getApplicationURI('/comment/'.$paste->getID().'/'))
->setSubmitButtonName(pht('Add Comment'));
- return $this->buildApplicationPage(
- array(
- $crumbs,
- $object_box,
- $source_code,
- $timeline,
- $add_comment_form,
- ),
- array(
- 'title' => $paste->getFullName(),
- 'pageObjects' => array($paste->getPHID()),
- ));
+ return $this->newPage()
+ ->setTitle($paste->getFullName())
+ ->setCrumbs($crumbs)
+ ->setPageObjectPHIDs(
+ array(
+ $paste->getPHID(),
+ ))
+ ->appendChild(
+ array(
+ $object_box,
+ $source_code,
+ $timeline,
+ $add_comment_form,
+ ));
}
private function buildHeaderView(PhabricatorPaste $paste) {
@@ -135,9 +137,7 @@ final class PhabricatorPasteViewController extends PhabricatorPasteController {
$paste,
PhabricatorPolicyCapability::CAN_EDIT);
- $can_fork = $viewer->isLoggedIn();
$id = $paste->getID();
- $fork_uri = $this->getApplicationURI('/create/?parent='.$id);
return id(new PhabricatorActionListView())
->setUser($viewer)
@@ -150,13 +150,6 @@ final class PhabricatorPasteViewController extends PhabricatorPasteController {
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit)
->setHref($this->getApplicationURI("edit/{$id}/")))
- ->addAction(
- id(new PhabricatorActionView())
- ->setName(pht('Fork This Paste'))
- ->setIcon('fa-code-fork')
- ->setDisabled(!$can_fork)
- ->setWorkflow(!$can_fork)
- ->setHref($fork_uri))
->addAction(
id(new PhabricatorActionView())
->setName(pht('View Raw File'))
diff --git a/src/applications/paste/editor/PhabricatorPasteEditEngine.php b/src/applications/paste/editor/PhabricatorPasteEditEngine.php
new file mode 100644
index 0000000000..b92042f93f
--- /dev/null
+++ b/src/applications/paste/editor/PhabricatorPasteEditEngine.php
@@ -0,0 +1,77 @@
+getViewer());
+ }
+
+ protected function newObjectQuery() {
+ return id(new PhabricatorPasteQuery())
+ ->needRawContent(true);
+ }
+
+ protected function getObjectCreateTitleText($object) {
+ return pht('Create New Paste');
+ }
+
+ protected function getObjectEditTitleText($object) {
+ return pht('Edit %s %s', $object->getMonogram(), $object->getTitle());
+ }
+
+ protected function getObjectEditShortText($object) {
+ return $object->getMonogram();
+ }
+
+ protected function getObjectCreateShortText($object) {
+ return pht('Create Paste');
+ }
+
+ protected function getObjectViewURI($object) {
+ return '/P'.$object->getID();
+ }
+
+ protected function buildCustomEditFields($object) {
+ $langs = array(
+ '' => pht('(Detect From Filename in Title)'),
+ ) + PhabricatorEnv::getEnvConfig('pygments.dropdown-choices');
+
+ return array(
+ id(new PhabricatorTextEditField())
+ ->setKey('title')
+ ->setLabel(pht('Title'))
+ ->setDescription(pht('Name of the paste.'))
+ ->setTransactionType(PhabricatorPasteTransaction::TYPE_TITLE)
+ ->setValue($object->getTitle()),
+ id(new PhabricatorSelectEditField())
+ ->setKey('language')
+ ->setLabel(pht('Language'))
+ ->setDescription(
+ pht(
+ 'Programming language to interpret the paste as for syntax '.
+ 'highlighting. By default, the language is inferred from the '.
+ 'title.'))
+ ->setAliases(array('lang'))
+ ->setTransactionType(PhabricatorPasteTransaction::TYPE_LANGUAGE)
+ ->setValue($object->getLanguage())
+ ->setOptions($langs),
+ id(new PhabricatorSelectEditField())
+ ->setKey('status')
+ ->setLabel(pht('Status'))
+ ->setDescription(pht('Archive the paste.'))
+ ->setTransactionType(PhabricatorPasteTransaction::TYPE_STATUS)
+ ->setValue($object->getStatus())
+ ->setOptions(PhabricatorPaste::getStatusNameMap()),
+ id(new PhabricatorTextAreaEditField())
+ ->setKey('text')
+ ->setLabel(pht('Text'))
+ ->setDescription(pht('The main body text of the paste.'))
+ ->setTransactionType(PhabricatorPasteTransaction::TYPE_CONTENT)
+ ->setMonospaced(true)
+ ->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
+ ->setValue($object->getRawContent()),
+ );
+ }
+
+}
diff --git a/src/applications/paste/editor/PhabricatorPasteEditor.php b/src/applications/paste/editor/PhabricatorPasteEditor.php
index bae2003afe..cd7a0f271a 100644
--- a/src/applications/paste/editor/PhabricatorPasteEditor.php
+++ b/src/applications/paste/editor/PhabricatorPasteEditor.php
@@ -3,6 +3,8 @@
final class PhabricatorPasteEditor
extends PhabricatorApplicationTransactionEditor {
+ private $fileName;
+
public function getEditorApplicationClass() {
return 'PhabricatorPasteApplication';
}
@@ -41,6 +43,59 @@ final class PhabricatorPasteEditor
return $types;
}
+ protected function shouldApplyInitialEffects(
+ PhabricatorLiskDAO $object,
+ array $xactions) {
+ return true;
+ }
+
+ protected function applyInitialEffects(
+ PhabricatorLiskDAO $object,
+ array $xactions) {
+
+ // Find the most user-friendly filename we can by examining the title of
+ // the paste and the pending transactions. We'll use this if we create a
+ // new file to store raw content later.
+
+ $name = $object->getTitle();
+ if (!strlen($name)) {
+ $name = 'paste.raw';
+ }
+
+ $type_title = PhabricatorPasteTransaction::TYPE_TITLE;
+ foreach ($xactions as $xaction) {
+ if ($xaction->getTransactionType() == $type_title) {
+ $name = $xaction->getNewValue();
+ }
+ }
+
+ $this->fileName = $name;
+ }
+
+ protected function validateTransaction(
+ PhabricatorLiskDAO $object,
+ $type,
+ array $xactions) {
+
+ $errors = parent::validateTransaction($object, $type, $xactions);
+ switch ($type) {
+ case PhabricatorPasteTransaction::TYPE_CONTENT:
+ if (!$object->getFilePHID() && !$xactions) {
+ $error = new PhabricatorApplicationTransactionValidationError(
+ $type,
+ pht('Required'),
+ pht('You must provide content to create a paste.'),
+ null);
+
+ $error->setIsMissingFieldError(true);
+ $errors[] = $error;
+ }
+ break;
+ }
+
+ return $errors;
+ }
+
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
@@ -62,11 +117,26 @@ final class PhabricatorPasteEditor
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
- case PhabricatorPasteTransaction::TYPE_CONTENT:
case PhabricatorPasteTransaction::TYPE_TITLE:
case PhabricatorPasteTransaction::TYPE_LANGUAGE:
case PhabricatorPasteTransaction::TYPE_STATUS:
return $xaction->getNewValue();
+ case PhabricatorPasteTransaction::TYPE_CONTENT:
+ // If this transaction does not really change the paste content, return
+ // the current file PHID so this transaction no-ops.
+ $new_content = $xaction->getNewValue();
+ $old_content = $object->getRawContent();
+ $file_phid = $object->getFilePHID();
+ if (($new_content === $old_content) && $file_phid) {
+ return $file_phid;
+ }
+
+ $file = self::initializeFileForPaste(
+ $this->getActor(),
+ $this->fileName,
+ $xaction->getNewValue());
+
+ return $file->getPHID();
}
}
diff --git a/src/applications/paste/mail/PasteCreateMailReceiver.php b/src/applications/paste/mail/PasteCreateMailReceiver.php
index d0c50d5fcf..672667cd65 100644
--- a/src/applications/paste/mail/PasteCreateMailReceiver.php
+++ b/src/applications/paste/mail/PasteCreateMailReceiver.php
@@ -21,16 +21,11 @@ final class PasteCreateMailReceiver extends PhabricatorMailReceiver {
$title = pht('Email Paste');
}
- $file = PhabricatorPasteEditor::initializeFileForPaste(
- $sender,
- $title,
- $mail->getCleanTextBody());
-
$xactions = array();
$xactions[] = id(new PhabricatorPasteTransaction())
->setTransactionType(PhabricatorPasteTransaction::TYPE_CONTENT)
- ->setNewValue($file->getPHID());
+ ->setNewValue($mail->getCleanTextBody());
$xactions[] = id(new PhabricatorPasteTransaction())
->setTransactionType(PhabricatorPasteTransaction::TYPE_TITLE)
diff --git a/src/applications/paste/phid/PhabricatorPastePastePHIDType.php b/src/applications/paste/phid/PhabricatorPastePastePHIDType.php
index c07f902316..d08d52e2e1 100644
--- a/src/applications/paste/phid/PhabricatorPastePastePHIDType.php
+++ b/src/applications/paste/phid/PhabricatorPastePastePHIDType.php
@@ -12,6 +12,10 @@ final class PhabricatorPastePastePHIDType extends PhabricatorPHIDType {
return new PhabricatorPaste();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPasteApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/paste/storage/PhabricatorPaste.php b/src/applications/paste/storage/PhabricatorPaste.php
index 8aeda09aae..ee381e9493 100644
--- a/src/applications/paste/storage/PhabricatorPaste.php
+++ b/src/applications/paste/storage/PhabricatorPaste.php
@@ -41,11 +41,13 @@ final class PhabricatorPaste extends PhabricatorPasteDAO
return id(new PhabricatorPaste())
->setTitle('')
+ ->setLanguage('')
->setStatus(self::STATUS_ACTIVE)
->setAuthorPHID($actor->getPHID())
->setViewPolicy($view_policy)
->setEditPolicy($edit_policy)
- ->setSpacePHID($actor->getDefaultSpacePHID());
+ ->setSpacePHID($actor->getDefaultSpacePHID())
+ ->attachRawContent(null);
}
public static function getStatusNameMap() {
diff --git a/src/applications/people/controller/PhabricatorPeopleDeleteController.php b/src/applications/people/controller/PhabricatorPeopleDeleteController.php
index e95dd4c646..01b37b37fe 100644
--- a/src/applications/people/controller/PhabricatorPeopleDeleteController.php
+++ b/src/applications/people/controller/PhabricatorPeopleDeleteController.php
@@ -49,9 +49,9 @@ final class PhabricatorPeopleDeleteController
$form = id(new AphrontFormView())
->setUser($admin)
->appendRemarkupInstructions(
- pht(
- " phabricator/ $ ./bin/remove destroy %s\n",
- csprintf('%R', '@'.$user->getUsername())));
+ csprintf(
+ " phabricator/ $ ./bin/remove destroy %R\n",
+ '@'.$user->getUsername()));
return $this->newDialog()
->setWidth(AphrontDialogView::WIDTH_FORM)
diff --git a/src/applications/people/phid/PhabricatorPeopleExternalPHIDType.php b/src/applications/people/phid/PhabricatorPeopleExternalPHIDType.php
index 9fd565700c..4be4cc5359 100644
--- a/src/applications/people/phid/PhabricatorPeopleExternalPHIDType.php
+++ b/src/applications/people/phid/PhabricatorPeopleExternalPHIDType.php
@@ -12,6 +12,10 @@ final class PhabricatorPeopleExternalPHIDType extends PhabricatorPHIDType {
return new PhabricatorExternalAccount();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPeopleApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/people/phid/PhabricatorPeopleUserPHIDType.php b/src/applications/people/phid/PhabricatorPeopleUserPHIDType.php
index f09c75087e..0304173f90 100644
--- a/src/applications/people/phid/PhabricatorPeopleUserPHIDType.php
+++ b/src/applications/people/phid/PhabricatorPeopleUserPHIDType.php
@@ -8,10 +8,6 @@ final class PhabricatorPeopleUserPHIDType extends PhabricatorPHIDType {
return pht('User');
}
- public function getPHIDTypeApplicationClass() {
- return 'PhabricatorPeopleApplication';
- }
-
public function getTypeIcon() {
return 'fa-user bluegrey';
}
@@ -20,6 +16,10 @@ final class PhabricatorPeopleUserPHIDType extends PhabricatorPHIDType {
return new PhabricatorUser();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPeopleApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/phame/controller/PhameController.php b/src/applications/phame/controller/PhameController.php
index fba717e8d9..0cfe877898 100644
--- a/src/applications/phame/controller/PhameController.php
+++ b/src/applications/phame/controller/PhameController.php
@@ -2,27 +2,6 @@
abstract class PhameController extends PhabricatorController {
- protected function renderSideNavFilterView() {
-
- $base_uri = new PhutilURI($this->getApplicationURI());
-
- $nav = new AphrontSideNavFilterView();
- $nav->setBaseURI($base_uri);
-
- $nav->addLabel(pht('Posts'));
- $nav->addFilter('post/all', pht('Latest Posts'));
- $nav->addFilter('post/draft', pht('My Drafts'));
- $nav->addFilter('post', pht('My Posts'));
-
- $nav->addLabel(pht('Blogs'));
- $nav->addFilter('blog/user', pht('Joinable Blogs'));
- $nav->addFilter('blog/all', pht('All Blogs'));
-
- $nav->selectFilter(null);
-
- return $nav;
- }
-
protected function renderPostList(
array $posts,
PhabricatorUser $viewer,
@@ -111,10 +90,6 @@ abstract class PhameController extends PhabricatorController {
return $stories;
}
- public function buildApplicationMenu() {
- return $this->renderSideNavFilterView()->getMenu();
- }
-
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$crumbs->addAction(
diff --git a/src/applications/phame/controller/blog/PhameBlogController.php b/src/applications/phame/controller/blog/PhameBlogController.php
new file mode 100644
index 0000000000..97152e5813
--- /dev/null
+++ b/src/applications/phame/controller/blog/PhameBlogController.php
@@ -0,0 +1,10 @@
+newApplicationMenu()
+ ->setSearchEngine(new PhameBlogSearchEngine());
+ }
+
+}
diff --git a/src/applications/phame/controller/blog/PhameBlogDeleteController.php b/src/applications/phame/controller/blog/PhameBlogDeleteController.php
index 33282582ae..c60e27b2d7 100644
--- a/src/applications/phame/controller/blog/PhameBlogDeleteController.php
+++ b/src/applications/phame/controller/blog/PhameBlogDeleteController.php
@@ -1,13 +1,13 @@
getUser();
+ $viewer = $request->getViewer();
$id = $request->getURIData('id');
$blog = id(new PhameBlogQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
@@ -27,7 +27,7 @@ final class PhameBlogDeleteController extends PhameController {
$cancel_uri = $this->getApplicationURI('/blog/view/'.$blog->getID().'/');
$dialog = id(new AphrontDialogView())
- ->setUser($user)
+ ->setUser($viewer)
->setTitle(pht('Delete Blog?'))
->appendChild(
pht(
diff --git a/src/applications/phame/controller/blog/PhameBlogEditController.php b/src/applications/phame/controller/blog/PhameBlogEditController.php
index 19862fbfbe..24c5681583 100644
--- a/src/applications/phame/controller/blog/PhameBlogEditController.php
+++ b/src/applications/phame/controller/blog/PhameBlogEditController.php
@@ -1,15 +1,15 @@
getUser();
+ $viewer = $request->getViewer();
$id = $request->getURIData('id');
if ($id) {
$blog = id(new PhameBlogQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
@@ -30,7 +30,7 @@ final class PhameBlogEditController
$v_projects = array_reverse($v_projects);
} else {
- $blog = PhameBlog::initializeNewBlog($user);
+ $blog = PhameBlog::initializeNewBlog($viewer);
$submit_button = pht('Create Blog');
$page_title = pht('Create Blog');
@@ -90,7 +90,7 @@ final class PhameBlogEditController
->setNewValue(array('=' => array_fuse($v_projects)));
$editor = id(new PhameBlogEditor())
- ->setActor($user)
+ ->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true);
@@ -111,7 +111,7 @@ final class PhameBlogEditController
}
$policies = id(new PhabricatorPolicyQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->setObject($blog)
->execute();
@@ -119,7 +119,7 @@ final class PhameBlogEditController
$skins = mpull($skins, 'getName');
$form = id(new AphrontFormView())
- ->setUser($user)
+ ->setUser($viewer)
->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('Name'))
@@ -129,16 +129,16 @@ final class PhameBlogEditController
->setError($e_name))
->appendChild(
id(new PhabricatorRemarkupControl())
- ->setUser($user)
+ ->setUser($viewer)
->setLabel(pht('Description'))
->setName('description')
->setValue($description)
->setID('blog-description')
- ->setUser($user)
+ ->setUser($viewer)
->setDisableMacros(true))
->appendChild(
id(new AphrontFormPolicyControl())
- ->setUser($user)
+ ->setUser($viewer)
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
->setPolicyObject($blog)
->setPolicies($policies)
@@ -147,7 +147,7 @@ final class PhameBlogEditController
->setName('can_view'))
->appendChild(
id(new AphrontFormPolicyControl())
- ->setUser($user)
+ ->setUser($viewer)
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
->setPolicyObject($blog)
->setPolicies($policies)
@@ -155,7 +155,7 @@ final class PhameBlogEditController
->setName('can_edit'))
->appendChild(
id(new AphrontFormPolicyControl())
- ->setUser($user)
+ ->setUser($viewer)
->setCapability(PhabricatorPolicyCapability::CAN_JOIN)
->setPolicyObject($blog)
->setPolicies($policies)
@@ -195,13 +195,12 @@ final class PhameBlogEditController
$crumbs->addTextCrumb(pht('Blogs'), $this->getApplicationURI('blog/'));
$crumbs->addTextCrumb($page_title, $this->getApplicationURI('blog/new'));
- return $this->buildApplicationPage(
- array(
- $crumbs,
- $form_box,
- ),
- array(
- 'title' => $page_title,
+ return $this->newPage()
+ ->setTitle($page_title)
+ ->setCrumbs($crumbs)
+ ->appendChild(
+ array(
+ $form_box,
));
}
}
diff --git a/src/applications/phame/controller/blog/PhameBlogFeedController.php b/src/applications/phame/controller/blog/PhameBlogFeedController.php
index fc8c1c48da..0941555ed2 100644
--- a/src/applications/phame/controller/blog/PhameBlogFeedController.php
+++ b/src/applications/phame/controller/blog/PhameBlogFeedController.php
@@ -1,17 +1,17 @@
getUser();
+ $viewer = $request->getViewer();
$id = $request->getURIData('id');
$blog = id(new PhameBlogQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withIDs(array($id))
->executeOne();
if (!$blog) {
@@ -19,7 +19,7 @@ final class PhameBlogFeedController extends PhameController {
}
$posts = id(new PhamePostQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withBlogPHIDs(array($blog->getPHID()))
->withVisibility(PhamePost::VISIBILITY_PUBLISHED)
->execute();
@@ -47,7 +47,7 @@ final class PhameBlogFeedController extends PhameController {
$content[] = phutil_tag('subtitle', array(), $description);
}
- $engine = id(new PhabricatorMarkupEngine())->setViewer($user);
+ $engine = id(new PhabricatorMarkupEngine())->setViewer($viewer);
foreach ($posts as $post) {
$engine->addObject($post, PhamePost::MARKUP_FIELD_BODY);
}
@@ -55,7 +55,7 @@ final class PhameBlogFeedController extends PhameController {
$blogger_phids = mpull($posts, 'getBloggerPHID');
$bloggers = id(new PhabricatorHandleQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withPHIDs($blogger_phids)
->execute();
diff --git a/src/applications/phame/controller/blog/PhameBlogListController.php b/src/applications/phame/controller/blog/PhameBlogListController.php
index 965e1eec49..c162b82b6b 100644
--- a/src/applications/phame/controller/blog/PhameBlogListController.php
+++ b/src/applications/phame/controller/blog/PhameBlogListController.php
@@ -1,6 +1,6 @@
getUser();
+ $viewer = $request->getViewer();
$site = $request->getSite();
if ($site instanceof PhameBlogSite) {
@@ -16,7 +16,7 @@ final class PhameBlogLiveController extends PhameController {
$id = $request->getURIData('id');
$blog = id(new PhameBlogQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withIDs(array($id))
->executeOne();
if (!$blog) {
@@ -38,7 +38,7 @@ final class PhameBlogLiveController extends PhameController {
$dialog = id(new AphrontDialogView())
->setTitle(pht('Blog Moved'))
- ->setUser($user)
+ ->setUser($viewer)
->appendParagraph(pht('This blog is now hosted here:'))
->appendParagraph(
phutil_tag(
diff --git a/src/applications/phame/controller/blog/PhameBlogViewController.php b/src/applications/phame/controller/blog/PhameBlogViewController.php
index c8eddfbad3..03dfc8c1c6 100644
--- a/src/applications/phame/controller/blog/PhameBlogViewController.php
+++ b/src/applications/phame/controller/blog/PhameBlogViewController.php
@@ -1,13 +1,13 @@
getUser();
+ $viewer = $request->getViewer();
$id = $request->getURIData('id');
$blog = id(new PhameBlogQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withIDs(array($id))
->executeOne();
if (!$blog) {
@@ -18,20 +18,20 @@ final class PhameBlogViewController extends PhameController {
->readFromRequest($request);
$posts = id(new PhamePostQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withBlogPHIDs(array($blog->getPHID()))
->executeWithCursorPager($pager);
$header = id(new PHUIHeaderView())
->setHeader($blog->getName())
- ->setUser($user)
+ ->setUser($viewer)
->setPolicyObject($blog);
- $actions = $this->renderActions($blog, $user);
- $properties = $this->renderProperties($blog, $user, $actions);
+ $actions = $this->renderActions($blog, $viewer);
+ $properties = $this->renderProperties($blog, $viewer, $actions);
$post_list = $this->renderPostList(
$posts,
- $user,
+ $viewer,
pht('This blog has no visible posts.'));
$post_list = id(new PHUIObjectBoxView())
@@ -46,27 +46,26 @@ final class PhameBlogViewController extends PhameController {
->setHeader($header)
->addPropertyList($properties);
- return $this->buildApplicationPage(
- array(
- $crumbs,
- $object_box,
- $post_list,
- ),
- array(
- 'title' => $blog->getName(),
+ return $this->newPage()
+ ->setTitle($blog->getName())
+ ->setCrumbs($crumbs)
+ ->appendChild(
+ array(
+ $object_box,
+ $post_list,
));
}
private function renderProperties(
PhameBlog $blog,
- PhabricatorUser $user,
+ PhabricatorUser $viewer,
PhabricatorActionListView $actions) {
require_celerity_resource('aphront-tooltip-css');
Javelin::initBehavior('phabricator-tooltips');
$properties = id(new PHUIPropertyListView())
- ->setUser($user)
+ ->setUser($viewer)
->setObject($blog)
->setActionList($actions);
@@ -94,7 +93,7 @@ final class PhameBlogViewController extends PhameController {
$feed_uri));
$descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
- $user,
+ $viewer,
$blog);
$properties->addProperty(
@@ -106,7 +105,7 @@ final class PhameBlogViewController extends PhameController {
$descriptions[PhabricatorPolicyCapability::CAN_JOIN]);
$engine = id(new PhabricatorMarkupEngine())
- ->setViewer($user)
+ ->setViewer($viewer)
->addObject($blog, PhameBlog::MARKUP_FIELD_DESCRIPTION)
->process();
@@ -116,7 +115,7 @@ final class PhameBlogViewController extends PhameController {
$description = PhabricatorMarkupEngine::renderOneObject(
id(new PhabricatorMarkupOneOff())->setContent($blog->getDescription()),
'default',
- $user);
+ $viewer);
$properties->addSectionHeader(
pht('Description'),
PHUIPropertyListView::ICON_SUMMARY);
@@ -126,19 +125,19 @@ final class PhameBlogViewController extends PhameController {
return $properties;
}
- private function renderActions(PhameBlog $blog, PhabricatorUser $user) {
+ private function renderActions(PhameBlog $blog, PhabricatorUser $viewer) {
$actions = id(new PhabricatorActionListView())
->setObject($blog)
->setObjectURI($this->getRequest()->getRequestURI())
- ->setUser($user);
+ ->setUser($viewer);
$can_edit = PhabricatorPolicyFilter::hasCapability(
- $user,
+ $viewer,
$blog,
PhabricatorPolicyCapability::CAN_EDIT);
$can_join = PhabricatorPolicyFilter::hasCapability(
- $user,
+ $viewer,
$blog,
PhabricatorPolicyCapability::CAN_JOIN);
@@ -152,7 +151,7 @@ final class PhameBlogViewController extends PhameController {
$actions->addAction(
id(new PhabricatorActionView())
- ->setUser($user)
+ ->setUser($viewer)
->setIcon('fa-globe')
->setHref($blog->getLiveURI())
->setName(pht('View Live')));
diff --git a/src/applications/phame/controller/post/PhamePostController.php b/src/applications/phame/controller/post/PhamePostController.php
new file mode 100644
index 0000000000..c6ee2fb86b
--- /dev/null
+++ b/src/applications/phame/controller/post/PhamePostController.php
@@ -0,0 +1,10 @@
+newApplicationMenu()
+ ->setSearchEngine(new PhamePostSearchEngine());
+ }
+
+}
diff --git a/src/applications/phame/controller/post/PhamePostDeleteController.php b/src/applications/phame/controller/post/PhamePostDeleteController.php
index 80038edd1d..292fa6c18c 100644
--- a/src/applications/phame/controller/post/PhamePostDeleteController.php
+++ b/src/applications/phame/controller/post/PhamePostDeleteController.php
@@ -1,12 +1,12 @@
getUser();
+ $viewer = $request->getViewer();
$post = id(new PhamePostQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withIDs(array($request->getURIData('id')))
->requireCapabilities(
array(
@@ -26,7 +26,7 @@ final class PhamePostDeleteController extends PhameController {
$cancel_uri = $this->getApplicationURI('/post/view/'.$post->getID().'/');
$dialog = id(new AphrontDialogView())
- ->setUser($user)
+ ->setUser($viewer)
->setTitle(pht('Delete Post?'))
->appendChild(
pht(
diff --git a/src/applications/phame/controller/post/PhamePostEditController.php b/src/applications/phame/controller/post/PhamePostEditController.php
index e79d435deb..3de92906a8 100644
--- a/src/applications/phame/controller/post/PhamePostEditController.php
+++ b/src/applications/phame/controller/post/PhamePostEditController.php
@@ -1,14 +1,14 @@
getUser();
+ $viewer = $request->getViewer();
$id = $request->getURIData('id');
if ($id) {
$post = id(new PhamePostQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
@@ -29,7 +29,7 @@ final class PhamePostEditController extends PhameController {
$v_projects = array_reverse($v_projects);
} else {
$blog = id(new PhameBlogQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withIDs(array($request->getInt('blog')))
->requireCapabilities(
array(
@@ -42,7 +42,7 @@ final class PhamePostEditController extends PhameController {
}
$v_projects = array();
- $post = PhamePost::initializePost($user, $blog);
+ $post = PhamePost::initializePost($viewer, $blog);
$cancel_uri = $this->getApplicationURI('/blog/view/'.$blog->getID().'/');
$submit_button = pht('Save Draft');
@@ -87,7 +87,7 @@ final class PhamePostEditController extends PhameController {
->setNewValue(array('=' => array_fuse($v_projects)));
$editor = id(new PhamePostEditor())
- ->setActor($user)
+ ->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true);
@@ -106,12 +106,12 @@ final class PhamePostEditController extends PhameController {
}
$handle = id(new PhabricatorHandleQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withPHIDs(array($post->getBlogPHID()))
->executeOne();
$form = id(new AphrontFormView())
- ->setUser($user)
+ ->setUser($viewer)
->addHiddenInput('blog', $request->getInt('blog'))
->appendChild(
id(new AphrontFormMarkupControl())
@@ -141,7 +141,7 @@ final class PhamePostEditController extends PhameController {
->setValue($body)
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
->setID('post-body')
- ->setUser($user)
+ ->setUser($viewer)
->setDisableMacros(true))
->appendControl(
id(new AphrontFormTokenizerControl())
@@ -160,14 +160,18 @@ final class PhamePostEditController extends PhameController {
->addCancelButton($cancel_uri)
->setValue($submit_button));
- $loading = phutil_tag_div(
- 'aphront-panel-preview-loading-text',
- pht('Loading preview...'));
+ $header = id(new PHUIHeaderView())
+ ->setHeader(pht('%s (Post Preview)', $title));
- $preview_panel = phutil_tag_div('aphront-panel-preview', array(
- phutil_tag_div('phame-post-preview-header', pht('Post Preview')),
- phutil_tag('div', array('id' => 'post-preview'), $loading),
- ));
+ $container = id(new PHUIBoxView())
+ ->setID('post-preview');
+
+ $document = id(new PHUIDocumentViewPro())
+ ->setHeader($header)
+ ->appendChild($container);
+
+ $preview_panel = id(new PHUIObjectBoxView())
+ ->appendChild($document);
Javelin::initBehavior(
'phame-post-preview',
@@ -189,14 +193,13 @@ final class PhamePostEditController extends PhameController {
$page_title,
$this->getApplicationURI('/post/view/'.$id.'/'));
- return $this->buildApplicationPage(
- array(
- $crumbs,
- $form_box,
- $preview_panel,
- ),
- array(
- 'title' => $page_title,
+ return $this->newPage()
+ ->setTitle($page_title)
+ ->setCrumbs($crumbs)
+ ->appendChild(
+ array(
+ $form_box,
+ $preview_panel,
));
}
diff --git a/src/applications/phame/controller/post/PhamePostFramedController.php b/src/applications/phame/controller/post/PhamePostFramedController.php
index 46f723aa81..180eca0849 100644
--- a/src/applications/phame/controller/post/PhamePostFramedController.php
+++ b/src/applications/phame/controller/post/PhamePostFramedController.php
@@ -1,13 +1,13 @@
getViewer();
+ $viewer = $request->getViewer();
$id = $request->getURIData('id');
$post = id(new PhamePostQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
diff --git a/src/applications/phame/controller/post/PhamePostListController.php b/src/applications/phame/controller/post/PhamePostListController.php
index fb38a830bb..71e73f1dc6 100644
--- a/src/applications/phame/controller/post/PhamePostListController.php
+++ b/src/applications/phame/controller/post/PhamePostListController.php
@@ -1,6 +1,6 @@
getUser();
+ $viewer = $request->getViewer();
$id = $request->getURIData('id');
$post = null;
$view_uri = null;
if ($id) {
$post = id(new PhamePostQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
@@ -26,7 +26,7 @@ final class PhamePostNewController extends PhameController {
if ($request->isFormPost()) {
$blog = id(new PhameBlogQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withIDs(array($request->getInt('blog')))
->requireCapabilities(
array(
@@ -49,7 +49,7 @@ final class PhamePostNewController extends PhameController {
}
$blogs = id(new PhameBlogQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_JOIN,
@@ -58,9 +58,9 @@ final class PhamePostNewController extends PhameController {
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($title, $view_uri);
- $display = array();
- $display[] = $crumbs;
+ $notification = null;
+ $form_box = null;
if (!$blogs) {
$notification = id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_NODATA)
@@ -68,7 +68,6 @@ final class PhamePostNewController extends PhameController {
pht('You do not have permission to join any blogs. Create a blog '.
'first, then you can post to it.'));
- $display[] = $notification;
} else {
$options = mpull($blogs, 'getName', 'getID');
asort($options);
@@ -79,7 +78,7 @@ final class PhamePostNewController extends PhameController {
}
$form = id(new AphrontFormView())
- ->setUser($user)
+ ->setUser($viewer)
->appendChild(
id(new AphrontFormSelectControl())
->setLabel(pht('Blog'))
@@ -102,19 +101,20 @@ final class PhamePostNewController extends PhameController {
->setValue(pht('Continue')));
}
-
$form_box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setForm($form);
-
- $display[] = $form_box;
}
- return $this->buildApplicationPage(
- $display,
- array(
- 'title' => $title,
+ return $this->newPage()
+ ->setTitle($title)
+ ->setCrumbs($crumbs)
+ ->appendChild(
+ array(
+ $notification,
+ $form_box,
));
- }
+
+ }
}
diff --git a/src/applications/phame/controller/post/PhamePostNotLiveController.php b/src/applications/phame/controller/post/PhamePostNotLiveController.php
index 3f69860003..c0f986ffda 100644
--- a/src/applications/phame/controller/post/PhamePostNotLiveController.php
+++ b/src/applications/phame/controller/post/PhamePostNotLiveController.php
@@ -1,13 +1,13 @@
getUser();
+ $viewer = $request->getViewer();
$id = $request->getURIData('id');
$post = id(new PhamePostQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withIDs(array($id))
->executeOne();
if (!$post) {
@@ -32,7 +32,7 @@ final class PhamePostNotLiveController extends PhameController {
$cancel_uri = $this->getApplicationURI('/post/view/'.$post->getID().'/');
$dialog = id(new AphrontDialogView())
- ->setUser($user)
+ ->setUser($viewer)
->setTitle(pht('Post Not Live'))
->addCancelButton($cancel_uri);
diff --git a/src/applications/phame/controller/post/PhamePostPreviewController.php b/src/applications/phame/controller/post/PhamePostPreviewController.php
index 5b87ec680b..3f81481576 100644
--- a/src/applications/phame/controller/post/PhamePostPreviewController.php
+++ b/src/applications/phame/controller/post/PhamePostPreviewController.php
@@ -1,15 +1,14 @@
getRequest();
- $user = $request->getUser();
- $body = $request->getStr('body');
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $request->getViewer();
+ $body = $request->getStr('body');
$post = id(new PhamePost())
->setBody($body);
@@ -17,7 +16,7 @@ final class PhamePostPreviewController extends PhameController {
$content = PhabricatorMarkupEngine::renderOneObject(
$post,
PhamePost::MARKUP_FIELD_BODY,
- $user);
+ $viewer);
$content = phutil_tag_div('phabricator-remarkup', $content);
diff --git a/src/applications/phame/controller/post/PhamePostPublishController.php b/src/applications/phame/controller/post/PhamePostPublishController.php
index 1b3cac79a4..6ca8ff5d54 100644
--- a/src/applications/phame/controller/post/PhamePostPublishController.php
+++ b/src/applications/phame/controller/post/PhamePostPublishController.php
@@ -1,13 +1,13 @@
getUser();
+ $viewer = $request->getViewer();
$id = $request->getURIData('id');
$post = id(new PhamePostQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
@@ -29,7 +29,7 @@ final class PhamePostPublishController extends PhameController {
}
$form = id(new AphrontFormView())
- ->setUser($user)
+ ->setUser($viewer)
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Publish Post'))
@@ -44,35 +44,30 @@ final class PhamePostPublishController extends PhameController {
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Preview'), $view_uri);
- $nav = $this->renderSideNavFilterView(null);
- $nav->appendChild(
- array(
- $crumbs,
- $form_box,
- $frame,
- ));
-
- return $this->buildApplicationPage(
- $nav,
- array(
- 'title' => pht('Preview Post'),
+ return $this->newPage()
+ ->setTitle(pht('Preview Post'))
+ ->setCrumbs($crumbs)
+ ->appendChild(
+ array(
+ $form_box,
+ $frame,
));
}
private function renderPreviewFrame(PhamePost $post) {
- // TODO: Clean up this CSS.
-
return phutil_tag(
'div',
array(
- 'style' => 'text-align: center; padding: 1em;',
+ 'style' => 'text-align: center; padding: 16px;',
),
phutil_tag(
'iframe',
array(
'style' => 'width: 100%; height: 600px; '.
- 'border: 1px solid #303030;',
+ 'border: 1px solid #BFCFDA; '.
+ 'background-color: #fff; '.
+ 'border-radius: 3px; ',
'src' => $this->getApplicationURI('/post/framed/'.$post->getID().'/'),
),
''));
diff --git a/src/applications/phame/controller/post/PhamePostUnpublishController.php b/src/applications/phame/controller/post/PhamePostUnpublishController.php
index e2634e710e..80a320344d 100644
--- a/src/applications/phame/controller/post/PhamePostUnpublishController.php
+++ b/src/applications/phame/controller/post/PhamePostUnpublishController.php
@@ -1,13 +1,13 @@
getUser();
+ $viewer = $request->getViewer();
$id = $request->getURIData('id');
$post = id(new PhamePostQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
@@ -30,7 +30,7 @@ final class PhamePostUnpublishController extends PhameController {
$cancel_uri = $this->getApplicationURI('/post/view/'.$post->getID().'/');
$dialog = id(new AphrontDialogView())
- ->setUser($user)
+ ->setUser($viewer)
->setTitle(pht('Unpublish Post?'))
->appendChild(
pht(
diff --git a/src/applications/phame/controller/post/PhamePostViewController.php b/src/applications/phame/controller/post/PhamePostViewController.php
index 1b2b8c1a3c..3afdf5401d 100644
--- a/src/applications/phame/controller/post/PhamePostViewController.php
+++ b/src/applications/phame/controller/post/PhamePostViewController.php
@@ -1,12 +1,12 @@
getUser();
+ $viewer = $request->getViewer();
$post = id(new PhamePostQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withIDs(array($request->getURIData('id')))
->executeOne();
@@ -14,29 +14,35 @@ final class PhamePostViewController extends PhameController {
return new Aphront404Response();
}
- $nav = $this->renderSideNavFilterView();
-
- $actions = $this->renderActions($post, $user);
- $properties = $this->renderProperties($post, $user, $actions);
-
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(
$post->getTitle(),
$this->getApplicationURI('post/view/'.$post->getID().'/'));
+ $crumbs->setBorder(true);
- $nav->appendChild($crumbs);
+ $actions = $this->renderActions($post, $viewer);
+ $properties = $this->renderProperties($post, $viewer);
+
+ $action_button = id(new PHUIButtonView())
+ ->setTag('a')
+ ->setText(pht('Actions'))
+ ->setHref('#')
+ ->setIconFont('fa-bars')
+ ->addClass('phui-mobile-menu')
+ ->setDropdownMenu($actions);
$header = id(new PHUIHeaderView())
- ->setHeader($post->getTitle())
- ->setUser($user)
- ->setPolicyObject($post);
+ ->setHeader($post->getTitle())
+ ->setUser($viewer)
+ ->setPolicyObject($post)
+ ->addActionLink($action_button);
- $object_box = id(new PHUIObjectBoxView())
+ $document = id(new PHUIDocumentViewPro())
->setHeader($header)
- ->addPropertyList($properties);
+ ->setPropertyList($properties);
if ($post->isDraft()) {
- $object_box->appendChild(
+ $document->appendChild(
id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
->setTitle(pht('Draft Post'))
@@ -47,7 +53,7 @@ final class PhamePostViewController extends PhameController {
}
if (!$post->getBlog()) {
- $object_box->appendChild(
+ $document->appendChild(
id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
->setTitle(pht('Not On A Blog'))
@@ -57,32 +63,40 @@ final class PhamePostViewController extends PhameController {
'been deleted). Use "Move Post" to move it to a new blog.')));
}
- $nav->appendChild(
- array(
- $object_box,
- $this->buildTransactionTimeline(
- $post,
- new PhamePostTransactionQuery()),
- ));
+ $engine = id(new PhabricatorMarkupEngine())
+ ->setViewer($viewer)
+ ->addObject($post, PhamePost::MARKUP_FIELD_BODY)
+ ->process();
- return $this->buildApplicationPage(
- $nav,
- array(
- 'title' => $post->getTitle(),
+ $document->appendChild(
+ phutil_tag(
+ 'div',
+ array(
+ 'class' => 'phabricator-remarkup',
+ ),
+ $engine->getOutput($post, PhamePost::MARKUP_FIELD_BODY)));
+
+ return $this->newPage()
+ ->setTitle($post->getTitle())
+ ->addClass('pro-white-background')
+ ->setCrumbs($crumbs)
+ ->appendChild(
+ array(
+ $document,
));
}
private function renderActions(
PhamePost $post,
- PhabricatorUser $user) {
+ PhabricatorUser $viewer) {
$actions = id(new PhabricatorActionListView())
->setObject($post)
->setObjectURI($this->getRequest()->getRequestURI())
- ->setUser($user);
+ ->setUser($viewer);
$can_edit = PhabricatorPolicyFilter::hasCapability(
- $user,
+ $viewer,
$post,
PhabricatorPolicyCapability::CAN_EDIT);
@@ -139,7 +153,7 @@ final class PhamePostViewController extends PhameController {
$actions->addAction(
id(new PhabricatorActionView())
- ->setUser($user)
+ ->setUser($viewer)
->setIcon('fa-globe')
->setHref($live_uri)
->setName(pht('View Live'))
@@ -151,43 +165,28 @@ final class PhamePostViewController extends PhameController {
private function renderProperties(
PhamePost $post,
- PhabricatorUser $user,
- PhabricatorActionListView $actions) {
+ PhabricatorUser $viewer) {
$properties = id(new PHUIPropertyListView())
- ->setUser($user)
- ->setObject($post)
- ->setActionList($actions);
+ ->setUser($viewer)
+ ->setObject($post);
$properties->addProperty(
pht('Blog'),
- $user->renderHandle($post->getBlogPHID()));
+ $viewer->renderHandle($post->getBlogPHID()));
$properties->addProperty(
pht('Blogger'),
- $user->renderHandle($post->getBloggerPHID()));
+ $viewer->renderHandle($post->getBloggerPHID()));
$properties->addProperty(
pht('Published'),
$post->isDraft()
? pht('Draft')
- : phabricator_datetime($post->getDatePublished(), $user));
-
- $engine = id(new PhabricatorMarkupEngine())
- ->setViewer($user)
- ->addObject($post, PhamePost::MARKUP_FIELD_BODY)
- ->process();
+ : phabricator_datetime($post->getDatePublished(), $viewer));
$properties->invokeWillRenderEvent();
- $properties->addTextContent(
- phutil_tag(
- 'div',
- array(
- 'class' => 'phabricator-remarkup',
- ),
- $engine->getOutput($post, PhamePost::MARKUP_FIELD_BODY)));
-
return $properties;
}
diff --git a/src/applications/phame/editor/PhameBlogEditor.php b/src/applications/phame/editor/PhameBlogEditor.php
index 289b55cf57..d665d92541 100644
--- a/src/applications/phame/editor/PhameBlogEditor.php
+++ b/src/applications/phame/editor/PhameBlogEditor.php
@@ -8,7 +8,7 @@ final class PhameBlogEditor
}
public function getEditorObjectsDescription() {
- return pht('Blogs');
+ return pht('Phame Blogs');
}
public function getTransactionTypes() {
diff --git a/src/applications/phame/editor/PhamePostEditor.php b/src/applications/phame/editor/PhamePostEditor.php
index ef6cd21307..ab4b1a1465 100644
--- a/src/applications/phame/editor/PhamePostEditor.php
+++ b/src/applications/phame/editor/PhamePostEditor.php
@@ -8,7 +8,7 @@ final class PhamePostEditor
}
public function getEditorObjectsDescription() {
- return pht('Blog Posts');
+ return pht('Phame Posts');
}
public function getTransactionTypes() {
@@ -149,13 +149,74 @@ final class PhamePostEditor
protected function shouldSendMail(
PhabricatorLiskDAO $object,
array $xactions) {
- return false;
+ if ($object->isDraft()) {
+ return false;
+ }
+ return true;
}
protected function shouldPublishFeedStory(
PhabricatorLiskDAO $object,
array $xactions) {
- return false;
+ if ($object->isDraft()) {
+ return false;
+ }
+ return true;
+ }
+
+ protected function getMailTo(PhabricatorLiskDAO $object) {
+ $phids = array();
+ $phids[] = $object->getBloggerPHID();
+ $phids[] = $this->requireActor()->getPHID();
+
+ $blog_phid = $object->getBlogPHID();
+ if ($blog_phid) {
+ $phids[] = PhabricatorSubscribersQuery::loadSubscribersForPHID(
+ $blog_phid);
+ }
+ return $phids;
+ }
+
+ protected function buildMailTemplate(PhabricatorLiskDAO $object) {
+ $phid = $object->getPHID();
+ $title = $object->getTitle();
+
+ return id(new PhabricatorMetaMTAMail())
+ ->setSubject($title)
+ ->addHeader('Thread-Topic', $phid);
+ }
+
+ protected function buildReplyHandler(PhabricatorLiskDAO $object) {
+ return id(new PhamePostReplyHandler())
+ ->setMailReceiver($object);
+ }
+
+ protected function buildMailBody(
+ PhabricatorLiskDAO $object,
+ array $xactions) {
+
+ $body = parent::buildMailBody($object, $xactions);
+
+ $body->addLinkSection(
+ pht('POST DETAIL'),
+ PhabricatorEnv::getProductionURI($object->getViewURI()));
+
+ return $body;
+ }
+
+ public function getMailTagsMap() {
+ return array(
+ PhamePostTransaction::MAILTAG_CONTENT =>
+ pht("A post's content changes."),
+ PhamePostTransaction::MAILTAG_COMMENT =>
+ pht('Someone comments on a post.'),
+ PhamePostTransaction::MAILTAG_OTHER =>
+ pht('Other post activity not listed above occurs.'),
+ );
+ }
+
+ protected function getMailSubjectPrefix() {
+ return '[Phame]';
}
protected function supportsSearch() {
diff --git a/src/applications/phame/mail/PhamePostReplyHandler.php b/src/applications/phame/mail/PhamePostReplyHandler.php
new file mode 100644
index 0000000000..f994763709
--- /dev/null
+++ b/src/applications/phame/mail/PhamePostReplyHandler.php
@@ -0,0 +1,21 @@
+ pht('All'),
+ 'all' => pht('All Blogs'),
);
return $names;
}
diff --git a/src/applications/phame/query/PhamePostSearchEngine.php b/src/applications/phame/query/PhamePostSearchEngine.php
index cedc02cc7a..d832b08192 100644
--- a/src/applications/phame/query/PhamePostSearchEngine.php
+++ b/src/applications/phame/query/PhamePostSearchEngine.php
@@ -44,9 +44,9 @@ final class PhamePostSearchEngine
protected function getBuiltinQueryNames() {
$names = array(
- 'all' => pht('All'),
- 'live' => pht('Live'),
- 'draft' => pht('Draft'),
+ 'all' => pht('All Posts'),
+ 'live' => pht('Live Posts'),
+ 'draft' => pht('Draft Posts'),
);
return $names;
}
diff --git a/src/applications/phame/skins/PhameBasicBlogSkin.php b/src/applications/phame/skins/PhameBasicBlogSkin.php
index efaa85ec8a..5ba8d0999b 100644
--- a/src/applications/phame/skins/PhameBasicBlogSkin.php
+++ b/src/applications/phame/skins/PhameBasicBlogSkin.php
@@ -16,6 +16,7 @@ abstract class PhameBasicBlogSkin extends PhameBlogSkin {
$this->uriPath = $uri_path;
return $this;
}
+
public function getURIPath() {
return $this->uriPath;
}
@@ -24,6 +25,7 @@ abstract class PhameBasicBlogSkin extends PhameBlogSkin {
$this->oGType = $og_type;
return $this;
}
+
protected function getOGType() {
return $this->oGType;
}
@@ -32,6 +34,7 @@ abstract class PhameBasicBlogSkin extends PhameBlogSkin {
$this->description = $description;
return $this;
}
+
protected function getDescription() {
return $this->description;
}
@@ -40,13 +43,12 @@ abstract class PhameBasicBlogSkin extends PhameBlogSkin {
$this->title = $title;
return $this;
}
+
protected function getTitle() {
return $this->title;
}
- public function processRequest() {
- $request = $this->getRequest();
-
+ public function handleRequest(AphrontRequest $request) {
$content = $this->renderContent($request);
if (!$content) {
@@ -69,7 +71,6 @@ abstract class PhameBasicBlogSkin extends PhameBlogSkin {
$view->setFrameable(true);
}
-
$view->appendChild($content);
$response = new AphrontWebpageResponse();
@@ -222,7 +223,7 @@ abstract class PhameBasicBlogSkin extends PhameBlogSkin {
* @task internal
*/
protected function renderContent(AphrontRequest $request) {
- $user = $request->getUser();
+ $viewer = $request->getViewer();
$matches = null;
$path = $request->getPath();
@@ -233,7 +234,7 @@ abstract class PhameBasicBlogSkin extends PhameBlogSkin {
$this->setURIPath('');
if (preg_match('@^/post/(?P.*)$@', $path, $matches)) {
$post = id(new PhamePostQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withBlogPHIDs(array($this->getBlog()->getPHID()))
->withPhameTitles(array($matches['name']))
->executeOne();
@@ -263,7 +264,7 @@ abstract class PhameBasicBlogSkin extends PhameBlogSkin {
$pager->setPageSize($this->getPageSize());
$posts = id(new PhamePostQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withBlogPHIDs(array($this->getBlog()->getPHID()))
->executeWithCursorPager($pager);
@@ -280,10 +281,10 @@ abstract class PhameBasicBlogSkin extends PhameBlogSkin {
private function buildPostViews(array $posts) {
assert_instances_of($posts, 'PhamePost');
- $user = $this->getRequest()->getUser();
+ $viewer = $this->getViewer();
$engine = id(new PhabricatorMarkupEngine())
- ->setViewer($user);
+ ->setViewer($viewer);
$phids = array();
foreach ($posts as $post) {
@@ -294,7 +295,7 @@ abstract class PhameBasicBlogSkin extends PhameBlogSkin {
}
$handles = id(new PhabricatorHandleQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withPHIDs($phids)
->execute();
@@ -303,7 +304,7 @@ abstract class PhameBasicBlogSkin extends PhameBlogSkin {
$views = array();
foreach ($posts as $post) {
$view = id(new PhamePostView())
- ->setUser($user)
+ ->setUser($viewer)
->setSkin($this)
->setPost($post)
->setBody($engine->getOutput($post, PhamePost::MARKUP_FIELD_BODY))
diff --git a/src/applications/phame/skins/PhameBasicTemplateBlogSkin.php b/src/applications/phame/skins/PhameBasicTemplateBlogSkin.php
index 5b4c802c6f..f473eedd49 100644
--- a/src/applications/phame/skins/PhameBasicTemplateBlogSkin.php
+++ b/src/applications/phame/skins/PhameBasicTemplateBlogSkin.php
@@ -27,15 +27,26 @@ final class PhameBasicTemplateBlogSkin extends PhameBasicBlogSkin {
}
$map = CelerityResourceMap::getNamedInstance('phabricator');
- $resource_symbol = 'syntax-highlighting-css';
- $resource_uri = $map->getURIForSymbol($resource_symbol);
+ $highlight_symbol = 'syntax-highlighting-css';
+ $highlight_uri = $map->getURIForSymbol($highlight_symbol);
$this->cssResources[] = phutil_tag(
'link',
array(
'rel' => 'stylesheet',
'type' => 'text/css',
- 'href' => PhabricatorEnv::getCDNURI($resource_uri),
+ 'href' => PhabricatorEnv::getCDNURI($highlight_uri),
+ ));
+
+ $remarkup_symbol = 'phabricator-remarkup-css';
+ $remarkup_uri = $map->getURIForSymbol($remarkup_symbol);
+
+ $this->cssResources[] = phutil_tag(
+ 'link',
+ array(
+ 'rel' => 'stylesheet',
+ 'type' => 'text/css',
+ 'href' => PhabricatorEnv::getCDNURI($remarkup_uri),
));
$this->cssResources = phutil_implode_html("\n", $this->cssResources);
@@ -68,6 +79,12 @@ final class PhameBasicTemplateBlogSkin extends PhameBasicBlogSkin {
return $this->cssResources;
}
+ public function remarkup($corpus) {
+ $view = id(new PHUIRemarkupView($this->getViewer(), $corpus));
+
+ return hsprintf('%s', $view);
+ }
+
public function getName() {
return $this->getSpecification()->getName();
}
@@ -96,13 +113,16 @@ final class PhameBasicTemplateBlogSkin extends PhameBasicBlogSkin {
private function getDefaultScope() {
return array(
- 'skin' => $this,
- 'blog' => $this->getBlog(),
- 'uri' => $this->getURI($this->getURIPath()),
- 'home_uri' => $this->getURI(''),
- 'title' => $this->getTitle(),
+ 'skin' => $this,
+ 'blog' => $this->getBlog(),
+ 'uri' => $this->getURI($this->getURIPath()),
+ 'home_uri' => $this->getURI(''),
+
+ // TODO: This is wrong for detail pages, which should show the post
+ // title, but getting it right is a pain and this is better than nothing.
+ 'title' => $this->getBlog()->getName(),
'description' => $this->getDescription(),
- 'og_type' => $this->getOGType(),
+ 'og_type' => $this->getOGType(),
);
}
@@ -124,7 +144,7 @@ final class PhameBasicTemplateBlogSkin extends PhameBasicBlogSkin {
return $this->renderTemplate(
'post-detail.php',
array(
- 'post' => $post,
+ 'post' => $post,
));
}
diff --git a/src/applications/phame/storage/PhamePost.php b/src/applications/phame/storage/PhamePost.php
index afbb4e8e16..eecb27b566 100644
--- a/src/applications/phame/storage/PhamePost.php
+++ b/src/applications/phame/storage/PhamePost.php
@@ -24,6 +24,7 @@ final class PhamePost extends PhameDAO
protected $configData;
protected $datePublished;
protected $blogPHID;
+ protected $mailKey;
private $blog;
@@ -102,6 +103,7 @@ final class PhamePost extends PhameDAO
'title' => 'text255',
'phameTitle' => 'sort64',
'visibility' => 'uint32',
+ 'mailKey' => 'bytes20',
// T6203/NULLABILITY
// These seem like they should always be non-null?
@@ -135,6 +137,13 @@ final class PhamePost extends PhameDAO
) + parent::getConfiguration();
}
+ public function save() {
+ if (!$this->getMailKey()) {
+ $this->setMailKey(Filesystem::readRandomCharacters(20));
+ }
+ return parent::save();
+ }
+
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorPhamePostPHIDType::TYPECONST);
diff --git a/src/applications/phame/storage/PhamePostTransaction.php b/src/applications/phame/storage/PhamePostTransaction.php
index 04841cda9f..38910c9845 100644
--- a/src/applications/phame/storage/PhamePostTransaction.php
+++ b/src/applications/phame/storage/PhamePostTransaction.php
@@ -3,10 +3,14 @@
final class PhamePostTransaction
extends PhabricatorApplicationTransaction {
- const TYPE_TITLE = 'phame.post.title';
- const TYPE_PHAME_TITLE = 'phame.post.phame.title';
- const TYPE_BODY = 'phame.post.body';
- const TYPE_COMMENTS_WIDGET = 'phame.post.comments.widget';
+ const TYPE_TITLE = 'phame.post.title';
+ const TYPE_PHAME_TITLE = 'phame.post.phame.title';
+ const TYPE_BODY = 'phame.post.body';
+ const TYPE_COMMENTS_WIDGET = 'phame.post.comments.widget';
+
+ const MAILTAG_CONTENT = 'phame-post-content';
+ const MAILTAG_COMMENT = 'phame-post-comment';
+ const MAILTAG_OTHER = 'phame-post-other';
public function getApplicationName() {
return 'phame';
@@ -57,6 +61,27 @@ final class PhamePostTransaction
return parent::getIcon();
}
+ public function getMailTags() {
+ $tags = parent::getMailTags();
+
+ switch ($this->getTransactionType()) {
+ case self::TYPE_COMMENTS_WIDGET:
+ case PhabricatorTransactions::TYPE_COMMENT:
+ $tags[] = self::MAILTAG_COMMENT;
+ break;
+ case self::TYPE_TITLE:
+ case self::TYPE_PHAME_TITLE:
+ case self::TYPE_BODY:
+ $tags[] = self::MAILTAG_CONTENT;
+ break;
+ default:
+ $tags[] = self::MAILTAG_OTHER;
+ break;
+ }
+ return $tags;
+ }
+
+
public function getTitle() {
$author_phid = $this->getAuthorPHID();
$object_phid = $this->getObjectPHID();
@@ -69,7 +94,7 @@ final class PhamePostTransaction
case self::TYPE_TITLE:
if ($old === null) {
return pht(
- '%s created this post.',
+ '%s authored this post.',
$this->renderHandleLink($author_phid));
} else {
return pht(
@@ -80,12 +105,12 @@ final class PhamePostTransaction
break;
case self::TYPE_BODY:
return pht(
- '%s updated the post\'s body.',
+ '%s updated the blog post.',
$this->renderHandleLink($author_phid));
break;
case self::TYPE_PHAME_TITLE:
return pht(
- '%s updated the post\'s phame title to "%s".',
+ '%s updated the post\'s Phame title to "%s".',
$this->renderHandleLink($author_phid),
rtrim($new, '/'));
break;
@@ -112,7 +137,7 @@ final class PhamePostTransaction
case self::TYPE_TITLE:
if ($old === null) {
return pht(
- '%s created %s.',
+ '%s authored %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
} else {
@@ -124,13 +149,13 @@ final class PhamePostTransaction
break;
case self::TYPE_BODY:
return pht(
- '%s updated the body for %s.',
+ '%s updated the blog post %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
break;
case self::TYPE_PHAME_TITLE:
return pht(
- '%s updated the phame title for %s.',
+ '%s updated the Phame title for %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
break;
@@ -145,6 +170,23 @@ final class PhamePostTransaction
return parent::getTitleForFeed();
}
+ public function getBodyForFeed(PhabricatorFeedStory $story) {
+ $new = $this->getNewValue();
+
+ $body = null;
+
+ switch ($this->getTransactionType()) {
+ case self::TYPE_TITLE:
+ case self::TYPE_BODY:
+ return phutil_escape_html_newlines(
+ id(new PhutilUTF8StringTruncator())
+ ->setMaximumGlyphs(128)
+ ->truncateString($new));
+ break;
+ }
+ return parent::getBodyForFeed($story);
+ }
+
public function getColor() {
$old = $this->getOldValue();
diff --git a/src/applications/phame/view/PhamePostView.php b/src/applications/phame/view/PhamePostView.php
index f35125f255..9fef145e02 100644
--- a/src/applications/phame/view/PhamePostView.php
+++ b/src/applications/phame/view/PhamePostView.php
@@ -87,7 +87,7 @@ final class PhamePostView extends AphrontView {
return phutil_tag(
'div',
array(
- 'class' => 'phame-post-body',
+ 'class' => 'phame-post-body phabricator-remarkup',
),
$this->getBody());
}
@@ -96,7 +96,7 @@ final class PhamePostView extends AphrontView {
return phutil_tag(
'div',
array(
- 'class' => 'phame-post-body',
+ 'class' => 'phame-post-body phabricator-remarkup',
),
$this->getSummary());
}
diff --git a/src/applications/phid/PhabricatorMetaMTAApplicationEmailPHIDType.php b/src/applications/phid/PhabricatorMetaMTAApplicationEmailPHIDType.php
index 1069b35793..93d8a47de7 100644
--- a/src/applications/phid/PhabricatorMetaMTAApplicationEmailPHIDType.php
+++ b/src/applications/phid/PhabricatorMetaMTAApplicationEmailPHIDType.php
@@ -9,10 +9,6 @@ final class PhabricatorMetaMTAApplicationEmailPHIDType
return pht('Application Email');
}
- public function getPHIDTypeApplicationClass() {
- return 'PhabricatorMetaMTAApplication';
- }
-
public function getTypeIcon() {
return 'fa-email bluegrey';
}
@@ -21,6 +17,10 @@ final class PhabricatorMetaMTAApplicationEmailPHIDType
return new PhabricatorMetaMTAApplicationEmail();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorMetaMTAApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/phid/resolver/PhabricatorPHIDResolver.php b/src/applications/phid/resolver/PhabricatorPHIDResolver.php
new file mode 100644
index 0000000000..9070139a0b
--- /dev/null
+++ b/src/applications/phid/resolver/PhabricatorPHIDResolver.php
@@ -0,0 +1,46 @@
+viewer = $viewer;
+ return $this;
+ }
+
+ final public function getViewer() {
+ return $this->viewer;
+ }
+
+ final public function resolvePHIDs(array $phids) {
+ $type_unknown = PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN;
+
+ $names = array();
+ foreach ($phids as $key => $phid) {
+ if (phid_get_type($phid) == $type_unknown) {
+ $names[$key] = $phid;
+ }
+ }
+
+ if ($names) {
+ $map = $this->getResolutionMap($names);
+ foreach ($names as $key => $name) {
+ if (isset($map[$name])) {
+ $phids[$key] = $map[$name];
+ }
+ }
+ }
+
+ return $phids;
+ }
+
+ abstract protected function getResolutionMap(array $names);
+
+}
diff --git a/src/applications/phid/resolver/PhabricatorProjectPHIDResolver.php b/src/applications/phid/resolver/PhabricatorProjectPHIDResolver.php
new file mode 100644
index 0000000000..7abecd730b
--- /dev/null
+++ b/src/applications/phid/resolver/PhabricatorProjectPHIDResolver.php
@@ -0,0 +1,28 @@
+ $name) {
+ $names[$key] = '#'.$name;
+ }
+
+ $query = id(new PhabricatorObjectQuery())
+ ->setViewer($this->getViewer());
+
+ $projects = id(new PhabricatorProjectProjectPHIDType())
+ ->loadNamedObjects($query, $names);
+
+ $results = array();
+ foreach ($projects as $hashtag => $project) {
+ $results[substr($hashtag, 1)] = $project->getPHID();
+ }
+
+ return $results;
+ }
+
+}
diff --git a/src/applications/phid/resolver/PhabricatorUserPHIDResolver.php b/src/applications/phid/resolver/PhabricatorUserPHIDResolver.php
new file mode 100644
index 0000000000..a2a75fe310
--- /dev/null
+++ b/src/applications/phid/resolver/PhabricatorUserPHIDResolver.php
@@ -0,0 +1,27 @@
+ $name) {
+ $names[$key] = '@'.$name;
+ }
+
+ $query = id(new PhabricatorObjectQuery())
+ ->setViewer($this->getViewer());
+
+ $users = id(new PhabricatorPeopleUserPHIDType())
+ ->loadNamedObjects($query, $names);
+
+ $results = array();
+ foreach ($users as $at_username => $user) {
+ $results[substr($at_username, 1)] = $user->getPHID();
+ }
+
+ return $results;
+ }
+
+}
diff --git a/src/applications/phid/type/PhabricatorPHIDType.php b/src/applications/phid/type/PhabricatorPHIDType.php
index a8502b12f7..e39ff5f562 100644
--- a/src/applications/phid/type/PhabricatorPHIDType.php
+++ b/src/applications/phid/type/PhabricatorPHIDType.php
@@ -20,10 +20,6 @@ abstract class PhabricatorPHIDType extends Phobject {
abstract public function getTypeName();
- public function newObject() {
- return null;
- }
-
public function getTypeIcon() {
// Default to the application icon if the type doesn't specify one.
$application_class = $this->getPHIDTypeApplicationClass();
@@ -35,6 +31,10 @@ abstract class PhabricatorPHIDType extends Phobject {
return null;
}
+ public function newObject() {
+ return null;
+ }
+
/**
* Get the class name for the application this type belongs to.
@@ -42,12 +42,7 @@ abstract class PhabricatorPHIDType extends Phobject {
* @return string|null Class name of the corresponding application, or null
* if the type is not bound to an application.
*/
- public function getPHIDTypeApplicationClass() {
- // TODO: Some day this should probably be abstract, but for now it only
- // affects global search and there's no real burning need to go classify
- // every PHID type.
- return null;
- }
+ abstract public function getPHIDTypeApplicationClass();
/**
* Build a @{class:PhabricatorPolicyAwareQuery} to load objects of this type
diff --git a/src/applications/phid/type/__tests__/PhabricatorPHIDTypeTestCase.php b/src/applications/phid/type/__tests__/PhabricatorPHIDTypeTestCase.php
index e7707095ad..ec2d932047 100644
--- a/src/applications/phid/type/__tests__/PhabricatorPHIDTypeTestCase.php
+++ b/src/applications/phid/type/__tests__/PhabricatorPHIDTypeTestCase.php
@@ -7,4 +7,16 @@ final class PhabricatorPHIDTypeTestCase extends PhutilTestCase {
$this->assertTrue(true);
}
+ public function testGetPHIDTypeApplicationClass() {
+ $types = PhabricatorPHIDType::getAllTypes();
+
+ foreach ($types as $type) {
+ $application_class = $type->getPHIDTypeApplicationClass();
+
+ if ($application_class !== null) {
+ $this->assertTrue(class_exists($application_class));
+ }
+ }
+ }
+
}
diff --git a/src/applications/phlux/phid/PhluxVariablePHIDType.php b/src/applications/phlux/phid/PhluxVariablePHIDType.php
index 643025fd9c..97525c4052 100644
--- a/src/applications/phlux/phid/PhluxVariablePHIDType.php
+++ b/src/applications/phlux/phid/PhluxVariablePHIDType.php
@@ -12,6 +12,10 @@ final class PhluxVariablePHIDType extends PhabricatorPHIDType {
return new PhluxVariable();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPhluxApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/pholio/phid/PholioImagePHIDType.php b/src/applications/pholio/phid/PholioImagePHIDType.php
index 9278977b77..b28dbd64d5 100644
--- a/src/applications/pholio/phid/PholioImagePHIDType.php
+++ b/src/applications/pholio/phid/PholioImagePHIDType.php
@@ -12,6 +12,10 @@ final class PholioImagePHIDType extends PhabricatorPHIDType {
return new PholioImage();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPholioApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/pholio/phid/PholioMockPHIDType.php b/src/applications/pholio/phid/PholioMockPHIDType.php
index e41f326e94..13ee4cb81f 100644
--- a/src/applications/pholio/phid/PholioMockPHIDType.php
+++ b/src/applications/pholio/phid/PholioMockPHIDType.php
@@ -8,14 +8,14 @@ final class PholioMockPHIDType extends PhabricatorPHIDType {
return pht('Pholio Mock');
}
- public function getPHIDTypeApplicationClass() {
- return 'PhabricatorPholioApplication';
- }
-
public function newObject() {
return new PholioMock();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPholioApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/pholio/view/PholioMockThumbGridView.php b/src/applications/pholio/view/PholioMockThumbGridView.php
index d7d174d928..6467106c14 100644
--- a/src/applications/pholio/view/PholioMockThumbGridView.php
+++ b/src/applications/pholio/view/PholioMockThumbGridView.php
@@ -156,7 +156,7 @@ final class PholioMockThumbGridView extends AphrontView {
array(
'class' => 'pholio-mock-thumb-grid-comment-count',
),
- pht('%s', new PhutilNumber(count($image->getInlineComments()))));
+ pht('%s', phutil_count($image->getInlineComments())));
}
return javelin_tag(
diff --git a/src/applications/phortune/phid/PhortuneAccountPHIDType.php b/src/applications/phortune/phid/PhortuneAccountPHIDType.php
index b9d1bee1a6..cf5f5d06f2 100644
--- a/src/applications/phortune/phid/PhortuneAccountPHIDType.php
+++ b/src/applications/phortune/phid/PhortuneAccountPHIDType.php
@@ -12,6 +12,10 @@ final class PhortuneAccountPHIDType extends PhabricatorPHIDType {
return new PhortuneAccount();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPhortuneApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/phortune/phid/PhortuneCartPHIDType.php b/src/applications/phortune/phid/PhortuneCartPHIDType.php
index f42e563cee..c805a4a921 100644
--- a/src/applications/phortune/phid/PhortuneCartPHIDType.php
+++ b/src/applications/phortune/phid/PhortuneCartPHIDType.php
@@ -12,6 +12,10 @@ final class PhortuneCartPHIDType extends PhabricatorPHIDType {
return new PhortuneCart();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPhortuneApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/phortune/phid/PhortuneChargePHIDType.php b/src/applications/phortune/phid/PhortuneChargePHIDType.php
index b88a605d0c..013db6ab1c 100644
--- a/src/applications/phortune/phid/PhortuneChargePHIDType.php
+++ b/src/applications/phortune/phid/PhortuneChargePHIDType.php
@@ -12,6 +12,10 @@ final class PhortuneChargePHIDType extends PhabricatorPHIDType {
return new PhortuneCharge();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPhortuneApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/phortune/phid/PhortuneMerchantPHIDType.php b/src/applications/phortune/phid/PhortuneMerchantPHIDType.php
index a1b8b73871..941f704ab8 100644
--- a/src/applications/phortune/phid/PhortuneMerchantPHIDType.php
+++ b/src/applications/phortune/phid/PhortuneMerchantPHIDType.php
@@ -12,6 +12,10 @@ final class PhortuneMerchantPHIDType extends PhabricatorPHIDType {
return new PhortuneMerchant();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPhortuneApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/phortune/phid/PhortunePaymentMethodPHIDType.php b/src/applications/phortune/phid/PhortunePaymentMethodPHIDType.php
index 2df0a0acd5..7906f87414 100644
--- a/src/applications/phortune/phid/PhortunePaymentMethodPHIDType.php
+++ b/src/applications/phortune/phid/PhortunePaymentMethodPHIDType.php
@@ -12,6 +12,10 @@ final class PhortunePaymentMethodPHIDType extends PhabricatorPHIDType {
return new PhortunePaymentMethod();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPhortuneApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/phortune/phid/PhortunePaymentProviderPHIDType.php b/src/applications/phortune/phid/PhortunePaymentProviderPHIDType.php
index 7391e71108..dc96d08648 100644
--- a/src/applications/phortune/phid/PhortunePaymentProviderPHIDType.php
+++ b/src/applications/phortune/phid/PhortunePaymentProviderPHIDType.php
@@ -12,6 +12,10 @@ final class PhortunePaymentProviderPHIDType extends PhabricatorPHIDType {
return new PhortunePaymentProviderConfig();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPhortuneApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/phortune/phid/PhortuneProductPHIDType.php b/src/applications/phortune/phid/PhortuneProductPHIDType.php
index 7acbafe9a3..409377186f 100644
--- a/src/applications/phortune/phid/PhortuneProductPHIDType.php
+++ b/src/applications/phortune/phid/PhortuneProductPHIDType.php
@@ -12,6 +12,10 @@ final class PhortuneProductPHIDType extends PhabricatorPHIDType {
return new PhortuneProduct();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPhortuneApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/phortune/phid/PhortunePurchasePHIDType.php b/src/applications/phortune/phid/PhortunePurchasePHIDType.php
index b00faa585c..08f88b1d33 100644
--- a/src/applications/phortune/phid/PhortunePurchasePHIDType.php
+++ b/src/applications/phortune/phid/PhortunePurchasePHIDType.php
@@ -12,6 +12,10 @@ final class PhortunePurchasePHIDType extends PhabricatorPHIDType {
return new PhortunePurchase();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPhortuneApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/phortune/phid/PhortuneSubscriptionPHIDType.php b/src/applications/phortune/phid/PhortuneSubscriptionPHIDType.php
index 9eafc4ed83..6d7275c62b 100644
--- a/src/applications/phortune/phid/PhortuneSubscriptionPHIDType.php
+++ b/src/applications/phortune/phid/PhortuneSubscriptionPHIDType.php
@@ -12,6 +12,10 @@ final class PhortuneSubscriptionPHIDType extends PhabricatorPHIDType {
return new PhortuneSubscription();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPhortuneApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/phragment/controller/PhragmentController.php b/src/applications/phragment/controller/PhragmentController.php
index a96c25878e..c08adcecc6 100644
--- a/src/applications/phragment/controller/PhragmentController.php
+++ b/src/applications/phragment/controller/PhragmentController.php
@@ -199,7 +199,9 @@ abstract class PhragmentController extends PhabricatorController {
$alt = PhabricatorEnv::getEnvConfig('security.alternate-file-domain');
if ($alt === null) {
return id(new PHUIInfoView())
- ->setTitle(pht('security.alternate-file-domain must be configured!'))
+ ->setTitle(pht(
+ '%s must be configured!',
+ 'security.alternate-file-domain'))
->setSeverity(PHUIInfoView::SEVERITY_ERROR)
->appendChild(
phutil_tag(
diff --git a/src/applications/phragment/phid/PhragmentFragmentPHIDType.php b/src/applications/phragment/phid/PhragmentFragmentPHIDType.php
index 3722b2fd69..2947bca98e 100644
--- a/src/applications/phragment/phid/PhragmentFragmentPHIDType.php
+++ b/src/applications/phragment/phid/PhragmentFragmentPHIDType.php
@@ -12,6 +12,10 @@ final class PhragmentFragmentPHIDType extends PhabricatorPHIDType {
return new PhragmentFragment();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPhragmentApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/phragment/phid/PhragmentFragmentVersionPHIDType.php b/src/applications/phragment/phid/PhragmentFragmentVersionPHIDType.php
index 2ab0240b5c..2fa00b15ce 100644
--- a/src/applications/phragment/phid/PhragmentFragmentVersionPHIDType.php
+++ b/src/applications/phragment/phid/PhragmentFragmentVersionPHIDType.php
@@ -12,6 +12,10 @@ final class PhragmentFragmentVersionPHIDType extends PhabricatorPHIDType {
return new PhragmentFragmentVersion();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPhragmentApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/phragment/phid/PhragmentSnapshotPHIDType.php b/src/applications/phragment/phid/PhragmentSnapshotPHIDType.php
index 060b37963c..d97026a601 100644
--- a/src/applications/phragment/phid/PhragmentSnapshotPHIDType.php
+++ b/src/applications/phragment/phid/PhragmentSnapshotPHIDType.php
@@ -12,6 +12,10 @@ final class PhragmentSnapshotPHIDType extends PhabricatorPHIDType {
return new PhragmentSnapshot();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPhragmentApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/phriction/phid/PhrictionDocumentPHIDType.php b/src/applications/phriction/phid/PhrictionDocumentPHIDType.php
index 934dc73b30..57afdb84d6 100644
--- a/src/applications/phriction/phid/PhrictionDocumentPHIDType.php
+++ b/src/applications/phriction/phid/PhrictionDocumentPHIDType.php
@@ -8,14 +8,14 @@ final class PhrictionDocumentPHIDType extends PhabricatorPHIDType {
return pht('Phriction Wiki Document');
}
- public function getPHIDTypeApplicationClass() {
- return 'PhabricatorPhrictionApplication';
- }
-
public function newObject() {
return new PhrictionDocument();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPhrictionApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/phurl/application/PhabricatorPhurlApplication.php b/src/applications/phurl/application/PhabricatorPhurlApplication.php
index c0cf1bf86d..7b01a3f4c5 100644
--- a/src/applications/phurl/application/PhabricatorPhurlApplication.php
+++ b/src/applications/phurl/application/PhabricatorPhurlApplication.php
@@ -26,9 +26,18 @@ final class PhabricatorPhurlApplication extends PhabricatorApplication {
return true;
}
+ public function getRemarkupRules() {
+ return array(
+ new PhabricatorPhurlRemarkupRule(),
+ new PhabricatorPhurlLinkRemarkupRule(),
+ );
+ }
+
public function getRoutes() {
return array(
'/U(?P[1-9]\d*)' => 'PhabricatorPhurlURLViewController',
+ '/u/(?P[1-9]\d*)' => 'PhabricatorPhurlURLAccessController',
+ '/u/(?P[^/]+)' => 'PhabricatorPhurlURLAccessController',
'/phurl/' => array(
'(?:query/(?P[^/]+)/)?'
=> 'PhabricatorPhurlURLListController',
diff --git a/src/applications/phurl/controller/PhabricatorPhurlURLAccessController.php b/src/applications/phurl/controller/PhabricatorPhurlURLAccessController.php
new file mode 100644
index 0000000000..8d15f7a37b
--- /dev/null
+++ b/src/applications/phurl/controller/PhabricatorPhurlURLAccessController.php
@@ -0,0 +1,36 @@
+getViewer();
+ $id = $request->getURIData('id');
+ $alias = $request->getURIData('alias');
+
+ if ($id) {
+ $url = id(new PhabricatorPhurlURLQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($id))
+ ->executeOne();
+ } else if ($alias) {
+ $url = id(new PhabricatorPhurlURLQuery())
+ ->setViewer($viewer)
+ ->withAliases(array($alias))
+ ->executeOne();
+ }
+
+ if (!$url) {
+ return new Aphront404Response();
+ }
+
+ if ($url->isValid()) {
+ return id(new AphrontRedirectResponse())
+ ->setURI($url->getLongURL())
+ ->setIsExternal(true);
+ } else {
+ return id(new AphrontRedirectResponse())->setURI('/'.$url->getMonogram());
+ }
+ }
+
+}
diff --git a/src/applications/phurl/controller/PhabricatorPhurlURLEditController.php b/src/applications/phurl/controller/PhabricatorPhurlURLEditController.php
index 15c25408a8..5a7cd9686d 100644
--- a/src/applications/phurl/controller/PhabricatorPhurlURLEditController.php
+++ b/src/applications/phurl/controller/PhabricatorPhurlURLEditController.php
@@ -7,10 +7,11 @@ final class PhabricatorPhurlURLEditController
$id = $request->getURIData('id');
$is_create = !$id;
- $viewer = $request->getViewer();
+ $viewer = $this->getViewer();
$user_phid = $viewer->getPHID();
$error_name = true;
$error_long_url = true;
+ $error_alias = null;
$validation_exception = null;
$next_workflow = $request->getStr('next');
@@ -58,6 +59,7 @@ final class PhabricatorPhurlURLEditController
$name = $url->getName();
$long_url = $url->getLongURL();
+ $alias = $url->getAlias();
$description = $url->getDescription();
$edit_policy = $url->getEditPolicy();
$view_policy = $url->getViewPolicy();
@@ -67,6 +69,7 @@ final class PhabricatorPhurlURLEditController
$xactions = array();
$name = $request->getStr('name');
$long_url = $request->getStr('longURL');
+ $alias = $request->getStr('alias');
$projects = $request->getArr('projects');
$description = $request->getStr('description');
$subscribers = $request->getArr('subscribers');
@@ -84,6 +87,11 @@ final class PhabricatorPhurlURLEditController
PhabricatorPhurlURLTransaction::TYPE_URL)
->setNewValue($long_url);
+ $xactions[] = id(new PhabricatorPhurlURLTransaction())
+ ->setTransactionType(
+ PhabricatorPhurlURLTransaction::TYPE_ALIAS)
+ ->setNewValue($alias);
+
$xactions[] = id(new PhabricatorPhurlURLTransaction())
->setTransactionType(
PhabricatorTransactions::TYPE_SUBSCRIBERS)
@@ -127,6 +135,8 @@ final class PhabricatorPhurlURLEditController
PhabricatorPhurlURLTransaction::TYPE_NAME);
$error_long_url = $ex->getShortMessage(
PhabricatorPhurlURLTransaction::TYPE_URL);
+ $error_alias = $ex->getShortMessage(
+ PhabricatorPhurlURLTransaction::TYPE_ALIAS);
}
}
@@ -147,6 +157,12 @@ final class PhabricatorPhurlURLEditController
->setValue($long_url)
->setError($error_long_url);
+ $alias = id(new AphrontFormTextControl())
+ ->setLabel(pht('Alias'))
+ ->setName('alias')
+ ->setValue($alias)
+ ->setError($error_alias);
+
$projects = id(new AphrontFormTokenizerControl())
->setLabel(pht('Projects'))
->setName('projects')
@@ -187,6 +203,7 @@ final class PhabricatorPhurlURLEditController
->setUser($viewer)
->appendChild($name)
->appendChild($long_url)
+ ->appendChild($alias)
->appendControl($view_policies)
->appendControl($edit_policies)
->appendControl($subscribers)
diff --git a/src/applications/phurl/controller/PhabricatorPhurlURLViewController.php b/src/applications/phurl/controller/PhabricatorPhurlURLViewController.php
index 4483b9bb77..7702d67b7c 100644
--- a/src/applications/phurl/controller/PhabricatorPhurlURLViewController.php
+++ b/src/applications/phurl/controller/PhabricatorPhurlURLViewController.php
@@ -35,9 +35,13 @@ final class PhabricatorPhurlURLViewController
$properties = $this->buildPropertyView($url);
$properties->setActionList($actions);
+ $url_error = id(new PHUIInfoView())
+ ->setErrors(array(pht('This URL is invalid due to a bad protocol.')))
+ ->setIsHidden($url->isValid());
$box = id(new PHUIObjectBoxView())
->setHeader($header)
- ->addPropertyList($properties);
+ ->addPropertyList($properties)
+ ->setInfoView($url_error);
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
$add_comment_header = $is_serious
@@ -96,13 +100,20 @@ final class PhabricatorPhurlURLViewController
$url,
PhabricatorPolicyCapability::CAN_EDIT);
- $actions->addAction(
- id(new PhabricatorActionView())
- ->setName(pht('Edit'))
- ->setIcon('fa-pencil')
- ->setHref($this->getApplicationURI("url/edit/{$id}/"))
- ->setDisabled(!$can_edit)
- ->setWorkflow(!$can_edit));
+ $actions
+ ->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Edit'))
+ ->setIcon('fa-pencil')
+ ->setHref($this->getApplicationURI("url/edit/{$id}/"))
+ ->setDisabled(!$can_edit)
+ ->setWorkflow(!$can_edit))
+ ->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Visit URL'))
+ ->setIcon('fa-external-link')
+ ->setHref("u/{$id}")
+ ->setDisabled(!$url->isValid()));
return $actions;
}
@@ -118,6 +129,10 @@ final class PhabricatorPhurlURLViewController
pht('Original URL'),
$url->getLongURL());
+ $properties->addProperty(
+ pht('Alias'),
+ $url->getAlias());
+
$properties->invokeWillRenderEvent();
if (strlen($url->getDescription())) {
diff --git a/src/applications/phurl/editor/PhabricatorPhurlURLEditor.php b/src/applications/phurl/editor/PhabricatorPhurlURLEditor.php
index 2065245e36..e7a3c7394b 100644
--- a/src/applications/phurl/editor/PhabricatorPhurlURLEditor.php
+++ b/src/applications/phurl/editor/PhabricatorPhurlURLEditor.php
@@ -16,6 +16,7 @@ final class PhabricatorPhurlURLEditor
$types[] = PhabricatorPhurlURLTransaction::TYPE_NAME;
$types[] = PhabricatorPhurlURLTransaction::TYPE_URL;
+ $types[] = PhabricatorPhurlURLTransaction::TYPE_ALIAS;
$types[] = PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION;
$types[] = PhabricatorTransactions::TYPE_COMMENT;
@@ -33,6 +34,8 @@ final class PhabricatorPhurlURLEditor
return $object->getName();
case PhabricatorPhurlURLTransaction::TYPE_URL:
return $object->getLongURL();
+ case PhabricatorPhurlURLTransaction::TYPE_ALIAS:
+ return $object->getAlias();
case PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION:
return $object->getDescription();
}
@@ -48,6 +51,11 @@ final class PhabricatorPhurlURLEditor
case PhabricatorPhurlURLTransaction::TYPE_URL:
case PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION:
return $xaction->getNewValue();
+ case PhabricatorPhurlURLTransaction::TYPE_ALIAS:
+ if (!strlen($xaction->getNewValue())) {
+ return null;
+ }
+ return $xaction->getNewValue();
}
return parent::getCustomTransactionNewValue($object, $xaction);
@@ -64,6 +72,9 @@ final class PhabricatorPhurlURLEditor
case PhabricatorPhurlURLTransaction::TYPE_URL:
$object->setLongURL($xaction->getNewValue());
return;
+ case PhabricatorPhurlURLTransaction::TYPE_ALIAS:
+ $object->setAlias($xaction->getNewValue());
+ return;
case PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION:
$object->setDescription($xaction->getNewValue());
return;
@@ -79,6 +90,7 @@ final class PhabricatorPhurlURLEditor
switch ($xaction->getTransactionType()) {
case PhabricatorPhurlURLTransaction::TYPE_NAME:
case PhabricatorPhurlURLTransaction::TYPE_URL:
+ case PhabricatorPhurlURLTransaction::TYPE_ALIAS:
case PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION:
return;
}
@@ -109,6 +121,41 @@ final class PhabricatorPhurlURLEditor
$error->setIsMissingFieldError(true);
$errors[] = $error;
}
+ break;
+ case PhabricatorPhurlURLTransaction::TYPE_ALIAS:
+ $overdrawn = $this->validateIsTextFieldTooLong(
+ $object->getName(),
+ $xactions,
+ 64);
+
+ if ($overdrawn) {
+ $errors[] = new PhabricatorApplicationTransactionValidationError(
+ $type,
+ pht('Alias Too Long'),
+ pht('The alias can be no longer than 64 characters.'),
+ nonempty(last($xactions), null));
+ }
+
+ foreach ($xactions as $xaction) {
+ if ($xaction->getOldValue() != $xaction->getNewValue()) {
+ $new_alias = $xaction->getNewValue();
+ if (!preg_match('/[a-zA-Z]/', $new_alias)) {
+ $errors[] = new PhabricatorApplicationTransactionValidationError(
+ $type,
+ pht('Invalid Alias'),
+ pht('The alias must contain at least one letter.'),
+ $xaction);
+ }
+ if (preg_match('/[^a-z0-9]/i', $new_alias)) {
+ $errors[] = new PhabricatorApplicationTransactionValidationError(
+ $type,
+ pht('Invalid Alias'),
+ pht('The alias may only contain letters and numbers.'),
+ $xaction);
+ }
+ }
+ }
+
break;
case PhabricatorPhurlURLTransaction::TYPE_URL:
$missing = $this->validateIsEmptyTextField(
@@ -125,6 +172,21 @@ final class PhabricatorPhurlURLEditor
$error->setIsMissingFieldError(true);
$errors[] = $error;
}
+
+ foreach ($xactions as $xaction) {
+ if ($xaction->getOldValue() != $xaction->getNewValue()) {
+ $protocols = PhabricatorEnv::getEnvConfig('uri.allowed-protocols');
+ $uri = new PhutilURI($xaction->getNewValue());
+ if (!isset($protocols[$uri->getProtocol()])) {
+ $errors[] = new PhabricatorApplicationTransactionValidationError(
+ $type,
+ pht('Invalid URL'),
+ pht('The protocol of the URL is invalid.'),
+ null);
+ }
+ }
+ }
+
break;
}
@@ -203,5 +265,19 @@ final class PhabricatorPhurlURLEditor
return $body;
}
+ protected function didCatchDuplicateKeyException(
+ PhabricatorLiskDAO $object,
+ array $xactions,
+ Exception $ex) {
+
+ $errors = array();
+ $errors[] = new PhabricatorApplicationTransactionValidationError(
+ PhabricatorPhurlURLTransaction::TYPE_ALIAS,
+ pht('Duplicate'),
+ pht('This alias is already in use.'),
+ null);
+
+ throw new PhabricatorApplicationTransactionValidationException($errors);
+ }
}
diff --git a/src/applications/phurl/phid/PhabricatorPhurlURLPHIDType.php b/src/applications/phurl/phid/PhabricatorPhurlURLPHIDType.php
index f273732b82..979b25c791 100644
--- a/src/applications/phurl/phid/PhabricatorPhurlURLPHIDType.php
+++ b/src/applications/phurl/phid/PhabricatorPhurlURLPHIDType.php
@@ -8,14 +8,14 @@ final class PhabricatorPhurlURLPHIDType extends PhabricatorPHIDType {
return pht('URL');
}
- public function getPHIDTypeApplicationClass() {
- return 'PhabricatorPhurlApplication';
- }
-
public function newObject() {
return new PhabricatorPhurlURL();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPhurlApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/phurl/query/PhabricatorPhurlURLQuery.php b/src/applications/phurl/query/PhabricatorPhurlURLQuery.php
index 1edcb1e5c3..412b085635 100644
--- a/src/applications/phurl/query/PhabricatorPhurlURLQuery.php
+++ b/src/applications/phurl/query/PhabricatorPhurlURLQuery.php
@@ -7,6 +7,7 @@ final class PhabricatorPhurlURLQuery
private $phids;
private $names;
private $longURLs;
+ private $aliases;
private $authorPHIDs;
public function newResultObject() {
@@ -33,6 +34,11 @@ final class PhabricatorPhurlURLQuery
return $this;
}
+ public function withAliases(array $aliases) {
+ $this->aliases = $aliases;
+ return $this;
+ }
+
public function withAuthorPHIDs(array $author_phids) {
$this->authorPHIDs = $author_phids;
return $this;
@@ -87,6 +93,13 @@ final class PhabricatorPhurlURLQuery
$this->longURLs);
}
+ if ($this->aliases !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'url.alias IN (%Ls)',
+ $this->aliases);
+ }
+
return $where;
}
diff --git a/src/applications/phurl/remarkup/PhabricatorPhurlLinkRemarkupRule.php b/src/applications/phurl/remarkup/PhabricatorPhurlLinkRemarkupRule.php
new file mode 100644
index 0000000000..bdb6c1959f
--- /dev/null
+++ b/src/applications/phurl/remarkup/PhabricatorPhurlLinkRemarkupRule.php
@@ -0,0 +1,63 @@
+getEngine();
+ $viewer = $engine->getConfig('viewer');
+ $text_mode = $engine->isTextMode();
+
+ if (!$this->isFlatText($matches[0])) {
+ return $matches[0];
+ }
+
+ $ref = $matches[1];
+
+ if (ctype_digit($ref)) {
+ $phurls = id(new PhabricatorPhurlURLQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($ref))
+ ->execute();
+ } else {
+ $phurls = id(new PhabricatorPhurlURLQuery())
+ ->setViewer($viewer)
+ ->withAliases(array($ref))
+ ->execute();
+ }
+
+ $phurl = head($phurls);
+
+ if ($phurl) {
+ if ($text_mode) {
+ return $phurl->getName().' <'.$phurl->getLongURL().'>';
+ }
+
+ $link = phutil_tag(
+ 'a',
+ array(
+ 'href' => $phurl->getLongURL(),
+ 'target' => '_blank',
+ ),
+ $phurl->getName());
+
+ return $this->getEngine()->storeText($link);
+ } else {
+ return $matches[0];
+ }
+ }
+
+
+}
diff --git a/src/applications/phurl/remarkup/PhabricatorPhurlRemarkupRule.php b/src/applications/phurl/remarkup/PhabricatorPhurlRemarkupRule.php
new file mode 100644
index 0000000000..f444cdc7bd
--- /dev/null
+++ b/src/applications/phurl/remarkup/PhabricatorPhurlRemarkupRule.php
@@ -0,0 +1,19 @@
+getEngine()->getConfig('viewer');
+
+ return id(new PhabricatorPhurlURLQuery())
+ ->setViewer($viewer)
+ ->withIDs($ids)
+ ->execute();
+ }
+
+}
diff --git a/src/applications/phurl/storage/PhabricatorPhurlURL.php b/src/applications/phurl/storage/PhabricatorPhurlURL.php
index e59aea63fa..35c5382d52 100644
--- a/src/applications/phurl/storage/PhabricatorPhurlURL.php
+++ b/src/applications/phurl/storage/PhabricatorPhurlURL.php
@@ -72,6 +72,13 @@ final class PhabricatorPhurlURL extends PhabricatorPhurlDAO
return $uri;
}
+ public function isValid() {
+ $allowed_protocols = PhabricatorEnv::getEnvConfig('uri.allowed-protocols');
+ $uri = new PhutilURI($this->getLongURL());
+
+ return isset($allowed_protocols[$uri->getProtocol()]);
+ }
+
/* -( PhabricatorPolicyInterface )----------------------------------------- */
diff --git a/src/applications/phurl/storage/PhabricatorPhurlURLTransaction.php b/src/applications/phurl/storage/PhabricatorPhurlURLTransaction.php
index 0c00c67f2d..6d275bcefb 100644
--- a/src/applications/phurl/storage/PhabricatorPhurlURLTransaction.php
+++ b/src/applications/phurl/storage/PhabricatorPhurlURLTransaction.php
@@ -5,6 +5,7 @@ final class PhabricatorPhurlURLTransaction
const TYPE_NAME = 'phurl.name';
const TYPE_URL = 'phurl.longurl';
+ const TYPE_ALIAS = 'phurl.alias';
const TYPE_DESCRIPTION = 'phurl.description';
const MAILTAG_CONTENT = 'phurl:content';
@@ -28,6 +29,7 @@ final class PhabricatorPhurlURLTransaction
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
case self::TYPE_URL:
+ case self::TYPE_ALIAS:
case self::TYPE_DESCRIPTION:
$phids[] = $this->getObjectPHID();
break;
@@ -49,6 +51,7 @@ final class PhabricatorPhurlURLTransaction
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
case self::TYPE_URL:
+ case self::TYPE_ALIAS:
case self::TYPE_DESCRIPTION:
return 'fa-pencil';
break;
@@ -78,11 +81,35 @@ final class PhabricatorPhurlURLTransaction
$new);
}
case self::TYPE_URL:
- return pht(
- '%s changed the destination of the URL from %s to %s.',
- $this->renderHandleLink($author_phid),
- $old,
- $new);
+ if ($old === null) {
+ return pht(
+ '%s set the destination of the URL to %s.',
+ $this->renderHandleLink($author_phid),
+ $new);
+ } else {
+ return pht(
+ '%s changed the destination of the URL from %s to %s.',
+ $this->renderHandleLink($author_phid),
+ $old,
+ $new);
+ }
+ case self::TYPE_ALIAS:
+ if ($old === null) {
+ return pht(
+ '%s set the alias of the URL to %s.',
+ $this->renderHandleLink($author_phid),
+ $new);
+ } else if ($new === null) {
+ return pht(
+ '%s removed the alias of the URL.',
+ $this->renderHandleLink($author_phid));
+ } else {
+ return pht(
+ '%s changed the alias of the URL from %s to %s.',
+ $this->renderHandleLink($author_phid),
+ $old,
+ $new);
+ }
case self::TYPE_DESCRIPTION:
return pht(
"%s updated the URL's description.",
@@ -119,12 +146,33 @@ final class PhabricatorPhurlURLTransaction
case self::TYPE_URL:
if ($old === null) {
return pht(
- '%s created %s.',
+ '%s set the destination of %s to %s.',
+ $this->renderHandleLink($author_phid),
+ $this->renderHandleLink($object_phid),
+ $new);
+ } else {
+ return pht(
+ '%s changed the destination of %s from %s to %s.',
+ $this->renderHandleLink($author_phid),
+ $this->renderHandleLink($object_phid),
+ $old,
+ $new);
+ }
+ case self::TYPE_ALIAS:
+ if ($old === null) {
+ return pht(
+ '%s set the alias of %s to %s.',
+ $this->renderHandleLink($author_phid),
+ $this->renderHandleLink($object_phid),
+ $new);
+ } else if ($new === null) {
+ return pht(
+ '%s removed the alias of %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
} else {
return pht(
- '%s changed the destination of %s from %s to %s',
+ '%s changed the alias of %s from %s to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$old,
@@ -147,6 +195,7 @@ final class PhabricatorPhurlURLTransaction
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
case self::TYPE_URL:
+ case self::TYPE_ALIAS:
case self::TYPE_DESCRIPTION:
return PhabricatorTransactions::COLOR_GREEN;
}
@@ -185,6 +234,7 @@ final class PhabricatorPhurlURLTransaction
case self::TYPE_NAME:
case self::TYPE_DESCRIPTION:
case self::TYPE_URL:
+ case self::TYPE_ALIAS:
$tags[] = self::MAILTAG_CONTENT;
break;
}
diff --git a/src/applications/policy/phid/PhabricatorPolicyPHIDTypePolicy.php b/src/applications/policy/phid/PhabricatorPolicyPHIDTypePolicy.php
index 225aa22ac1..ed75561327 100644
--- a/src/applications/policy/phid/PhabricatorPolicyPHIDTypePolicy.php
+++ b/src/applications/policy/phid/PhabricatorPolicyPHIDTypePolicy.php
@@ -12,6 +12,10 @@ final class PhabricatorPolicyPHIDTypePolicy extends PhabricatorPHIDType {
return new PhabricatorPolicy();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPolicyApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/ponder/controller/PonderQuestionViewController.php b/src/applications/ponder/controller/PonderQuestionViewController.php
index f7e70caab0..0e92f8e90c 100644
--- a/src/applications/ponder/controller/PonderQuestionViewController.php
+++ b/src/applications/ponder/controller/PonderQuestionViewController.php
@@ -292,7 +292,9 @@ final class PonderQuestionViewController extends PonderController {
$item->setObject($question);
$item->addAttribute(
- pht('%d Answer(s)', $question->getAnswerCount()));
+ pht(
+ '%s Answer(s)',
+ new PhutilNumber($question->getAnswerCount())));
$list->addItem($item);
}
diff --git a/src/applications/ponder/phid/PonderQuestionPHIDType.php b/src/applications/ponder/phid/PonderQuestionPHIDType.php
index db1d5acff2..9bdd80aae6 100644
--- a/src/applications/ponder/phid/PonderQuestionPHIDType.php
+++ b/src/applications/ponder/phid/PonderQuestionPHIDType.php
@@ -8,14 +8,14 @@ final class PonderQuestionPHIDType extends PhabricatorPHIDType {
return pht('Ponder Question');
}
- public function getPHIDTypeApplicationClass() {
- return 'PhabricatorPonderApplication';
- }
-
public function newObject() {
return new PonderQuestion();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPonderApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/ponder/query/PonderQuestionSearchEngine.php b/src/applications/ponder/query/PonderQuestionSearchEngine.php
index 6692d8282a..c16c5442db 100644
--- a/src/applications/ponder/query/PonderQuestionSearchEngine.php
+++ b/src/applications/ponder/query/PonderQuestionSearchEngine.php
@@ -134,11 +134,11 @@ final class PonderQuestionSearchEngine
foreach ($questions as $question) {
$color = PonderQuestionStatus::getQuestionStatusTagColor(
- $question->getStatus());
+ $question->getStatus());
$icon = PonderQuestionStatus::getQuestionStatusIcon(
- $question->getStatus());
+ $question->getStatus());
$full_status = PonderQuestionStatus::getQuestionStatusFullName(
- $question->getStatus());
+ $question->getStatus());
$item = new PHUIObjectItemView();
$item->setObjectName('Q'.$question->getID());
$item->setHeader($question->getTitle());
@@ -158,7 +158,9 @@ final class PonderQuestionSearchEngine
$handles[$question->getAuthorPHID()]->renderLink()));
$item->addAttribute(
- pht('%d Answer(s)', $question->getAnswerCount()));
+ pht(
+ '%s Answer(s)',
+ new PhutilNumber($question->getAnswerCount())));
if ($project_handles) {
$item->addAttribute(
diff --git a/src/applications/project/herald/PhabricatorProjectHeraldAction.php b/src/applications/project/herald/PhabricatorProjectHeraldAction.php
index a720ebe5b0..3459da92cc 100644
--- a/src/applications/project/herald/PhabricatorProjectHeraldAction.php
+++ b/src/applications/project/herald/PhabricatorProjectHeraldAction.php
@@ -112,12 +112,12 @@ abstract class PhabricatorProjectHeraldAction
case self::DO_ADD_PROJECTS:
return pht(
'Added %s project(s): %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
case self::DO_REMOVE_PROJECTS:
return pht(
'Removed %s project(s): %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
}
}
diff --git a/src/applications/project/phid/PhabricatorProjectColumnPHIDType.php b/src/applications/project/phid/PhabricatorProjectColumnPHIDType.php
index 4ac0399cf7..07c7f7a0ee 100644
--- a/src/applications/project/phid/PhabricatorProjectColumnPHIDType.php
+++ b/src/applications/project/phid/PhabricatorProjectColumnPHIDType.php
@@ -8,12 +8,16 @@ final class PhabricatorProjectColumnPHIDType extends PhabricatorPHIDType {
return pht('Project Column');
}
+ public function getTypeIcon() {
+ return 'fa-columns bluegrey';
+ }
+
public function newObject() {
return new PhabricatorProjectColumn();
}
- public function getTypeIcon() {
- return 'fa-columns bluegrey';
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorProjectApplication';
}
protected function buildQueryForObjects(
diff --git a/src/applications/project/phid/PhabricatorProjectProjectPHIDType.php b/src/applications/project/phid/PhabricatorProjectProjectPHIDType.php
index 5689be49ce..c3d9bdd3fb 100644
--- a/src/applications/project/phid/PhabricatorProjectProjectPHIDType.php
+++ b/src/applications/project/phid/PhabricatorProjectProjectPHIDType.php
@@ -8,10 +8,6 @@ final class PhabricatorProjectProjectPHIDType extends PhabricatorPHIDType {
return pht('Project');
}
- public function getPHIDTypeApplicationClass() {
- return 'PhabricatorProjectApplication';
- }
-
public function getTypeIcon() {
return 'fa-briefcase bluegrey';
}
@@ -20,6 +16,10 @@ final class PhabricatorProjectProjectPHIDType extends PhabricatorPHIDType {
return new PhabricatorProject();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorProjectApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/releeph/controller/product/ReleephProductEditController.php b/src/applications/releeph/controller/product/ReleephProductEditController.php
index 7fd8e81563..6a58a39bd9 100644
--- a/src/applications/releeph/controller/product/ReleephProductEditController.php
+++ b/src/applications/releeph/controller/product/ReleephProductEditController.php
@@ -49,7 +49,7 @@ final class ReleephProductEditController extends ReleephProductController {
if (!$product_name) {
$e_name = pht('Required');
$errors[] =
- pht('Your releeph product should have a simple descriptive name.');
+ pht('Your Releeph product should have a simple descriptive name.');
}
if (!$trunk_branch) {
diff --git a/src/applications/releeph/field/specification/ReleephDiffChurnFieldSpecification.php b/src/applications/releeph/field/specification/ReleephDiffChurnFieldSpecification.php
index 18c3c78c87..112ef09885 100644
--- a/src/applications/releeph/field/specification/ReleephDiffChurnFieldSpecification.php
+++ b/src/applications/releeph/field/specification/ReleephDiffChurnFieldSpecification.php
@@ -31,6 +31,7 @@ final class ReleephDiffChurnFieldSpecification
$rejections = 0;
$comments = 0;
$updates = 0;
+
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorTransactions::TYPE_COMMENT:
@@ -60,13 +61,13 @@ final class ReleephDiffChurnFieldSpecification
} else {
$parts = array();
if ($rejections) {
- $parts[] = pht('%d rejection(s)', $rejections);
+ $parts[] = pht('%s rejection(s)', new PhutilNumber($rejections));
}
if ($comments) {
- $parts[] = pht('%d comment(s)', $comments);
+ $parts[] = pht('%s comment(s)', new PhutilNumber($comments));
}
if ($updates) {
- $parts[] = pht('%d update(s)', $updates);
+ $parts[] = pht('%s update(s)', new PhutilNumber($updates));
}
if (count($parts) === 0) {
diff --git a/src/applications/releeph/field/specification/ReleephDiffSizeFieldSpecification.php b/src/applications/releeph/field/specification/ReleephDiffSizeFieldSpecification.php
index fe1a39277c..5975f208e6 100644
--- a/src/applications/releeph/field/specification/ReleephDiffSizeFieldSpecification.php
+++ b/src/applications/releeph/field/specification/ReleephDiffSizeFieldSpecification.php
@@ -55,7 +55,7 @@ final class ReleephDiffSizeFieldSpecification
$mr_changes['tests']['lines'],
count($mr_changes['tests']['paths']));
foreach ($mr_changes['tests']['paths'] as $mr_test_path) {
- $test_blurb .= pht("%s\n", $mr_test_path);
+ $test_blurb .= sprintf("%s\n", $mr_test_path);
}
$test_tag = javelin_tag(
diff --git a/src/applications/releeph/phid/ReleephBranchPHIDType.php b/src/applications/releeph/phid/ReleephBranchPHIDType.php
index 487f5eebb0..d3a545d0df 100644
--- a/src/applications/releeph/phid/ReleephBranchPHIDType.php
+++ b/src/applications/releeph/phid/ReleephBranchPHIDType.php
@@ -12,6 +12,10 @@ final class ReleephBranchPHIDType extends PhabricatorPHIDType {
return new ReleephBranch();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorReleephApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/releeph/phid/ReleephProductPHIDType.php b/src/applications/releeph/phid/ReleephProductPHIDType.php
index 7e8079b309..c7979cfba3 100644
--- a/src/applications/releeph/phid/ReleephProductPHIDType.php
+++ b/src/applications/releeph/phid/ReleephProductPHIDType.php
@@ -12,6 +12,10 @@ final class ReleephProductPHIDType extends PhabricatorPHIDType {
return new ReleephProject();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorReleephApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/releeph/phid/ReleephRequestPHIDType.php b/src/applications/releeph/phid/ReleephRequestPHIDType.php
index 202b146fe8..7bd853f984 100644
--- a/src/applications/releeph/phid/ReleephRequestPHIDType.php
+++ b/src/applications/releeph/phid/ReleephRequestPHIDType.php
@@ -12,6 +12,10 @@ final class ReleephRequestPHIDType extends PhabricatorPHIDType {
return new ReleephRequest();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorReleephApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/releeph/query/ReleephBranchSearchEngine.php b/src/applications/releeph/query/ReleephBranchSearchEngine.php
index cbe5da5339..68ec126eb5 100644
--- a/src/applications/releeph/query/ReleephBranchSearchEngine.php
+++ b/src/applications/releeph/query/ReleephBranchSearchEngine.php
@@ -182,7 +182,9 @@ final class ReleephBranchSearchEngine
$item->setStatusIcon('fa-code-fork orange');
$item->addIcon(
'fa-code-fork',
- pht('%d Open Pull Request(s)', new PhutilNumber($open_count)));
+ pht(
+ '%s Open Pull Request(s)',
+ new PhutilNumber($open_count)));
}
$list->addItem($item);
diff --git a/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php b/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php
index 3ed78f5161..bccb58e35a 100644
--- a/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php
+++ b/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php
@@ -172,7 +172,7 @@ final class PhabricatorRepositoryPullLocalDaemon
pht(
'Not enough process slots to schedule the other %s '.
'repository(s) for updates yet.',
- new PhutilNumber(count($queue))));
+ phutil_count($queue)));
}
if ($futures) {
diff --git a/src/applications/repository/management/PhabricatorRepositoryManagementEditWorkflow.php b/src/applications/repository/management/PhabricatorRepositoryManagementEditWorkflow.php
index d42ecf9526..adee507c51 100644
--- a/src/applications/repository/management/PhabricatorRepositoryManagementEditWorkflow.php
+++ b/src/applications/repository/management/PhabricatorRepositoryManagementEditWorkflow.php
@@ -7,7 +7,10 @@ final class PhabricatorRepositoryManagementEditWorkflow
$this
->setName('edit')
->setExamples('**edit** --as __username__ __repository__ ...')
- ->setSynopsis(pht('Edit __repository__, named by callsign.'))
+ ->setSynopsis(
+ pht(
+ 'Edit __repository__, named by callsign '.
+ '(will eventually be deprecated by Conduit).'))
->setArguments(
array(
array(
@@ -24,6 +27,16 @@ final class PhabricatorRepositoryManagementEditWorkflow
'param' => 'path',
'help' => pht('Edit the local path.'),
),
+ array(
+ 'name' => 'serve-http',
+ 'param' => 'string',
+ 'help' => pht('Edit the http serving policy.'),
+ ),
+ array(
+ 'name' => 'serve-ssh',
+ 'param' => 'string',
+ 'help' => pht('Edit the ssh serving policy.'),
+ ),
));
}
@@ -68,12 +81,33 @@ final class PhabricatorRepositoryManagementEditWorkflow
$xactions = array();
$type_local_path = PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH;
+ $type_protocol_http =
+ PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP;
+ $type_protocol_ssh = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH;
+ $allowed_serve_modes = array(
+ PhabricatorRepository::SERVE_OFF,
+ PhabricatorRepository::SERVE_READONLY,
+ PhabricatorRepository::SERVE_READWRITE,
+ );
if ($args->getArg('local-path')) {
$xactions[] = id(new PhabricatorRepositoryTransaction())
->setTransactionType($type_local_path)
->setNewValue($args->getArg('local-path'));
}
+ $serve_http = $args->getArg('serve-http');
+ if ($serve_http && in_array($serve_http, $allowed_serve_modes)) {
+ $xactions[] = id(new PhabricatorRepositoryTransaction())
+ ->setTransactionType($type_protocol_http)
+ ->setNewValue($serve_http);
+ }
+ $serve_ssh = $args->getArg('serve-ssh');
+ if ($serve_ssh && in_array($serve_ssh, $allowed_serve_modes)) {
+ $xactions[] = id(new PhabricatorRepositoryTransaction())
+ ->setTransactionType($type_protocol_ssh)
+ ->setNewValue($serve_ssh);
+ }
+
if (!$xactions) {
throw new PhutilArgumentUsageException(
diff --git a/src/applications/repository/management/PhabricatorRepositoryManagementParentsWorkflow.php b/src/applications/repository/management/PhabricatorRepositoryManagementParentsWorkflow.php
index 3cbbf5b5bf..61c5fedf96 100644
--- a/src/applications/repository/management/PhabricatorRepositoryManagementParentsWorkflow.php
+++ b/src/applications/repository/management/PhabricatorRepositoryManagementParentsWorkflow.php
@@ -91,7 +91,7 @@ final class PhabricatorRepositoryManagementParentsWorkflow
"%s\n",
pht(
'Found %s total commit(s); updating...',
- new PhutilNumber(count($graph))));
+ phutil_count($graph)));
$commit_table = id(new PhabricatorRepositoryCommit());
$commit_table_name = $commit_table->getTableName();
diff --git a/src/applications/repository/management/PhabricatorRepositoryManagementReparseWorkflow.php b/src/applications/repository/management/PhabricatorRepositoryManagementReparseWorkflow.php
index d36fb3f4ee..524cc606aa 100644
--- a/src/applications/repository/management/PhabricatorRepositoryManagementReparseWorkflow.php
+++ b/src/applications/repository/management/PhabricatorRepositoryManagementReparseWorkflow.php
@@ -260,11 +260,12 @@ final class PhabricatorRepositoryManagementReparseWorkflow
if ($all_from_repo && !$force_local) {
$console->writeOut("%s\n", pht(
- '**NOTE**: This script will queue tasks to reparse the data. Once the '.
- 'tasks have been queued, you need to run Taskmaster daemons to '.
- 'execute them.'."\n\n".
- "QUEUEING TASKS (%s Commits):",
- new PhutilNumber(count($commits))));
+ "**NOTE**: This script will queue tasks to reparse the data. Once the ".
+ "tasks have been queued, you need to run Taskmaster daemons to ".
+ "execute them.\n\n%s",
+ pht(
+ 'QUEUEING TASKS (%s Commit(s)):',
+ phutil_count($commits))));
}
$progress = new PhutilConsoleProgressBar();
diff --git a/src/applications/repository/phid/PhabricatorRepositoryCommitPHIDType.php b/src/applications/repository/phid/PhabricatorRepositoryCommitPHIDType.php
index a176c5b7dd..0f62d523d2 100644
--- a/src/applications/repository/phid/PhabricatorRepositoryCommitPHIDType.php
+++ b/src/applications/repository/phid/PhabricatorRepositoryCommitPHIDType.php
@@ -8,14 +8,14 @@ final class PhabricatorRepositoryCommitPHIDType extends PhabricatorPHIDType {
return pht('Diffusion Commit');
}
- public function getPHIDTypeApplicationClass() {
- return 'PhabricatorDiffusionApplication';
- }
-
public function newObject() {
return new PhabricatorRepositoryCommit();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorDiffusionApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/repository/phid/PhabricatorRepositoryMirrorPHIDType.php b/src/applications/repository/phid/PhabricatorRepositoryMirrorPHIDType.php
index f10af8ac58..42737c7281 100644
--- a/src/applications/repository/phid/PhabricatorRepositoryMirrorPHIDType.php
+++ b/src/applications/repository/phid/PhabricatorRepositoryMirrorPHIDType.php
@@ -12,6 +12,10 @@ final class PhabricatorRepositoryMirrorPHIDType extends PhabricatorPHIDType {
return new PhabricatorRepositoryMirror();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorDiffusionApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/repository/phid/PhabricatorRepositoryPushEventPHIDType.php b/src/applications/repository/phid/PhabricatorRepositoryPushEventPHIDType.php
index db02bd8c1f..364ce62e5d 100644
--- a/src/applications/repository/phid/PhabricatorRepositoryPushEventPHIDType.php
+++ b/src/applications/repository/phid/PhabricatorRepositoryPushEventPHIDType.php
@@ -12,6 +12,10 @@ final class PhabricatorRepositoryPushEventPHIDType extends PhabricatorPHIDType {
return new PhabricatorRepositoryPushEvent();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorDiffusionApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/repository/phid/PhabricatorRepositoryPushLogPHIDType.php b/src/applications/repository/phid/PhabricatorRepositoryPushLogPHIDType.php
index 4a315ac004..6af117db19 100644
--- a/src/applications/repository/phid/PhabricatorRepositoryPushLogPHIDType.php
+++ b/src/applications/repository/phid/PhabricatorRepositoryPushLogPHIDType.php
@@ -12,6 +12,10 @@ final class PhabricatorRepositoryPushLogPHIDType extends PhabricatorPHIDType {
return new PhabricatorRepositoryPushLog();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorDiffusionApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/repository/phid/PhabricatorRepositoryRepositoryPHIDType.php b/src/applications/repository/phid/PhabricatorRepositoryRepositoryPHIDType.php
index d46a69dd33..5a3bca339d 100644
--- a/src/applications/repository/phid/PhabricatorRepositoryRepositoryPHIDType.php
+++ b/src/applications/repository/phid/PhabricatorRepositoryRepositoryPHIDType.php
@@ -17,6 +17,10 @@ final class PhabricatorRepositoryRepositoryPHIDType
return new PhabricatorRepository();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorDiffusionApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/search/controller/PhabricatorApplicationSearchController.php b/src/applications/search/controller/PhabricatorApplicationSearchController.php
index 16faecbfc8..6f6891d781 100644
--- a/src/applications/search/controller/PhabricatorApplicationSearchController.php
+++ b/src/applications/search/controller/PhabricatorApplicationSearchController.php
@@ -58,11 +58,6 @@ final class PhabricatorApplicationSearchController
throw new PhutilInvalidStateException('setEngine');
}
- $nav = $this->getNavigation();
- if (!$nav) {
- throw new PhutilInvalidStateException('setNavigation');
- }
-
$engine->setViewer($this->getRequest()->getUser());
$parent = $this->getDelegatingController();
@@ -85,6 +80,9 @@ final class PhabricatorApplicationSearchController
$user = $request->getUser();
$engine = $this->getSearchEngine();
$nav = $this->getNavigation();
+ if (!$nav) {
+ $nav = $this->buildNavigation();
+ }
if ($request->isFormPost()) {
$saved_query = $engine->buildSavedQueryFromRequest($request);
@@ -174,9 +172,10 @@ final class PhabricatorApplicationSearchController
// we sort out T5307.
$form->appendChild($submit);
+ $body = array();
if ($this->getPreface()) {
- $nav->appendChild($this->getPreface());
+ $body[] = $this->getPreface();
}
if ($named_query) {
@@ -202,7 +201,7 @@ final class PhabricatorApplicationSearchController
$box->setForm($form);
}
- $nav->appendChild($box);
+ $body[] = $box;
if ($run_query) {
$box->setAnchor(
@@ -257,7 +256,7 @@ final class PhabricatorApplicationSearchController
->addMargin(PHUI::MARGIN_LARGE)
->setBorder(true)
->appendChild($pager);
- $nav->appendChild($pager_box);
+ $body[] = $pager_box;
}
} catch (PhabricatorTypeaheadInvalidTokenException $ex) {
@@ -275,13 +274,12 @@ final class PhabricatorApplicationSearchController
->buildApplicationCrumbs()
->addTextCrumb($title);
- $nav->setCrumbs($crumbs);
-
- return $this->buildApplicationPage(
- $nav,
- array(
- 'title' => pht('Query: %s', $title),
- ));
+ return $this->newPage()
+ ->setApplicationMenu($this->buildApplicationMenu())
+ ->setTitle(pht('Query: %s', $title))
+ ->setCrumbs($crumbs)
+ ->setNavigation($nav)
+ ->appendChild($body);
}
private function processEditRequest() {
@@ -289,7 +287,11 @@ final class PhabricatorApplicationSearchController
$request = $this->getRequest();
$user = $request->getUser();
$engine = $this->getSearchEngine();
+
$nav = $this->getNavigation();
+ if (!$nav) {
+ $nav = $this->buildNavigation();
+ }
$named_queries = $engine->loadAllNamedQueries();
@@ -357,23 +359,41 @@ final class PhabricatorApplicationSearchController
->addTextCrumb(pht('Saved Queries'), $engine->getQueryManagementURI());
$nav->selectFilter('query/edit');
- $nav->setCrumbs($crumbs);
$box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Saved Queries'))
->setObjectList($list);
- $nav->appendChild($box);
-
- return $parent->buildApplicationPage(
- $nav,
- array(
- 'title' => pht('Saved Queries'),
- ));
+ return $this->newPage()
+ ->setApplicationMenu($this->buildApplicationMenu())
+ ->setTitle(pht('Saved Queries'))
+ ->setCrumbs($crumbs)
+ ->setNavigation($nav)
+ ->appendChild($box);
}
public function buildApplicationMenu() {
- return $this->getDelegatingController()->buildApplicationMenu();
+ $menu = $this->getDelegatingController()
+ ->buildApplicationMenu();
+
+ if ($menu instanceof PHUIApplicationMenuView) {
+ $menu->setSearchEngine($this->getSearchEngine());
+ }
+
+ return $menu;
+ }
+
+ private function buildNavigation() {
+ $viewer = $this->getViewer();
+ $engine = $this->getSearchEngine();
+
+ $nav = id(new AphrontSideNavFilterView())
+ ->setUser($viewer)
+ ->setBaseURI(new PhutilURI($this->getApplicationURI()));
+
+ $engine->addNavigationItems($nav->getMenu());
+
+ return $nav;
}
}
diff --git a/src/applications/search/controller/PhabricatorSearchBaseController.php b/src/applications/search/controller/PhabricatorSearchBaseController.php
index 86573b38bd..85ac1eb285 100644
--- a/src/applications/search/controller/PhabricatorSearchBaseController.php
+++ b/src/applications/search/controller/PhabricatorSearchBaseController.php
@@ -8,17 +8,4 @@ abstract class PhabricatorSearchBaseController extends PhabricatorController {
const ACTION_BLOCKS = 'blocks';
const ACTION_EDGE = 'edge';
- public function buildStandardPageResponse($view, array $data) {
- $page = $this->buildStandardPageView();
-
- $page->setApplicationName('Search');
- $page->setBaseURI('/search/');
- $page->setTitle(idx($data, 'title'));
- $page->setGlyph("\xC2\xBF");
- $page->appendChild($view);
-
- $response = new AphrontWebpageResponse();
- return $response->setContent($page->render());
- }
-
}
diff --git a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php
index 036b3871ce..4edd9df2cb 100644
--- a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php
+++ b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php
@@ -22,10 +22,32 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
private $customFields = false;
private $request;
private $context;
+ private $controller;
+ private $namedQueries;
const CONTEXT_LIST = 'list';
const CONTEXT_PANEL = 'panel';
+ public function setController(PhabricatorController $controller) {
+ $this->controller = $controller;
+ return $this;
+ }
+
+ public function getController() {
+ return $this->controller;
+ }
+
+ public function buildResponse() {
+ $controller = $this->getController();
+ $request = $controller->getRequest();
+
+ $search = id(new PhabricatorApplicationSearchController())
+ ->setQueryKey($request->getURIData('queryKey'))
+ ->setSearchEngine($this);
+
+ return $controller->delegateToController($search);
+ }
+
public function newResultObject() {
// We may be able to get this automatically if newQuery() is implemented.
$query = $this->newQuery();
@@ -459,33 +481,36 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
public function loadAllNamedQueries() {
$viewer = $this->requireViewer();
-
- $named_queries = id(new PhabricatorNamedQueryQuery())
- ->setViewer($viewer)
- ->withUserPHIDs(array($viewer->getPHID()))
- ->withEngineClassNames(array(get_class($this)))
- ->execute();
- $named_queries = mpull($named_queries, null, 'getQueryKey');
-
$builtin = $this->getBuiltinQueries($viewer);
- $builtin = mpull($builtin, null, 'getQueryKey');
- foreach ($named_queries as $key => $named_query) {
- if ($named_query->getIsBuiltin()) {
- if (isset($builtin[$key])) {
- $named_queries[$key]->setQueryName($builtin[$key]->getQueryName());
- unset($builtin[$key]);
- } else {
- unset($named_queries[$key]);
+ if ($this->namedQueries === null) {
+ $named_queries = id(new PhabricatorNamedQueryQuery())
+ ->setViewer($viewer)
+ ->withUserPHIDs(array($viewer->getPHID()))
+ ->withEngineClassNames(array(get_class($this)))
+ ->execute();
+ $named_queries = mpull($named_queries, null, 'getQueryKey');
+
+ $builtin = mpull($builtin, null, 'getQueryKey');
+
+ foreach ($named_queries as $key => $named_query) {
+ if ($named_query->getIsBuiltin()) {
+ if (isset($builtin[$key])) {
+ $named_queries[$key]->setQueryName($builtin[$key]->getQueryName());
+ unset($builtin[$key]);
+ } else {
+ unset($named_queries[$key]);
+ }
}
+
+ unset($builtin[$key]);
}
- unset($builtin[$key]);
+ $named_queries = msort($named_queries, 'getSortKey');
+ $this->namedQueries = $named_queries;
}
- $named_queries = msort($named_queries, 'getSortKey');
-
- return $named_queries + $builtin;
+ return $this->namedQueries + $builtin;
}
public function loadEnabledNamedQueries() {
diff --git a/src/applications/search/engine/PhabricatorElasticSearchEngine.php b/src/applications/search/engine/PhabricatorElasticSearchEngine.php
index e99160839f..fa6bdf8fee 100644
--- a/src/applications/search/engine/PhabricatorElasticSearchEngine.php
+++ b/src/applications/search/engine/PhabricatorElasticSearchEngine.php
@@ -79,7 +79,7 @@ final class PhabricatorElasticSearchEngine extends PhabricatorSearchEngine {
$spec['relationship'][$rtype][] = array(
'phid' => $to_phid,
'phidType' => $to_type,
- 'when' => $time,
+ 'when' => (int)$time,
);
}
diff --git a/src/applications/settings/panel/PhabricatorConduitCertificateSettingsPanel.php b/src/applications/settings/panel/PhabricatorConduitCertificateSettingsPanel.php
deleted file mode 100644
index aca40d5521..0000000000
--- a/src/applications/settings/panel/PhabricatorConduitCertificateSettingsPanel.php
+++ /dev/null
@@ -1,138 +0,0 @@
-getUser()->getIsMailingList()) {
- return false;
- }
-
- return true;
- }
-
- public function processRequest(AphrontRequest $request) {
- $user = $this->getUser();
- $viewer = $request->getUser();
-
- id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
- $viewer,
- $request,
- '/settings/');
-
- if ($request->isFormPost()) {
- if (!$request->isDialogFormPost()) {
- $dialog = new AphrontDialogView();
- $dialog->setUser($viewer);
- $dialog->setTitle(pht('Really regenerate session?'));
- $dialog->setSubmitURI($this->getPanelURI());
- $dialog->addSubmitButton(pht('Regenerate'));
- $dialog->addCancelbutton($this->getPanelURI());
- $dialog->appendChild(phutil_tag('p', array(), pht(
- 'Really destroy the old certificate? Any established '.
- 'sessions will be terminated.')));
-
- return id(new AphrontDialogResponse())
- ->setDialog($dialog);
- }
-
- $sessions = id(new PhabricatorAuthSessionQuery())
- ->setViewer($user)
- ->withIdentityPHIDs(array($user->getPHID()))
- ->withSessionTypes(array(PhabricatorAuthSession::TYPE_CONDUIT))
- ->execute();
- foreach ($sessions as $session) {
- $session->delete();
- }
-
- // This implicitly regenerates the certificate.
- $user->setConduitCertificate(null);
- $user->save();
- return id(new AphrontRedirectResponse())
- ->setURI($this->getPanelURI('?regenerated=true'));
- }
-
- if ($request->getStr('regenerated')) {
- $notice = new PHUIInfoView();
- $notice->setSeverity(PHUIInfoView::SEVERITY_NOTICE);
- $notice->setTitle(pht('Certificate Regenerated'));
- $notice->appendChild(phutil_tag(
- 'p',
- array(),
- pht(
- 'Your old certificate has been destroyed and you have been issued '.
- 'a new certificate. Sessions established under the old certificate '.
- 'are no longer valid.')));
- $notice = $notice->render();
- } else {
- $notice = null;
- }
-
- Javelin::initBehavior('select-on-click');
-
- $cert_form = new AphrontFormView();
- $cert_form
- ->setUser($viewer)
- ->appendChild(phutil_tag(
- 'p',
- array('class' => 'aphront-form-instructions'),
- pht(
- 'This certificate allows you to authenticate over Conduit, '.
- 'the Phabricator API. Normally, you just run %s to install it.',
- phutil_tag('tt', array(), 'arc install-certificate'))))
- ->appendChild(
- id(new AphrontFormTextAreaControl())
- ->setLabel(pht('Certificate'))
- ->setHeight(AphrontFormTextAreaControl::HEIGHT_SHORT)
- ->setReadonly(true)
- ->setSigil('select-on-click')
- ->setValue($user->getConduitCertificate()));
-
- $cert_form = id(new PHUIObjectBoxView())
- ->setHeaderText(pht('Arcanist Certificate'))
- ->setForm($cert_form);
-
- $regen_instruction = pht(
- 'You can regenerate this certificate, which '.
- 'will invalidate the old certificate and create a new one.');
-
- $regen_form = new AphrontFormView();
- $regen_form
- ->setUser($viewer)
- ->setAction($this->getPanelURI())
- ->setWorkflow(true)
- ->appendChild(phutil_tag(
- 'p',
- array('class' => 'aphront-form-instructions'),
- $regen_instruction))
- ->appendChild(
- id(new AphrontFormSubmitControl())
- ->setValue(pht('Regenerate Certificate')));
-
- $regen_form = id(new PHUIObjectBoxView())
- ->setHeaderText(pht('Regenerate Certificate'))
- ->setForm($regen_form);
-
- return array(
- $notice,
- $cert_form,
- $regen_form,
- );
- }
-}
diff --git a/src/applications/slowvote/phid/PhabricatorSlowvotePollPHIDType.php b/src/applications/slowvote/phid/PhabricatorSlowvotePollPHIDType.php
index 927e6a3942..42ced85b22 100644
--- a/src/applications/slowvote/phid/PhabricatorSlowvotePollPHIDType.php
+++ b/src/applications/slowvote/phid/PhabricatorSlowvotePollPHIDType.php
@@ -12,6 +12,10 @@ final class PhabricatorSlowvotePollPHIDType extends PhabricatorPHIDType {
return new PhabricatorSlowvotePoll();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorSlowvoteApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/spaces/phid/PhabricatorSpacesNamespacePHIDType.php b/src/applications/spaces/phid/PhabricatorSpacesNamespacePHIDType.php
index 6645c7edbd..86371d6420 100644
--- a/src/applications/spaces/phid/PhabricatorSpacesNamespacePHIDType.php
+++ b/src/applications/spaces/phid/PhabricatorSpacesNamespacePHIDType.php
@@ -9,14 +9,14 @@ final class PhabricatorSpacesNamespacePHIDType
return pht('Space');
}
- public function getPHIDTypeApplicationClass() {
- return 'PhabricatorSpacesApplication';
- }
-
public function newObject() {
return new PhabricatorSpacesNamespace();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorSpacesApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/subscriptions/herald/PhabricatorSubscriptionsHeraldAction.php b/src/applications/subscriptions/herald/PhabricatorSubscriptionsHeraldAction.php
index 6ec7b6f776..bf0df4fd97 100644
--- a/src/applications/subscriptions/herald/PhabricatorSubscriptionsHeraldAction.php
+++ b/src/applications/subscriptions/herald/PhabricatorSubscriptionsHeraldAction.php
@@ -163,22 +163,22 @@ abstract class PhabricatorSubscriptionsHeraldAction
return pht(
'Declined to resubscribe %s target(s) because they previously '.
'unsubscribed: %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
case self::DO_AUTOSUBSCRIBED:
return pht(
'%s automatically subscribed target(s) were not affected: %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
case self::DO_SUBSCRIBED:
return pht(
'Added %s subscriber(s): %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
case self::DO_UNSUBSCRIBED:
return pht(
'Removed %s subscriber(s): %s.',
- new PhutilNumber(count($data)),
+ phutil_count($data),
$this->renderHandleList($data));
}
}
diff --git a/src/applications/system/management/PhabricatorSystemRemoveDestroyWorkflow.php b/src/applications/system/management/PhabricatorSystemRemoveDestroyWorkflow.php
index 2abbc52691..baaf4f7af9 100644
--- a/src/applications/system/management/PhabricatorSystemRemoveDestroyWorkflow.php
+++ b/src/applications/system/management/PhabricatorSystemRemoveDestroyWorkflow.php
@@ -119,7 +119,7 @@ EOBANNER;
$console->writeOut(
pht(
'These %s object(s) will be destroyed forever:',
- new PhutilNumber(count($named_objects)))."\n\n");
+ phutil_count($named_objects))."\n\n");
foreach ($named_objects as $object_name => $object) {
$phid = $object->getPHID();
@@ -136,7 +136,7 @@ EOBANNER;
$ok = $console->confirm(
pht(
'Are you absolutely certain you want to destroy these %s object(s)?',
- new PhutilNumber(count($named_objects))));
+ phutil_count($named_objects)));
if (!$ok) {
throw new PhutilArgumentUsageException(
pht('Aborted, your objects are safe.'));
@@ -160,7 +160,7 @@ EOBANNER;
"%s\n",
pht(
'Permanently destroyed %s object(s).',
- new PhutilNumber(count($named_objects))));
+ phutil_count($named_objects)));
return 0;
}
diff --git a/src/applications/tokens/phid/PhabricatorTokenTokenPHIDType.php b/src/applications/tokens/phid/PhabricatorTokenTokenPHIDType.php
index 1791cc88c7..93ff9500ac 100644
--- a/src/applications/tokens/phid/PhabricatorTokenTokenPHIDType.php
+++ b/src/applications/tokens/phid/PhabricatorTokenTokenPHIDType.php
@@ -12,6 +12,10 @@ final class PhabricatorTokenTokenPHIDType extends PhabricatorPHIDType {
return new PhabricatorToken();
}
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorTokensApplication';
+ }
+
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
diff --git a/src/applications/transactions/editengine/PhabricatorApplicationEditEngine.php b/src/applications/transactions/editengine/PhabricatorApplicationEditEngine.php
new file mode 100644
index 0000000000..86a03b51f4
--- /dev/null
+++ b/src/applications/transactions/editengine/PhabricatorApplicationEditEngine.php
@@ -0,0 +1,776 @@
+viewer = $viewer;
+ return $this;
+ }
+
+ final public function getViewer() {
+ return $this->viewer;
+ }
+
+ final public function setController(PhabricatorController $controller) {
+ $this->controller = $controller;
+ $this->setViewer($controller->getViewer());
+ return $this;
+ }
+
+ final public function getController() {
+ return $this->controller;
+ }
+
+
+/* -( Managing Fields )---------------------------------------------------- */
+
+
+ abstract protected function buildCustomEditFields($object);
+
+ final protected function buildEditFields($object) {
+ $viewer = $this->getViewer();
+ $editor = $object->getApplicationTransactionEditor();
+
+ $types = $editor->getTransactionTypesForObject($object);
+ $types = array_fuse($types);
+
+ $fields = $this->buildCustomEditFields($object);
+
+ if ($object instanceof PhabricatorPolicyInterface) {
+ $policies = id(new PhabricatorPolicyQuery())
+ ->setViewer($viewer)
+ ->setObject($object)
+ ->execute();
+
+ $map = array(
+ PhabricatorTransactions::TYPE_VIEW_POLICY => array(
+ 'key' => 'policy.view',
+ 'aliases' => array('view'),
+ 'capability' => PhabricatorPolicyCapability::CAN_VIEW,
+ 'label' => pht('View Policy'),
+ 'description' => pht('Controls who can view the object.'),
+ 'edit' => 'view',
+ ),
+ PhabricatorTransactions::TYPE_EDIT_POLICY => array(
+ 'key' => 'policy.edit',
+ 'aliases' => array('edit'),
+ 'capability' => PhabricatorPolicyCapability::CAN_EDIT,
+ 'label' => pht('Edit Policy'),
+ 'description' => pht('Controls who can edit the object.'),
+ 'edit' => 'edit',
+ ),
+ PhabricatorTransactions::TYPE_JOIN_POLICY => array(
+ 'key' => 'policy.join',
+ 'aliases' => array('join'),
+ 'capability' => PhabricatorPolicyCapability::CAN_JOIN,
+ 'label' => pht('Join Policy'),
+ 'description' => pht('Controls who can join the object.'),
+ 'edit' => 'join',
+ ),
+ );
+
+ foreach ($map as $type => $spec) {
+ if (empty($types[$type])) {
+ continue;
+ }
+
+ $capability = $spec['capability'];
+ $key = $spec['key'];
+ $aliases = $spec['aliases'];
+ $label = $spec['label'];
+ $description = $spec['description'];
+ $edit = $spec['edit'];
+
+ $policy_field = id(new PhabricatorPolicyEditField())
+ ->setKey($key)
+ ->setLabel($label)
+ ->setDescription($description)
+ ->setAliases($aliases)
+ ->setCapability($capability)
+ ->setPolicies($policies)
+ ->setTransactionType($type)
+ ->setEditTypeKey($edit)
+ ->setValue($object->getPolicy($capability));
+ $fields[] = $policy_field;
+
+ if ($object instanceof PhabricatorSpacesInterface) {
+ if ($capability == PhabricatorPolicyCapability::CAN_VIEW) {
+ $type_space = PhabricatorTransactions::TYPE_SPACE;
+ if (isset($types[$type_space])) {
+ $space_field = id(new PhabricatorSpaceEditField())
+ ->setKey('spacePHID')
+ ->setLabel(pht('Space'))
+ ->setEditTypeKey('space')
+ ->setDescription(
+ pht('Shifts the object in the Spaces application.'))
+ ->setAliases(array('space', 'policy.space'))
+ ->setTransactionType($type_space)
+ ->setValue($object->getSpacePHID());
+ $fields[] = $space_field;
+
+ $policy_field->setSpaceField($space_field);
+ }
+ }
+ }
+ }
+ }
+
+ $edge_type = PhabricatorTransactions::TYPE_EDGE;
+ $object_phid = $object->getPHID();
+
+ $project_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
+
+ if ($object instanceof PhabricatorProjectInterface) {
+ if (isset($types[$edge_type])) {
+ if ($object_phid) {
+ $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
+ $object_phid,
+ $project_edge_type);
+ $project_phids = array_reverse($project_phids);
+ } else {
+ $project_phids = array();
+ }
+
+ $edge_field = id(new PhabricatorProjectsEditField())
+ ->setKey('projectPHIDs')
+ ->setLabel(pht('Projects'))
+ ->setEditTypeKey('projects')
+ ->setDescription(pht('Add or remove associated projects.'))
+ ->setAliases(array('project', 'projects'))
+ ->setTransactionType($edge_type)
+ ->setMetadataValue('edge:type', $project_edge_type)
+ ->setValue($project_phids);
+ $fields[] = $edge_field;
+ }
+ }
+
+ $subscribers_type = PhabricatorTransactions::TYPE_SUBSCRIBERS;
+
+ if ($object instanceof PhabricatorSubscribableInterface) {
+ if (isset($types[$subscribers_type])) {
+ if ($object_phid) {
+ $sub_phids = PhabricatorSubscribersQuery::loadSubscribersForPHID(
+ $object_phid);
+ } else {
+ // TODO: Allow applications to provide default subscribers; Maniphest
+ // does this at a minimum.
+ $sub_phids = array();
+ }
+
+ $subscribers_field = id(new PhabricatorSubscribersEditField())
+ ->setKey('subscriberPHIDs')
+ ->setLabel(pht('Subscribers'))
+ ->setEditTypeKey('subscribers')
+ ->setDescription(pht('Manage subscribers.'))
+ ->setAliases(array('subscriber', 'subscribers'))
+ ->setTransactionType($subscribers_type)
+ ->setValue($sub_phids);
+ $fields[] = $subscribers_field;
+ }
+ }
+
+ foreach ($fields as $field) {
+ $field
+ ->setViewer($viewer)
+ ->setObject($object);
+ }
+
+ return $fields;
+ }
+
+
+/* -( Display Text )------------------------------------------------------- */
+
+
+ /**
+ * @task text
+ */
+ abstract protected function getObjectCreateTitleText($object);
+
+
+ /**
+ * @task text
+ */
+ abstract protected function getObjectEditTitleText($object);
+
+
+ /**
+ * @task text
+ */
+ abstract protected function getObjectCreateShortText($object);
+
+
+ /**
+ * @task text
+ */
+ abstract protected function getObjectEditShortText($object);
+
+
+ /**
+ * @task text
+ */
+ protected function getObjectCreateButtonText($object) {
+ return $this->getObjectCreateTitleText($object);
+ }
+
+
+ /**
+ * @task text
+ */
+ protected function getObjectEditButtonText($object) {
+ return pht('Save Changes');
+ }
+
+
+/* -( Managing URIs )------------------------------------------------------ */
+
+
+ /**
+ * @task uri
+ */
+ abstract protected function getObjectViewURI($object);
+
+
+ /**
+ * @task uri
+ */
+ protected function getObjectEditURI($object) {
+ return $this->getController()->getApplicationURI('edit/');
+ }
+
+
+ /**
+ * @task uri
+ */
+ protected function getObjectCreateCancelURI($object) {
+ return $this->getController()->getApplicationURI();
+ }
+
+
+ /**
+ * @task uri
+ */
+ protected function getObjectEditCancelURI($object) {
+ return $this->getObjectViewURI($object);
+ }
+
+
+ /**
+ * @task uri
+ */
+ protected function getEditURI($object, $path = null) {
+ $parts = array(
+ $this->getObjectEditURI($object),
+ );
+
+ if (!$this->getIsCreate()) {
+ $parts[] = $object->getID().'/';
+ }
+
+ if ($path !== null) {
+ $parts[] = $path;
+ }
+
+ return implode('', $parts);
+ }
+
+
+/* -( Creating and Loading Objects )--------------------------------------- */
+
+
+ /**
+ * Initialize a new object for creation.
+ *
+ * @return object Newly initialized object.
+ * @task load
+ */
+ abstract protected function newEditableObject();
+
+
+ /**
+ * Build an empty query for objects.
+ *
+ * @return PhabricatorPolicyAwareQuery Query.
+ * @task load
+ */
+ abstract protected function newObjectQuery();
+
+
+ /**
+ * Test if this workflow is creating a new object or editing an existing one.
+ *
+ * @return bool True if a new object is being created.
+ * @task load
+ */
+ final protected function getIsCreate() {
+ return $this->isCreate;
+ }
+
+
+ /**
+ * Flag this workflow as a create or edit.
+ *
+ * @param bool True if this is a create workflow.
+ * @return this
+ * @task load
+ */
+ private function setIsCreate($is_create) {
+ $this->isCreate = $is_create;
+ return $this;
+ }
+
+
+ /**
+ * Load an object by ID.
+ *
+ * @param int Object ID.
+ * @return object|null Object, or null if no such object exists.
+ * @task load
+ */
+ private function newObjectFromID($id) {
+ $query = $this->newObjectQuery()
+ ->withIDs(array($id));
+
+ return $this->newObjectFromQuery($query);
+ }
+
+
+ /**
+ * Load an object by PHID.
+ *
+ * @param phid Object PHID.
+ * @return object|null Object, or null if no such object exists.
+ * @task load
+ */
+ private function newObjectFromPHID($phid) {
+ $query = $this->newObjectQuery()
+ ->withPHIDs(array($phid));
+
+ return $this->newObjectFromQuery($query);
+ }
+
+
+ /**
+ * Load an object given a configured query.
+ *
+ * @param PhabricatorPolicyAwareQuery Configured query.
+ * @return object|null Object, or null if no such object exists.
+ * @task load
+ */
+ private function newObjectFromQuery(PhabricatorPolicyAwareQuery $query) {
+ $viewer = $this->getViewer();
+
+ $object = $query
+ ->setViewer($viewer)
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ ))
+ ->executeOne();
+ if (!$object) {
+ return null;
+ }
+
+ return $object;
+ }
+
+
+/* -( Responding to Web Requests )----------------------------------------- */
+
+
+ final public function buildResponse() {
+ $viewer = $this->getViewer();
+ $controller = $this->getController();
+ $request = $controller->getRequest();
+
+ $id = $request->getURIData('id');
+ if ($id) {
+ $this->setIsCreate(false);
+ $object = $this->newObjectFromID($id);
+ if (!$object) {
+ return new Aphront404Response();
+ }
+ } else {
+ $this->setIsCreate(true);
+ $object = $this->newEditableObject();
+ }
+
+ $action = $request->getURIData('editAction');
+ switch ($action) {
+ case 'parameters':
+ return $this->buildParametersResponse($object);
+ default:
+ return $this->buildEditResponse($object);
+ }
+ }
+
+ private function buildCrumbs($object, $final = false) {
+ $controller = $this->getcontroller();
+
+ $crumbs = $controller->buildApplicationCrumbsForEditEngine();
+ if ($this->getIsCreate()) {
+ $create_text = $this->getObjectCreateShortText($object);
+ if ($final) {
+ $crumbs->addTextCrumb($create_text);
+ } else {
+ $edit_uri = $this->getEditURI($object);
+ $crumbs->addTextCrumb($create_text, $edit_uri);
+ }
+ } else {
+ $crumbs->addTextCrumb(
+ $this->getObjectEditShortText($object),
+ $this->getObjectViewURI($object));
+
+ $edit_text = pht('Edit');
+ if ($final) {
+ $crumbs->addTextCrumb($edit_text);
+ } else {
+ $edit_uri = $this->getEditURI($object);
+ $crumbs->addTextCrumb($edit_text, $edit_uri);
+ }
+ }
+
+ return $crumbs;
+ }
+
+ private function buildEditResponse($object) {
+ $viewer = $this->getViewer();
+ $controller = $this->getController();
+ $request = $controller->getRequest();
+
+ $fields = $this->buildEditFields($object);
+ $template = $object->getApplicationTransactionTemplate();
+
+ $validation_exception = null;
+ if ($request->isFormPost()) {
+ foreach ($fields as $field) {
+ $field->readValueFromSubmit($request);
+ }
+
+ $xactions = array();
+ foreach ($fields as $field) {
+ $xactions[] = $field->generateTransaction(clone $template);
+ }
+
+ $editor = $object->getApplicationTransactionEditor()
+ ->setActor($viewer)
+ ->setContentSourceFromRequest($request)
+ ->setContinueOnNoEffect(true);
+
+ try {
+
+ $editor->applyTransactions($object, $xactions);
+
+ return id(new AphrontRedirectResponse())
+ ->setURI($this->getObjectViewURI($object));
+ } catch (PhabricatorApplicationTransactionValidationException $ex) {
+ $validation_exception = $ex;
+ }
+ } else {
+ if ($this->getIsCreate()) {
+ foreach ($fields as $field) {
+ $field->readValueFromRequest($request);
+ }
+ } else {
+ foreach ($fields as $field) {
+ $field->readValueFromObject($object);
+ }
+ }
+ }
+
+ $action_button = $this->buildEditFormActionButton($object);
+
+ if ($this->getIsCreate()) {
+ $header_text = $this->getObjectCreateTitleText($object);
+ } else {
+ $header_text = $this->getObjectEditTitleText($object);
+ }
+
+ $header = id(new PHUIHeaderView())
+ ->setHeader($header_text)
+ ->addActionLink($action_button);
+
+ $crumbs = $this->buildCrumbs($object, $final = true);
+ $form = $this->buildEditForm($object, $fields);
+
+ $box = id(new PHUIObjectBoxView())
+ ->setUser($viewer)
+ ->setHeader($header)
+ ->setValidationException($validation_exception)
+ ->appendChild($form);
+
+ return $controller->newPage()
+ ->setTitle($header_text)
+ ->setCrumbs($crumbs)
+ ->appendChild($box);
+ }
+
+ private function buildEditForm($object, array $fields) {
+ $viewer = $this->getViewer();
+
+ $form = id(new AphrontFormView())
+ ->setUser($viewer);
+
+ foreach ($fields as $field) {
+ $field->appendToForm($form);
+ }
+
+ if ($this->getIsCreate()) {
+ $cancel_uri = $this->getObjectCreateCancelURI($object);
+ $submit_button = $this->getObjectCreateButtonText($object);
+ } else {
+ $cancel_uri = $this->getObjectEditCancelURI($object);
+ $submit_button = $this->getObjectEditButtonText($object);
+ }
+
+ $form->appendControl(
+ id(new AphrontFormSubmitControl())
+ ->addCancelButton($cancel_uri)
+ ->setValue($submit_button));
+
+ return $form;
+ }
+
+ private function buildEditFormActionButton($object) {
+ $viewer = $this->getViewer();
+
+ $action_view = id(new PhabricatorActionListView())
+ ->setUser($viewer);
+
+ foreach ($this->buildEditFormActions($object) as $action) {
+ $action_view->addAction($action);
+ }
+
+ $action_button = id(new PHUIButtonView())
+ ->setTag('a')
+ ->setText(pht('Actions'))
+ ->setHref('#')
+ ->setIconFont('fa-bars')
+ ->setDropdownMenu($action_view);
+
+ return $action_button;
+ }
+
+ private function buildEditFormActions($object) {
+ $actions = array();
+
+ $actions[] = id(new PhabricatorActionView())
+ ->setName(pht('Show HTTP Parameters'))
+ ->setIcon('fa-crosshairs')
+ ->setHref($this->getEditURI($object, 'parameters/'));
+
+ return $actions;
+ }
+
+
+/* -( Responding to HTTP Parameter Requests )------------------------------ */
+
+
+ /**
+ * Respond to a request for documentation on HTTP parameters.
+ *
+ * @param object Editable object.
+ * @return AphrontResponse Response object.
+ * @task http
+ */
+ private function buildParametersResponse($object) {
+ $controller = $this->getController();
+ $viewer = $this->getViewer();
+ $request = $controller->getRequest();
+ $fields = $this->buildEditFields($object);
+
+ $crumbs = $this->buildCrumbs($object);
+ $crumbs->addTextCrumb(pht('HTTP Parameters'));
+ $crumbs->setBorder(true);
+
+ $header_text = pht(
+ 'HTTP Parameters: %s',
+ $this->getObjectCreateShortText($object));
+
+ $header = id(new PHUIHeaderView())
+ ->setHeader($header_text);
+
+ $help_view = id(new PhabricatorApplicationEditHTTPParameterHelpView())
+ ->setUser($viewer)
+ ->setFields($fields);
+
+ $document = id(new PHUIDocumentViewPro())
+ ->setUser($viewer)
+ ->setHeader($header)
+ ->appendChild($help_view);
+
+ return $controller->newPage()
+ ->setTitle(pht('HTTP Parameters'))
+ ->setCrumbs($crumbs)
+ ->addClass('pro-white-background')
+ ->appendChild($document);
+ }
+
+
+/* -( Conduit )------------------------------------------------------------ */
+
+
+ /**
+ * Respond to a Conduit edit request.
+ *
+ * This method accepts a list of transactions to apply to an object, and
+ * either edits an existing object or creates a new one.
+ *
+ * @task conduit
+ */
+ final public function buildConduitResponse(ConduitAPIRequest $request) {
+ $viewer = $this->getViewer();
+
+ $phid = $request->getValue('objectPHID');
+ if ($phid) {
+ $this->setIsCreate(false);
+ $object = $this->newObjectFromPHID($phid);
+ if (!$object) {
+ throw new Exception(pht('No such object with PHID "%s".', $phid));
+ }
+ } else {
+ $this->setIsCreate(true);
+ $object = $this->newEditableObject();
+ }
+
+ $fields = $this->buildEditFields($object);
+
+ $types = $this->getAllEditTypesFromFields($fields);
+ $template = $object->getApplicationTransactionTemplate();
+
+ $xactions = $this->getConduitTransactions($request, $types, $template);
+
+ $editor = $object->getApplicationTransactionEditor()
+ ->setActor($viewer)
+ ->setContentSourceFromConduitRequest($request)
+ ->setContinueOnNoEffect(true);
+
+ $xactions = $editor->applyTransactions($object, $xactions);
+
+ $xactions_struct = array();
+ foreach ($xactions as $xaction) {
+ $xactions_struct[] = array(
+ 'phid' => $xaction->getPHID(),
+ );
+ }
+
+ return array(
+ 'object' => array(
+ 'id' => $object->getID(),
+ 'phid' => $object->getPHID(),
+ ),
+ 'transactions' => $xactions_struct,
+ );
+ }
+
+
+ /**
+ * Generate transactions which can be applied from edit actions in a Conduit
+ * request.
+ *
+ * @param ConduitAPIRequest The request.
+ * @param list Supported edit types.
+ * @param PhabricatorApplicationTransaction Template transaction.
+ * @return list Generated transactions.
+ * @task conduit
+ */
+ private function getConduitTransactions(
+ ConduitAPIRequest $request,
+ array $types,
+ PhabricatorApplicationTransaction $template) {
+
+ $transactions_key = 'transactions';
+
+ $xactions = $request->getValue($transactions_key);
+ if (!is_array($xactions)) {
+ throw new Exception(
+ pht(
+ 'Parameter "%s" is not a list of transactions.',
+ $transactions_key));
+ }
+
+ foreach ($xactions as $key => $xaction) {
+ if (!is_array($xaction)) {
+ throw new Exception(
+ pht(
+ 'Parameter "%s" must contain a list of transaction descriptions, '.
+ 'but item with key "%s" is not a dictionary.',
+ $transactions_key,
+ $key));
+ }
+
+ if (!array_key_exists('type', $xaction)) {
+ throw new Exception(
+ pht(
+ 'Parameter "%s" must contain a list of transaction descriptions, '.
+ 'but item with key "%s" is missing a "type" field. Each '.
+ 'transaction must have a type field.',
+ $transactions_key,
+ $key));
+ }
+
+ $type = $xaction['type'];
+ if (empty($types[$type])) {
+ throw new Exception(
+ pht(
+ 'Transaction with key "%s" has invalid type "%s". This type is '.
+ 'not recognized. Valid types are: %s.',
+ $key,
+ $type,
+ implode(', ', array_keys($types))));
+ }
+ }
+
+ $results = array();
+ foreach ($xactions as $xaction) {
+ $type = $types[$xaction['type']];
+
+ $results[] = $type->generateTransaction(
+ clone $template,
+ $xaction);
+ }
+
+ return $results;
+ }
+
+
+ /**
+ * @return map
+ * @task conduit
+ */
+ private function getAllEditTypesFromFields(array $fields) {
+ $types = array();
+ foreach ($fields as $field) {
+ $field_types = $field->getEditTransactionTypes();
+ foreach ($field_types as $field_type) {
+ $field_type->setField($field);
+ $types[$field_type->getEditType()] = $field_type;
+ }
+ }
+ return $types;
+ }
+
+ public function getAllEditTypes() {
+ $object = $this->newEditableObject();
+ $fields = $this->buildEditFields($object);
+ return $this->getAllEditTypesFromFields($fields);
+ }
+
+
+}
diff --git a/src/applications/transactions/editengine/PhabricatorApplicationEditEngineAPIMethod.php b/src/applications/transactions/editengine/PhabricatorApplicationEditEngineAPIMethod.php
new file mode 100644
index 0000000000..9fc6495455
--- /dev/null
+++ b/src/applications/transactions/editengine/PhabricatorApplicationEditEngineAPIMethod.php
@@ -0,0 +1,188 @@
+ 'list