Merge branch 'master' into blender-tweaks

Conflicts:
	resources/celerity/map.php
	src/applications/maniphest/controller/ManiphestTaskListController.php
This commit is contained in:
2014-11-01 17:23:50 +05:00
288 changed files with 7950 additions and 1228 deletions

View File

@@ -7,14 +7,14 @@
*/
return array(
'names' => array(
'core.pkg.css' => 'a3c49f47',
'core.pkg.css' => '85697954',
'core.pkg.js' => 'cbdbd552',
'darkconsole.pkg.js' => 'df001cab',
'differential.pkg.css' => '0f9c3082',
'differential.pkg.css' => '8af45893',
'differential.pkg.js' => '73337d1d',
'diffusion.pkg.css' => '591664fa',
'diffusion.pkg.js' => 'bfc0737b',
'maniphest.pkg.css' => 'f5d89daf',
'maniphest.pkg.css' => 'e34dfbec',
'maniphest.pkg.js' => 'df4aa49f',
'rsrc/css/aphront/aphront-bars.css' => '231ac33c',
'rsrc/css/aphront/context-bar.css' => '1c3b0529',
@@ -24,7 +24,7 @@ return array(
'rsrc/css/aphront/lightbox-attachment.css' => '7acac05d',
'rsrc/css/aphront/list-filter-view.css' => '2ae43867',
'rsrc/css/aphront/multi-column.css' => '1b95ab2e',
'rsrc/css/aphront/notification.css' => 'ef2c9b34',
'rsrc/css/aphront/notification.css' => '9c279160',
'rsrc/css/aphront/pager-view.css' => '2e3539af',
'rsrc/css/aphront/panel-view.css' => '5846dfa2',
'rsrc/css/aphront/phabricator-nav-view.css' => '9283c2df',
@@ -60,7 +60,7 @@ return array(
'rsrc/css/application/differential/revision-comment.css' => '48186045',
'rsrc/css/application/differential/revision-history.css' => '0e8eb855',
'rsrc/css/application/differential/revision-list.css' => 'f3c47d33',
'rsrc/css/application/differential/table-of-contents.css' => '6bf8e1d2',
'rsrc/css/application/differential/table-of-contents.css' => '63f3ef4a',
'rsrc/css/application/diffusion/diffusion-icons.css' => '9c5828da',
'rsrc/css/application/diffusion/diffusion-source.css' => '66fdf661',
'rsrc/css/application/feed/feed.css' => '7bfc6f12',
@@ -72,15 +72,15 @@ return array(
'rsrc/css/application/maniphest/batch-editor.css' => '8f380ebc',
'rsrc/css/application/maniphest/report.css' => '6fc16517',
'rsrc/css/application/maniphest/task-edit.css' => '8e23031b',
'rsrc/css/application/maniphest/task-summary.css' => '00c3be7a',
'rsrc/css/application/maniphest/task-summary.css' => '13ed8360',
'rsrc/css/application/objectselector/object-selector.css' => '029a133d',
'rsrc/css/application/owners/owners-path-editor.css' => '2f00933b',
'rsrc/css/application/paste/paste.css' => 'aa1767d1',
'rsrc/css/application/people/people-profile.css' => '5402f7a5',
'rsrc/css/application/people/people-profile.css' => '0d5f6498',
'rsrc/css/application/phame/phame.css' => '19ecc703',
'rsrc/css/application/pholio/pholio-edit.css' => '3ad9d1ee',
'rsrc/css/application/pholio/pholio-inline-comments.css' => '8e545e49',
'rsrc/css/application/pholio/pholio.css' => '47dffb9c',
'rsrc/css/application/pholio/pholio.css' => '95174bdd',
'rsrc/css/application/phortune/phortune-credit-card-form.css' => 'b25b4beb',
'rsrc/css/application/phortune/phortune.css' => '9149f103',
'rsrc/css/application/phrequent/phrequent.css' => 'ffc185ad',
@@ -104,12 +104,12 @@ return array(
'rsrc/css/application/uiexample/example.css' => '528b19de',
'rsrc/css/core/core.css' => '40151074',
'rsrc/css/core/remarkup.css' => '45313445',
'rsrc/css/core/syntax.css' => '863f3cd8',
'rsrc/css/core/syntax.css' => '56c1ba38',
'rsrc/css/core/z-index.css' => '44e1d311',
'rsrc/css/diviner/diviner-shared.css' => '38813222',
'rsrc/css/font/font-awesome.css' => '73d075c3',
'rsrc/css/font/font-source-sans-pro.css' => '91d53463',
'rsrc/css/font/phui-font-icon-base.css' => 'eb84f033',
'rsrc/css/font/phui-font-icon-base.css' => '3dad2ae3',
'rsrc/css/layout/phabricator-action-header-view.css' => '83e2cc86',
'rsrc/css/layout/phabricator-crumbs-view.css' => 'a49339de',
'rsrc/css/layout/phabricator-filetree-view.css' => 'fccf9f82',
@@ -119,13 +119,13 @@ return array(
'rsrc/css/phui/calendar/phui-calendar-day.css' => 'de035c8a',
'rsrc/css/phui/calendar/phui-calendar-list.css' => 'c1d0ca59',
'rsrc/css/phui/calendar/phui-calendar-month.css' => 'a92e47d2',
'rsrc/css/phui/calendar/phui-calendar.css' => '5e1ad989',
'rsrc/css/phui/calendar/phui-calendar.css' => '8675968e',
'rsrc/css/phui/phui-action-list.css' => '9ee9910a',
'rsrc/css/phui/phui-box.css' => '7b3a2eed',
'rsrc/css/phui/phui-button.css' => 'c7412aa1',
'rsrc/css/phui/phui-document.css' => 'a5615198',
'rsrc/css/phui/phui-feed-story.css' => '55dc7732',
'rsrc/css/phui/phui-fontkit.css' => 'fff25cfa',
'rsrc/css/phui/phui-fontkit.css' => '9c3d2dce',
'rsrc/css/phui/phui-form-view.css' => '1ff38f33',
'rsrc/css/phui/phui-form.css' => 'b78ec020',
'rsrc/css/phui/phui-header-view.css' => '39594ac0',
@@ -134,15 +134,15 @@ return array(
'rsrc/css/phui/phui-info-panel.css' => '27ea50a1',
'rsrc/css/phui/phui-list.css' => '43ed2d93',
'rsrc/css/phui/phui-object-box.css' => 'e9f7e938',
'rsrc/css/phui/phui-object-item-list-view.css' => 'e1e6425f',
'rsrc/css/phui/phui-object-item-list-view.css' => '5053dee8',
'rsrc/css/phui/phui-pinboard-view.css' => '3dd4a269',
'rsrc/css/phui/phui-property-list-view.css' => '86f9df88',
'rsrc/css/phui/phui-remarkup-preview.css' => '19ad512b',
'rsrc/css/phui/phui-spacing.css' => '042804d6',
'rsrc/css/phui/phui-status.css' => '2f562399',
'rsrc/css/phui/phui-tag-view.css' => 'c4158073',
'rsrc/css/phui/phui-text.css' => '23e9b4b7',
'rsrc/css/phui/phui-timeline-view.css' => 'bbd990d0',
'rsrc/css/phui/phui-status.css' => '888cedb8',
'rsrc/css/phui/phui-tag-view.css' => 'b0c282e0',
'rsrc/css/phui/phui-text.css' => 'cf019f54',
'rsrc/css/phui/phui-timeline-view.css' => '8c6fefe7',
'rsrc/css/phui/phui-workboard-view.css' => '2bf82d00',
'rsrc/css/phui/phui-workpanel-view.css' => '198c7e6c',
'rsrc/css/sprite-apps-large.css' => '20ec0cc0',
@@ -150,7 +150,7 @@ return array(
'rsrc/css/sprite-conpherence.css' => '3b4a0487',
'rsrc/css/sprite-docs.css' => '5f65d0da',
'rsrc/css/sprite-gradient.css' => '4bdb98a7',
'rsrc/css/sprite-login.css' => 'cf08ac44',
'rsrc/css/sprite-login.css' => 'a355d921',
'rsrc/css/sprite-main-header.css' => '92720ee2',
'rsrc/css/sprite-menu.css' => '8fead76a',
'rsrc/css/sprite-payments.css' => 'cc085d44',
@@ -323,8 +323,8 @@ return array(
'rsrc/image/sprite-docs-X2.png' => '6dc1adad',
'rsrc/image/sprite-docs.png' => '4636297f',
'rsrc/image/sprite-gradient.png' => 'ec15a417',
'rsrc/image/sprite-login-X2.png' => '46f95dcc',
'rsrc/image/sprite-login.png' => '4e0e66ee',
'rsrc/image/sprite-login-X2.png' => '5ae6de3a',
'rsrc/image/sprite-login.png' => '07f2c67c',
'rsrc/image/sprite-main-header.png' => '83521873',
'rsrc/image/sprite-menu-X2.png' => '39d78f97',
'rsrc/image/sprite-menu.png' => '259dab45',
@@ -524,7 +524,7 @@ return array(
'differential-revision-comment-css' => '48186045',
'differential-revision-history-css' => '0e8eb855',
'differential-revision-list-css' => 'f3c47d33',
'differential-table-of-contents-css' => '6bf8e1d2',
'differential-table-of-contents-css' => '63f3ef4a',
'diffusion-icons-css' => '9c5828da',
'diffusion-source-css' => '66fdf661',
'diviner-shared-css' => '38813222',
@@ -692,13 +692,13 @@ return array(
'maniphest-batch-editor' => '8f380ebc',
'maniphest-report-css' => '6fc16517',
'maniphest-task-edit-css' => '8e23031b',
'maniphest-task-summary-css' => '00c3be7a',
'maniphest-task-summary-css' => '13ed8360',
'multirow-row-manager' => '41e47dea',
'owners-path-editor' => 'aa1733d0',
'owners-path-editor-css' => '2f00933b',
'paste-css' => 'aa1767d1',
'path-typeahead' => 'f7fc67ec',
'people-profile-css' => '5402f7a5',
'people-profile-css' => '0d5f6498',
'phabricator-action-list-view-css' => '9ee9910a',
'phabricator-application-launch-view-css' => '5d71008f',
'phabricator-busy' => '6453c869',
@@ -722,7 +722,7 @@ return array(
'phabricator-main-menu-view' => 'a1c976b2',
'phabricator-nav-view-css' => '9283c2df',
'phabricator-notification' => '0c6946e7',
'phabricator-notification-css' => 'ef2c9b34',
'phabricator-notification-css' => '9c279160',
'phabricator-notification-menu-css' => '6aa0a74b',
'phabricator-object-selector-css' => '029a133d',
'phabricator-phtize' => 'd254d646',
@@ -753,7 +753,7 @@ return array(
'phabricator-welcome-page' => 'c370f13b',
'phabricator-zindex-css' => '44e1d311',
'phame-css' => '19ecc703',
'pholio-css' => '47dffb9c',
'pholio-css' => '95174bdd',
'pholio-edit-css' => '3ad9d1ee',
'pholio-inline-comments-css' => '8e545e49',
'phortune-credit-card-form' => '2290aeef',
@@ -764,14 +764,14 @@ return array(
'phui-action-header-view-css' => '83e2cc86',
'phui-box-css' => '7b3a2eed',
'phui-button-css' => 'c7412aa1',
'phui-calendar-css' => '5e1ad989',
'phui-calendar-css' => '8675968e',
'phui-calendar-day-css' => 'de035c8a',
'phui-calendar-list-css' => 'c1d0ca59',
'phui-calendar-month-css' => 'a92e47d2',
'phui-document-view-css' => 'a5615198',
'phui-feed-story-css' => '55dc7732',
'phui-font-icon-base-css' => 'eb84f033',
'phui-fontkit-css' => 'fff25cfa',
'phui-font-icon-base-css' => '3dad2ae3',
'phui-fontkit-css' => '9c3d2dce',
'phui-form-css' => 'b78ec020',
'phui-form-view-css' => '1ff38f33',
'phui-header-view-css' => '39594ac0',
@@ -780,15 +780,15 @@ return array(
'phui-info-panel-css' => '27ea50a1',
'phui-list-view-css' => '43ed2d93',
'phui-object-box-css' => 'e9f7e938',
'phui-object-item-list-view-css' => 'e1e6425f',
'phui-object-item-list-view-css' => '5053dee8',
'phui-pinboard-view-css' => '3dd4a269',
'phui-property-list-view-css' => '86f9df88',
'phui-remarkup-preview-css' => '19ad512b',
'phui-spacing-css' => '042804d6',
'phui-status-list-view-css' => '2f562399',
'phui-tag-view-css' => 'c4158073',
'phui-text-css' => '23e9b4b7',
'phui-timeline-view-css' => 'bbd990d0',
'phui-status-list-view-css' => '888cedb8',
'phui-tag-view-css' => 'b0c282e0',
'phui-text-css' => 'cf019f54',
'phui-timeline-view-css' => '8c6fefe7',
'phui-workboard-view-css' => '2bf82d00',
'phui-workpanel-view-css' => '198c7e6c',
'phuix-action-list-view' => 'b5c256b8',
@@ -815,13 +815,13 @@ return array(
'sprite-conpherence-css' => '3b4a0487',
'sprite-docs-css' => '5f65d0da',
'sprite-gradient-css' => '4bdb98a7',
'sprite-login-css' => 'cf08ac44',
'sprite-login-css' => 'a355d921',
'sprite-main-header-css' => '92720ee2',
'sprite-menu-css' => '8fead76a',
'sprite-payments-css' => 'cc085d44',
'sprite-projects-css' => '7578fa56',
'sprite-tokens-css' => '1706b943',
'syntax-highlighting-css' => '863f3cd8',
'syntax-highlighting-css' => '56c1ba38',
'tokens-css' => '3d0f239e',
),
'requires' => array(

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@@ -74,7 +74,7 @@
"login-MediaWiki" : {
"name" : "login-MediaWiki",
"rule" : ".login-MediaWiki",
"hash" : "6e9e75fdad545f415d78719bd2dee3ec"
"hash" : "51c7e71ab0e44126e72d8a130779b02c"
},
"login-Openid" : {
"name" : "login-Openid",

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_phortune.phortune_merchant
DROP editPolicy;

View File

@@ -0,0 +1,19 @@
CREATE TABLE {$NAMESPACE}_phortune.phortune_carttransaction (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
phid VARCHAR(64) COLLATE utf8_bin NOT NULL,
authorPHID VARCHAR(64) COLLATE utf8_bin NOT NULL,
objectPHID VARCHAR(64) COLLATE utf8_bin NOT NULL,
viewPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL,
editPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL,
commentPHID VARCHAR(64) COLLATE utf8_bin DEFAULT NULL,
commentVersion INT UNSIGNED NOT NULL,
transactionType VARCHAR(32) COLLATE utf8_bin NOT NULL,
oldValue LONGTEXT COLLATE utf8_bin NOT NULL,
newValue LONGTEXT COLLATE utf8_bin NOT NULL,
contentSource LONGTEXT COLLATE utf8_bin NOT NULL,
metadata LONGTEXT COLLATE utf8_bin NOT NULL,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL,
UNIQUE KEY `key_phid` (`phid`),
KEY `key_object` (`objectPHID`)
) ENGINE=InnoDB, COLLATE utf8_general_ci;

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_phortune.phortune_cart
ADD mailKey BINARY(20) NOT NULL;

View File

@@ -0,0 +1,22 @@
TRUNCATE TABLE {$NAMESPACE}_almanac.almanac_device;
ALTER TABLE {$NAMESPACE}_almanac.almanac_device
CHANGE name name VARCHAR(128) NOT NULL COLLATE utf8_bin;
ALTER TABLE {$NAMESPACE}_almanac.almanac_device
ADD nameIndex BINARY(12) NOT NULL;
ALTER TABLE {$NAMESPACE}_almanac.almanac_device
ADD mailKey BINARY(20) NOT NULL;
ALTER TABLE {$NAMESPACE}_almanac.almanac_device
ADD UNIQUE KEY `key_name` (nameIndex);
ALTER TABLE {$NAMESPACE}_almanac.almanac_device
ADD KEY `key_nametext` (name);
ALTER TABLE {$NAMESPACE}_almanac.almanac_device
ADD viewPolicy VARBINARY(64) NOT NULL;
ALTER TABLE {$NAMESPACE}_almanac.almanac_device
ADD editPolicy VARBINARY(64) NOT NULL;

View File

@@ -0,0 +1,19 @@
CREATE TABLE {$NAMESPACE}_almanac.almanac_devicetransaction (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
phid VARCHAR(64) COLLATE utf8_bin NOT NULL,
authorPHID VARCHAR(64) COLLATE utf8_bin NOT NULL,
objectPHID VARCHAR(64) COLLATE utf8_bin NOT NULL,
viewPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL,
editPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL,
commentPHID VARCHAR(64) COLLATE utf8_bin DEFAULT NULL,
commentVersion INT UNSIGNED NOT NULL,
transactionType VARCHAR(32) COLLATE utf8_bin NOT NULL,
oldValue LONGTEXT COLLATE utf8_bin NOT NULL,
newValue LONGTEXT COLLATE utf8_bin NOT NULL,
contentSource LONGTEXT COLLATE utf8_bin NOT NULL,
metadata LONGTEXT COLLATE utf8_bin NOT NULL,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL,
UNIQUE KEY `key_phid` (`phid`),
KEY `key_object` (`objectPHID`)
) ENGINE=InnoDB, COLLATE utf8_general_ci;

View File

@@ -0,0 +1,13 @@
CREATE TABLE {$NAMESPACE}_almanac.almanac_interface (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
phid VARBINARY(64) NOT NULL,
devicePHID VARBINARY(64) NOT NULL,
networkPHID VARBINARY(64) NOT NULL,
address VARCHAR(128) NOT NULL COLLATE utf8_bin,
port INT UNSIGNED NOT NULL,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL,
UNIQUE KEY `key_phid` (phid),
KEY `key_location` (networkPHID, address, port),
KEY `key_device` (devicePHID)
) ENGINE=InnoDB, COLLATE utf8_general_ci;

View File

@@ -0,0 +1,11 @@
CREATE TABLE {$NAMESPACE}_almanac.almanac_network (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
phid VARBINARY(64) NOT NULL,
name VARCHAR(128) NOT NULL COLLATE utf8_bin,
mailKey BINARY(20) NOT NULL,
viewPolicy VARBINARY(64) NOT NULL,
editPolicy VARBINARY(64) NOT NULL,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL,
UNIQUE KEY `key_phid` (phid)
) ENGINE=InnoDB, COLLATE utf8_general_ci;

View File

@@ -0,0 +1,19 @@
CREATE TABLE {$NAMESPACE}_almanac.almanac_networktransaction (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
phid VARCHAR(64) COLLATE utf8_bin NOT NULL,
authorPHID VARCHAR(64) COLLATE utf8_bin NOT NULL,
objectPHID VARCHAR(64) COLLATE utf8_bin NOT NULL,
viewPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL,
editPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL,
commentPHID VARCHAR(64) COLLATE utf8_bin DEFAULT NULL,
commentVersion INT UNSIGNED NOT NULL,
transactionType VARCHAR(32) COLLATE utf8_bin NOT NULL,
oldValue LONGTEXT COLLATE utf8_bin NOT NULL,
newValue LONGTEXT COLLATE utf8_bin NOT NULL,
contentSource LONGTEXT COLLATE utf8_bin NOT NULL,
metadata LONGTEXT COLLATE utf8_bin NOT NULL,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL,
UNIQUE KEY `key_phid` (`phid`),
KEY `key_object` (`objectPHID`)
) ENGINE=InnoDB, COLLATE utf8_general_ci;

View File

@@ -0,0 +1,14 @@
CREATE TABLE {$NAMESPACE}_almanac.almanac_service (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
phid VARBINARY(64) NOT NULL,
name VARCHAR(128) NOT NULL COLLATE utf8_bin,
nameIndex BINARY(12) NOT NULL,
mailKey BINARY(20) NOT NULL,
viewPolicy VARBINARY(64) NOT NULL,
editPolicy VARBINARY(64) NOT NULL,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL,
UNIQUE KEY `key_phid` (phid),
UNIQUE KEY `key_name` (nameIndex),
KEY `key_nametext` (name)
) ENGINE=InnoDB, COLLATE utf8_general_ci;

View File

@@ -0,0 +1,19 @@
CREATE TABLE {$NAMESPACE}_almanac.almanac_servicetransaction (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
phid VARCHAR(64) COLLATE utf8_bin NOT NULL,
authorPHID VARCHAR(64) COLLATE utf8_bin NOT NULL,
objectPHID VARCHAR(64) COLLATE utf8_bin NOT NULL,
viewPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL,
editPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL,
commentPHID VARCHAR(64) COLLATE utf8_bin DEFAULT NULL,
commentVersion INT UNSIGNED NOT NULL,
transactionType VARCHAR(32) COLLATE utf8_bin NOT NULL,
oldValue LONGTEXT COLLATE utf8_bin NOT NULL,
newValue LONGTEXT COLLATE utf8_bin NOT NULL,
contentSource LONGTEXT COLLATE utf8_bin NOT NULL,
metadata LONGTEXT COLLATE utf8_bin NOT NULL,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL,
UNIQUE KEY `key_phid` (`phid`),
KEY `key_object` (`objectPHID`)
) ENGINE=InnoDB, COLLATE utf8_general_ci;

View File

@@ -0,0 +1,14 @@
CREATE TABLE {$NAMESPACE}_almanac.almanac_binding (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
phid VARBINARY(64) NOT NULL,
servicePHID VARBINARY(64) NOT NULL,
devicePHID VARBINARY(64) NOT NULL,
interfacePHID VARBINARY(64) NOT NULL,
mailKey BINARY(20) NOT NULL,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL,
UNIQUE KEY `key_phid` (phid),
UNIQUE KEY `key_service` (servicePHID, interfacePHID),
KEY `key_device` (devicePHID),
KEY `key_interface` (interfacePHID)
) ENGINE=InnoDB, COLLATE utf8_general_ci;

View File

@@ -0,0 +1,19 @@
CREATE TABLE {$NAMESPACE}_almanac.almanac_bindingtransaction (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
phid VARCHAR(64) COLLATE utf8_bin NOT NULL,
authorPHID VARCHAR(64) COLLATE utf8_bin NOT NULL,
objectPHID VARCHAR(64) COLLATE utf8_bin NOT NULL,
viewPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL,
editPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL,
commentPHID VARCHAR(64) COLLATE utf8_bin DEFAULT NULL,
commentVersion INT UNSIGNED NOT NULL,
transactionType VARCHAR(32) COLLATE utf8_bin NOT NULL,
oldValue LONGTEXT COLLATE utf8_bin NOT NULL,
newValue LONGTEXT COLLATE utf8_bin NOT NULL,
contentSource LONGTEXT COLLATE utf8_bin NOT NULL,
metadata LONGTEXT COLLATE utf8_bin NOT NULL,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL,
UNIQUE KEY `key_phid` (`phid`),
KEY `key_object` (`objectPHID`)
) ENGINE=InnoDB, COLLATE utf8_general_ci;

View File

@@ -0,0 +1,19 @@
CREATE TABLE {$NAMESPACE}_phriction.phriction_transaction (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
phid VARCHAR(64) COLLATE utf8_bin NOT NULL,
authorPHID VARCHAR(64) COLLATE utf8_bin NOT NULL,
objectPHID VARCHAR(64) COLLATE utf8_bin NOT NULL,
viewPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL,
editPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL,
commentPHID VARCHAR(64) COLLATE utf8_bin DEFAULT NULL,
commentVersion INT UNSIGNED NOT NULL,
transactionType VARCHAR(32) COLLATE utf8_bin NOT NULL,
oldValue LONGTEXT COLLATE utf8_bin NOT NULL,
newValue LONGTEXT COLLATE utf8_bin NOT NULL,
contentSource LONGTEXT COLLATE utf8_bin NOT NULL,
metadata LONGTEXT COLLATE utf8_bin NOT NULL,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL,
UNIQUE KEY `key_phid` (`phid`),
KEY `key_object` (`objectPHID`)
) ENGINE=InnoDB, COLLATE utf8_general_ci;

View File

@@ -0,0 +1,16 @@
CREATE TABLE {$NAMESPACE}_phriction.phriction_transaction_comment (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
phid VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
transactionPHID VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
authorPHID VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
viewPolicy VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
editPolicy VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
commentVersion INT UNSIGNED NOT NULL,
content LONGTEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
contentSource LONGTEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
isDeleted TINYINT(1) NOT NULL,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL,
UNIQUE KEY `key_phid` (`phid`),
UNIQUE KEY `key_version` (`transactionPHID`,`commentVersion`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

View File

@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_phriction.phriction_document
ADD mailKey VARCHAR(20) NOT NULL COLLATE utf8_bin;

View File

@@ -1,6 +1,6 @@
create table {$NAMESPACE}_project.project (
id int unsigned not null auto_increment primary key,
name varchar(255) not null,
name varchar(255) COLLATE `binary` not null,
unique key (name),
phid varchar(64) binary not null,
authorPHID varchar(64) binary not null,

View File

@@ -1,8 +1,8 @@
create table {$NAMESPACE}_user.user_oauthinfo (
id int unsigned not null auto_increment primary key,
userID int unsigned not null,
oauthProvider varchar(255) not null,
oauthUID varchar(255) not null,
oauthProvider varchar(255) COLLATE `binary` not null,
oauthUID varchar(255) COLLATE `binary` not null,
unique key (userID, oauthProvider),
unique key (oauthProvider, oauthUID),
dateCreated int unsigned not null,

View File

@@ -23,6 +23,6 @@ create table {$NAMESPACE}_timeline.timeline_eventdata (
);
create table {$NAMESPACE}_timeline.timeline_cursor (
name varchar(255) not null primary key,
name varchar(255) COLLATE `binary` not null primary key,
position int unsigned not null
);

View File

@@ -7,7 +7,7 @@ CREATE TABLE {$NAMESPACE}_herald.herald_action (
CREATE TABLE {$NAMESPACE}_herald.herald_rule (
id int unsigned not null auto_increment primary key,
name varchar(255) not null,
name varchar(255) COLLATE `binary` not null,
authorPHID varchar(64) binary not null,
contentType varchar(255) not null,
mustMatchAll bool not null,

View File

@@ -1,4 +1,4 @@
CREATE TABLE {$NAMESPACE}_repository.repository_badcommit (
fullCommitName varchar(255) binary not null primary key,
fullCommitName varchar(255) COLLATE `binary` not null primary key,
description longblob not null
);

View File

@@ -2,7 +2,7 @@ CREATE TABLE {$NAMESPACE}_owners.owners_package (
id int unsigned not null auto_increment primary key,
phid varchar(64) binary not null,
unique key(phid),
name varchar(255) not null,
name varchar(255) COLLATE `binary` not null,
unique key(name),
description text not null,
primaryOwnerPHID varchar(64) binary

View File

@@ -2,7 +2,7 @@ CREATE TABLE {$NAMESPACE}_repository.repository_arcanistproject (
id int unsigned not null auto_increment primary key,
phid varchar(64) binary not null,
unique key(phid),
name varchar(255) not null,
name varchar(255) COLLATE `binary` not null,
unique key (name),
repositoryID int unsigned
);

View File

@@ -1,6 +1,6 @@
CREATE TABLE {$NAMESPACE}_file.file_proxyimage (
id int unsigned not null primary key auto_increment,
uri varchar(255) binary not null,
uri varchar(255) COLLATE `binary` not null,
unique key(uri),
filePHID varchar(64) binary not null
) ENGINE=InnoDB;

View File

@@ -1,7 +1,7 @@
CREATE TABLE {$NAMESPACE}_file.file_transformedfile (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
originalPHID varchar(64) BINARY NOT NULL,
transform varchar(255) BINARY NOT NULL,
originalPHID varchar(64) COLLATE `binary` NOT NULL,
transform varchar(255) COLLATE `binary` NOT NULL,
unique key (originalPHID, transform),
transformedPHID varchar(64) BINARY NOT NULL,
key (transformedPHID),

View File

@@ -1,7 +1,7 @@
create table {$NAMESPACE}_maniphest.maniphest_taskauxiliarystorage
(id int unsigned not null auto_increment primary key,
taskPHID varchar(64) binary not null,
name varchar(255) not null,
name varchar(255) COLLATE `binary` not null,
value varchar(255) not null,
unique key (taskPHID,name),
dateCreated int unsigned not null,

View File

@@ -64,6 +64,13 @@ try {
'help' => 'Do not actually change anything, just show what would be '.
'changed.',
),
array(
'name' => 'disable-utf8mb4',
'help' => pht(
'Disable utf8mb4, even if the database supports it. This is an '.
'advanced feature used for testing changes to Phabricator; you '.
'should not normally use this flag.'),
)
));
} catch (PhutilArgumentUsageException $ex) {
$args->printUsageException($ex);
@@ -126,6 +133,7 @@ $api->setHost($default_host);
$api->setPort($default_port);
$api->setPassword($password);
$api->setNamespace($args->getArg('namespace'));
$api->setDisableUTF8MB4($args->getArg('disable-utf8mb4'));
try {
queryfx(

View File

@@ -9,14 +9,67 @@
phutil_register_library_map(array(
'__library_version__' => 2,
'class' => array(
'AlmanacAddress' => 'applications/almanac/util/AlmanacAddress.php',
'AlmanacBinding' => 'applications/almanac/storage/AlmanacBinding.php',
'AlmanacBindingEditController' => 'applications/almanac/controller/AlmanacBindingEditController.php',
'AlmanacBindingEditor' => 'applications/almanac/editor/AlmanacBindingEditor.php',
'AlmanacBindingPHIDType' => 'applications/almanac/phid/AlmanacBindingPHIDType.php',
'AlmanacBindingQuery' => 'applications/almanac/query/AlmanacBindingQuery.php',
'AlmanacBindingTableView' => 'applications/almanac/view/AlmanacBindingTableView.php',
'AlmanacBindingTransaction' => 'applications/almanac/storage/AlmanacBindingTransaction.php',
'AlmanacBindingTransactionQuery' => 'applications/almanac/query/AlmanacBindingTransactionQuery.php',
'AlmanacBindingViewController' => 'applications/almanac/controller/AlmanacBindingViewController.php',
'AlmanacConduitUtil' => 'applications/almanac/util/AlmanacConduitUtil.php',
'AlmanacConsoleController' => 'applications/almanac/controller/AlmanacConsoleController.php',
'AlmanacController' => 'applications/almanac/controller/AlmanacController.php',
'AlmanacCreateDevicesCapability' => 'applications/almanac/capability/AlmanacCreateDevicesCapability.php',
'AlmanacCreateNetworksCapability' => 'applications/almanac/capability/AlmanacCreateNetworksCapability.php',
'AlmanacCreateServicesCapability' => 'applications/almanac/capability/AlmanacCreateServicesCapability.php',
'AlmanacDAO' => 'applications/almanac/storage/AlmanacDAO.php',
'AlmanacDevice' => 'applications/almanac/storage/AlmanacDevice.php',
'AlmanacDeviceController' => 'applications/almanac/controller/AlmanacDeviceController.php',
'AlmanacDeviceEditController' => 'applications/almanac/controller/AlmanacDeviceEditController.php',
'AlmanacDeviceEditor' => 'applications/almanac/editor/AlmanacDeviceEditor.php',
'AlmanacDeviceListController' => 'applications/almanac/controller/AlmanacDeviceListController.php',
'AlmanacDevicePHIDType' => 'applications/almanac/phid/AlmanacDevicePHIDType.php',
'AlmanacDeviceProperty' => 'applications/almanac/storage/AlmanacDeviceProperty.php',
'AlmanacDeviceQuery' => 'applications/almanac/query/AlmanacDeviceQuery.php',
'AlmanacDeviceSearchEngine' => 'applications/almanac/query/AlmanacDeviceSearchEngine.php',
'AlmanacDeviceTransaction' => 'applications/almanac/storage/AlmanacDeviceTransaction.php',
'AlmanacDeviceTransactionQuery' => 'applications/almanac/query/AlmanacDeviceTransactionQuery.php',
'AlmanacDeviceViewController' => 'applications/almanac/controller/AlmanacDeviceViewController.php',
'AlmanacInterface' => 'applications/almanac/storage/AlmanacInterface.php',
'AlmanacInterfaceDatasource' => 'applications/almanac/typeahead/AlmanacInterfaceDatasource.php',
'AlmanacInterfaceEditController' => 'applications/almanac/controller/AlmanacInterfaceEditController.php',
'AlmanacInterfacePHIDType' => 'applications/almanac/phid/AlmanacInterfacePHIDType.php',
'AlmanacInterfaceQuery' => 'applications/almanac/query/AlmanacInterfaceQuery.php',
'AlmanacInterfaceTableView' => 'applications/almanac/view/AlmanacInterfaceTableView.php',
'AlmanacManagementRegisterWorkflow' => 'applications/almanac/management/AlmanacManagementRegisterWorkflow.php',
'AlmanacManagementWorkflow' => 'applications/almanac/management/AlmanacManagementWorkflow.php',
'AlmanacNames' => 'applications/almanac/util/AlmanacNames.php',
'AlmanacNamesTestCase' => 'applications/almanac/util/__tests__/AlmanacNamesTestCase.php',
'AlmanacNetwork' => 'applications/almanac/storage/AlmanacNetwork.php',
'AlmanacNetworkController' => 'applications/almanac/controller/AlmanacNetworkController.php',
'AlmanacNetworkEditController' => 'applications/almanac/controller/AlmanacNetworkEditController.php',
'AlmanacNetworkEditor' => 'applications/almanac/editor/AlmanacNetworkEditor.php',
'AlmanacNetworkListController' => 'applications/almanac/controller/AlmanacNetworkListController.php',
'AlmanacNetworkPHIDType' => 'applications/almanac/phid/AlmanacNetworkPHIDType.php',
'AlmanacNetworkQuery' => 'applications/almanac/query/AlmanacNetworkQuery.php',
'AlmanacNetworkSearchEngine' => 'applications/almanac/query/AlmanacNetworkSearchEngine.php',
'AlmanacNetworkTransaction' => 'applications/almanac/storage/AlmanacNetworkTransaction.php',
'AlmanacNetworkTransactionQuery' => 'applications/almanac/query/AlmanacNetworkTransactionQuery.php',
'AlmanacNetworkViewController' => 'applications/almanac/controller/AlmanacNetworkViewController.php',
'AlmanacService' => 'applications/almanac/storage/AlmanacService.php',
'AlmanacServiceController' => 'applications/almanac/controller/AlmanacServiceController.php',
'AlmanacServiceEditController' => 'applications/almanac/controller/AlmanacServiceEditController.php',
'AlmanacServiceEditor' => 'applications/almanac/editor/AlmanacServiceEditor.php',
'AlmanacServiceListController' => 'applications/almanac/controller/AlmanacServiceListController.php',
'AlmanacServicePHIDType' => 'applications/almanac/phid/AlmanacServicePHIDType.php',
'AlmanacServiceQuery' => 'applications/almanac/query/AlmanacServiceQuery.php',
'AlmanacServiceSearchEngine' => 'applications/almanac/query/AlmanacServiceSearchEngine.php',
'AlmanacServiceTransaction' => 'applications/almanac/storage/AlmanacServiceTransaction.php',
'AlmanacServiceTransactionQuery' => 'applications/almanac/query/AlmanacServiceTransactionQuery.php',
'AlmanacServiceViewController' => 'applications/almanac/controller/AlmanacServiceViewController.php',
'Aphront304Response' => 'aphront/response/Aphront304Response.php',
'Aphront400Response' => 'aphront/response/Aphront400Response.php',
'Aphront403Response' => 'aphront/response/Aphront403Response.php',
@@ -109,22 +162,22 @@ phutil_register_library_map(array(
'CalendarConstants' => 'applications/calendar/constants/CalendarConstants.php',
'CalendarTimeUtil' => 'applications/calendar/util/CalendarTimeUtil.php',
'CalendarTimeUtilTestCase' => 'applications/calendar/__tests__/CalendarTimeUtilTestCase.php',
'CelerityAPI' => 'infrastructure/celerity/CelerityAPI.php',
'CelerityManagementMapWorkflow' => 'infrastructure/celerity/management/CelerityManagementMapWorkflow.php',
'CelerityManagementWorkflow' => 'infrastructure/celerity/management/CelerityManagementWorkflow.php',
'CelerityPhabricatorResourceController' => 'infrastructure/celerity/CelerityPhabricatorResourceController.php',
'CelerityPhabricatorResources' => 'infrastructure/celerity/resources/CelerityPhabricatorResources.php',
'CelerityPhysicalResources' => 'infrastructure/celerity/resources/CelerityPhysicalResources.php',
'CelerityResourceController' => 'infrastructure/celerity/CelerityResourceController.php',
'CelerityResourceGraph' => 'infrastructure/celerity/CelerityResourceGraph.php',
'CelerityResourceMap' => 'infrastructure/celerity/CelerityResourceMap.php',
'CelerityResourceMapGenerator' => 'infrastructure/celerity/CelerityResourceMapGenerator.php',
'CelerityResourceTransformer' => 'infrastructure/celerity/CelerityResourceTransformer.php',
'CelerityResourceTransformerTestCase' => 'infrastructure/celerity/__tests__/CelerityResourceTransformerTestCase.php',
'CelerityResources' => 'infrastructure/celerity/resources/CelerityResources.php',
'CelerityResourcesOnDisk' => 'infrastructure/celerity/resources/CelerityResourcesOnDisk.php',
'CeleritySpriteGenerator' => 'infrastructure/celerity/CeleritySpriteGenerator.php',
'CelerityStaticResourceResponse' => 'infrastructure/celerity/CelerityStaticResourceResponse.php',
'CelerityAPI' => 'applications/celerity/CelerityAPI.php',
'CelerityManagementMapWorkflow' => 'applications/celerity/management/CelerityManagementMapWorkflow.php',
'CelerityManagementWorkflow' => 'applications/celerity/management/CelerityManagementWorkflow.php',
'CelerityPhabricatorResourceController' => 'applications/celerity/controller/CelerityPhabricatorResourceController.php',
'CelerityPhabricatorResources' => 'applications/celerity/resources/CelerityPhabricatorResources.php',
'CelerityPhysicalResources' => 'applications/celerity/resources/CelerityPhysicalResources.php',
'CelerityResourceController' => 'applications/celerity/controller/CelerityResourceController.php',
'CelerityResourceGraph' => 'applications/celerity/CelerityResourceGraph.php',
'CelerityResourceMap' => 'applications/celerity/CelerityResourceMap.php',
'CelerityResourceMapGenerator' => 'applications/celerity/CelerityResourceMapGenerator.php',
'CelerityResourceTransformer' => 'applications/celerity/CelerityResourceTransformer.php',
'CelerityResourceTransformerTestCase' => 'applications/celerity/__tests__/CelerityResourceTransformerTestCase.php',
'CelerityResources' => 'applications/celerity/resources/CelerityResources.php',
'CelerityResourcesOnDisk' => 'applications/celerity/resources/CelerityResourcesOnDisk.php',
'CeleritySpriteGenerator' => 'applications/celerity/CeleritySpriteGenerator.php',
'CelerityStaticResourceResponse' => 'applications/celerity/CelerityStaticResourceResponse.php',
'ChatLogConduitAPIMethod' => 'applications/chatlog/conduit/ChatLogConduitAPIMethod.php',
'ChatLogQueryConduitAPIMethod' => 'applications/chatlog/conduit/ChatLogQueryConduitAPIMethod.php',
'ChatLogRecordConduitAPIMethod' => 'applications/chatlog/conduit/ChatLogRecordConduitAPIMethod.php',
@@ -185,18 +238,18 @@ phutil_register_library_map(array(
'ConpherenceViewController' => 'applications/conpherence/controller/ConpherenceViewController.php',
'ConpherenceWidgetController' => 'applications/conpherence/controller/ConpherenceWidgetController.php',
'ConpherenceWidgetView' => 'applications/conpherence/view/ConpherenceWidgetView.php',
'DarkConsoleController' => 'aphront/console/DarkConsoleController.php',
'DarkConsoleCore' => 'aphront/console/DarkConsoleCore.php',
'DarkConsoleDataController' => 'aphront/console/DarkConsoleDataController.php',
'DarkConsoleErrorLogPlugin' => 'aphront/console/plugin/DarkConsoleErrorLogPlugin.php',
'DarkConsoleErrorLogPluginAPI' => 'aphront/console/plugin/errorlog/DarkConsoleErrorLogPluginAPI.php',
'DarkConsoleEventPlugin' => 'aphront/console/plugin/DarkConsoleEventPlugin.php',
'DarkConsoleEventPluginAPI' => 'aphront/console/plugin/event/DarkConsoleEventPluginAPI.php',
'DarkConsolePlugin' => 'aphront/console/plugin/DarkConsolePlugin.php',
'DarkConsoleRequestPlugin' => 'aphront/console/plugin/DarkConsoleRequestPlugin.php',
'DarkConsoleServicesPlugin' => 'aphront/console/plugin/DarkConsoleServicesPlugin.php',
'DarkConsoleXHProfPlugin' => 'aphront/console/plugin/DarkConsoleXHProfPlugin.php',
'DarkConsoleXHProfPluginAPI' => 'aphront/console/plugin/xhprof/DarkConsoleXHProfPluginAPI.php',
'DarkConsoleController' => 'applications/console/controller/DarkConsoleController.php',
'DarkConsoleCore' => 'applications/console/core/DarkConsoleCore.php',
'DarkConsoleDataController' => 'applications/console/controller/DarkConsoleDataController.php',
'DarkConsoleErrorLogPlugin' => 'applications/console/plugin/DarkConsoleErrorLogPlugin.php',
'DarkConsoleErrorLogPluginAPI' => 'applications/console/plugin/errorlog/DarkConsoleErrorLogPluginAPI.php',
'DarkConsoleEventPlugin' => 'applications/console/plugin/DarkConsoleEventPlugin.php',
'DarkConsoleEventPluginAPI' => 'applications/console/plugin/event/DarkConsoleEventPluginAPI.php',
'DarkConsolePlugin' => 'applications/console/plugin/DarkConsolePlugin.php',
'DarkConsoleRequestPlugin' => 'applications/console/plugin/DarkConsoleRequestPlugin.php',
'DarkConsoleServicesPlugin' => 'applications/console/plugin/DarkConsoleServicesPlugin.php',
'DarkConsoleXHProfPlugin' => 'applications/console/plugin/DarkConsoleXHProfPlugin.php',
'DarkConsoleXHProfPluginAPI' => 'applications/console/plugin/xhprof/DarkConsoleXHProfPluginAPI.php',
'DatabaseConfigurationProvider' => 'infrastructure/storage/configuration/DatabaseConfigurationProvider.php',
'DefaultDatabaseConfigurationProvider' => 'infrastructure/storage/configuration/DefaultDatabaseConfigurationProvider.php',
'DifferentialAction' => 'applications/differential/constants/DifferentialAction.php',
@@ -330,6 +383,7 @@ phutil_register_library_map(array(
'DifferentialReviewersField' => 'applications/differential/customfield/DifferentialReviewersField.php',
'DifferentialReviewersView' => 'applications/differential/view/DifferentialReviewersView.php',
'DifferentialRevision' => 'applications/differential/storage/DifferentialRevision.php',
'DifferentialRevisionCloseDetailsController' => 'applications/differential/controller/DifferentialRevisionCloseDetailsController.php',
'DifferentialRevisionControlSystem' => 'applications/differential/constants/DifferentialRevisionControlSystem.php',
'DifferentialRevisionDetailView' => 'applications/differential/view/DifferentialRevisionDetailView.php',
'DifferentialRevisionEditController' => 'applications/differential/controller/DifferentialRevisionEditController.php',
@@ -684,6 +738,7 @@ phutil_register_library_map(array(
'FundInitiativeCloseController' => 'applications/fund/controller/FundInitiativeCloseController.php',
'FundInitiativeEditController' => 'applications/fund/controller/FundInitiativeEditController.php',
'FundInitiativeEditor' => 'applications/fund/editor/FundInitiativeEditor.php',
'FundInitiativeIndexer' => 'applications/fund/search/FundInitiativeIndexer.php',
'FundInitiativeListController' => 'applications/fund/controller/FundInitiativeListController.php',
'FundInitiativePHIDType' => 'applications/fund/phid/FundInitiativePHIDType.php',
'FundInitiativeQuery' => 'applications/fund/query/FundInitiativeQuery.php',
@@ -1320,6 +1375,7 @@ phutil_register_library_map(array(
'PhabricatorCalendarHolidayTestCase' => 'applications/calendar/storage/__tests__/PhabricatorCalendarHolidayTestCase.php',
'PhabricatorCalendarViewController' => 'applications/calendar/controller/PhabricatorCalendarViewController.php',
'PhabricatorCampfireProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorCampfireProtocolAdapter.php',
'PhabricatorCelerityApplication' => 'applications/celerity/application/PhabricatorCelerityApplication.php',
'PhabricatorCelerityTestCase' => '__tests__/PhabricatorCelerityTestCase.php',
'PhabricatorChangeParserTestCase' => 'applications/repository/worker/__tests__/PhabricatorChangeParserTestCase.php',
'PhabricatorChangesetResponse' => 'infrastructure/diff/PhabricatorChangesetResponse.php',
@@ -1405,6 +1461,7 @@ phutil_register_library_map(array(
'PhabricatorConfigWelcomeController' => 'applications/config/controller/PhabricatorConfigWelcomeController.php',
'PhabricatorConpherenceApplication' => 'applications/conpherence/application/PhabricatorConpherenceApplication.php',
'PhabricatorConpherenceThreadPHIDType' => 'applications/conpherence/phid/PhabricatorConpherenceThreadPHIDType.php',
'PhabricatorConsoleApplication' => 'applications/console/application/PhabricatorConsoleApplication.php',
'PhabricatorContentSource' => 'applications/metamta/contentsource/PhabricatorContentSource.php',
'PhabricatorContentSourceView' => 'applications/metamta/contentsource/PhabricatorContentSourceView.php',
'PhabricatorController' => 'applications/base/controller/PhabricatorController.php',
@@ -2567,16 +2624,23 @@ phutil_register_library_map(array(
'PhortuneCartCancelController' => 'applications/phortune/controller/PhortuneCartCancelController.php',
'PhortuneCartCheckoutController' => 'applications/phortune/controller/PhortuneCartCheckoutController.php',
'PhortuneCartController' => 'applications/phortune/controller/PhortuneCartController.php',
'PhortuneCartEditor' => 'applications/phortune/editor/PhortuneCartEditor.php',
'PhortuneCartImplementation' => 'applications/phortune/cart/PhortuneCartImplementation.php',
'PhortuneCartListController' => 'applications/phortune/controller/PhortuneCartListController.php',
'PhortuneCartPHIDType' => 'applications/phortune/phid/PhortuneCartPHIDType.php',
'PhortuneCartQuery' => 'applications/phortune/query/PhortuneCartQuery.php',
'PhortuneCartReplyHandler' => 'applications/phortune/mail/PhortuneCartReplyHandler.php',
'PhortuneCartSearchEngine' => 'applications/phortune/query/PhortuneCartSearchEngine.php',
'PhortuneCartTransaction' => 'applications/phortune/storage/PhortuneCartTransaction.php',
'PhortuneCartTransactionQuery' => 'applications/phortune/query/PhortuneCartTransactionQuery.php',
'PhortuneCartUpdateController' => 'applications/phortune/controller/PhortuneCartUpdateController.php',
'PhortuneCartViewController' => 'applications/phortune/controller/PhortuneCartViewController.php',
'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php',
'PhortuneChargeListController' => 'applications/phortune/controller/PhortuneChargeListController.php',
'PhortuneChargePHIDType' => 'applications/phortune/phid/PhortuneChargePHIDType.php',
'PhortuneChargeQuery' => 'applications/phortune/query/PhortuneChargeQuery.php',
'PhortuneChargeSearchEngine' => 'applications/phortune/query/PhortuneChargeSearchEngine.php',
'PhortuneChargeTableView' => 'applications/phortune/view/PhortuneChargeTableView.php',
'PhortuneConstants' => 'applications/phortune/constants/PhortuneConstants.php',
'PhortuneController' => 'applications/phortune/controller/PhortuneController.php',
'PhortuneCreditCardForm' => 'applications/phortune/view/PhortuneCreditCardForm.php',
@@ -2587,11 +2651,13 @@ phutil_register_library_map(array(
'PhortuneErrCode' => 'applications/phortune/constants/PhortuneErrCode.php',
'PhortuneLandingController' => 'applications/phortune/controller/PhortuneLandingController.php',
'PhortuneMemberHasAccountEdgeType' => 'applications/phortune/edge/PhortuneMemberHasAccountEdgeType.php',
'PhortuneMemberHasMerchantEdgeType' => 'applications/phortune/edge/PhortuneMemberHasMerchantEdgeType.php',
'PhortuneMerchant' => 'applications/phortune/storage/PhortuneMerchant.php',
'PhortuneMerchantCapability' => 'applications/phortune/capability/PhortuneMerchantCapability.php',
'PhortuneMerchantController' => 'applications/phortune/controller/PhortuneMerchantController.php',
'PhortuneMerchantEditController' => 'applications/phortune/controller/PhortuneMerchantEditController.php',
'PhortuneMerchantEditor' => 'applications/phortune/editor/PhortuneMerchantEditor.php',
'PhortuneMerchantHasMemberEdgeType' => 'applications/phortune/edge/PhortuneMerchantHasMemberEdgeType.php',
'PhortuneMerchantListController' => 'applications/phortune/controller/PhortuneMerchantListController.php',
'PhortuneMerchantPHIDType' => 'applications/phortune/phid/PhortuneMerchantPHIDType.php',
'PhortuneMerchantQuery' => 'applications/phortune/query/PhortuneMerchantQuery.php',
@@ -2603,6 +2669,7 @@ phutil_register_library_map(array(
'PhortuneMultiplePaymentProvidersException' => 'applications/phortune/exception/PhortuneMultiplePaymentProvidersException.php',
'PhortuneNoPaymentProviderException' => 'applications/phortune/exception/PhortuneNoPaymentProviderException.php',
'PhortuneNotImplementedException' => 'applications/phortune/exception/PhortuneNotImplementedException.php',
'PhortuneOrderTableView' => 'applications/phortune/view/PhortuneOrderTableView.php',
'PhortunePayPalPaymentProvider' => 'applications/phortune/provider/PhortunePayPalPaymentProvider.php',
'PhortunePaymentMethod' => 'applications/phortune/storage/PhortunePaymentMethod.php',
'PhortunePaymentMethodCreateController' => 'applications/phortune/controller/PhortunePaymentMethodCreateController.php',
@@ -2629,7 +2696,6 @@ phutil_register_library_map(array(
'PhortunePurchase' => 'applications/phortune/storage/PhortunePurchase.php',
'PhortunePurchasePHIDType' => 'applications/phortune/phid/PhortunePurchasePHIDType.php',
'PhortunePurchaseQuery' => 'applications/phortune/query/PhortunePurchaseQuery.php',
'PhortunePurchaseViewController' => 'applications/phortune/controller/PhortunePurchaseViewController.php',
'PhortuneSchemaSpec' => 'applications/phortune/storage/PhortuneSchemaSpec.php',
'PhortuneStripePaymentProvider' => 'applications/phortune/provider/PhortuneStripePaymentProvider.php',
'PhortuneTestPaymentProvider' => 'applications/phortune/provider/PhortuneTestPaymentProvider.php',
@@ -2710,9 +2776,14 @@ phutil_register_library_map(array(
'PhrictionMoveController' => 'applications/phriction/controller/PhrictionMoveController.php',
'PhrictionNewController' => 'applications/phriction/controller/PhrictionNewController.php',
'PhrictionRemarkupRule' => 'applications/phriction/markup/PhrictionRemarkupRule.php',
'PhrictionReplyHandler' => 'applications/phriction/mail/PhrictionReplyHandler.php',
'PhrictionSchemaSpec' => 'applications/phriction/storage/PhrictionSchemaSpec.php',
'PhrictionSearchEngine' => 'applications/phriction/query/PhrictionSearchEngine.php',
'PhrictionSearchIndexer' => 'applications/phriction/search/PhrictionSearchIndexer.php',
'PhrictionTransaction' => 'applications/phriction/storage/PhrictionTransaction.php',
'PhrictionTransactionComment' => 'applications/phriction/storage/PhrictionTransactionComment.php',
'PhrictionTransactionEditor' => 'applications/phriction/editor/PhrictionTransactionEditor.php',
'PhrictionTransactionQuery' => 'applications/phriction/query/PhrictionTransactionQuery.php',
'PonderAddAnswerView' => 'applications/ponder/view/PonderAddAnswerView.php',
'PonderAnswer' => 'applications/ponder/storage/PonderAnswer.php',
'PonderAnswerCommentController' => 'applications/ponder/controller/PonderAnswerCommentController.php',
@@ -2762,6 +2833,7 @@ phutil_register_library_map(array(
'ProjectCreateProjectsCapability' => 'applications/project/capability/ProjectCreateProjectsCapability.php',
'ProjectQueryConduitAPIMethod' => 'applications/project/conduit/ProjectQueryConduitAPIMethod.php',
'ProjectRemarkupRule' => 'applications/project/remarkup/ProjectRemarkupRule.php',
'ProjectRemarkupRuleTestCase' => 'applications/project/remarkup/__tests__/ProjectRemarkupRuleTestCase.php',
'QueryFormattingTestCase' => 'infrastructure/storage/__tests__/QueryFormattingTestCase.php',
'ReleephAuthorFieldSpecification' => 'applications/releeph/field/specification/ReleephAuthorFieldSpecification.php',
'ReleephBranch' => 'applications/releeph/storage/ReleephBranch.php',
@@ -2878,8 +2950,8 @@ phutil_register_library_map(array(
),
'function' => array(
'_phabricator_time_format' => 'view/viewutils.php',
'celerity_generate_unique_node_id' => 'infrastructure/celerity/api.php',
'celerity_get_resource_uri' => 'infrastructure/celerity/api.php',
'celerity_generate_unique_node_id' => 'applications/celerity/api.php',
'celerity_get_resource_uri' => 'applications/celerity/api.php',
'implode_selected_handle_links' => 'applications/phid/handle/view/render.php',
'javelin_tag' => 'infrastructure/javelin/markup.php',
'phabricator_date' => 'view/viewutils.php',
@@ -2892,20 +2964,85 @@ phutil_register_library_map(array(
'phid_get_subtype' => 'applications/phid/utils.php',
'phid_get_type' => 'applications/phid/utils.php',
'phid_group_by_type' => 'applications/phid/utils.php',
'require_celerity_resource' => 'infrastructure/celerity/api.php',
'require_celerity_resource' => 'applications/celerity/api.php',
),
'xmap' => array(
'AlmanacAddress' => 'Phobject',
'AlmanacBinding' => array(
'AlmanacDAO',
'PhabricatorPolicyInterface',
),
'AlmanacBindingEditController' => 'AlmanacServiceController',
'AlmanacBindingEditor' => 'PhabricatorApplicationTransactionEditor',
'AlmanacBindingPHIDType' => 'PhabricatorPHIDType',
'AlmanacBindingQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'AlmanacBindingTableView' => 'AphrontView',
'AlmanacBindingTransaction' => 'PhabricatorApplicationTransaction',
'AlmanacBindingTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'AlmanacBindingViewController' => 'AlmanacServiceController',
'AlmanacConduitUtil' => 'Phobject',
'AlmanacConsoleController' => 'AlmanacController',
'AlmanacController' => 'PhabricatorController',
'AlmanacCreateDevicesCapability' => 'PhabricatorPolicyCapability',
'AlmanacCreateNetworksCapability' => 'PhabricatorPolicyCapability',
'AlmanacCreateServicesCapability' => 'PhabricatorPolicyCapability',
'AlmanacDAO' => 'PhabricatorLiskDAO',
'AlmanacDevice' => array(
'AlmanacDAO',
'PhabricatorPolicyInterface',
),
'AlmanacDeviceController' => 'AlmanacController',
'AlmanacDeviceEditController' => 'AlmanacDeviceController',
'AlmanacDeviceEditor' => 'PhabricatorApplicationTransactionEditor',
'AlmanacDeviceListController' => 'AlmanacDeviceController',
'AlmanacDevicePHIDType' => 'PhabricatorPHIDType',
'AlmanacDeviceProperty' => 'AlmanacDAO',
'AlmanacDeviceQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'AlmanacDeviceSearchEngine' => 'PhabricatorApplicationSearchEngine',
'AlmanacDeviceTransaction' => 'PhabricatorApplicationTransaction',
'AlmanacDeviceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'AlmanacDeviceViewController' => 'AlmanacDeviceController',
'AlmanacInterface' => array(
'AlmanacDAO',
'PhabricatorPolicyInterface',
),
'AlmanacInterfaceDatasource' => 'PhabricatorTypeaheadDatasource',
'AlmanacInterfaceEditController' => 'AlmanacDeviceController',
'AlmanacInterfacePHIDType' => 'PhabricatorPHIDType',
'AlmanacInterfaceQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'AlmanacInterfaceTableView' => 'AphrontView',
'AlmanacManagementRegisterWorkflow' => 'AlmanacManagementWorkflow',
'AlmanacManagementWorkflow' => 'PhabricatorManagementWorkflow',
'AlmanacNames' => 'Phobject',
'AlmanacNamesTestCase' => 'PhabricatorTestCase',
'AlmanacNetwork' => array(
'AlmanacDAO',
'PhabricatorPolicyInterface',
),
'AlmanacNetworkController' => 'AlmanacController',
'AlmanacNetworkEditController' => 'AlmanacNetworkController',
'AlmanacNetworkEditor' => 'PhabricatorApplicationTransactionEditor',
'AlmanacNetworkListController' => 'AlmanacNetworkController',
'AlmanacNetworkPHIDType' => 'PhabricatorPHIDType',
'AlmanacNetworkQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'AlmanacNetworkSearchEngine' => 'PhabricatorApplicationSearchEngine',
'AlmanacNetworkTransaction' => 'PhabricatorApplicationTransaction',
'AlmanacNetworkTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'AlmanacNetworkViewController' => 'AlmanacNetworkController',
'AlmanacService' => array(
'AlmanacDAO',
'PhabricatorPolicyInterface',
),
'AlmanacServiceController' => 'AlmanacController',
'AlmanacServiceEditController' => 'AlmanacServiceController',
'AlmanacServiceEditor' => 'PhabricatorApplicationTransactionEditor',
'AlmanacServiceListController' => 'AlmanacServiceController',
'AlmanacServicePHIDType' => 'PhabricatorPHIDType',
'AlmanacServiceQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'AlmanacServiceSearchEngine' => 'PhabricatorApplicationSearchEngine',
'AlmanacServiceTransaction' => 'PhabricatorApplicationTransaction',
'AlmanacServiceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'AlmanacServiceViewController' => 'AlmanacServiceController',
'Aphront304Response' => 'AphrontResponse',
'Aphront400Response' => 'AphrontResponse',
'Aphront403Response' => 'AphrontHTMLResponse',
@@ -3216,6 +3353,7 @@ phutil_register_library_map(array(
'PhabricatorDestructibleInterface',
'PhabricatorProjectInterface',
),
'DifferentialRevisionCloseDetailsController' => 'DifferentialController',
'DifferentialRevisionDetailView' => 'AphrontView',
'DifferentialRevisionEditController' => 'DifferentialController',
'DifferentialRevisionHasTaskEdgeType' => 'PhabricatorEdgeType',
@@ -3582,6 +3720,7 @@ phutil_register_library_map(array(
'FundInitiativeCloseController' => 'FundController',
'FundInitiativeEditController' => 'FundController',
'FundInitiativeEditor' => 'PhabricatorApplicationTransactionEditor',
'FundInitiativeIndexer' => 'PhabricatorSearchDocumentIndexer',
'FundInitiativeListController' => 'FundController',
'FundInitiativePHIDType' => 'PhabricatorPHIDType',
'FundInitiativeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
@@ -4284,6 +4423,7 @@ phutil_register_library_map(array(
'PhabricatorCalendarHolidayTestCase' => 'PhabricatorTestCase',
'PhabricatorCalendarViewController' => 'PhabricatorCalendarController',
'PhabricatorCampfireProtocolAdapter' => 'PhabricatorBotBaseStreamingProtocolAdapter',
'PhabricatorCelerityApplication' => 'PhabricatorApplication',
'PhabricatorCelerityTestCase' => 'PhabricatorTestCase',
'PhabricatorChangeParserTestCase' => 'PhabricatorWorkingCopyTestCase',
'PhabricatorChangesetResponse' => 'AphrontProxyResponse',
@@ -4380,6 +4520,7 @@ phutil_register_library_map(array(
'PhabricatorConfigWelcomeController' => 'PhabricatorConfigController',
'PhabricatorConpherenceApplication' => 'PhabricatorApplication',
'PhabricatorConpherenceThreadPHIDType' => 'PhabricatorPHIDType',
'PhabricatorConsoleApplication' => 'PhabricatorApplication',
'PhabricatorContentSourceView' => 'AphrontView',
'PhabricatorController' => 'AphrontController',
'PhabricatorCookies' => 'Phobject',
@@ -5634,18 +5775,25 @@ phutil_register_library_map(array(
'PhortuneCartCancelController' => 'PhortuneCartController',
'PhortuneCartCheckoutController' => 'PhortuneCartController',
'PhortuneCartController' => 'PhortuneController',
'PhortuneCartEditor' => 'PhabricatorApplicationTransactionEditor',
'PhortuneCartListController' => 'PhortuneController',
'PhortuneCartPHIDType' => 'PhabricatorPHIDType',
'PhortuneCartQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhortuneCartReplyHandler' => 'PhabricatorMailReplyHandler',
'PhortuneCartSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhortuneCartTransaction' => 'PhabricatorApplicationTransaction',
'PhortuneCartTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhortuneCartUpdateController' => 'PhortuneCartController',
'PhortuneCartViewController' => 'PhortuneCartController',
'PhortuneCharge' => array(
'PhortuneDAO',
'PhabricatorPolicyInterface',
),
'PhortuneChargeListController' => 'PhortuneController',
'PhortuneChargePHIDType' => 'PhabricatorPHIDType',
'PhortuneChargeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhortuneChargeSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhortuneChargeTableView' => 'AphrontView',
'PhortuneController' => 'PhabricatorController',
'PhortuneCurrency' => 'Phobject',
'PhortuneCurrencySerializer' => 'PhabricatorLiskSerializer',
@@ -5654,6 +5802,7 @@ phutil_register_library_map(array(
'PhortuneErrCode' => 'PhortuneConstants',
'PhortuneLandingController' => 'PhortuneController',
'PhortuneMemberHasAccountEdgeType' => 'PhabricatorEdgeType',
'PhortuneMemberHasMerchantEdgeType' => 'PhabricatorEdgeType',
'PhortuneMerchant' => array(
'PhortuneDAO',
'PhabricatorPolicyInterface',
@@ -5662,6 +5811,7 @@ phutil_register_library_map(array(
'PhortuneMerchantController' => 'PhortuneController',
'PhortuneMerchantEditController' => 'PhortuneMerchantController',
'PhortuneMerchantEditor' => 'PhabricatorApplicationTransactionEditor',
'PhortuneMerchantHasMemberEdgeType' => 'PhabricatorEdgeType',
'PhortuneMerchantListController' => 'PhortuneMerchantController',
'PhortuneMerchantPHIDType' => 'PhabricatorPHIDType',
'PhortuneMerchantQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
@@ -5673,6 +5823,7 @@ phutil_register_library_map(array(
'PhortuneMultiplePaymentProvidersException' => 'Exception',
'PhortuneNoPaymentProviderException' => 'Exception',
'PhortuneNotImplementedException' => 'Exception',
'PhortuneOrderTableView' => 'AphrontView',
'PhortunePayPalPaymentProvider' => 'PhortunePaymentProvider',
'PhortunePaymentMethod' => array(
'PhortuneDAO',
@@ -5709,7 +5860,6 @@ phutil_register_library_map(array(
),
'PhortunePurchasePHIDType' => 'PhabricatorPHIDType',
'PhortunePurchaseQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhortunePurchaseViewController' => 'PhortuneController',
'PhortuneSchemaSpec' => 'PhabricatorConfigSchemaSpec',
'PhortuneStripePaymentProvider' => 'PhortunePaymentProvider',
'PhortuneTestPaymentProvider' => 'PhortunePaymentProvider',
@@ -5813,9 +5963,14 @@ phutil_register_library_map(array(
'PhrictionMoveController' => 'PhrictionController',
'PhrictionNewController' => 'PhrictionController',
'PhrictionRemarkupRule' => 'PhutilRemarkupRule',
'PhrictionReplyHandler' => 'PhabricatorMailReplyHandler',
'PhrictionSchemaSpec' => 'PhabricatorConfigSchemaSpec',
'PhrictionSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhrictionSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhrictionTransaction' => 'PhabricatorApplicationTransaction',
'PhrictionTransactionComment' => 'PhabricatorApplicationTransactionComment',
'PhrictionTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
'PhrictionTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PonderAddAnswerView' => 'AphrontView',
'PonderAnswer' => array(
'PonderDAO',
@@ -5881,6 +6036,7 @@ phutil_register_library_map(array(
'ProjectCreateProjectsCapability' => 'PhabricatorPolicyCapability',
'ProjectQueryConduitAPIMethod' => 'ProjectConduitAPIMethod',
'ProjectRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'ProjectRemarkupRuleTestCase' => 'PhabricatorTestCase',
'QueryFormattingTestCase' => 'PhabricatorTestCase',
'ReleephAuthorFieldSpecification' => 'ReleephFieldSpecification',
'ReleephBranch' => array(

View File

@@ -28,25 +28,45 @@ abstract class AphrontController extends Phobject {
return $response;
}
abstract public function processRequest();
public function handleRequest(AphrontRequest $request) {
if (method_exists($this, 'processRequest')) {
return $this->processRequest();
}
final public function __construct(AphrontRequest $request) {
throw new PhutilMethodNotImplementedException(
pht(
'Controllers must implement either handleRequest() (recommended) '.
'or processRequest() (deprecated).'));
}
final public function setRequest(AphrontRequest $request) {
$this->request = $request;
return $this;
}
final public function getRequest() {
if (!$this->request) {
throw new Exception(pht('Call setRequest() before getRequest()!'));
}
return $this->request;
}
final public function getViewer() {
return $this->getRequest()->getViewer();
}
final public function delegateToController(AphrontController $controller) {
$request = $this->getRequest();
$controller->setDelegatingController($this);
$controller->setRequest($request);
$application = $this->getCurrentApplication();
if ($application) {
$controller->setCurrentApplication($application);
}
return $controller->processRequest();
return $controller->handleRequest($request);
}
final public function setCurrentApplication(

View File

@@ -25,12 +25,26 @@ final class AphrontRequest {
private $requestData;
private $user;
private $applicationConfiguration;
private $uriData;
final public function __construct($host, $path) {
$this->host = $host;
$this->path = $path;
}
final public function setURIMap(array $uri_data) {
$this->uriData = $uri_data;
return $this;
}
final public function getURIMap() {
return $this->uriData;
}
final public function getURIData($key, $default = null) {
return idx($this->uriData, $key, $default);
}
final public function setApplicationConfiguration(
$application_configuration) {
$this->applicationConfiguration = $application_configuration;
@@ -476,6 +490,10 @@ final class AphrontRequest {
return $this->user;
}
final public function getViewer() {
return $this->user;
}
final public function getRequestURI() {
$get = $_GET;
unset($get['__path__']);

View File

@@ -11,7 +11,6 @@ abstract class AphrontApplicationConfiguration {
private $console;
abstract public function getApplicationName();
abstract public function getURIMap();
abstract public function buildRequest();
abstract public function build404Controller();
abstract public function buildRedirectController($uri, $external);
@@ -64,8 +63,8 @@ abstract class AphrontApplicationConfiguration {
* first test if the HTTP_HOST is configured as a valid Phabricator URI. If
* it isn't, we do a special check to see if it's a custom domain for a blog
* in the Phame application and if that fails we error. Otherwise, we test
* the URI against all builtin routes from @{method:getURIMap}, then against
* all application routes from installed @{class:PhabricatorApplication}s.
* against all application routes from installed
* @{class:PhabricatorApplication}s.
*
* If we match a route, we construct the controller it points at, build it,
* and return it.
@@ -212,7 +211,6 @@ abstract class AphrontApplicationConfiguration {
*/
final public function buildControllerForPath($path) {
$maps = array();
$maps[] = array(null, $this->getURIMap());
$applications = PhabricatorApplication::getAllInstalledApplications();
foreach ($applications as $application) {
@@ -241,7 +239,7 @@ abstract class AphrontApplicationConfiguration {
$request = $this->getRequest();
$controller = newv($controller_class, array($request));
$controller = newv($controller_class, array());
if ($current_application) {
$controller->setCurrentApplication($current_application);
}

View File

@@ -14,31 +14,6 @@ class AphrontDefaultApplicationConfiguration
return 'aphront-default';
}
public function getURIMap() {
return $this->getResourceURIMapRules() + array(
'/~/' => array(
'' => 'DarkConsoleController',
'data/(?P<key>[^/]+)/' => 'DarkConsoleDataController',
),
);
}
protected function getResourceURIMapRules() {
$extensions = CelerityResourceController::getSupportedResourceTypes();
$extensions = array_keys($extensions);
$extensions = implode('|', $extensions);
return array(
'/res/' => array(
'(?:(?P<mtime>[0-9]+)T/)?'.
'(?P<library>[^/]+)/'.
'(?P<hash>[a-f0-9]{8})/'.
'(?P<path>.+\.(?:'.$extensions.'))'
=> 'CelerityPhabricatorResourceController',
),
);
}
/**
* @phutil-external-symbol class PhabricatorStartup
*/
@@ -177,13 +152,14 @@ class AphrontDefaultApplicationConfiguration
//
// Possibly we should add a header here like "you need to login to see
// the thing you are trying to look at".
$login_controller = new PhabricatorAuthStartController($request);
$login_controller = new PhabricatorAuthStartController();
$login_controller->setRequest($request);
$auth_app_class = 'PhabricatorAuthApplication';
$auth_app = PhabricatorApplication::getByClass($auth_app_class);
$login_controller->setCurrentApplication($auth_app);
return $login_controller->processRequest();
return $login_controller->handleRequest($request);
}
$list = $ex->getMoreInfo();
@@ -297,12 +273,12 @@ class AphrontDefaultApplicationConfiguration
}
public function build404Controller() {
return array(new Phabricator404Controller($this->getRequest()), array());
return array(new Phabricator404Controller(), array());
}
public function buildRedirectController($uri, $external) {
return array(
new PhabricatorRedirectController($this->getRequest()),
new PhabricatorRedirectController(),
array(
'uri' => $uri,
'external' => $external,

View File

@@ -30,12 +30,48 @@ final class PhabricatorAlmanacApplication extends PhabricatorApplication {
return true;
}
public function isLaunchable() {
return false;
public function getRoutes() {
return array(
'/almanac/' => array(
'' => 'AlmanacConsoleController',
'service/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'AlmanacServiceListController',
'edit/(?:(?P<id>\d+)/)?' => 'AlmanacServiceEditController',
'view/(?P<name>[^/]+)/' => 'AlmanacServiceViewController',
),
'device/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'AlmanacDeviceListController',
'edit/(?:(?P<id>\d+)/)?' => 'AlmanacDeviceEditController',
'view/(?P<name>[^/]+)/' => 'AlmanacDeviceViewController',
),
'interface/' => array(
'edit/(?:(?P<id>\d+)/)?' => 'AlmanacInterfaceEditController',
),
'binding/' => array(
'edit/(?:(?P<id>\d+)/)?' => 'AlmanacBindingEditController',
'(?P<id>\d+)/' => 'AlmanacBindingViewController',
),
'network/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'AlmanacNetworkListController',
'edit/(?:(?P<id>\d+)/)?' => 'AlmanacNetworkEditController',
'(?P<id>\d+)/' => 'AlmanacNetworkViewController',
),
),
);
}
public function getRoutes() {
return array();
protected function getCustomCapabilities() {
return array(
AlmanacCreateServicesCapability::CAPABILITY => array(
'default' => PhabricatorPolicies::POLICY_ADMIN,
),
AlmanacCreateDevicesCapability::CAPABILITY => array(
'default' => PhabricatorPolicies::POLICY_ADMIN,
),
AlmanacCreateNetworksCapability::CAPABILITY => array(
'default' => PhabricatorPolicies::POLICY_ADMIN,
),
);
}
}

View File

@@ -0,0 +1,16 @@
<?php
final class AlmanacCreateDevicesCapability
extends PhabricatorPolicyCapability {
const CAPABILITY = 'almanac.devices';
public function getCapabilityName() {
return pht('Can Create Devices');
}
public function describeCapabilityRejection() {
return pht('You do not have permission to create Almanac devices.');
}
}

View File

@@ -0,0 +1,16 @@
<?php
final class AlmanacCreateNetworksCapability
extends PhabricatorPolicyCapability {
const CAPABILITY = 'almanac.networks';
public function getCapabilityName() {
return pht('Can Create Networks');
}
public function describeCapabilityRejection() {
return pht('You do not have permission to create Almanac networks.');
}
}

View File

@@ -0,0 +1,16 @@
<?php
final class AlmanacCreateServicesCapability
extends PhabricatorPolicyCapability {
const CAPABILITY = 'almanac.services';
public function getCapabilityName() {
return pht('Can Create Services');
}
public function describeCapabilityRejection() {
return pht('You do not have permission to create Almanac services.');
}
}

View File

@@ -0,0 +1,128 @@
<?php
final class AlmanacBindingEditController
extends AlmanacServiceController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
if ($id) {
$binding = id(new AlmanacBindingQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$binding) {
return new Aphront404Response();
}
$service = $binding->getService();
$is_new = false;
$service_uri = $service->getURI();
$cancel_uri = $binding->getURI();
$title = pht('Edit Binding');
$save_button = pht('Save Changes');
} else {
$service = id(new AlmanacServiceQuery())
->setViewer($viewer)
->withIDs(array($request->getStr('serviceID')))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
$binding = AlmanacBinding::initializeNewBinding($service);
$is_new = true;
$service_uri = $service->getURI();
$cancel_uri = $service_uri;
$title = pht('Create Binding');
$save_button = pht('Create Binding');
}
$v_interface = array();
if ($binding->getInterfacePHID()) {
$v_interface = array($binding->getInterfacePHID());
}
$e_interface = true;
$validation_exception = null;
if ($request->isFormPost()) {
$v_interface = $request->getArr('interfacePHIDs');
$type_interface = AlmanacBindingTransaction::TYPE_INTERFACE;
$xactions = array();
$xactions[] = id(new AlmanacBindingTransaction())
->setTransactionType($type_interface)
->setNewValue(head($v_interface));
$editor = id(new AlmanacBindingEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true);
try {
$editor->applyTransactions($binding, $xactions);
$binding_uri = $binding->getURI();
return id(new AphrontRedirectResponse())->setURI($binding_uri);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
$e_interface = $ex->getShortMessage($type_interface);
}
}
$interface_handles = array();
if ($v_interface) {
$interface_handles = $this->loadViewerHandles($v_interface);
}
$form = id(new AphrontFormView())
->setUser($viewer)
->appendChild(
id(new AphrontFormTokenizerControl())
->setName('interfacePHIDs')
->setLabel('Interface')
->setLimit(1)
->setDatasource(new AlmanacInterfaceDatasource())
->setValue($interface_handles)
->setError($e_interface))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton($cancel_uri)
->setValue($save_button));
$box = id(new PHUIObjectBoxView())
->setValidationException($validation_exception)
->setHeaderText($title)
->appendChild($form);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($service->getName(), $service_uri);
if ($is_new) {
$crumbs->addTextCrumb(pht('Create Binding'));
} else {
$crumbs->addTextCrumb(pht('Edit Binding'));
}
return $this->buildApplicationPage(
array(
$crumbs,
$box,
),
array(
'title' => $title,
));
}
}

View File

@@ -0,0 +1,122 @@
<?php
final class AlmanacBindingViewController
extends AlmanacServiceController {
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
$binding = id(new AlmanacBindingQuery())
->setViewer($viewer)
->withIDs(array($id))
->executeOne();
if (!$binding) {
return new Aphront404Response();
}
$service = $binding->getService();
$service_uri = $service->getURI();
$title = pht('Binding %s', $binding->getID());
$property_list = $this->buildPropertyList($binding);
$action_list = $this->buildActionList($binding);
$property_list->setActionList($action_list);
$header = id(new PHUIHeaderView())
->setUser($viewer)
->setHeader($title)
->setPolicyObject($binding);
$box = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($property_list);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($service->getName(), $service_uri);
$crumbs->addTextCrumb($title);
$xactions = id(new AlmanacBindingTransactionQuery())
->setViewer($viewer)
->withObjectPHIDs(array($binding->getPHID()))
->execute();
$xaction_view = id(new PhabricatorApplicationTransactionView())
->setUser($viewer)
->setObjectPHID($binding->getPHID())
->setTransactions($xactions)
->setShouldTerminate(true);
return $this->buildApplicationPage(
array(
$crumbs,
$box,
$xaction_view,
),
array(
'title' => $title,
));
}
private function buildPropertyList(AlmanacBinding $binding) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer);
$handles = $this->loadViewerHandles(
array(
$binding->getServicePHID(),
$binding->getDevicePHID(),
$binding->getInterface()->getNetworkPHID(),
));
$properties->addProperty(
pht('Service'),
$handles[$binding->getServicePHID()]->renderLink());
$properties->addProperty(
pht('Device'),
$handles[$binding->getDevicePHID()]->renderLink());
$properties->addProperty(
pht('Network'),
$handles[$binding->getInterface()->getNetworkPHID()]->renderLink());
$properties->addProperty(
pht('Interface'),
$binding->getInterface()->renderDisplayAddress());
return $properties;
}
private function buildActionList(AlmanacBinding $binding) {
$viewer = $this->getViewer();
$id = $binding->getID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$binding,
PhabricatorPolicyCapability::CAN_EDIT);
$actions = id(new PhabricatorActionListView())
->setUser($viewer);
$actions->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Binding'))
->setHref($this->getApplicationURI("binding/edit/{$id}/"))
->setWorkflow(!$can_edit)
->setDisabled(!$can_edit));
return $actions;
}
}

View File

@@ -0,0 +1,52 @@
<?php
final class AlmanacConsoleController extends AlmanacController {
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$menu = id(new PHUIObjectItemListView())
->setUser($viewer);
$menu->addItem(
id(new PHUIObjectItemView())
->setHeader(pht('Services'))
->setHref($this->getApplicationURI('service/'))
->addAttribute(
pht(
'Manage Almanac services.')));
$menu->addItem(
id(new PHUIObjectItemView())
->setHeader(pht('Devices'))
->setHref($this->getApplicationURI('device/'))
->addAttribute(
pht(
'Manage Almanac devices.')));
$menu->addItem(
id(new PHUIObjectItemView())
->setHeader(pht('Networks'))
->setHref($this->getApplicationURI('network/'))
->addAttribute(
pht(
'Manage Almanac networks.')));
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Console'));
return $this->buildApplicationPage(
array(
$crumbs,
$menu,
),
array(
'title' => pht('Almanac Console'),
));
}
}

View File

@@ -0,0 +1,4 @@
<?php
abstract class AlmanacController
extends PhabricatorController {}

View File

@@ -0,0 +1,14 @@
<?php
abstract class AlmanacDeviceController extends AlmanacController {
public function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$list_uri = $this->getApplicationURI('device/');
$crumbs->addTextCrumb(pht('Devices'), $list_uri);
return $crumbs;
}
}

View File

@@ -0,0 +1,142 @@
<?php
final class AlmanacDeviceEditController
extends AlmanacDeviceController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$list_uri = $this->getApplicationURI('device/');
$id = $request->getURIData('id');
if ($id) {
$device = id(new AlmanacDeviceQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$device) {
return new Aphront404Response();
}
$is_new = false;
$device_uri = $device->getURI();
$cancel_uri = $device_uri;
$title = pht('Edit Device');
$save_button = pht('Save Changes');
} else {
$this->requireApplicationCapability(
AlmanacCreateDevicesCapability::CAPABILITY);
$device = AlmanacDevice::initializeNewDevice();
$is_new = true;
$cancel_uri = $list_uri;
$title = pht('Create Device');
$save_button = pht('Create Device');
}
$v_name = $device->getName();
$e_name = true;
$validation_exception = null;
if ($request->isFormPost()) {
$v_name = $request->getStr('name');
$v_view = $request->getStr('viewPolicy');
$v_edit = $request->getStr('editPolicy');
$type_name = AlmanacDeviceTransaction::TYPE_NAME;
$type_view = PhabricatorTransactions::TYPE_VIEW_POLICY;
$type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY;
$xactions = array();
$xactions[] = id(new AlmanacDeviceTransaction())
->setTransactionType($type_name)
->setNewValue($v_name);
$xactions[] = id(new AlmanacDeviceTransaction())
->setTransactionType($type_view)
->setNewValue($v_view);
$xactions[] = id(new AlmanacDeviceTransaction())
->setTransactionType($type_edit)
->setNewValue($v_edit);
$editor = id(new AlmanacDeviceEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true);
try {
$editor->applyTransactions($device, $xactions);
$device_uri = $device->getURI();
return id(new AphrontRedirectResponse())->setURI($device_uri);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
$e_name = $ex->getShortMessage($type_name);
$device->setViewPolicy($v_view);
$device->setEditPolicy($v_edit);
}
}
$policies = id(new PhabricatorPolicyQuery())
->setViewer($viewer)
->setObject($device)
->execute();
$form = id(new AphrontFormView())
->setUser($viewer)
->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('Name'))
->setName('name')
->setValue($v_name)
->setError($e_name))
->appendChild(
id(new AphrontFormPolicyControl())
->setName('viewPolicy')
->setPolicyObject($device)
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
->setPolicies($policies))
->appendChild(
id(new AphrontFormPolicyControl())
->setName('editPolicy')
->setPolicyObject($device)
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
->setPolicies($policies))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton($cancel_uri)
->setValue($save_button));
$box = id(new PHUIObjectBoxView())
->setValidationException($validation_exception)
->setHeaderText($title)
->appendChild($form);
$crumbs = $this->buildApplicationCrumbs();
if ($is_new) {
$crumbs->addTextCrumb(pht('Create Device'));
} else {
$crumbs->addTextCrumb($device->getName(), $device_uri);
$crumbs->addTextCrumb(pht('Edit'));
}
return $this->buildApplicationPage(
array(
$crumbs,
$box,
),
array(
'title' => $title,
));
}
}

View File

@@ -0,0 +1,52 @@
<?php
final class AlmanacDeviceListController
extends AlmanacDeviceController {
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) {
$controller = id(new PhabricatorApplicationSearchController())
->setQueryKey($request->getURIData('queryKey'))
->setSearchEngine(new AlmanacDeviceSearchEngine())
->setNavigation($this->buildSideNavView());
return $this->delegateToController($controller);
}
public function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$can_create = $this->hasApplicationCapability(
AlmanacCreateDevicesCapability::CAPABILITY);
$crumbs->addAction(
id(new PHUIListItemView())
->setName(pht('Create Device'))
->setHref($this->getApplicationURI('device/edit/'))
->setIcon('fa-plus-square')
->setDisabled(!$can_create)
->setWorkflow(!$can_create));
return $crumbs;
}
public function buildSideNavView() {
$viewer = $this->getViewer();
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
id(new AlmanacDeviceSearchEngine())
->setViewer($viewer)
->addNavigationItems($nav->getMenu());
$nav->selectFilter(null);
return $nav;
}
}

View File

@@ -0,0 +1,142 @@
<?php
final class AlmanacDeviceViewController
extends AlmanacDeviceController {
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$name = $request->getURIData('name');
$device = id(new AlmanacDeviceQuery())
->setViewer($viewer)
->withNames(array($name))
->executeOne();
if (!$device) {
return new Aphront404Response();
}
$title = pht('Device %s', $device->getName());
$property_list = $this->buildPropertyList($device);
$action_list = $this->buildActionList($device);
$property_list->setActionList($action_list);
$header = id(new PHUIHeaderView())
->setUser($viewer)
->setHeader($device->getName())
->setPolicyObject($device);
$box = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($property_list);
$interfaces = $this->buildInterfaceList($device);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($device->getName());
$xactions = id(new AlmanacDeviceTransactionQuery())
->setViewer($viewer)
->withObjectPHIDs(array($device->getPHID()))
->execute();
$xaction_view = id(new PhabricatorApplicationTransactionView())
->setUser($viewer)
->setObjectPHID($device->getPHID())
->setTransactions($xactions)
->setShouldTerminate(true);
return $this->buildApplicationPage(
array(
$crumbs,
$box,
$interfaces,
$xaction_view,
),
array(
'title' => $title,
));
}
private function buildPropertyList(AlmanacDevice $device) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer);
return $properties;
}
private function buildActionList(AlmanacDevice $device) {
$viewer = $this->getViewer();
$id = $device->getID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$device,
PhabricatorPolicyCapability::CAN_EDIT);
$actions = id(new PhabricatorActionListView())
->setUser($viewer);
$actions->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Device'))
->setHref($this->getApplicationURI("device/edit/{$id}/"))
->setWorkflow(!$can_edit)
->setDisabled(!$can_edit));
return $actions;
}
private function buildInterfaceList(AlmanacDevice $device) {
$viewer = $this->getViewer();
$id = $device->getID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$device,
PhabricatorPolicyCapability::CAN_EDIT);
$interfaces = id(new AlmanacInterfaceQuery())
->setViewer($viewer)
->withDevicePHIDs(array($device->getPHID()))
->execute();
$phids = array();
foreach ($interfaces as $interface) {
$phids[] = $interface->getNetworkPHID();
$phids[] = $interface->getDevicePHID();
}
$handles = $this->loadViewerHandles($phids);
$table = id(new AlmanacInterfaceTableView())
->setUser($viewer)
->setInterfaces($interfaces)
->setHandles($handles);
$header = id(new PHUIHeaderView())
->setHeader(pht('Device Interfaces'))
->addActionLink(
id(new PHUIButtonView())
->setTag('a')
->setHref($this->getApplicationURI("interface/edit/?deviceID={$id}"))
->setWorkflow(!$can_edit)
->setDisabled(!$can_edit)
->setText(pht('Add Interface'))
->setIcon(
id(new PHUIIconView())
->setIconFont('fa-plus')));
return id(new PHUIObjectBoxView())
->setHeader($header)
->appendChild($table);
}
}

View File

@@ -0,0 +1,155 @@
<?php
final class AlmanacInterfaceEditController
extends AlmanacDeviceController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
if ($id) {
$interface = id(new AlmanacInterfaceQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$interface) {
return new Aphront404Response();
}
$device = $interface->getDevice();
$is_new = false;
$title = pht('Edit Interface');
$save_button = pht('Save Changes');
} else {
$device = id(new AlmanacDeviceQuery())
->setViewer($viewer)
->withIDs(array($request->getStr('deviceID')))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$device) {
return new Aphront404Response();
}
$interface = AlmanacInterface::initializeNewInterface();
$is_new = true;
$title = pht('Create Interface');
$save_button = pht('Create Interface');
}
$device_uri = $device->getURI();
$cancel_uri = $device_uri;
$v_network = $interface->getNetworkPHID();
$v_address = $interface->getAddress();
$e_address = true;
$v_port = $interface->getPort();
$validation_exception = null;
if ($request->isFormPost()) {
$v_network = $request->getStr('networkPHID');
$v_address = $request->getStr('address');
$v_port = $request->getStr('port');
$type_interface = AlmanacDeviceTransaction::TYPE_INTERFACE;
$address = AlmanacAddress::newFromParts($v_network, $v_address, $v_port);
$xaction = id(new AlmanacDeviceTransaction())
->setTransactionType($type_interface)
->setNewValue($address->toDictionary());
if ($interface->getID()) {
$xaction->setOldValue(array(
'id' => $interface->getID(),
) + $interface->toAddress()->toDictionary());
} else {
$xaction->setOldValue(array());
}
$xactions = array();
$xactions[] = $xaction;
$editor = id(new AlmanacDeviceEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true)
->setContinueOnMissingFields(true);
try {
$editor->applyTransactions($device, $xactions);
$device_uri = $device->getURI();
return id(new AphrontRedirectResponse())->setURI($device_uri);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
$e_address = $ex->getShortMessage($type_interface);
}
}
$networks = id(new AlmanacNetworkQuery())
->setViewer($viewer)
->execute();
$form = id(new AphrontFormView())
->setUser($viewer)
->appendChild(
id(new AphrontFormSelectControl())
->setLabel(pht('Network'))
->setName('networkPHID')
->setValue($v_network)
->setOptions(mpull($networks, 'getName', 'getPHID')))
->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('Address'))
->setName('address')
->setValue($v_address)
->setError($e_address))
->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('Port'))
->setName('port')
->setValue($v_port)
->setError($e_address))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton($cancel_uri)
->setValue($save_button));
$box = id(new PHUIObjectBoxView())
->setValidationException($validation_exception)
->setHeaderText($title)
->appendChild($form);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($device->getName(), $device_uri);
if ($is_new) {
$crumbs->addTextCrumb(pht('Create Interface'));
} else {
$crumbs->addTextCrumb(pht('Edit Interface'));
}
return $this->buildApplicationPage(
array(
$crumbs,
$box,
),
array(
'title' => $title,
));
}
}

View File

@@ -0,0 +1,14 @@
<?php
abstract class AlmanacNetworkController extends AlmanacController {
public function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$list_uri = $this->getApplicationURI('network/');
$crumbs->addTextCrumb(pht('Networks'), $list_uri);
return $crumbs;
}
}

View File

@@ -0,0 +1,143 @@
<?php
final class AlmanacNetworkEditController
extends AlmanacNetworkController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$list_uri = $this->getApplicationURI('network/');
$id = $request->getURIData('id');
if ($id) {
$network = id(new AlmanacNetworkQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$network) {
return new Aphront404Response();
}
$is_new = false;
$network_uri = $this->getApplicationURI('network/'.$network->getID().'/');
$cancel_uri = $network_uri;
$title = pht('Edit Network');
$save_button = pht('Save Changes');
} else {
$this->requireApplicationCapability(
AlmanacCreateNetworksCapability::CAPABILITY);
$network = AlmanacNetwork::initializeNewNetwork();
$is_new = true;
$cancel_uri = $list_uri;
$title = pht('Create Network');
$save_button = pht('Create Network');
}
$v_name = $network->getName();
$e_name = true;
$validation_exception = null;
if ($request->isFormPost()) {
$v_name = $request->getStr('name');
$v_view = $request->getStr('viewPolicy');
$v_edit = $request->getStr('editPolicy');
$type_name = AlmanacNetworkTransaction::TYPE_NAME;
$type_view = PhabricatorTransactions::TYPE_VIEW_POLICY;
$type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY;
$xactions = array();
$xactions[] = id(new AlmanacNetworkTransaction())
->setTransactionType($type_name)
->setNewValue($v_name);
$xactions[] = id(new AlmanacNetworkTransaction())
->setTransactionType($type_view)
->setNewValue($v_view);
$xactions[] = id(new AlmanacNetworkTransaction())
->setTransactionType($type_edit)
->setNewValue($v_edit);
$editor = id(new AlmanacNetworkEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true);
try {
$editor->applyTransactions($network, $xactions);
$id = $network->getID();
$network_uri = $this->getApplicationURI("network/{$id}/");
return id(new AphrontRedirectResponse())->setURI($network_uri);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
$e_name = $ex->getShortMessage($type_name);
$network->setViewPolicy($v_view);
$network->setEditPolicy($v_edit);
}
}
$policies = id(new PhabricatorPolicyQuery())
->setViewer($viewer)
->setObject($network)
->execute();
$form = id(new AphrontFormView())
->setUser($viewer)
->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('Name'))
->setName('name')
->setValue($v_name)
->setError($e_name))
->appendChild(
id(new AphrontFormPolicyControl())
->setName('viewPolicy')
->setPolicyObject($network)
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
->setPolicies($policies))
->appendChild(
id(new AphrontFormPolicyControl())
->setName('editPolicy')
->setPolicyObject($network)
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
->setPolicies($policies))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton($cancel_uri)
->setValue($save_button));
$box = id(new PHUIObjectBoxView())
->setValidationException($validation_exception)
->setHeaderText($title)
->appendChild($form);
$crumbs = $this->buildApplicationCrumbs();
if ($is_new) {
$crumbs->addTextCrumb(pht('Create Network'));
} else {
$crumbs->addTextCrumb($network->getName(), $network_uri);
$crumbs->addTextCrumb(pht('Edit'));
}
return $this->buildApplicationPage(
array(
$crumbs,
$box,
),
array(
'title' => $title,
));
}
}

View File

@@ -0,0 +1,52 @@
<?php
final class AlmanacNetworkListController
extends AlmanacNetworkController {
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) {
$controller = id(new PhabricatorApplicationSearchController())
->setQueryKey($request->getURIData('queryKey'))
->setSearchEngine(new AlmanacNetworkSearchEngine())
->setNavigation($this->buildSideNavView());
return $this->delegateToController($controller);
}
public function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$can_create = $this->hasApplicationCapability(
AlmanacCreateNetworksCapability::CAPABILITY);
$crumbs->addAction(
id(new PHUIListItemView())
->setName(pht('Create Network'))
->setHref($this->getApplicationURI('network/edit/'))
->setIcon('fa-plus-square')
->setDisabled(!$can_create)
->setWorkflow(!$can_create));
return $crumbs;
}
public function buildSideNavView() {
$viewer = $this->getViewer();
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
id(new AlmanacNetworkSearchEngine())
->setViewer($viewer)
->addNavigationItems($nav->getMenu());
$nav->selectFilter(null);
return $nav;
}
}

View File

@@ -0,0 +1,95 @@
<?php
final class AlmanacNetworkViewController
extends AlmanacNetworkController {
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
$network = id(new AlmanacNetworkQuery())
->setViewer($viewer)
->withIDs(array($id))
->executeOne();
if (!$network) {
return new Aphront404Response();
}
$title = pht('Network %s', $network->getName());
$property_list = $this->buildPropertyList($network);
$action_list = $this->buildActionList($network);
$property_list->setActionList($action_list);
$header = id(new PHUIHeaderView())
->setUser($viewer)
->setHeader($network->getName())
->setPolicyObject($network);
$box = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($property_list);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($network->getName());
$xactions = id(new AlmanacNetworkTransactionQuery())
->setViewer($viewer)
->withObjectPHIDs(array($network->getPHID()))
->execute();
$xaction_view = id(new PhabricatorApplicationTransactionView())
->setUser($viewer)
->setObjectPHID($network->getPHID())
->setTransactions($xactions)
->setShouldTerminate(true);
return $this->buildApplicationPage(
array(
$crumbs,
$box,
$xaction_view,
),
array(
'title' => $title,
));
}
private function buildPropertyList(AlmanacNetwork $network) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer);
return $properties;
}
private function buildActionList(AlmanacNetwork $network) {
$viewer = $this->getViewer();
$id = $network->getID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$network,
PhabricatorPolicyCapability::CAN_EDIT);
$actions = id(new PhabricatorActionListView())
->setUser($viewer);
$actions->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Network'))
->setHref($this->getApplicationURI("network/edit/{$id}/"))
->setWorkflow(!$can_edit)
->setDisabled(!$can_edit));
return $actions;
}
}

View File

@@ -0,0 +1,14 @@
<?php
abstract class AlmanacServiceController extends AlmanacController {
public function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$list_uri = $this->getApplicationURI('service/');
$crumbs->addTextCrumb(pht('Services'), $list_uri);
return $crumbs;
}
}

View File

@@ -0,0 +1,142 @@
<?php
final class AlmanacServiceEditController
extends AlmanacServiceController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$list_uri = $this->getApplicationURI('service/');
$id = $request->getURIData('id');
if ($id) {
$service = id(new AlmanacServiceQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$service) {
return new Aphront404Response();
}
$is_new = false;
$service_uri = $service->getURI();
$cancel_uri = $service_uri;
$title = pht('Edit Service');
$save_button = pht('Save Changes');
} else {
$this->requireApplicationCapability(
AlmanacCreateServicesCapability::CAPABILITY);
$service = AlmanacService::initializeNewService();
$is_new = true;
$cancel_uri = $list_uri;
$title = pht('Create Service');
$save_button = pht('Create Service');
}
$v_name = $service->getName();
$e_name = true;
$validation_exception = null;
if ($request->isFormPost()) {
$v_name = $request->getStr('name');
$v_view = $request->getStr('viewPolicy');
$v_edit = $request->getStr('editPolicy');
$type_name = AlmanacServiceTransaction::TYPE_NAME;
$type_view = PhabricatorTransactions::TYPE_VIEW_POLICY;
$type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY;
$xactions = array();
$xactions[] = id(new AlmanacServiceTransaction())
->setTransactionType($type_name)
->setNewValue($v_name);
$xactions[] = id(new AlmanacServiceTransaction())
->setTransactionType($type_view)
->setNewValue($v_view);
$xactions[] = id(new AlmanacServiceTransaction())
->setTransactionType($type_edit)
->setNewValue($v_edit);
$editor = id(new AlmanacServiceEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true);
try {
$editor->applyTransactions($service, $xactions);
$service_uri = $service->getURI();
return id(new AphrontRedirectResponse())->setURI($service_uri);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
$e_name = $ex->getShortMessage($type_name);
$service->setViewPolicy($v_view);
$service->setEditPolicy($v_edit);
}
}
$policies = id(new PhabricatorPolicyQuery())
->setViewer($viewer)
->setObject($service)
->execute();
$form = id(new AphrontFormView())
->setUser($viewer)
->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('Name'))
->setName('name')
->setValue($v_name)
->setError($e_name))
->appendChild(
id(new AphrontFormPolicyControl())
->setName('viewPolicy')
->setPolicyObject($service)
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
->setPolicies($policies))
->appendChild(
id(new AphrontFormPolicyControl())
->setName('editPolicy')
->setPolicyObject($service)
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
->setPolicies($policies))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton($cancel_uri)
->setValue($save_button));
$box = id(new PHUIObjectBoxView())
->setValidationException($validation_exception)
->setHeaderText($title)
->appendChild($form);
$crumbs = $this->buildApplicationCrumbs();
if ($is_new) {
$crumbs->addTextCrumb(pht('Create Service'));
} else {
$crumbs->addTextCrumb($service->getName(), $service_uri);
$crumbs->addTextCrumb(pht('Edit'));
}
return $this->buildApplicationPage(
array(
$crumbs,
$box,
),
array(
'title' => $title,
));
}
}

View File

@@ -0,0 +1,52 @@
<?php
final class AlmanacServiceListController
extends AlmanacServiceController {
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) {
$controller = id(new PhabricatorApplicationSearchController())
->setQueryKey($request->getURIData('queryKey'))
->setSearchEngine(new AlmanacServiceSearchEngine())
->setNavigation($this->buildSideNavView());
return $this->delegateToController($controller);
}
public function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$can_create = $this->hasApplicationCapability(
AlmanacCreateServicesCapability::CAPABILITY);
$crumbs->addAction(
id(new PHUIListItemView())
->setName(pht('Create Service'))
->setHref($this->getApplicationURI('service/edit/'))
->setIcon('fa-plus-square')
->setDisabled(!$can_create)
->setWorkflow(!$can_create));
return $crumbs;
}
public function buildSideNavView() {
$viewer = $this->getViewer();
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
id(new AlmanacServiceSearchEngine())
->setViewer($viewer)
->addNavigationItems($nav->getMenu());
$nav->selectFilter(null);
return $nav;
}
}

View File

@@ -0,0 +1,145 @@
<?php
final class AlmanacServiceViewController
extends AlmanacServiceController {
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$name = $request->getURIData('name');
$service = id(new AlmanacServiceQuery())
->setViewer($viewer)
->withNames(array($name))
->executeOne();
if (!$service) {
return new Aphront404Response();
}
$title = pht('Service %s', $service->getName());
$property_list = $this->buildPropertyList($service);
$action_list = $this->buildActionList($service);
$property_list->setActionList($action_list);
$header = id(new PHUIHeaderView())
->setUser($viewer)
->setHeader($service->getName())
->setPolicyObject($service);
$box = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($property_list);
$bindings = $this->buildBindingList($service);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($service->getName());
$xactions = id(new AlmanacServiceTransactionQuery())
->setViewer($viewer)
->withObjectPHIDs(array($service->getPHID()))
->execute();
$xaction_view = id(new PhabricatorApplicationTransactionView())
->setUser($viewer)
->setObjectPHID($service->getPHID())
->setTransactions($xactions)
->setShouldTerminate(true);
return $this->buildApplicationPage(
array(
$crumbs,
$box,
$bindings,
$xaction_view,
),
array(
'title' => $title,
));
}
private function buildPropertyList(AlmanacService $service) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer);
return $properties;
}
private function buildActionList(AlmanacService $service) {
$viewer = $this->getViewer();
$id = $service->getID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$service,
PhabricatorPolicyCapability::CAN_EDIT);
$actions = id(new PhabricatorActionListView())
->setUser($viewer);
$actions->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Service'))
->setHref($this->getApplicationURI("service/edit/{$id}/"))
->setWorkflow(!$can_edit)
->setDisabled(!$can_edit));
return $actions;
}
private function buildBindingList(AlmanacService $service) {
$viewer = $this->getViewer();
$id = $service->getID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$service,
PhabricatorPolicyCapability::CAN_EDIT);
$bindings = id(new AlmanacBindingQuery())
->setViewer($viewer)
->withServicePHIDs(array($service->getPHID()))
->execute();
$phids = array();
foreach ($bindings as $binding) {
$phids[] = $binding->getServicePHID();
$phids[] = $binding->getDevicePHID();
$phids[] = $binding->getInterface()->getNetworkPHID();
}
$handles = $this->loadViewerHandles($phids);
$table = id(new AlmanacBindingTableView())
->setNoDataString(
pht('This service has not been bound to any device interfaces yet.'))
->setUser($viewer)
->setBindings($bindings)
->setHandles($handles);
$header = id(new PHUIHeaderView())
->setHeader(pht('Service Bindings'))
->addActionLink(
id(new PHUIButtonView())
->setTag('a')
->setHref($this->getApplicationURI("binding/edit/?serviceID={$id}"))
->setWorkflow(!$can_edit)
->setDisabled(!$can_edit)
->setText(pht('Add Binding'))
->setIcon(
id(new PHUIIconView())
->setIconFont('fa-plus')));
return id(new PHUIObjectBoxView())
->setHeader($header)
->appendChild($table);
}
}

View File

@@ -0,0 +1,139 @@
<?php
final class AlmanacBindingEditor
extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorAlmanacApplication';
}
public function getEditorObjectsDescription() {
return pht('Almanac Binding');
}
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
$types[] = AlmanacBindingTransaction::TYPE_INTERFACE;
return $types;
}
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case AlmanacBindingTransaction::TYPE_INTERFACE:
return $object->getInterfacePHID();
}
return parent::getCustomTransactionOldValue($object, $xaction);
}
protected function getCustomTransactionNewValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case AlmanacBindingTransaction::TYPE_INTERFACE:
return $xaction->getNewValue();
}
return parent::getCustomTransactionNewValue($object, $xaction);
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case AlmanacBindingTransaction::TYPE_INTERFACE:
$interface = id(new AlmanacInterfaceQuery())
->setViewer($this->requireActor())
->withPHIDs(array($xaction->getNewValue()))
->executeOne();
$object->setDevicePHID($interface->getDevicePHID());
$object->setInterfacePHID($interface->getPHID());
return;
}
return parent::applyCustomInternalTransaction($object, $xaction);
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case AlmanacBindingTransaction::TYPE_INTERFACE:
return;
}
return parent::applyCustomExternalTransaction($object, $xaction);
}
protected function validateTransaction(
PhabricatorLiskDAO $object,
$type,
array $xactions) {
$errors = parent::validateTransaction($object, $type, $xactions);
switch ($type) {
case AlmanacBindingTransaction::TYPE_INTERFACE:
$missing = $this->validateIsEmptyTextField(
$object->getInterfacePHID(),
$xactions);
if ($missing) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
pht('Bindings must specify an interface.'),
nonempty(last($xactions), null));
$error->setIsMissingFieldError(true);
$errors[] = $error;
} else if ($xactions) {
foreach ($xactions as $xaction) {
$interfaces = id(new AlmanacInterfaceQuery())
->setViewer($this->requireActor())
->withPHIDs(array($xaction->getNewValue()))
->execute();
if (!$interfaces) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht(
'You can not bind a service to an invalid or restricted '.
'interface.'),
$xaction);
$errors[] = $error;
}
}
$final_value = last($xactions)->getNewValue();
$binding = id(new AlmanacBindingQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withServicePHIDs(array($object->getServicePHID()))
->withInterfacePHIDs(array($final_value))
->executeOne();
if ($binding && ($binding->getID() != $object->getID())) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Already Bound'),
pht(
'You can not bind a service to the same interface multiple '.
'times.'),
last($xactions));
$errors[] = $error;
}
}
break;
}
return $errors;
}
}

View File

@@ -0,0 +1,292 @@
<?php
final class AlmanacDeviceEditor
extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorAlmanacApplication';
}
public function getEditorObjectsDescription() {
return pht('Almanac Device');
}
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
$types[] = AlmanacDeviceTransaction::TYPE_NAME;
$types[] = AlmanacDeviceTransaction::TYPE_INTERFACE;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
return $types;
}
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case AlmanacDeviceTransaction::TYPE_NAME:
return $object->getName();
}
return parent::getCustomTransactionOldValue($object, $xaction);
}
protected function getCustomTransactionNewValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case AlmanacDeviceTransaction::TYPE_NAME:
case AlmanacDeviceTransaction::TYPE_INTERFACE:
return $xaction->getNewValue();
}
return parent::getCustomTransactionNewValue($object, $xaction);
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case AlmanacDeviceTransaction::TYPE_NAME:
$object->setName($xaction->getNewValue());
return;
case AlmanacDeviceTransaction::TYPE_INTERFACE:
case PhabricatorTransactions::TYPE_VIEW_POLICY:
case PhabricatorTransactions::TYPE_EDIT_POLICY:
return;
}
return parent::applyCustomInternalTransaction($object, $xaction);
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case AlmanacDeviceTransaction::TYPE_NAME:
case PhabricatorTransactions::TYPE_VIEW_POLICY:
case PhabricatorTransactions::TYPE_EDIT_POLICY:
return;
case AlmanacDeviceTransaction::TYPE_INTERFACE:
$old = $xaction->getOldValue();
if ($old) {
$interface = id(new AlmanacInterfaceQuery())
->setViewer($this->requireActor())
->withIDs(array($old['id']))
->executeOne();
if (!$interface) {
throw new Exception(pht('Unable to load interface!'));
}
} else {
$interface = AlmanacInterface::initializeNewInterface()
->setDevicePHID($object->getPHID());
}
$new = $xaction->getNewValue();
if ($new) {
$interface
->setNetworkPHID($new['networkPHID'])
->setAddress($new['address'])
->setPort((int)$new['port'])
->save();
} else {
$interface->delete();
}
return;
}
return parent::applyCustomExternalTransaction($object, $xaction);
}
protected function validateTransaction(
PhabricatorLiskDAO $object,
$type,
array $xactions) {
$errors = parent::validateTransaction($object, $type, $xactions);
switch ($type) {
case AlmanacDeviceTransaction::TYPE_NAME:
$missing = $this->validateIsEmptyTextField(
$object->getName(),
$xactions);
if ($missing) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
pht('Device name is required.'),
nonempty(last($xactions), null));
$error->setIsMissingFieldError(true);
$errors[] = $error;
} else {
foreach ($xactions as $xaction) {
$message = null;
$name = $xaction->getNewValue();
try {
AlmanacNames::validateServiceOrDeviceName($name);
} catch (Exception $ex) {
$message = $ex->getMessage();
}
if ($message !== null) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
$message,
$xaction);
$errors[] = $error;
}
}
}
if ($xactions) {
$duplicate = id(new AlmanacDeviceQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withNames(array(last($xactions)->getNewValue()))
->executeOne();
if ($duplicate && ($duplicate->getID() != $object->getID())) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Not Unique'),
pht('Almanac devices must have unique names.'),
last($xactions));
$errors[] = $error;
}
}
break;
case AlmanacDeviceTransaction::TYPE_INTERFACE:
// We want to make sure that all the affected networks are visible to
// the actor, any edited interfaces exist, and that the actual address
// components are valid.
$network_phids = array();
foreach ($xactions as $xaction) {
$old = $xaction->getOldValue();
$new = $xaction->getNewValue();
if ($old) {
$network_phids[] = $old['networkPHID'];
}
if ($new) {
$network_phids[] = $new['networkPHID'];
$address = $new['address'];
if (!strlen($address)) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht('Interfaces must have an address.'),
$xaction);
$errors[] = $error;
} else {
// TODO: Validate addresses, but IPv6 addresses are not trival
// to validate.
}
$port = $new['port'];
if (!strlen($port)) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht('Interfaces must have a port.'),
$xaction);
$errors[] = $error;
} else if ((int)$port < 1 || (int)$port > 65535) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht(
'Port numbers must be between 1 and 65535, inclusive.'),
$xaction);
$errors[] = $error;
}
}
}
if ($network_phids) {
$networks = id(new AlmanacNetworkQuery())
->setViewer($this->requireActor())
->withPHIDs($network_phids)
->execute();
$networks = mpull($networks, null, 'getPHID');
} else {
$networks = array();
}
$addresses = array();
foreach ($xactions as $xaction) {
$old = $xaction->getOldValue();
if ($old) {
$network = idx($networks, $old['networkPHID']);
if (!$network) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht(
'You can not edit an interface which belongs to a '.
'nonexistent or restricted network.'),
$xaction);
$errors[] = $error;
}
$addresses[] = $old['id'];
}
$new = $xaction->getNewValue();
if ($new) {
$network = idx($networks, $new['networkPHID']);
if (!$network) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht(
'You can not add an interface on a nonexistent or '.
'restricted network.'),
$xaction);
$errors[] = $error;
}
}
}
if ($addresses) {
$interfaces = id(new AlmanacInterfaceQuery())
->setViewer($this->requireActor())
->withDevicePHIDs(array($object->getPHID()))
->withIDs($addresses)
->execute();
$interfaces = mpull($interfaces, null, 'getID');
} else {
$interfaces = array();
}
foreach ($xactions as $xaction) {
$old = $xaction->getOldValue();
if ($old) {
$interface = idx($interfaces, $old['id']);
if (!$interface) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht('You can not edit an invalid or restricted interface.'),
$xaction);
$errors[] = $error;
}
}
}
break;
}
return $errors;
}
}

View File

@@ -0,0 +1,108 @@
<?php
final class AlmanacNetworkEditor
extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorAlmanacApplication';
}
public function getEditorObjectsDescription() {
return pht('Almanac Network');
}
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
$types[] = AlmanacNetworkTransaction::TYPE_NAME;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
return $types;
}
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case AlmanacNetworkTransaction::TYPE_NAME:
return $object->getName();
}
return parent::getCustomTransactionOldValue($object, $xaction);
}
protected function getCustomTransactionNewValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case AlmanacNetworkTransaction::TYPE_NAME:
return $xaction->getNewValue();
}
return parent::getCustomTransactionNewValue($object, $xaction);
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case AlmanacNetworkTransaction::TYPE_NAME:
$object->setName($xaction->getNewValue());
return;
case PhabricatorTransactions::TYPE_VIEW_POLICY:
case PhabricatorTransactions::TYPE_EDIT_POLICY:
return;
}
return parent::applyCustomInternalTransaction($object, $xaction);
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case AlmanacNetworkTransaction::TYPE_NAME:
case PhabricatorTransactions::TYPE_VIEW_POLICY:
case PhabricatorTransactions::TYPE_EDIT_POLICY:
return;
}
return parent::applyCustomExternalTransaction($object, $xaction);
}
protected function validateTransaction(
PhabricatorLiskDAO $object,
$type,
array $xactions) {
$errors = parent::validateTransaction($object, $type, $xactions);
switch ($type) {
case AlmanacServiceTransaction::TYPE_NAME:
$missing = $this->validateIsEmptyTextField(
$object->getName(),
$xactions);
if ($missing) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
pht('Network name is required.'),
nonempty(last($xactions), null));
$error->setIsMissingFieldError(true);
$errors[] = $error;
}
break;
}
return $errors;
}
}

View File

@@ -0,0 +1,145 @@
<?php
final class AlmanacServiceEditor
extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorAlmanacApplication';
}
public function getEditorObjectsDescription() {
return pht('Almanac Service');
}
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
$types[] = AlmanacServiceTransaction::TYPE_NAME;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
return $types;
}
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case AlmanacServiceTransaction::TYPE_NAME:
return $object->getName();
}
return parent::getCustomTransactionOldValue($object, $xaction);
}
protected function getCustomTransactionNewValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case AlmanacServiceTransaction::TYPE_NAME:
return $xaction->getNewValue();
}
return parent::getCustomTransactionNewValue($object, $xaction);
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case AlmanacServiceTransaction::TYPE_NAME:
$object->setName($xaction->getNewValue());
return;
case PhabricatorTransactions::TYPE_VIEW_POLICY:
case PhabricatorTransactions::TYPE_EDIT_POLICY:
return;
}
return parent::applyCustomInternalTransaction($object, $xaction);
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case AlmanacServiceTransaction::TYPE_NAME:
case PhabricatorTransactions::TYPE_VIEW_POLICY:
case PhabricatorTransactions::TYPE_EDIT_POLICY:
return;
}
return parent::applyCustomExternalTransaction($object, $xaction);
}
protected function validateTransaction(
PhabricatorLiskDAO $object,
$type,
array $xactions) {
$errors = parent::validateTransaction($object, $type, $xactions);
switch ($type) {
case AlmanacServiceTransaction::TYPE_NAME:
$missing = $this->validateIsEmptyTextField(
$object->getName(),
$xactions);
if ($missing) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
pht('Service name is required.'),
nonempty(last($xactions), null));
$error->setIsMissingFieldError(true);
$errors[] = $error;
} else {
foreach ($xactions as $xaction) {
$message = null;
$name = $xaction->getNewValue();
try {
AlmanacNames::validateServiceOrDeviceName($name);
} catch (Exception $ex) {
$message = $ex->getMessage();
}
if ($message !== null) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
$message,
$xaction);
$errors[] = $error;
}
}
}
if ($xactions) {
$duplicate = id(new AlmanacServiceQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withNames(array(last($xactions)->getNewValue()))
->executeOne();
if ($duplicate && ($duplicate->getID() != $object->getID())) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Not Unique'),
pht('Almanac services must have unique names.'),
last($xactions));
$errors[] = $error;
}
}
break;
}
return $errors;
}
}

View File

@@ -0,0 +1,38 @@
<?php
final class AlmanacBindingPHIDType extends PhabricatorPHIDType {
const TYPECONST = 'ABND';
public function getTypeName() {
return pht('Almanac Binding');
}
public function newObject() {
return new AlmanacBinding();
}
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
return id(new AlmanacBindingQuery())
->withPHIDs($phids);
}
public function loadHandles(
PhabricatorHandleQuery $query,
array $handles,
array $objects) {
foreach ($handles as $phid => $handle) {
$binding = $objects[$phid];
$id = $binding->getID();
$handle->setObjectName(pht('Binding %d', $id));
$handle->setName(pht('Binding %d', $id));
}
}
}

View File

@@ -33,6 +33,7 @@ final class AlmanacDevicePHIDType extends PhabricatorPHIDType {
$handle->setObjectName(pht('Device %d', $id));
$handle->setName($name);
$handle->setURI($device->getURI());
}
}

View File

@@ -0,0 +1,50 @@
<?php
final class AlmanacInterfacePHIDType extends PhabricatorPHIDType {
const TYPECONST = 'AINT';
public function getTypeName() {
return pht('Almanac Interface');
}
public function newObject() {
return new AlmanacInterface();
}
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
return id(new AlmanacInterfaceQuery())
->withPHIDs($phids);
}
public function loadHandles(
PhabricatorHandleQuery $query,
array $handles,
array $objects) {
foreach ($handles as $phid => $handle) {
$interface = $objects[$phid];
$id = $interface->getID();
$device_name = $interface->getDevice()->getName();
$address = $interface->getAddress();
$port = $interface->getPort();
$network = $interface->getNetwork()->getName();
$name = pht(
'%s:%s (%s on %s)',
$device_name,
$port,
$address,
$network);
$handle->setObjectName(pht('Interface %d', $id));
$handle->setName($name);
}
}
}

View File

@@ -0,0 +1,40 @@
<?php
final class AlmanacNetworkPHIDType extends PhabricatorPHIDType {
const TYPECONST = 'ANET';
public function getTypeName() {
return pht('Almanac Network');
}
public function newObject() {
return new AlmanacNetwork();
}
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
return id(new AlmanacNetworkQuery())
->withPHIDs($phids);
}
public function loadHandles(
PhabricatorHandleQuery $query,
array $handles,
array $objects) {
foreach ($handles as $phid => $handle) {
$network = $objects[$phid];
$id = $network->getID();
$name = $network->getName();
$handle->setObjectName(pht('Network %d', $id));
$handle->setName($name);
$handle->setURI($network->getURI());
}
}
}

View File

@@ -0,0 +1,40 @@
<?php
final class AlmanacServicePHIDType extends PhabricatorPHIDType {
const TYPECONST = 'ASRV';
public function getTypeName() {
return pht('Almanac Service');
}
public function newObject() {
return new AlmanacService();
}
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
return id(new AlmanacServiceQuery())
->withPHIDs($phids);
}
public function loadHandles(
PhabricatorHandleQuery $query,
array $handles,
array $objects) {
foreach ($handles as $phid => $handle) {
$service = $objects[$phid];
$id = $service->getID();
$name = $service->getName();
$handle->setObjectName(pht('Service %d', $id));
$handle->setName($name);
$handle->setURI($service->getURI());
}
}
}

View File

@@ -0,0 +1,143 @@
<?php
final class AlmanacBindingQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $servicePHIDs;
private $devicePHIDs;
private $interfacePHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withServicePHIDs(array $phids) {
$this->servicePHIDs = $phids;
return $this;
}
public function withDevicePHIDs(array $phids) {
$this->devicePHIDs = $phids;
return $this;
}
public function withInterfacePHIDs(array $phids) {
$this->interfacePHIDs = $phids;
return $this;
}
protected function loadPage() {
$table = new AlmanacBinding();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $bindings) {
$service_phids = mpull($bindings, 'getServicePHID');
$device_phids = mpull($bindings, 'getDevicePHID');
$interface_phids = mpull($bindings, 'getInterfacePHID');
$services = id(new AlmanacServiceQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($service_phids)
->execute();
$services = mpull($services, null, 'getPHID');
$devices = id(new AlmanacDeviceQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($device_phids)
->execute();
$devices = mpull($devices, null, 'getPHID');
$interfaces = id(new AlmanacInterfaceQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($interface_phids)
->execute();
$interfaces = mpull($interfaces, null, 'getPHID');
foreach ($bindings as $key => $binding) {
$service = idx($services, $binding->getServicePHID());
$device = idx($devices, $binding->getDevicePHID());
$interface = idx($interfaces, $binding->getInterfacePHID());
if (!$service || !$device || !$interface) {
$this->didRejectResult($binding);
unset($bindings[$key]);
continue;
}
$binding->attachService($service);
$binding->attachDevice($device);
$binding->attachInterface($interface);
}
return $bindings;
}
protected function buildWhereClause($conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->servicePHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'servicePHID IN (%Ls)',
$this->servicePHIDs);
}
if ($this->devicePHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'devicePHID IN (%Ls)',
$this->devicePHIDs);
}
if ($this->interfacePHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'interfacePHID IN (%Ls)',
$this->interfacePHIDs);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorAlmanacApplication';
}
}

View File

@@ -0,0 +1,10 @@
<?php
final class AlmanacBindingTransactionQuery
extends PhabricatorApplicationTransactionQuery {
public function getTemplateApplicationTransaction() {
return new AlmanacBindingTransaction();
}
}

View File

@@ -5,6 +5,8 @@ final class AlmanacDeviceQuery
private $ids;
private $phids;
private $names;
private $datasourceQuery;
public function withIDs(array $ids) {
$this->ids = $ids;
@@ -16,6 +18,16 @@ final class AlmanacDeviceQuery
return $this;
}
public function withNames(array $names) {
$this->names = $names;
return $this;
}
public function withDatasourceQuery($query) {
$this->datasourceQuery = $query;
return $this;
}
protected function loadPage() {
$table = new AlmanacDevice();
$conn_r = $table->establishConnection('r');
@@ -48,6 +60,24 @@ final class AlmanacDeviceQuery
$this->phids);
}
if ($this->names !== null) {
$hashes = array();
foreach ($this->names as $name) {
$hashes[] = PhabricatorHash::digestForIndex($name);
}
$where[] = qsprintf(
$conn_r,
'nameIndex IN (%Ls)',
$hashes);
}
if ($this->datasourceQuery !== null) {
$where[] = qsprintf(
$conn_r,
'name LIKE %>',
$this->datasourceQuery);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);

View File

@@ -0,0 +1,84 @@
<?php
final class AlmanacDeviceSearchEngine
extends PhabricatorApplicationSearchEngine {
public function getResultTypeDescription() {
return pht('Almanac Devices');
}
protected function getApplicationClassName() {
return 'PhabricatorAlmanacApplication';
}
public function buildSavedQueryFromRequest(AphrontRequest $request) {
$saved = new PhabricatorSavedQuery();
return $saved;
}
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
$query = id(new AlmanacDeviceQuery());
return $query;
}
public function buildSearchForm(
AphrontFormView $form,
PhabricatorSavedQuery $saved_query) {}
protected function getURI($path) {
return '/almanac/device/'.$path;
}
public function getBuiltinQueryNames() {
$names = array(
'all' => pht('All Devices'),
);
return $names;
}
public function buildSavedQueryFromBuiltin($query_key) {
$query = $this->newSavedQuery();
$query->setQueryKey($query_key);
switch ($query_key) {
case 'all':
return $query;
}
return parent::buildSavedQueryFromBuiltin($query_key);
}
protected function getRequiredHandlePHIDsForResultList(
array $devices,
PhabricatorSavedQuery $query) {
return array();
}
protected function renderResultList(
array $devices,
PhabricatorSavedQuery $query,
array $handles) {
assert_instances_of($devices, 'AlmanacDevice');
$viewer = $this->requireViewer();
$list = new PHUIObjectItemListView();
$list->setUser($viewer);
foreach ($devices as $device) {
$item = id(new PHUIObjectItemView())
->setObjectName(pht('Device %d', $device->getID()))
->setHeader($device->getName())
->setHref($device->getURI())
->setObject($device);
$list->addItem($item);
}
return $list;
}
}

View File

@@ -0,0 +1,10 @@
<?php
final class AlmanacDeviceTransactionQuery
extends PhabricatorApplicationTransactionQuery {
public function getTemplateApplicationTransaction() {
return new AlmanacDeviceTransaction();
}
}

View File

@@ -0,0 +1,139 @@
<?php
final class AlmanacInterfaceQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $networkPHIDs;
private $devicePHIDs;
private $addresses;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withNetworkPHIDs(array $phids) {
$this->networkPHIDs = $phids;
return $this;
}
public function withDevicePHIDs(array $phids) {
$this->devicePHIDs = $phids;
return $this;
}
public function withAddresses(array $addresses) {
$this->addresses = $addresses;
return $this;
}
protected function loadPage() {
$table = new AlmanacInterface();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function willFilterPage(array $interfaces) {
$network_phids = mpull($interfaces, 'getNetworkPHID');
$device_phids = mpull($interfaces, 'getDevicePHID');
$networks = id(new AlmanacNetworkQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($network_phids)
->execute();
$networks = mpull($networks, null, 'getPHID');
$devices = id(new AlmanacDeviceQuery())
->setParentQuery($this)
->setViewer($this->getViewer())
->withPHIDs($device_phids)
->execute();
$devices = mpull($devices, null, 'getPHID');
foreach ($interfaces as $key => $interface) {
$network = idx($networks, $interface->getNetworkPHID());
$device = idx($devices, $interface->getDevicePHID());
if (!$network || !$device) {
$this->didRejectResult($interface);
unset($interfaces[$key]);
continue;
}
$interface->attachNetwork($network);
$interface->attachDevice($device);
}
return $interfaces;
}
protected function buildWhereClause($conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->networkPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'networkPHID IN (%Ls)',
$this->networkPHIDs);
}
if ($this->devicePHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'devicePHID IN (%Ls)',
$this->devicePHIDs);
}
if ($this->addresses !== null) {
$parts = array();
foreach ($this->addresses as $address) {
$parts[] = qsprintf(
$conn_r,
'(networkPHID = %s AND address = %s AND port = %d)',
$address->getNetworkPHID(),
$address->getAddress(),
$address->getPort());
}
$where[] = implode(' OR ', $parts);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorAlmanacApplication';
}
}

View File

@@ -0,0 +1,60 @@
<?php
final class AlmanacNetworkQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
protected function loadPage() {
$table = new AlmanacNetwork();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function buildWhereClause($conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorAlmanacApplication';
}
}

View File

@@ -0,0 +1,85 @@
<?php
final class AlmanacNetworkSearchEngine
extends PhabricatorApplicationSearchEngine {
public function getResultTypeDescription() {
return pht('Almanac Networks');
}
protected function getApplicationClassName() {
return 'PhabricatorAlmanacApplication';
}
public function buildSavedQueryFromRequest(AphrontRequest $request) {
$saved = new PhabricatorSavedQuery();
return $saved;
}
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
$query = id(new AlmanacNetworkQuery());
return $query;
}
public function buildSearchForm(
AphrontFormView $form,
PhabricatorSavedQuery $saved_query) {}
protected function getURI($path) {
return '/almanac/network/'.$path;
}
public function getBuiltinQueryNames() {
$names = array(
'all' => pht('All Networks'),
);
return $names;
}
public function buildSavedQueryFromBuiltin($query_key) {
$query = $this->newSavedQuery();
$query->setQueryKey($query_key);
switch ($query_key) {
case 'all':
return $query;
}
return parent::buildSavedQueryFromBuiltin($query_key);
}
protected function getRequiredHandlePHIDsForResultList(
array $networks,
PhabricatorSavedQuery $query) {
return array();
}
protected function renderResultList(
array $networks,
PhabricatorSavedQuery $query,
array $handles) {
assert_instances_of($networks, 'AlmanacNetwork');
$viewer = $this->requireViewer();
$list = new PHUIObjectItemListView();
$list->setUser($viewer);
foreach ($networks as $network) {
$id = $network->getID();
$item = id(new PHUIObjectItemView())
->setObjectName(pht('Network %d', $id))
->setHeader($network->getName())
->setHref($this->getApplicationURI("network/{$id}/"))
->setObject($network);
$list->addItem($item);
}
return $list;
}
}

View File

@@ -0,0 +1,10 @@
<?php
final class AlmanacNetworkTransactionQuery
extends PhabricatorApplicationTransactionQuery {
public function getTemplateApplicationTransaction() {
return new AlmanacNetworkTransaction();
}
}

View File

@@ -0,0 +1,78 @@
<?php
final class AlmanacServiceQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $names;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withNames(array $names) {
$this->names = $names;
return $this;
}
protected function loadPage() {
$table = new AlmanacService();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
protected function buildWhereClause($conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->names !== null) {
$hashes = array();
foreach ($this->names as $name) {
$hashes[] = PhabricatorHash::digestForIndex($name);
}
$where[] = qsprintf(
$conn_r,
'nameIndex IN (%Ls)',
$hashes);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {
return 'PhabricatorAlmanacApplication';
}
}

View File

@@ -0,0 +1,83 @@
<?php
final class AlmanacServiceSearchEngine
extends PhabricatorApplicationSearchEngine {
public function getResultTypeDescription() {
return pht('Almanac Services');
}
protected function getApplicationClassName() {
return 'PhabricatorAlmanacApplication';
}
public function buildSavedQueryFromRequest(AphrontRequest $request) {
$saved = new PhabricatorSavedQuery();
return $saved;
}
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
$query = id(new AlmanacServiceQuery());
return $query;
}
public function buildSearchForm(
AphrontFormView $form,
PhabricatorSavedQuery $saved_query) {}
protected function getURI($path) {
return '/almanac/service/'.$path;
}
public function getBuiltinQueryNames() {
$names = array(
'all' => pht('All Services'),
);
return $names;
}
public function buildSavedQueryFromBuiltin($query_key) {
$query = $this->newSavedQuery();
$query->setQueryKey($query_key);
switch ($query_key) {
case 'all':
return $query;
}
return parent::buildSavedQueryFromBuiltin($query_key);
}
protected function getRequiredHandlePHIDsForResultList(
array $services,
PhabricatorSavedQuery $query) {
return array();
}
protected function renderResultList(
array $services,
PhabricatorSavedQuery $query,
array $handles) {
assert_instances_of($services, 'AlmanacService');
$viewer = $this->requireViewer();
$list = new PHUIObjectItemListView();
$list->setUser($viewer);
foreach ($services as $service) {
$item = id(new PHUIObjectItemView())
->setObjectName(pht('Service %d', $service->getID()))
->setHeader($service->getName())
->setHref($service->getURI())
->setObject($service);
$list->addItem($item);
}
return $list;
}
}

View File

@@ -0,0 +1,10 @@
<?php
final class AlmanacServiceTransactionQuery
extends PhabricatorApplicationTransactionQuery {
public function getTemplateApplicationTransaction() {
return new AlmanacServiceTransaction();
}
}

View File

@@ -0,0 +1,112 @@
<?php
final class AlmanacBinding
extends AlmanacDAO
implements PhabricatorPolicyInterface {
protected $servicePHID;
protected $devicePHID;
protected $interfacePHID;
protected $mailKey;
private $service = self::ATTACHABLE;
private $device = self::ATTACHABLE;
private $interface = self::ATTACHABLE;
public static function initializeNewBinding(AlmanacService $service) {
return id(new AlmanacBinding())
->setServicePHID($service->getPHID());
}
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_COLUMN_SCHEMA => array(
'mailKey' => 'bytes20',
),
self::CONFIG_KEY_SCHEMA => array(
'key_service' => array(
'columns' => array('servicePHID', 'interfacePHID'),
'unique' => true,
),
'key_device' => array(
'columns' => array('devicePHID'),
),
'key_interface' => array(
'columns' => array('interfacePHID'),
),
),
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(AlmanacBindingPHIDType::TYPECONST);
}
public function save() {
if (!$this->mailKey) {
$this->mailKey = Filesystem::readRandomCharacters(20);
}
return parent::save();
}
public function getURI() {
return '/almanac/binding/'.$this->getID().'/';
}
public function getService() {
return $this->assertAttached($this->service);
}
public function attachService(AlmanacService $service) {
$this->service = $service;
return $this;
}
public function getDevice() {
return $this->assertAttached($this->device);
}
public function attachDevice(AlmanacDevice $device) {
$this->device = $device;
return $this;
}
public function getInterface() {
return $this->assertAttached($this->interface);
}
public function attachInterface(AlmanacInterface $interface) {
$this->interface = $interface;
return $this;
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
return $this->getService()->getPolicy($capability);
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
return $this->getService()->hasAutomaticCapability($capability, $viewer);
}
public function describeAutomaticCapability($capability) {
return array(
pht('A binding inherits the policies of its service.'),
pht(
'To view a binding, you must also be able to view its device and '.
'interface.'),
);
}
}

View File

@@ -0,0 +1,65 @@
<?php
final class AlmanacBindingTransaction
extends PhabricatorApplicationTransaction {
const TYPE_INTERFACE = 'almanac:binding:interface';
public function getApplicationName() {
return 'almanac';
}
public function getApplicationTransactionType() {
return AlmanacBindingPHIDType::TYPECONST;
}
public function getApplicationTransactionCommentObject() {
return null;
}
public function getRequiredHandlePHIDs() {
$phids = parent::getRequiredHandlePHIDs();
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_INTERFACE:
if ($old) {
$phids[] = $old;
}
if ($new) {
$phids[] = $new;
}
break;
}
return $phids;
}
public function getTitle() {
$author_phid = $this->getAuthorPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_INTERFACE:
if ($old === null) {
return pht(
'%s created this binding.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s changed this binding from %s to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($old),
$this->renderHandleLink($new));
}
break;
}
return parent::getTitle();
}
}

View File

@@ -5,12 +5,33 @@ final class AlmanacDevice
implements PhabricatorPolicyInterface {
protected $name;
protected $nameIndex;
protected $mailKey;
protected $viewPolicy;
protected $editPolicy;
public static function initializeNewDevice() {
return id(new AlmanacDevice())
->setViewPolicy(PhabricatorPolicies::POLICY_USER)
->setEditPolicy(PhabricatorPolicies::POLICY_ADMIN);
}
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_COLUMN_SCHEMA => array(
'name' => 'text255',
'name' => 'text128',
'nameIndex' => 'bytes12',
'mailKey' => 'bytes20',
),
self::CONFIG_KEY_SCHEMA => array(
'key_name' => array(
'columns' => array('nameIndex'),
'unique' => true,
),
'key_nametext' => array(
'columns' => array('name'),
),
),
) + parent::getConfiguration();
}
@@ -19,6 +40,22 @@ final class AlmanacDevice
return PhabricatorPHID::generateNewPHID(AlmanacDevicePHIDType::TYPECONST);
}
public function save() {
AlmanacNames::validateServiceOrDeviceName($this->getName());
$this->nameIndex = PhabricatorHash::digestForIndex($this->getName());
if (!$this->mailKey) {
$this->mailKey = Filesystem::readRandomCharacters(20);
}
return parent::save();
}
public function getURI() {
return '/almanac/device/view/'.$this->getName().'/';
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
@@ -26,16 +63,16 @@ final class AlmanacDevice
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
// Until we get a clearer idea on what's going to be stored in this
// table, don't allow anyone (other than the omnipotent user) to find
// these objects.
return PhabricatorPolicies::POLICY_NOONE;
return $this->getViewPolicy();
case PhabricatorPolicyCapability::CAN_EDIT:
return $this->getEditPolicy();
}
}

View File

@@ -0,0 +1,100 @@
<?php
final class AlmanacDeviceTransaction
extends PhabricatorApplicationTransaction {
const TYPE_NAME = 'almanac:device:name';
const TYPE_INTERFACE = 'almanac:device:interface';
public function getApplicationName() {
return 'almanac';
}
public function getApplicationTransactionType() {
return AlmanacDevicePHIDType::TYPECONST;
}
public function getApplicationTransactionCommentObject() {
return null;
}
public function getRequiredHandlePHIDs() {
$phids = parent::getRequiredHandlePHIDs();
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_INTERFACE:
if ($old) {
$phids[] = $old['networkPHID'];
}
if ($new) {
$phids[] = $new['networkPHID'];
}
break;
}
return $phids;
}
public function getTitle() {
$author_phid = $this->getAuthorPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
if ($old === null) {
return pht(
'%s created this device.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s renamed this device from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
}
break;
case self::TYPE_INTERFACE:
if ($old && $new) {
return pht(
'%s changed interface %s on this device to %s.',
$this->renderHandleLink($author_phid),
$this->describeInterface($old),
$this->describeInterface($new));
} else if ($old) {
return pht(
'%s removed the interface %s from this device.',
$this->renderHandleLink($author_phid),
$this->describeInterface($new));
} else if ($new) {
return pht(
'%s added the interface %s to this device.',
$this->renderHandleLink($author_phid),
$this->describeInterface($new));
}
}
return parent::getTitle();
}
public function shouldGenerateOldValue() {
switch ($this->getTransactionType()) {
case self::TYPE_INTERFACE:
return false;
}
return parent::shouldGenerateOldValue();
}
private function describeInterface(array $info) {
return pht(
'%s:%s (%s)',
$info['address'],
$info['port'],
$this->renderHandleLink($info['networkPHID']));
}
}

View File

@@ -0,0 +1,103 @@
<?php
final class AlmanacInterface
extends AlmanacDAO
implements PhabricatorPolicyInterface {
protected $devicePHID;
protected $networkPHID;
protected $address;
protected $port;
private $device = self::ATTACHABLE;
private $network = self::ATTACHABLE;
public static function initializeNewInterface() {
return id(new AlmanacInterface());
}
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_COLUMN_SCHEMA => array(
'address' => 'text64',
'port' => 'uint32',
),
self::CONFIG_KEY_SCHEMA => array(
'key_location' => array(
'columns' => array('networkPHID', 'address', 'port'),
),
'key_device' => array(
'columns' => array('devicePHID'),
),
),
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
AlmanacInterfacePHIDType::TYPECONST);
}
public function getDevice() {
return $this->assertAttached($this->device);
}
public function attachDevice(AlmanacDevice $device) {
$this->device = $device;
return $this;
}
public function getNetwork() {
return $this->assertAttached($this->network);
}
public function attachNetwork(AlmanacNetwork $network) {
$this->network = $network;
return $this;
}
public function toAddress() {
return AlmanacAddress::newFromParts(
$this->getNetworkPHID(),
$this->getAddress(),
$this->getPort());
}
public function getAddressHash() {
return $this->toAddress()->toHash();
}
public function renderDisplayAddress() {
return $this->getAddress().':'.$this->getPort();
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
return $this->getDevice()->getPolicy($capability);
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
return $this->getDevice()->hasAutomaticCapability($capability, $viewer);
}
public function describeAutomaticCapability($capability) {
return array(
pht('An interface inherits the policies of the device it belongs to.'),
pht(
'You must be able to view the network an interface resides on to '.
'view the interface.'),
);
}
}

View File

@@ -0,0 +1,72 @@
<?php
final class AlmanacNetwork
extends AlmanacDAO
implements PhabricatorPolicyInterface {
protected $name;
protected $mailKey;
protected $viewPolicy;
protected $editPolicy;
public static function initializeNewNetwork() {
return id(new AlmanacNetwork())
->setViewPolicy(PhabricatorPolicies::POLICY_USER)
->setEditPolicy(PhabricatorPolicies::POLICY_ADMIN);
}
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_COLUMN_SCHEMA => array(
'name' => 'text128',
'mailKey' => 'bytes20',
),
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(AlmanacNetworkPHIDType::TYPECONST);
}
public function save() {
if (!$this->mailKey) {
$this->mailKey = Filesystem::readRandomCharacters(20);
}
return parent::save();
}
public function getURI() {
return '/almanac/network/view/'.$this->getName().'/';
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return $this->getViewPolicy();
case PhabricatorPolicyCapability::CAN_EDIT:
return $this->getEditPolicy();
}
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View File

@@ -0,0 +1,45 @@
<?php
final class AlmanacNetworkTransaction
extends PhabricatorApplicationTransaction {
const TYPE_NAME = 'almanac:network:name';
public function getApplicationName() {
return 'almanac';
}
public function getApplicationTransactionType() {
return AlmanacNetworkPHIDType::TYPECONST;
}
public function getApplicationTransactionCommentObject() {
return null;
}
public function getTitle() {
$author_phid = $this->getAuthorPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
if ($old === null) {
return pht(
'%s created this network.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s renamed this network from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
}
break;
}
return parent::getTitle();
}
}

View File

@@ -0,0 +1,86 @@
<?php
final class AlmanacService
extends AlmanacDAO
implements PhabricatorPolicyInterface {
protected $name;
protected $nameIndex;
protected $mailKey;
protected $viewPolicy;
protected $editPolicy;
public static function initializeNewService() {
return id(new AlmanacService())
->setViewPolicy(PhabricatorPolicies::POLICY_USER)
->setEditPolicy(PhabricatorPolicies::POLICY_ADMIN);
}
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_COLUMN_SCHEMA => array(
'name' => 'text128',
'nameIndex' => 'bytes12',
'mailKey' => 'bytes20',
),
self::CONFIG_KEY_SCHEMA => array(
'key_name' => array(
'columns' => array('nameIndex'),
'unique' => true,
),
'key_nametext' => array(
'columns' => array('name'),
),
),
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(AlmanacServicePHIDType::TYPECONST);
}
public function save() {
AlmanacNames::validateServiceOrDeviceName($this->getName());
$this->nameIndex = PhabricatorHash::digestForIndex($this->getName());
if (!$this->mailKey) {
$this->mailKey = Filesystem::readRandomCharacters(20);
}
return parent::save();
}
public function getURI() {
return '/almanac/service/view/'.$this->getName().'/';
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return $this->getViewPolicy();
case PhabricatorPolicyCapability::CAN_EDIT:
return $this->getEditPolicy();
}
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View File

@@ -0,0 +1,45 @@
<?php
final class AlmanacServiceTransaction
extends PhabricatorApplicationTransaction {
const TYPE_NAME = 'almanac:service:name';
public function getApplicationName() {
return 'almanac';
}
public function getApplicationTransactionType() {
return AlmanacServicePHIDType::TYPECONST;
}
public function getApplicationTransactionCommentObject() {
return null;
}
public function getTitle() {
$author_phid = $this->getAuthorPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
if ($old === null) {
return pht(
'%s created this service.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s renamed this service from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
}
break;
}
return parent::getTitle();
}
}

View File

@@ -0,0 +1,51 @@
<?php
final class AlmanacInterfaceDatasource
extends PhabricatorTypeaheadDatasource {
public function getPlaceholderText() {
return pht('Type an interface name...');
}
public function getDatasourceApplicationClass() {
return 'PhabricatorAlmanacApplication';
}
public function loadResults() {
$viewer = $this->getViewer();
$raw_query = $this->getRawQuery();
$devices = id(new AlmanacDeviceQuery())
->setViewer($viewer)
->withDatasourceQuery($raw_query)
->execute();
if ($devices) {
$interfaces = id(new AlmanacInterfaceQuery())
->setViewer($viewer)
->withDevicePHIDs(mpull($devices, 'getPHID'))
->execute();
} else {
$interfaces = array();
}
if ($interfaces) {
$handles = id(new PhabricatorHandleQuery())
->setViewer($viewer)
->withPHIDs(mpull($interfaces, 'getPHID'))
->execute();
} else {
$handles = array();
}
$results = array();
foreach ($handles as $handle) {
$results[] = id(new PhabricatorTypeaheadResult())
->setName($handle->getName())
->setPHID($handle->getPHID());
}
return $results;
}
}

View File

@@ -0,0 +1,54 @@
<?php
final class AlmanacAddress extends Phobject {
private $networkPHID;
private $address;
private $port;
private function __construct() {
// <private>
}
public function getNetworkPHID() {
return $this->networkPHID;
}
public function getAddress() {
return $this->address;
}
public function getPort() {
return $this->port;
}
public static function newFromDictionary(array $dictionary) {
return self::newFromParts(
$dictionary['networkPHID'],
$dictionary['address'],
$dictionary['port']);
}
public static function newFromParts($network_phid, $address, $port) {
$addr = new AlmanacAddress();
$addr->networkPHID = $network_phid;
$addr->address = $address;
$addr->port = (int)$port;
return $addr;
}
public function toDictionary() {
return array(
'networkPHID' => $this->getNetworkPHID(),
'address' => $this->getAddress(),
'port' => $this->getPort(),
);
}
public function toHash() {
return PhabricatorHash::digestForIndex(json_encode($this->toDictionary()));
}
}

View File

@@ -0,0 +1,56 @@
<?php
final class AlmanacNames extends Phobject {
public static function validateServiceOrDeviceName($name) {
if (strlen($name) < 3) {
throw new Exception(
pht(
'Almanac service and device names must be at least 3 '.
'characters long.'));
}
if (!preg_match('/^[a-z0-9.-]+\z/', $name)) {
throw new Exception(
pht(
'Almanac service and device names may only contain lowercase '.
'letters, numbers, hyphens, and periods.'));
}
if (preg_match('/(^|\\.)\d+(\z|\\.)/', $name)) {
throw new Exception(
pht(
'Almanac service and device names may not have any segments '.
'containing only digits.'));
}
if (preg_match('/\.\./', $name)) {
throw new Exception(
pht(
'Almanac service and device names may not contain multiple '.
'consecutive periods.'));
}
if (preg_match('/\\.-|-\\./', $name)) {
throw new Exception(
pht(
'Amanac service and device names may not contain hyphens adjacent '.
'to periods.'));
}
if (preg_match('/--/', $name)) {
throw new Exception(
pht(
'Almanac service and device names may not contain multiple '.
'consecutive hyphens.'));
}
if (!preg_match('/^[a-z0-9].*[a-z0-9]\z/', $name)) {
throw new Exception(
pht(
'Almanac service and device names must begin and end with a letter '.
'or number.'));
}
}
}

View File

@@ -0,0 +1,51 @@
<?php
final class AlmanacNamesTestCase extends PhabricatorTestCase {
public function testServiceOrDeviceNames() {
$map = array(
'' => false,
'a' => false,
'ab' => false,
'...' => false,
'ab.' => false,
'.ab' => false,
'A-B' => false,
'A!B' => false,
'A.B' => false,
'a..b' => false,
'1.2' => false,
'127.0.0.1' => false,
'1.b' => false,
'a.1' => false,
'a.1.b' => false,
'-.a' => false,
'-a.b' => false,
'a-.b' => false,
'a.-' => false,
'a.-b' => false,
'a.b-' => false,
'-.-' => false,
'a--b' => false,
'abc' => true,
'a.b' => true,
'db.phacility.instance' => true,
'web002.useast.example.com' => true,
'master.example-corp.com' => true,
);
foreach ($map as $input => $expect) {
$caught = null;
try {
AlmanacNames::validateServiceOrDeviceName($input);
} catch (Exception $ex) {
$caught = $ex;
}
$this->assertEqual(
$expect,
!($caught instanceof Exception),
$input);
}
}
}

View File

@@ -0,0 +1,86 @@
<?php
final class AlmanacBindingTableView extends AphrontView {
private $bindings;
private $handles;
private $noDataString;
public function setNoDataString($no_data_string) {
$this->noDataString = $no_data_string;
return $this;
}
public function getNoDataString() {
return $this->noDataString;
}
public function setHandles(array $handles) {
$this->handles = $handles;
return $this;
}
public function getHandles() {
return $this->handles;
}
public function setBindings(array $bindings) {
$this->bindings = $bindings;
return $this;
}
public function getBindings() {
return $this->bindings;
}
public function render() {
$bindings = $this->getBindings();
$handles = $this->getHandles();
$viewer = $this->getUser();
$rows = array();
foreach ($bindings as $binding) {
$addr = $binding->getInterface()->getAddress();
$port = $binding->getInterface()->getPort();
$rows[] = array(
$binding->getID(),
$handles[$binding->getServicePHID()]->renderLink(),
$handles[$binding->getDevicePHID()]->renderLink(),
$handles[$binding->getInterface()->getNetworkPHID()]->renderLink(),
$binding->getInterface()->renderDisplayAddress(),
phutil_tag(
'a',
array(
'class' => 'small grey button',
'href' => '/almanac/binding/'.$binding->getID().'/',
),
pht('Details')),
);
}
$table = id(new AphrontTableView($rows))
->setNoDataString($this->getNoDataString())
->setHeaders(
array(
pht('ID'),
pht('Service'),
pht('Device'),
pht('Network'),
pht('Interface'),
null,
))
->setColumnClasses(
array(
'',
'',
'',
'',
'wide',
'action',
));
return $table;
}
}

View File

@@ -0,0 +1,69 @@
<?php
final class AlmanacInterfaceTableView extends AphrontView {
private $interfaces;
private $handles;
public function setHandles(array $handles) {
$this->handles = $handles;
return $this;
}
public function getHandles() {
return $this->handles;
}
public function setInterfaces(array $interfaces) {
$this->interfaces = $interfaces;
return $this;
}
public function getInterfaces() {
return $this->interfaces;
}
public function render() {
$interfaces = $this->getInterfaces();
$handles = $this->getHandles();
$viewer = $this->getUser();
$rows = array();
foreach ($interfaces as $interface) {
$rows[] = array(
$interface->getID(),
$handles[$interface->getNetworkPHID()]->renderLink(),
$interface->getAddress(),
$interface->getPort(),
phutil_tag(
'a',
array(
'class' => 'small grey button',
'href' => '/almanac/interface/edit/'.$interface->getID().'/',
),
pht('Edit')),
);
}
$table = id(new AphrontTableView($rows))
->setHeaders(
array(
pht('ID'),
pht('Network'),
pht('Address'),
pht('Port'),
null,
))
->setColumnClasses(
array(
'',
'wide',
'',
'',
'action',
));
return $table;
}
}

View File

@@ -38,18 +38,50 @@ final class PhabricatorAuditStatusConstants {
$color = 'red';
break;
case self::AUDIT_REQUIRED:
case self::AUDIT_REQUESTED:
$color = 'orange';
break;
case self::ACCEPTED:
$color = 'green';
break;
case self::AUDIT_NOT_REQUIRED:
$color = 'blue';
break;
case self::RESIGNED:
case self::CLOSED:
$color = 'dark';
break;
default:
$color = null;
$color = 'bluegrey';
break;
}
return $color;
}
public static function getStatusIcon($code) {
switch ($code) {
case PhabricatorAuditStatusConstants::AUDIT_NOT_REQUIRED:
case PhabricatorAuditStatusConstants::RESIGNED:
$icon = PHUIStatusItemView::ICON_OPEN;
break;
case PhabricatorAuditStatusConstants::AUDIT_REQUIRED:
case PhabricatorAuditStatusConstants::AUDIT_REQUESTED:
$icon = PHUIStatusItemView::ICON_WARNING;
break;
case PhabricatorAuditStatusConstants::CONCERNED:
$icon = PHUIStatusItemView::ICON_REJECT;
break;
case PhabricatorAuditStatusConstants::ACCEPTED:
case PhabricatorAuditStatusConstants::CLOSED:
$icon = PHUIStatusItemView::ICON_ACCEPT;
break;
default:
$icon = PHUIStatusItemView::ICON_QUESTION;
break;
}
return $icon;
}
public static function getOpenStatusConstants() {
return array(
self::AUDIT_REQUIRED,

View File

@@ -3,22 +3,13 @@
final class PhabricatorAuditListController
extends PhabricatorAuditController {
private $queryKey;
private $name;
private $filterStatus;
public function shouldAllowPublic() {
return true;
}
public function willProcessRequest(array $data) {
$this->queryKey = idx($data, 'queryKey');
}
public function processRequest() {
$request = $this->getRequest();
$controller = id(new PhabricatorApplicationSearchController($request))
->setQueryKey($this->queryKey)
public function handleRequest(AphrontRequest $request) {
$controller = id(new PhabricatorApplicationSearchController())
->setQueryKey($request->getURIData('queryKey'))
->setSearchEngine(new PhabricatorCommitSearchEngine())
->setNavigation($this->buildSideNavView());

View File

@@ -3,6 +3,42 @@
final class PhabricatorAuditEditor
extends PhabricatorApplicationTransactionEditor {
const MAX_FILES_SHOWN_IN_EMAIL = 1000;
private $auditReasonMap = array();
private $heraldEmailPHIDs = array();
private $affectedFiles;
private $rawPatch;
public function addAuditReason($phid, $reason) {
if (!isset($this->auditReasonMap[$phid])) {
$this->auditReasonMap[$phid] = array();
}
$this->auditReasonMap[$phid][] = $reason;
return $this;
}
private function getAuditReasons($phid) {
if (isset($this->auditReasonMap[$phid])) {
return $this->auditReasonMap[$phid];
}
if ($this->getIsHeraldEditor()) {
$name = 'herald';
} else {
$name = $this->getActor()->getUsername();
}
return array('Added by '.$name.'.');
}
public function setRawPatch($patch) {
$this->rawPatch = $patch;
return $this;
}
public function getRawPatch() {
return $this->rawPatch;
}
public function getEditorApplicationClass() {
return 'PhabricatorAuditApplication';
}
@@ -17,6 +53,8 @@ final class PhabricatorAuditEditor
$types[] = PhabricatorTransactions::TYPE_COMMENT;
$types[] = PhabricatorTransactions::TYPE_EDGE;
$types[] = PhabricatorAuditTransaction::TYPE_COMMIT;
// TODO: These will get modernized eventually, but that can happen one
// at a time later on.
$types[] = PhabricatorAuditActionConstants::ACTION;
@@ -44,6 +82,7 @@ final class PhabricatorAuditEditor
switch ($xaction->getTransactionType()) {
case PhabricatorAuditActionConstants::ACTION:
case PhabricatorAuditActionConstants::INLINE:
case PhabricatorAuditTransaction::TYPE_COMMIT:
return null;
case PhabricatorAuditActionConstants::ADD_AUDITORS:
// TODO: For now, just record the added PHIDs. Eventually, turn these
@@ -62,6 +101,7 @@ final class PhabricatorAuditEditor
case PhabricatorAuditActionConstants::ACTION:
case PhabricatorAuditActionConstants::INLINE:
case PhabricatorAuditActionConstants::ADD_AUDITORS:
case PhabricatorAuditTransaction::TYPE_COMMIT:
return $xaction->getNewValue();
}
@@ -79,6 +119,7 @@ final class PhabricatorAuditEditor
case PhabricatorAuditActionConstants::ACTION:
case PhabricatorAuditActionConstants::INLINE:
case PhabricatorAuditActionConstants::ADD_AUDITORS:
case PhabricatorAuditTransaction::TYPE_COMMIT:
return;
}
@@ -95,6 +136,7 @@ final class PhabricatorAuditEditor
case PhabricatorTransactions::TYPE_EDGE:
case PhabricatorAuditActionConstants::ACTION:
case PhabricatorAuditActionConstants::INLINE:
case PhabricatorAuditTransaction::TYPE_COMMIT:
return;
case PhabricatorAuditActionConstants::ADD_AUDITORS:
$new = $xaction->getNewValue();
@@ -118,15 +160,19 @@ final class PhabricatorAuditEditor
continue;
}
if ($this->getIsHeraldEditor()) {
$audit_requested = $xaction->getMetadataValue('auditStatus');
$audit_reason_map = $xaction->getMetadataValue('auditReasonMap');
$audit_reason = $audit_reason_map[$phid];
} else {
$audit_requested = PhabricatorAuditStatusConstants::AUDIT_REQUESTED;
$audit_reason = $this->getAuditReasons($phid);
}
$requests[] = id (new PhabricatorRepositoryAuditRequest())
->setCommitPHID($object->getPHID())
->setAuditorPHID($phid)
->setAuditStatus($audit_requested)
->setAuditReasons(
array(
'Added by '.$actor->getUsername(),
))
->setAuditReasons($audit_reason)
->save();
}
@@ -165,8 +211,12 @@ final class PhabricatorAuditEditor
$actor_is_author = ($object->getAuthorPHID()) &&
($actor_phid == $object->getAuthorPHID());
$import_status_flag = null;
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorAuditTransaction::TYPE_COMMIT:
$import_status_flag = PhabricatorRepositoryCommit::IMPORTED_HERALD;
break;
case PhabricatorAuditActionConstants::ACTION:
$new = $xaction->getNewValue();
switch ($new) {
@@ -265,9 +315,67 @@ final class PhabricatorAuditEditor
$object->updateAuditStatus($requests);
$object->save();
if ($import_status_flag) {
$object->writeImportStatusFlag($import_status_flag);
}
return $xactions;
}
protected function expandTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
$xactions = parent::expandTransaction($object, $xaction);
switch ($xaction->getTransactionType()) {
case PhabricatorAuditTransaction::TYPE_COMMIT:
$request = $this->createAuditRequestTransactionFromCommitMessage(
$object);
if ($request) {
$xactions[] = $request;
$this->setUnmentionablePHIDMap($request->getNewValue());
}
break;
default:
break;
}
return $xactions;
}
private function createAuditRequestTransactionFromCommitMessage(
PhabricatorRepositoryCommit $commit) {
$data = $commit->getCommitData();
$message = $data->getCommitMessage();
$matches = null;
if (!preg_match('/^Auditors:\s*(.*)$/im', $message, $matches)) {
return array();
}
$phids = id(new PhabricatorObjectListQuery())
->setViewer($this->getActor())
->setAllowPartialResults(true)
->setAllowedTypes(
array(
PhabricatorPeopleUserPHIDType::TYPECONST,
PhabricatorProjectProjectPHIDType::TYPECONST,
))
->setObjectList($matches[1])
->execute();
if (!$phids) {
return array();
}
foreach ($phids as $phid) {
$this->addAuditReason($phid, 'Requested by Author');
}
return id(new PhabricatorAuditTransaction())
->setTransactionType(PhabricatorAuditActionConstants::ADD_AUDITORS)
->setNewValue(array_fuse($phids));
}
protected function sortTransactions(array $xactions) {
$xactions = parent::sortTransactions($xactions);
@@ -353,9 +461,75 @@ final class PhabricatorAuditEditor
return true;
}
protected function expandCustomRemarkupBlockTransactions(
PhabricatorLiskDAO $object,
array $xactions,
$blocks,
PhutilMarkupEngine $engine) {
// we are only really trying to find unmentionable phids here...
// don't bother with this outside initial commit (i.e. create)
// transaction
$is_commit = false;
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorAuditTransaction::TYPE_COMMIT:
$is_commit = true;
break;
}
}
// "result" is always an array....
$result = array();
if (!$is_commit) {
return $result;
}
$flat_blocks = array_mergev($blocks);
$huge_block = implode("\n\n", $flat_blocks);
$phid_map = array();
$phid_map[] = $this->getUnmentionablePHIDMap();
$monograms = array();
$task_refs = id(new ManiphestCustomFieldStatusParser())
->parseCorpus($huge_block);
foreach ($task_refs as $match) {
foreach ($match['monograms'] as $monogram) {
$monograms[] = $monogram;
}
}
$rev_refs = id(new DifferentialCustomFieldDependsOnParser())
->parseCorpus($huge_block);
foreach ($rev_refs as $match) {
foreach ($match['monograms'] as $monogram) {
$monograms[] = $monogram;
}
}
$objects = id(new PhabricatorObjectQuery())
->setViewer($this->getActor())
->withNames($monograms)
->execute();
$phid_map[] = mpull($objects, 'getPHID', 'getPHID');
$phid_map = array_mergev($phid_map);
$this->setUnmentionablePHIDMap($phid_map);
return $result;
}
protected function shouldSendMail(
PhabricatorLiskDAO $object,
array $xactions) {
// not every code path loads the repository so tread carefully
if ($object->getRepository($assert_attached = false)) {
$repository = $object->getRepository();
if ($repository->isImporting()) {
return false;
}
}
return $this->isCommitMostlyImported($object);
}
@@ -386,13 +560,23 @@ final class PhabricatorAuditEditor
$subject = "{$name}: {$summary}";
$thread_topic = "Commit {$monogram}{$identifier}";
return id(new PhabricatorMetaMTAMail())
$template = id(new PhabricatorMetaMTAMail())
->setSubject($subject)
->addHeader('Thread-Topic', $thread_topic);
$this->attachPatch(
$template,
$object);
return $template;
}
protected function getMailTo(PhabricatorLiskDAO $object) {
$phids = array();
if ($this->heraldEmailPHIDs) {
$phids = $this->heraldEmailPHIDs;
}
if ($object->getAuthorPHID()) {
$phids[] = $object->getAuthorPHID();
}
@@ -414,12 +598,17 @@ final class PhabricatorAuditEditor
$body = parent::buildMailBody($object, $xactions);
$type_inline = PhabricatorAuditActionConstants::INLINE;
$type_push = PhabricatorAuditTransaction::TYPE_COMMIT;
$is_commit = false;
$inlines = array();
foreach ($xactions as $xaction) {
if ($xaction->getTransactionType() == $type_inline) {
$inlines[] = $xaction;
}
if ($xaction->getTransactionType() == $type_push) {
$is_commit = true;
}
}
if ($inlines) {
@@ -428,6 +617,14 @@ final class PhabricatorAuditEditor
$this->renderInlineCommentsForMail($object, $inlines));
}
if ($is_commit) {
$data = $object->getCommitData();
$body->addTextSection(pht('AFFECTED FILES'), $this->affectedFiles);
$this->inlinePatch(
$body,
$object);
}
// Reload the commit to pull commit data.
$commit = id(new DiffusionCommitQuery())
->setViewer($this->requireActor())
@@ -440,7 +637,7 @@ final class PhabricatorAuditEditor
$author_phid = $commit->getAuthorPHID();
if ($author_phid) {
$user_phids[$commit->getAuthorPHID()][] = pht('Author');
$user_phids[$author_phid][] = pht('Author');
}
$committer_phid = $data->getCommitDetail('committerPHID');
@@ -448,6 +645,13 @@ final class PhabricatorAuditEditor
$user_phids[$committer_phid][] = pht('Committer');
}
// we loaded this in applyFinalEffects
$audit_requests = $object->getAudits();
$auditor_phids = mpull($audit_requests, 'getAuditorPHID');
foreach ($auditor_phids as $auditor_phid) {
$user_phids[$auditor_phid][] = pht('Auditor');
}
// TODO: It would be nice to show pusher here too, but that information
// is a little tricky to get at right now.
@@ -474,13 +678,75 @@ final class PhabricatorAuditEditor
$monogram = $object->getRepository()->formatCommitName(
$object->getCommitIdentifier());
$body->addTextSection(
$body->addLinkSection(
pht('COMMIT'),
PhabricatorEnv::getProductionURI('/'.$monogram));
return $body;
}
private function attachPatch(
PhabricatorMetaMTAMail $template,
PhabricatorRepositoryCommit $commit) {
if (!$this->getRawPatch()) {
return;
}
$attach_key = 'metamta.diffusion.attach-patches';
$attach_patches = PhabricatorEnv::getEnvConfig($attach_key);
if (!$attach_patches) {
return;
}
$repository = $commit->getRepository();
$encoding = $repository->getDetail('encoding', 'UTF-8');
$raw_patch = $this->getRawPatch();
$commit_name = $repository->formatCommitName(
$commit->getCommitIdentifier());
$template->addAttachment(
new PhabricatorMetaMTAAttachment(
$raw_patch,
$commit_name.'.patch',
'text/x-patch; charset='.$encoding));
}
private function inlinePatch(
PhabricatorMetaMTAMailBody $body,
PhabricatorRepositoryCommit $commit) {
if (!$this->getRawPatch()) {
return;
}
$inline_key = 'metamta.diffusion.inline-patches';
$inline_patches = PhabricatorEnv::getEnvConfig($inline_key);
if (!$inline_patches) {
return;
}
$repository = $commit->getRepository();
$raw_patch = $this->getRawPatch();
$result = null;
$len = substr_count($raw_patch, "\n");
if ($len <= $inline_patches) {
// We send email as utf8, so we need to convert the text to utf8 if
// we can.
$encoding = $repository->getDetail('encoding', 'UTF-8');
if ($encoding) {
$raw_patch = phutil_utf8_convert($raw_patch, 'UTF-8', $encoding);
}
$result = phutil_utf8ize($raw_patch);
}
if ($result) {
$result = "PATCH\n\n{$result}\n";
}
$body->addRawSection($result);
}
private function renderInlineCommentsForMail(
PhabricatorLiskDAO $object,
array $inline_xactions) {
@@ -515,10 +781,127 @@ final class PhabricatorAuditEditor
return implode("\n", $block);
}
public function getMailTagsMap() {
return array(
PhabricatorAuditTransaction::MAILTAG_COMMIT =>
pht('A commit is created.'),
PhabricatorAuditTransaction::MAILTAG_ACTION_CONCERN =>
pht('A commit has a concerned raised against it.'),
PhabricatorAuditTransaction::MAILTAG_ACTION_ACCEPT =>
pht('A commit is accepted.'),
PhabricatorAuditTransaction::MAILTAG_ACTION_RESIGN =>
pht('A commit has an auditor resign.'),
PhabricatorAuditTransaction::MAILTAG_ACTION_CLOSE =>
pht('A commit is closed.'),
PhabricatorAuditTransaction::MAILTAG_ADD_AUDITORS =>
pht('A commit has auditors added.'),
PhabricatorAuditTransaction::MAILTAG_ADD_CCS =>
pht("A commit's subscribers change."),
PhabricatorAuditTransaction::MAILTAG_PROJECTS =>
pht("A commit's projects change."),
PhabricatorAuditTransaction::MAILTAG_COMMENT =>
pht('Someone comments on a commit.'),
PhabricatorAuditTransaction::MAILTAG_OTHER =>
pht('Other commit activity not listed above occurs.'),
);
}
protected function shouldPublishFeedStory(
PhabricatorLiskDAO $object,
array $xactions) {
return $this->isCommitMostlyImported($object);
return $this->shouldSendMail($object, $xactions);
}
protected function shouldApplyHeraldRules(
PhabricatorLiskDAO $object,
array $xactions) {
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorAuditTransaction::TYPE_COMMIT:
$repository = $object->getRepository();
if ($repository->isImporting()) {
return false;
}
if ($repository->getDetail('herald-disabled')) {
return false;
}
return true;
default:
break;
}
}
return parent::shouldApplyHeraldRules($object, $xactions);
}
protected function buildHeraldAdapter(
PhabricatorLiskDAO $object,
array $xactions) {
return id(new HeraldCommitAdapter())
->setCommit($object);
}
protected function didApplyHeraldRules(
PhabricatorLiskDAO $object,
HeraldAdapter $adapter,
HeraldTranscript $transcript) {
$xactions = array();
$audit_phids = $adapter->getAuditMap();
foreach ($audit_phids as $phid => $rule_ids) {
foreach ($rule_ids as $rule_id) {
$this->addAuditReason(
$phid,
pht(
'%s Triggered Audit',
"H{$rule_id}"));
}
}
if ($audit_phids) {
$xactions[] = id(new PhabricatorAuditTransaction())
->setTransactionType(PhabricatorAuditActionConstants::ADD_AUDITORS)
->setNewValue(array_fuse(array_keys($audit_phids)))
->setMetadataValue(
'auditStatus',
PhabricatorAuditStatusConstants::AUDIT_REQUIRED)
->setMetadataValue(
'auditReasonMap', $this->auditReasonMap);
}
$cc_phids = $adapter->getAddCCMap();
$add_ccs = array('+' => array());
foreach ($cc_phids as $phid => $rule_ids) {
$add_ccs['+'][$phid] = $phid;
}
$xactions[] = id(new PhabricatorAuditTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)
->setNewValue($add_ccs);
$this->heraldEmailPHIDs = $adapter->getEmailPHIDs();
HarbormasterBuildable::applyBuildPlans(
$object->getPHID(),
$object->getRepository()->getPHID(),
$adapter->getBuildPlans());
$limit = self::MAX_FILES_SHOWN_IN_EMAIL;
$files = $adapter->loadAffectedPaths();
sort($files);
if (count($files) > $limit) {
array_splice($files, $limit);
$files[] = pht(
'(This commit affected more than %d files. Only %d are shown here '.
'and additional ones are truncated.)',
$limit,
$limit);
}
$this->affectedFiles = implode("\n", $files);
return $xactions;
}
private function isCommitMostlyImported(PhabricatorLiskDAO $object) {

View File

@@ -3,6 +3,19 @@
final class PhabricatorAuditTransaction
extends PhabricatorApplicationTransaction {
const TYPE_COMMIT = 'audit:commit';
const MAILTAG_ACTION_CONCERN = 'audit-action-concern';
const MAILTAG_ACTION_ACCEPT = 'audit-action-accept';
const MAILTAG_ACTION_RESIGN = 'audit-action-resign';
const MAILTAG_ACTION_CLOSE = 'audit-action-close';
const MAILTAG_ADD_AUDITORS = 'audit-add-auditors';
const MAILTAG_ADD_CCS = 'audit-add-ccs';
const MAILTAG_COMMENT = 'audit-comment';
const MAILTAG_COMMIT = 'audit-commit';
const MAILTAG_PROJECTS = 'audit-projects';
const MAILTAG_OTHER = 'audit-other';
public function getApplicationName() {
return 'audit';
}
@@ -15,12 +28,35 @@ final class PhabricatorAuditTransaction
return new PhabricatorAuditTransactionComment();
}
public function getRemarkupBlocks() {
$blocks = parent::getRemarkupBlocks();
switch ($this->getTransactionType()) {
case self::TYPE_COMMIT:
$data = $this->getNewValue();
$blocks[] = $data['description'];
break;
}
return $blocks;
}
public function getRequiredHandlePHIDs() {
$phids = parent::getRequiredHandlePHIDs();
$type = $this->getTransactionType();
switch ($type) {
case self::TYPE_COMMIT:
$phids[] = $this->getObjectPHID();
$data = $this->getNewValue();
if ($data['authorPHID']) {
$phids[] = $data['authorPHID'];
}
if ($data['committerPHID']) {
$phids[] = $data['committerPHID'];
}
break;
case PhabricatorAuditActionConstants::ADD_CCS:
case PhabricatorAuditActionConstants::ADD_AUDITORS:
$old = $this->getOldValue();
@@ -59,6 +95,8 @@ final class PhabricatorAuditTransaction
break;
case PhabricatorAuditActionConstants::ADD_AUDITORS:
return pht('Added Auditors');
case self::TYPE_COMMIT:
return pht('Committed');
}
return parent::getActionName();
@@ -104,10 +142,47 @@ final class PhabricatorAuditTransaction
}
switch ($type) {
case self::TYPE_COMMIT:
$author = null;
if ($new['authorPHID']) {
$author = $this->renderHandleLink($new['authorPHID']);
} else {
$author = $new['authorName'];
}
$committer = null;
if ($new['committerPHID']) {
$committer = $this->renderHandleLink($new['committerPHID']);
} else if ($new['committerName']) {
$committer = $new['committerName'];
}
$commit = $this->renderHandleLink($this->getObjectPHID());
if (!$committer) {
$committer = $author;
$author = null;
}
if ($author) {
$title = pht(
'%s committed %s (authored by %s).',
$committer,
$commit,
$author);
} else {
$title = pht(
'%s committed %s.',
$committer,
$commit);
}
return $title;
case PhabricatorAuditActionConstants::INLINE:
return pht(
'%s added inline comments.',
$author_handle);
case PhabricatorAuditActionConstants::ADD_CCS:
if ($add && $rem) {
return pht(
@@ -203,6 +278,40 @@ final class PhabricatorAuditTransaction
}
switch ($type) {
case self::TYPE_COMMIT:
$author = null;
if ($new['authorPHID']) {
$author = $this->renderHandleLink($new['authorPHID']);
} else {
$author = $new['authorName'];
}
$committer = null;
if ($new['committerPHID']) {
$committer = $this->renderHandleLink($new['committerPHID']);
} else if ($new['committerName']) {
$committer = $new['committerName'];
}
if (!$committer) {
$committer = $author;
$author = null;
}
if ($author) {
$title = pht(
'%s committed %s (authored by %s).',
$committer,
$object_handle,
$author);
} else {
$title = pht(
'%s committed %s.',
$committer,
$object_handle);
}
return $title;
case PhabricatorAuditActionConstants::INLINE:
return pht(
'%s added inline comments to %s.',
@@ -265,6 +374,15 @@ final class PhabricatorAuditTransaction
return parent::getTitleForFeed($story);
}
public function getBodyForFeed(PhabricatorFeedStory $story) {
switch ($this->getTransactionType()) {
case self::TYPE_COMMIT:
$data = $this->getNewValue();
return $story->renderSummary($data['summary']);
}
return parent::getBodyForFeed($story);
}
// TODO: These two mail methods can likely be abstracted by introducing a
// formal concept of "inline comment" transactions.
@@ -288,9 +406,63 @@ final class PhabricatorAuditTransaction
switch ($this->getTransactionType()) {
case PhabricatorAuditActionConstants::INLINE:
return null;
case self::TYPE_COMMIT:
$data = $this->getNewValue();
return $data['description'];
}
return parent::getBodyForMail();
}
public function getMailTags() {
$tags = array();
switch ($this->getTransactionType()) {
case PhabricatorAuditActionConstants::ACTION:
switch ($this->getNewValue()) {
case PhabricatorAuditActionConstants::CONCERN:
$tags[] = self::MAILTAG_ACTION_CONCERN;
break;
case PhabricatorAuditActionConstants::ACCEPT:
$tags[] = self::MAILTAG_ACTION_ACCEPT;
break;
case PhabricatorAuditActionConstants::RESIGN:
$tags[] = self::MAILTAG_ACTION_RESIGN;
break;
case PhabricatorAuditActionConstants::CLOSE:
$tags[] = self::MAILTAG_ACTION_CLOSE;
break;
}
break;
case PhabricatorAuditActionConstants::ADD_AUDITORS:
$tags[] = self::MAILTAG_ADD_AUDITORS;
break;
case PhabricatorAuditActionConstants::ADD_CCS:
$tags[] = self::MAILTAG_ADD_CCS;
break;
case PhabricatorAuditActionConstants::INLINE:
case PhabricatorTransactions::TYPE_COMMENT:
$tags[] = self::MAILTAG_COMMENT;
break;
case self::TYPE_COMMIT:
$tags[] = self::MAILTAG_COMMIT;
break;
case PhabricatorTransactions::TYPE_EDGE:
switch ($this->getMetadataValue('edge:type')) {
case PhabricatorProjectObjectHasProjectEdgeType::EDGECONST:
$tags[] = self::MAILTAG_PROJECTS;
break;
case PhabricatorEdgeConfig::TYPE_OBJECT_HAS_SUBSCRIBER:
$tags[] = self::MAILTAG_ADD_CCS;
break;
default:
$tags[] = self::MAILTAG_OTHER;
break;
}
break;
default:
$tags[] = self::MAILTAG_OTHER;
break;
}
return $tags;
}
}

View File

@@ -137,11 +137,11 @@ abstract class PhabricatorController extends AphrontController {
if ($this->shouldRequireEnabledUser()) {
if ($user->isLoggedIn() && !$user->getIsApproved()) {
$controller = new PhabricatorAuthNeedsApprovalController($request);
$controller = new PhabricatorAuthNeedsApprovalController();
return $this->delegateToController($controller);
}
if ($user->getIsDisabled()) {
$controller = new PhabricatorDisabledUserController($request);
$controller = new PhabricatorDisabledUserController();
return $this->delegateToController($controller);
}
}
@@ -166,7 +166,7 @@ abstract class PhabricatorController extends AphrontController {
if (!$this->shouldAllowPartialSessions()) {
if ($user->hasSession() &&
$user->getSession()->getIsPartial()) {
$login_controller = new PhabricatorAuthFinishController($request);
$login_controller = new PhabricatorAuthFinishController();
$this->setCurrentApplication($auth_application);
return $this->delegateToController($login_controller);
}
@@ -180,8 +180,7 @@ abstract class PhabricatorController extends AphrontController {
// and require MFA enrollment.
$user->updateMultiFactorEnrollment();
if (!$user->getIsEnrolledInMultiFactor()) {
$mfa_controller = new PhabricatorAuthNeedsMultiFactorController(
$request);
$mfa_controller = new PhabricatorAuthNeedsMultiFactorController();
$this->setCurrentApplication($auth_application);
return $this->delegateToController($mfa_controller);
}
@@ -198,7 +197,7 @@ abstract class PhabricatorController extends AphrontController {
// If this controller isn't public, and the user isn't logged in, require
// login.
if (!$allow_public && !$user->isLoggedIn()) {
$login_controller = new PhabricatorAuthStartController($request);
$login_controller = new PhabricatorAuthStartController();
$this->setCurrentApplication($auth_application);
return $this->delegateToController($login_controller);
}
@@ -206,7 +205,7 @@ abstract class PhabricatorController extends AphrontController {
if ($user->isLoggedIn()) {
if ($this->shouldRequireEmailVerification()) {
if (!$user->getIsEmailVerified()) {
$controller = new PhabricatorMustVerifyEmailController($request);
$controller = new PhabricatorMustVerifyEmailController();
$this->setCurrentApplication($auth_application);
return $this->delegateToController($controller);
}

View File

@@ -22,7 +22,8 @@ final class PhabricatorAccessControlTestCase extends PhabricatorTestCase {
->setApplicationConfiguration($application_configuration)
->setRequestData(array());
$controller = new PhabricatorTestController($request);
$controller = new PhabricatorTestController();
$controller->setRequest($request);
$u_public = id(new PhabricatorUser())
->setUsername('public');

View File

@@ -14,8 +14,7 @@ final class PhabricatorCalendarEventListController
}
public function processRequest() {
$request = $this->getRequest();
$controller = id(new PhabricatorApplicationSearchController($request))
$controller = id(new PhabricatorApplicationSearchController())
->setQueryKey($this->queryKey)
->setSearchEngine(new PhabricatorCalendarEventSearchEngine())
->setNavigation($this->buildSideNav());

Some files were not shown because too many files have changed in this diff Show More