diff --git a/resources/celerity/map.php b/resources/celerity/map.php index e3854c740c..2093e3e70e 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -9,7 +9,7 @@ return array( 'names' => array( 'conpherence.pkg.css' => 'e68cf1fa', 'conpherence.pkg.js' => 'b5b51108', - 'core.pkg.css' => '4ac857bf', + 'core.pkg.css' => 'e9473020', 'core.pkg.js' => '6c085267', 'darkconsole.pkg.js' => '1f9a31bc', 'differential.pkg.css' => '45951e9e', @@ -45,10 +45,9 @@ return array( 'rsrc/css/application/base/standard-page-view.css' => '34ee718b', 'rsrc/css/application/chatlog/chatlog.css' => 'd295b020', 'rsrc/css/application/conduit/conduit-api.css' => '7bc725c4', - 'rsrc/css/application/config/config-options.css' => 'd55ed093', - 'rsrc/css/application/config/config-page.css' => 'c1d5121b', + 'rsrc/css/application/config/config-options.css' => '4615667b', 'rsrc/css/application/config/config-template.css' => '8f18fa41', - 'rsrc/css/application/config/setup-issue.css' => 'f794cfc3', + 'rsrc/css/application/config/setup-issue.css' => '7dae7f18', 'rsrc/css/application/config/unhandled-exception.css' => '4c96257a', 'rsrc/css/application/conpherence/color.css' => 'abb4c358', 'rsrc/css/application/conpherence/durable-column.css' => '89ea6bef', @@ -132,7 +131,7 @@ return array( 'rsrc/css/phui/calendar/phui-calendar-list.css' => '576be600', 'rsrc/css/phui/calendar/phui-calendar-month.css' => '21154caf', 'rsrc/css/phui/calendar/phui-calendar.css' => 'f1ddf11c', - 'rsrc/css/phui/object-item/phui-oi-big-ui.css' => '19f9369b', + 'rsrc/css/phui/object-item/phui-oi-big-ui.css' => '628f59de', 'rsrc/css/phui/object-item/phui-oi-color.css' => 'cd2b9b77', 'rsrc/css/phui/object-item/phui-oi-drag-ui.css' => '08f4ccc3', 'rsrc/css/phui/object-item/phui-oi-flush-ui.css' => '9d9685d6', @@ -143,7 +142,7 @@ return array( 'rsrc/css/phui/phui-badge.css' => '22c0cf4f', 'rsrc/css/phui/phui-basic-nav-view.css' => '98c11ab3', 'rsrc/css/phui/phui-big-info-view.css' => 'acc3492c', - 'rsrc/css/phui/phui-box.css' => '745e881d', + 'rsrc/css/phui/phui-box.css' => '9f3745fb', 'rsrc/css/phui/phui-chart.css' => '6bf6f78e', 'rsrc/css/phui/phui-cms.css' => '504b4b23', 'rsrc/css/phui/phui-comment-form.css' => 'ac68149f', @@ -158,12 +157,12 @@ return array( 'rsrc/css/phui/phui-form-view.css' => 'ae9f8d16', 'rsrc/css/phui/phui-form.css' => '7aaa04e3', 'rsrc/css/phui/phui-head-thing.css' => 'fd311e5f', - 'rsrc/css/phui/phui-header-view.css' => '808b82c7', + 'rsrc/css/phui/phui-header-view.css' => '67fab16d', 'rsrc/css/phui/phui-hovercard.css' => 'f0592bcf', 'rsrc/css/phui/phui-icon-set-selector.css' => '87db8fee', 'rsrc/css/phui/phui-icon.css' => '5c4a5de6', 'rsrc/css/phui/phui-image-mask.css' => 'a8498f9c', - 'rsrc/css/phui/phui-info-view.css' => 'e1b4ec37', + 'rsrc/css/phui/phui-info-view.css' => 'e929f98c', 'rsrc/css/phui/phui-invisible-character-view.css' => '6993d9f0', 'rsrc/css/phui/phui-left-right.css' => '75227a4d', 'rsrc/css/phui/phui-lightbox.css' => '0a035e40', @@ -178,7 +177,7 @@ return array( 'rsrc/css/phui/phui-status.css' => 'd5263e49', 'rsrc/css/phui/phui-tag-view.css' => 'b4719c50', 'rsrc/css/phui/phui-timeline-view.css' => 'f21db7ca', - 'rsrc/css/phui/phui-two-column-view.css' => 'bf86c483', + 'rsrc/css/phui/phui-two-column-view.css' => '1ade9c5f', 'rsrc/css/phui/workboards/phui-workboard-color.css' => '783cdff5', 'rsrc/css/phui/workboards/phui-workboard.css' => '3bc85455', 'rsrc/css/phui/workboards/phui-workcard.css' => 'cca5fa92', @@ -551,8 +550,7 @@ return array( 'auth-css' => '0877ed6e', 'bulk-job-css' => 'df9c1d4a', 'conduit-api-css' => '7bc725c4', - 'config-options-css' => 'd55ed093', - 'config-page-css' => 'c1d5121b', + 'config-options-css' => '4615667b', 'conpherence-color-css' => 'abb4c358', 'conpherence-durable-column-view' => '89ea6bef', 'conpherence-header-pane-css' => 'cb6f4e19', @@ -822,7 +820,7 @@ return array( 'phui-badge-view-css' => '22c0cf4f', 'phui-basic-nav-view-css' => '98c11ab3', 'phui-big-info-view-css' => 'acc3492c', - 'phui-box-css' => '745e881d', + 'phui-box-css' => '9f3745fb', 'phui-button-bar-css' => 'f1ff5494', 'phui-button-css' => '1863cc6e', 'phui-button-simple-css' => '8e1baf68', @@ -845,20 +843,20 @@ return array( 'phui-form-css' => '7aaa04e3', 'phui-form-view-css' => 'ae9f8d16', 'phui-head-thing-view-css' => 'fd311e5f', - 'phui-header-view-css' => '808b82c7', + 'phui-header-view-css' => '67fab16d', 'phui-hovercard' => '1bd28176', 'phui-hovercard-view-css' => 'f0592bcf', 'phui-icon-set-selector-css' => '87db8fee', 'phui-icon-view-css' => '5c4a5de6', 'phui-image-mask-css' => 'a8498f9c', - 'phui-info-view-css' => 'e1b4ec37', + 'phui-info-view-css' => 'e929f98c', 'phui-inline-comment-view-css' => '65ae3bc2', 'phui-invisible-character-view-css' => '6993d9f0', 'phui-left-right-css' => '75227a4d', 'phui-lightbox-css' => '0a035e40', 'phui-list-view-css' => '38f8c9bd', 'phui-object-box-css' => '9cff003c', - 'phui-oi-big-ui-css' => '19f9369b', + 'phui-oi-big-ui-css' => '628f59de', 'phui-oi-color-css' => 'cd2b9b77', 'phui-oi-drag-ui-css' => '08f4ccc3', 'phui-oi-flush-ui-css' => '9d9685d6', @@ -874,7 +872,7 @@ return array( 'phui-tag-view-css' => 'b4719c50', 'phui-theme-css' => '9f261c6b', 'phui-timeline-view-css' => 'f21db7ca', - 'phui-two-column-view-css' => 'bf86c483', + 'phui-two-column-view-css' => '1ade9c5f', 'phui-workboard-color-css' => '783cdff5', 'phui-workboard-view-css' => '3bc85455', 'phui-workcard-view-css' => 'cca5fa92', @@ -896,7 +894,7 @@ return array( 'releeph-preview-branch' => 'b7a6f4a5', 'releeph-request-differential-create-dialog' => '8d8b92cd', 'releeph-request-typeahead-css' => '667a48ae', - 'setup-issue-css' => 'f794cfc3', + 'setup-issue-css' => '7dae7f18', 'sprite-login-css' => '396f3c3a', 'sprite-tokens-css' => '9cdfd599', 'syntax-default-css' => '9923583c', @@ -997,9 +995,6 @@ return array( '185bbd53' => array( 'javelin-install', ), - '19f9369b' => array( - 'phui-oi-list-view-css', - ), '1ad0a787' => array( 'javelin-install', 'javelin-reactor', @@ -1366,6 +1361,9 @@ return array( 'javelin-magical-init', 'javelin-util', ), + '628f59de' => array( + 'phui-oi-list-view-css', + ), '62dfea03' => array( 'javelin-install', 'javelin-util', diff --git a/resources/sql/autopatches/20170905.ferret.01.diff.doc.sql b/resources/sql/autopatches/20170905.ferret.01.diff.doc.sql new file mode 100644 index 0000000000..9fdadbf11c --- /dev/null +++ b/resources/sql/autopatches/20170905.ferret.01.diff.doc.sql @@ -0,0 +1,9 @@ +CREATE TABLE {$NAMESPACE}_differential.differential_revision_fdocument ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + objectPHID VARBINARY(64) NOT NULL, + isClosed BOOL NOT NULL, + authorPHID VARBINARY(64), + ownerPHID VARBINARY(64), + epochCreated INT UNSIGNED NOT NULL, + epochModified INT UNSIGNED NOT NULL +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170905.ferret.02.diff.field.sql b/resources/sql/autopatches/20170905.ferret.02.diff.field.sql new file mode 100644 index 0000000000..ff5f065a39 --- /dev/null +++ b/resources/sql/autopatches/20170905.ferret.02.diff.field.sql @@ -0,0 +1,8 @@ +CREATE TABLE {$NAMESPACE}_differential.differential_revision_ffield ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + fieldKey VARCHAR(4) NOT NULL COLLATE {$COLLATE_TEXT}, + rawCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + termCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + normalCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170905.ferret.03.diff.ngrams.sql b/resources/sql/autopatches/20170905.ferret.03.diff.ngrams.sql new file mode 100644 index 0000000000..ec12354e38 --- /dev/null +++ b/resources/sql/autopatches/20170905.ferret.03.diff.ngrams.sql @@ -0,0 +1,5 @@ +CREATE TABLE {$NAMESPACE}_differential.differential_revision_fngrams ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.01.user.doc.sql b/resources/sql/autopatches/20170907.ferret.01.user.doc.sql new file mode 100644 index 0000000000..39496a0de0 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.01.user.doc.sql @@ -0,0 +1,9 @@ +CREATE TABLE {$NAMESPACE}_user.user_user_fdocument ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + objectPHID VARBINARY(64) NOT NULL, + isClosed BOOL NOT NULL, + authorPHID VARBINARY(64), + ownerPHID VARBINARY(64), + epochCreated INT UNSIGNED NOT NULL, + epochModified INT UNSIGNED NOT NULL +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.02.user.field.sql b/resources/sql/autopatches/20170907.ferret.02.user.field.sql new file mode 100644 index 0000000000..3179e58e5b --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.02.user.field.sql @@ -0,0 +1,8 @@ +CREATE TABLE {$NAMESPACE}_user.user_user_ffield ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + fieldKey VARCHAR(4) NOT NULL COLLATE {$COLLATE_TEXT}, + rawCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + termCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + normalCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.03.user.ngrams.sql b/resources/sql/autopatches/20170907.ferret.03.user.ngrams.sql new file mode 100644 index 0000000000..2105a7b7af --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.03.user.ngrams.sql @@ -0,0 +1,5 @@ +CREATE TABLE {$NAMESPACE}_user.user_user_fngrams ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.04.fund.doc.sql b/resources/sql/autopatches/20170907.ferret.04.fund.doc.sql new file mode 100644 index 0000000000..a7f8324594 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.04.fund.doc.sql @@ -0,0 +1,9 @@ +CREATE TABLE {$NAMESPACE}_fund.fund_initiative_fdocument ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + objectPHID VARBINARY(64) NOT NULL, + isClosed BOOL NOT NULL, + authorPHID VARBINARY(64), + ownerPHID VARBINARY(64), + epochCreated INT UNSIGNED NOT NULL, + epochModified INT UNSIGNED NOT NULL +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.05.fund.field.sql b/resources/sql/autopatches/20170907.ferret.05.fund.field.sql new file mode 100644 index 0000000000..b8c544c2a7 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.05.fund.field.sql @@ -0,0 +1,8 @@ +CREATE TABLE {$NAMESPACE}_fund.fund_initiative_ffield ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + fieldKey VARCHAR(4) NOT NULL COLLATE {$COLLATE_TEXT}, + rawCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + termCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + normalCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.06.fund.ngrams.sql b/resources/sql/autopatches/20170907.ferret.06.fund.ngrams.sql new file mode 100644 index 0000000000..a509087bae --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.06.fund.ngrams.sql @@ -0,0 +1,5 @@ +CREATE TABLE {$NAMESPACE}_fund.fund_initiative_fngrams ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.07.passphrase.doc.sql b/resources/sql/autopatches/20170907.ferret.07.passphrase.doc.sql new file mode 100644 index 0000000000..6787528d0e --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.07.passphrase.doc.sql @@ -0,0 +1,9 @@ +CREATE TABLE {$NAMESPACE}_passphrase.passphrase_credential_fdocument ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + objectPHID VARBINARY(64) NOT NULL, + isClosed BOOL NOT NULL, + authorPHID VARBINARY(64), + ownerPHID VARBINARY(64), + epochCreated INT UNSIGNED NOT NULL, + epochModified INT UNSIGNED NOT NULL +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.08.passphrase.field.sql b/resources/sql/autopatches/20170907.ferret.08.passphrase.field.sql new file mode 100644 index 0000000000..6dc62d477e --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.08.passphrase.field.sql @@ -0,0 +1,8 @@ +CREATE TABLE {$NAMESPACE}_passphrase.passphrase_credential_ffield ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + fieldKey VARCHAR(4) NOT NULL COLLATE {$COLLATE_TEXT}, + rawCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + termCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + normalCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.09.passphrase.ngrams.sql b/resources/sql/autopatches/20170907.ferret.09.passphrase.ngrams.sql new file mode 100644 index 0000000000..2b64beb7ed --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.09.passphrase.ngrams.sql @@ -0,0 +1,5 @@ +CREATE TABLE {$NAMESPACE}_passphrase.passphrase_credential_fngrams ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.10.owners.doc.sql b/resources/sql/autopatches/20170907.ferret.10.owners.doc.sql new file mode 100644 index 0000000000..aaaa36623b --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.10.owners.doc.sql @@ -0,0 +1,9 @@ +CREATE TABLE {$NAMESPACE}_owners.owners_package_fdocument ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + objectPHID VARBINARY(64) NOT NULL, + isClosed BOOL NOT NULL, + authorPHID VARBINARY(64), + ownerPHID VARBINARY(64), + epochCreated INT UNSIGNED NOT NULL, + epochModified INT UNSIGNED NOT NULL +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.11.owners.field.sql b/resources/sql/autopatches/20170907.ferret.11.owners.field.sql new file mode 100644 index 0000000000..ebd72806f4 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.11.owners.field.sql @@ -0,0 +1,8 @@ +CREATE TABLE {$NAMESPACE}_owners.owners_package_ffield ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + fieldKey VARCHAR(4) NOT NULL COLLATE {$COLLATE_TEXT}, + rawCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + termCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + normalCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.12.owners.ngrams.sql b/resources/sql/autopatches/20170907.ferret.12.owners.ngrams.sql new file mode 100644 index 0000000000..0f8c6865bf --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.12.owners.ngrams.sql @@ -0,0 +1,5 @@ +CREATE TABLE {$NAMESPACE}_owners.owners_package_fngrams ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.13.blog.doc.sql b/resources/sql/autopatches/20170907.ferret.13.blog.doc.sql new file mode 100644 index 0000000000..d75232fae1 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.13.blog.doc.sql @@ -0,0 +1,9 @@ +CREATE TABLE {$NAMESPACE}_phame.phame_blog_fdocument ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + objectPHID VARBINARY(64) NOT NULL, + isClosed BOOL NOT NULL, + authorPHID VARBINARY(64), + ownerPHID VARBINARY(64), + epochCreated INT UNSIGNED NOT NULL, + epochModified INT UNSIGNED NOT NULL +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.14.blog.field.sql b/resources/sql/autopatches/20170907.ferret.14.blog.field.sql new file mode 100644 index 0000000000..9982914229 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.14.blog.field.sql @@ -0,0 +1,8 @@ +CREATE TABLE {$NAMESPACE}_phame.phame_blog_ffield ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + fieldKey VARCHAR(4) NOT NULL COLLATE {$COLLATE_TEXT}, + rawCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + termCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + normalCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.15.blog.ngrams.sql b/resources/sql/autopatches/20170907.ferret.15.blog.ngrams.sql new file mode 100644 index 0000000000..b20bb8fcbb --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.15.blog.ngrams.sql @@ -0,0 +1,5 @@ +CREATE TABLE {$NAMESPACE}_phame.phame_blog_fngrams ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.16.post.doc.sql b/resources/sql/autopatches/20170907.ferret.16.post.doc.sql new file mode 100644 index 0000000000..9f9155aa49 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.16.post.doc.sql @@ -0,0 +1,9 @@ +CREATE TABLE {$NAMESPACE}_phame.phame_post_fdocument ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + objectPHID VARBINARY(64) NOT NULL, + isClosed BOOL NOT NULL, + authorPHID VARBINARY(64), + ownerPHID VARBINARY(64), + epochCreated INT UNSIGNED NOT NULL, + epochModified INT UNSIGNED NOT NULL +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.17.post.field.sql b/resources/sql/autopatches/20170907.ferret.17.post.field.sql new file mode 100644 index 0000000000..26d729d05d --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.17.post.field.sql @@ -0,0 +1,8 @@ +CREATE TABLE {$NAMESPACE}_phame.phame_post_ffield ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + fieldKey VARCHAR(4) NOT NULL COLLATE {$COLLATE_TEXT}, + rawCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + termCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + normalCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.18.post.ngrams.sql b/resources/sql/autopatches/20170907.ferret.18.post.ngrams.sql new file mode 100644 index 0000000000..18e534e948 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.18.post.ngrams.sql @@ -0,0 +1,5 @@ +CREATE TABLE {$NAMESPACE}_phame.phame_post_fngrams ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.19.project.doc.sql b/resources/sql/autopatches/20170907.ferret.19.project.doc.sql new file mode 100644 index 0000000000..26272439cf --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.19.project.doc.sql @@ -0,0 +1,9 @@ +CREATE TABLE {$NAMESPACE}_project.project_project_fdocument ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + objectPHID VARBINARY(64) NOT NULL, + isClosed BOOL NOT NULL, + authorPHID VARBINARY(64), + ownerPHID VARBINARY(64), + epochCreated INT UNSIGNED NOT NULL, + epochModified INT UNSIGNED NOT NULL +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.20.project.field.sql b/resources/sql/autopatches/20170907.ferret.20.project.field.sql new file mode 100644 index 0000000000..36514eb55d --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.20.project.field.sql @@ -0,0 +1,8 @@ +CREATE TABLE {$NAMESPACE}_project.project_project_ffield ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + fieldKey VARCHAR(4) NOT NULL COLLATE {$COLLATE_TEXT}, + rawCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + termCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + normalCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.21.project.ngrams.sql b/resources/sql/autopatches/20170907.ferret.21.project.ngrams.sql new file mode 100644 index 0000000000..dec12b0e56 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.21.project.ngrams.sql @@ -0,0 +1,5 @@ +CREATE TABLE {$NAMESPACE}_project.project_project_fngrams ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.22.phriction.doc.sql b/resources/sql/autopatches/20170907.ferret.22.phriction.doc.sql new file mode 100644 index 0000000000..9de7124255 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.22.phriction.doc.sql @@ -0,0 +1,9 @@ +CREATE TABLE {$NAMESPACE}_phriction.phriction_document_fdocument ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + objectPHID VARBINARY(64) NOT NULL, + isClosed BOOL NOT NULL, + authorPHID VARBINARY(64), + ownerPHID VARBINARY(64), + epochCreated INT UNSIGNED NOT NULL, + epochModified INT UNSIGNED NOT NULL +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.23.phriction.field.sql b/resources/sql/autopatches/20170907.ferret.23.phriction.field.sql new file mode 100644 index 0000000000..0fc5b959d1 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.23.phriction.field.sql @@ -0,0 +1,8 @@ +CREATE TABLE {$NAMESPACE}_phriction.phriction_document_ffield ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + fieldKey VARCHAR(4) NOT NULL COLLATE {$COLLATE_TEXT}, + rawCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + termCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + normalCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.24.phriction.ngrams.sql b/resources/sql/autopatches/20170907.ferret.24.phriction.ngrams.sql new file mode 100644 index 0000000000..abbb90a1e4 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.24.phriction.ngrams.sql @@ -0,0 +1,5 @@ +CREATE TABLE {$NAMESPACE}_phriction.phriction_document_fngrams ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.25.event.doc.sql b/resources/sql/autopatches/20170907.ferret.25.event.doc.sql new file mode 100644 index 0000000000..d7298fad31 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.25.event.doc.sql @@ -0,0 +1,9 @@ +CREATE TABLE {$NAMESPACE}_calendar.calendar_event_fdocument ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + objectPHID VARBINARY(64) NOT NULL, + isClosed BOOL NOT NULL, + authorPHID VARBINARY(64), + ownerPHID VARBINARY(64), + epochCreated INT UNSIGNED NOT NULL, + epochModified INT UNSIGNED NOT NULL +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.26.event.field.sql b/resources/sql/autopatches/20170907.ferret.26.event.field.sql new file mode 100644 index 0000000000..2ec76c3511 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.26.event.field.sql @@ -0,0 +1,8 @@ +CREATE TABLE {$NAMESPACE}_calendar.calendar_event_ffield ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + fieldKey VARCHAR(4) NOT NULL COLLATE {$COLLATE_TEXT}, + rawCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + termCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + normalCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.27.event.ngrams.sql b/resources/sql/autopatches/20170907.ferret.27.event.ngrams.sql new file mode 100644 index 0000000000..e802e2d97e --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.27.event.ngrams.sql @@ -0,0 +1,5 @@ +CREATE TABLE {$NAMESPACE}_calendar.calendar_event_fngrams ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.28.mock.doc.sql b/resources/sql/autopatches/20170907.ferret.28.mock.doc.sql new file mode 100644 index 0000000000..eb80ef3937 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.28.mock.doc.sql @@ -0,0 +1,9 @@ +CREATE TABLE {$NAMESPACE}_pholio.pholio_mock_fdocument ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + objectPHID VARBINARY(64) NOT NULL, + isClosed BOOL NOT NULL, + authorPHID VARBINARY(64), + ownerPHID VARBINARY(64), + epochCreated INT UNSIGNED NOT NULL, + epochModified INT UNSIGNED NOT NULL +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.29.mock.field.sql b/resources/sql/autopatches/20170907.ferret.29.mock.field.sql new file mode 100644 index 0000000000..0cb0e97d05 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.29.mock.field.sql @@ -0,0 +1,8 @@ +CREATE TABLE {$NAMESPACE}_pholio.pholio_mock_ffield ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + fieldKey VARCHAR(4) NOT NULL COLLATE {$COLLATE_TEXT}, + rawCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + termCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + normalCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.30.mock.ngrams.sql b/resources/sql/autopatches/20170907.ferret.30.mock.ngrams.sql new file mode 100644 index 0000000000..e343ccf83b --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.30.mock.ngrams.sql @@ -0,0 +1,5 @@ +CREATE TABLE {$NAMESPACE}_pholio.pholio_mock_fngrams ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.31.repo.doc.sql b/resources/sql/autopatches/20170907.ferret.31.repo.doc.sql new file mode 100644 index 0000000000..4f37de60be --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.31.repo.doc.sql @@ -0,0 +1,9 @@ +CREATE TABLE {$NAMESPACE}_repository.repository_repository_fdocument ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + objectPHID VARBINARY(64) NOT NULL, + isClosed BOOL NOT NULL, + authorPHID VARBINARY(64), + ownerPHID VARBINARY(64), + epochCreated INT UNSIGNED NOT NULL, + epochModified INT UNSIGNED NOT NULL +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.32.repo.field.sql b/resources/sql/autopatches/20170907.ferret.32.repo.field.sql new file mode 100644 index 0000000000..c7d75eb29d --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.32.repo.field.sql @@ -0,0 +1,8 @@ +CREATE TABLE {$NAMESPACE}_repository.repository_repository_ffield ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + fieldKey VARCHAR(4) NOT NULL COLLATE {$COLLATE_TEXT}, + rawCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + termCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + normalCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.33.repo.ngrams.sql b/resources/sql/autopatches/20170907.ferret.33.repo.ngrams.sql new file mode 100644 index 0000000000..db7ad4f3a0 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.33.repo.ngrams.sql @@ -0,0 +1,5 @@ +CREATE TABLE {$NAMESPACE}_repository.repository_repository_fngrams ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.34.commit.doc.sql b/resources/sql/autopatches/20170907.ferret.34.commit.doc.sql new file mode 100644 index 0000000000..9c275b09b7 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.34.commit.doc.sql @@ -0,0 +1,9 @@ +CREATE TABLE {$NAMESPACE}_repository.repository_commit_fdocument ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + objectPHID VARBINARY(64) NOT NULL, + isClosed BOOL NOT NULL, + authorPHID VARBINARY(64), + ownerPHID VARBINARY(64), + epochCreated INT UNSIGNED NOT NULL, + epochModified INT UNSIGNED NOT NULL +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.35.commit.field.sql b/resources/sql/autopatches/20170907.ferret.35.commit.field.sql new file mode 100644 index 0000000000..c2520b693b --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.35.commit.field.sql @@ -0,0 +1,8 @@ +CREATE TABLE {$NAMESPACE}_repository.repository_commit_ffield ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + fieldKey VARCHAR(4) NOT NULL COLLATE {$COLLATE_TEXT}, + rawCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + termCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}, + normalCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20170907.ferret.36.commit.ngrams.sql b/resources/sql/autopatches/20170907.ferret.36.commit.ngrams.sql new file mode 100644 index 0000000000..32ed2275c3 --- /dev/null +++ b/resources/sql/autopatches/20170907.ferret.36.commit.ngrams.sql @@ -0,0 +1,5 @@ +CREATE TABLE {$NAMESPACE}_repository.repository_commit_fngrams ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + documentID INT UNSIGNED NOT NULL, + ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT} +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index ff30ddae98..83714d4e13 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -532,6 +532,7 @@ phutil_register_library_map(array( 'DifferentialRevisionEditConduitAPIMethod' => 'applications/differential/conduit/DifferentialRevisionEditConduitAPIMethod.php', 'DifferentialRevisionEditController' => 'applications/differential/controller/DifferentialRevisionEditController.php', 'DifferentialRevisionEditEngine' => 'applications/differential/editor/DifferentialRevisionEditEngine.php', + 'DifferentialRevisionFerretEngine' => 'applications/differential/search/DifferentialRevisionFerretEngine.php', 'DifferentialRevisionFulltextEngine' => 'applications/differential/search/DifferentialRevisionFulltextEngine.php', 'DifferentialRevisionGraph' => 'infrastructure/graph/DifferentialRevisionGraph.php', 'DifferentialRevisionHasChildRelationship' => 'applications/differential/relationships/DifferentialRevisionHasChildRelationship.php', @@ -651,6 +652,7 @@ phutil_register_library_map(array( 'DiffusionCommitEditConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionCommitEditConduitAPIMethod.php', 'DiffusionCommitEditController' => 'applications/diffusion/controller/DiffusionCommitEditController.php', 'DiffusionCommitEditEngine' => 'applications/diffusion/editor/DiffusionCommitEditEngine.php', + 'DiffusionCommitFerretEngine' => 'applications/repository/search/DiffusionCommitFerretEngine.php', 'DiffusionCommitFulltextEngine' => 'applications/repository/search/DiffusionCommitFulltextEngine.php', 'DiffusionCommitHasPackageEdgeType' => 'applications/diffusion/edge/DiffusionCommitHasPackageEdgeType.php', 'DiffusionCommitHasRevisionEdgeType' => 'applications/diffusion/edge/DiffusionCommitHasRevisionEdgeType.php', @@ -839,7 +841,6 @@ phutil_register_library_map(array( 'DiffusionRepositoryController' => 'applications/diffusion/controller/DiffusionRepositoryController.php', 'DiffusionRepositoryDatasource' => 'applications/diffusion/typeahead/DiffusionRepositoryDatasource.php', 'DiffusionRepositoryDefaultController' => 'applications/diffusion/controller/DiffusionRepositoryDefaultController.php', - 'DiffusionRepositoryDocumentationManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryDocumentationManagementPanel.php', 'DiffusionRepositoryEditActivateController' => 'applications/diffusion/controller/DiffusionRepositoryEditActivateController.php', 'DiffusionRepositoryEditConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionRepositoryEditConduitAPIMethod.php', 'DiffusionRepositoryEditController' => 'applications/diffusion/controller/DiffusionRepositoryEditController.php', @@ -860,7 +861,6 @@ phutil_register_library_map(array( 'DiffusionRepositoryRemarkupRule' => 'applications/diffusion/remarkup/DiffusionRepositoryRemarkupRule.php', 'DiffusionRepositorySearchConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionRepositorySearchConduitAPIMethod.php', 'DiffusionRepositoryStagingManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryStagingManagementPanel.php', - 'DiffusionRepositoryStatusManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryStatusManagementPanel.php', 'DiffusionRepositoryStorageManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryStorageManagementPanel.php', 'DiffusionRepositorySubversionManagementPanel' => 'applications/diffusion/management/DiffusionRepositorySubversionManagementPanel.php', 'DiffusionRepositorySymbolsManagementPanel' => 'applications/diffusion/management/DiffusionRepositorySymbolsManagementPanel.php', @@ -1151,6 +1151,7 @@ phutil_register_library_map(array( 'FundInitiativeEditController' => 'applications/fund/controller/FundInitiativeEditController.php', 'FundInitiativeEditEngine' => 'applications/fund/editor/FundInitiativeEditEngine.php', 'FundInitiativeEditor' => 'applications/fund/editor/FundInitiativeEditor.php', + 'FundInitiativeFerretEngine' => 'applications/fund/search/FundInitiativeFerretEngine.php', 'FundInitiativeFulltextEngine' => 'applications/fund/search/FundInitiativeFulltextEngine.php', 'FundInitiativeListController' => 'applications/fund/controller/FundInitiativeListController.php', 'FundInitiativeMerchantTransaction' => 'applications/fund/xaction/FundInitiativeMerchantTransaction.php', @@ -1533,10 +1534,7 @@ phutil_register_library_map(array( 'ManiphestTaskEditBulkJobType' => 'applications/maniphest/bulk/ManiphestTaskEditBulkJobType.php', 'ManiphestTaskEditController' => 'applications/maniphest/controller/ManiphestTaskEditController.php', 'ManiphestTaskEditEngineLock' => 'applications/maniphest/editor/ManiphestTaskEditEngineLock.php', - 'ManiphestTaskFerretDocument' => 'applications/maniphest/storage/ManiphestTaskFerretDocument.php', 'ManiphestTaskFerretEngine' => 'applications/maniphest/search/ManiphestTaskFerretEngine.php', - 'ManiphestTaskFerretField' => 'applications/maniphest/storage/ManiphestTaskFerretField.php', - 'ManiphestTaskFerretNgrams' => 'applications/maniphest/storage/ManiphestTaskFerretNgrams.php', 'ManiphestTaskFulltextEngine' => 'applications/maniphest/search/ManiphestTaskFulltextEngine.php', 'ManiphestTaskGraph' => 'infrastructure/graph/ManiphestTaskGraph.php', 'ManiphestTaskHasCommitEdgeType' => 'applications/maniphest/edge/ManiphestTaskHasCommitEdgeType.php', @@ -1834,6 +1832,7 @@ phutil_register_library_map(array( 'PassphraseCredentialDestroyController' => 'applications/passphrase/controller/PassphraseCredentialDestroyController.php', 'PassphraseCredentialDestroyTransaction' => 'applications/passphrase/xaction/PassphraseCredentialDestroyTransaction.php', 'PassphraseCredentialEditController' => 'applications/passphrase/controller/PassphraseCredentialEditController.php', + 'PassphraseCredentialFerretEngine' => 'applications/passphrase/search/PassphraseCredentialFerretEngine.php', 'PassphraseCredentialFulltextEngine' => 'applications/passphrase/search/PassphraseCredentialFulltextEngine.php', 'PassphraseCredentialListController' => 'applications/passphrase/controller/PassphraseCredentialListController.php', 'PassphraseCredentialLockController' => 'applications/passphrase/controller/PassphraseCredentialLockController.php', @@ -2210,6 +2209,7 @@ phutil_register_library_map(array( 'PhabricatorCalendarEventEmailCommand' => 'applications/calendar/command/PhabricatorCalendarEventEmailCommand.php', 'PhabricatorCalendarEventEndDateTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventEndDateTransaction.php', 'PhabricatorCalendarEventExportController' => 'applications/calendar/controller/PhabricatorCalendarEventExportController.php', + 'PhabricatorCalendarEventFerretEngine' => 'applications/calendar/search/PhabricatorCalendarEventFerretEngine.php', 'PhabricatorCalendarEventForkTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventForkTransaction.php', 'PhabricatorCalendarEventFrequencyTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventFrequencyTransaction.php', 'PhabricatorCalendarEventFulltextEngine' => 'applications/calendar/search/PhabricatorCalendarEventFulltextEngine.php', @@ -2445,7 +2445,6 @@ phutil_register_library_map(array( 'PhabricatorConfigOption' => 'applications/config/option/PhabricatorConfigOption.php', 'PhabricatorConfigOptionType' => 'applications/config/custom/PhabricatorConfigOptionType.php', 'PhabricatorConfigPHIDModule' => 'applications/config/module/PhabricatorConfigPHIDModule.php', - 'PhabricatorConfigPageView' => 'applications/config/view/PhabricatorConfigPageView.php', 'PhabricatorConfigProxySource' => 'infrastructure/env/PhabricatorConfigProxySource.php', 'PhabricatorConfigPurgeCacheController' => 'applications/config/controller/PhabricatorConfigPurgeCacheController.php', 'PhabricatorConfigRegexOptionType' => 'applications/config/custom/PhabricatorConfigRegexOptionType.php', @@ -2832,12 +2831,13 @@ phutil_register_library_map(array( 'PhabricatorFeedStoryNotification' => 'applications/notification/storage/PhabricatorFeedStoryNotification.php', 'PhabricatorFeedStoryPublisher' => 'applications/feed/PhabricatorFeedStoryPublisher.php', 'PhabricatorFeedStoryReference' => 'applications/feed/storage/PhabricatorFeedStoryReference.php', - 'PhabricatorFerretDocument' => 'applications/search/ferret/PhabricatorFerretDocument.php', 'PhabricatorFerretEngine' => 'applications/search/ferret/PhabricatorFerretEngine.php', - 'PhabricatorFerretField' => 'applications/search/ferret/PhabricatorFerretField.php', + 'PhabricatorFerretEngineTestCase' => 'applications/search/ferret/__tests__/PhabricatorFerretEngineTestCase.php', 'PhabricatorFerretFulltextEngineExtension' => 'applications/search/engineextension/PhabricatorFerretFulltextEngineExtension.php', + 'PhabricatorFerretFulltextStorageEngine' => 'applications/search/fulltextstorage/PhabricatorFerretFulltextStorageEngine.php', 'PhabricatorFerretInterface' => 'applications/search/ferret/PhabricatorFerretInterface.php', - 'PhabricatorFerretNgrams' => 'applications/search/ferret/PhabricatorFerretNgrams.php', + 'PhabricatorFerretMetadata' => 'applications/search/ferret/PhabricatorFerretMetadata.php', + 'PhabricatorFerretSearchEngineExtension' => 'applications/search/engineextension/PhabricatorFerretSearchEngineExtension.php', 'PhabricatorFile' => 'applications/files/storage/PhabricatorFile.php', 'PhabricatorFileAES256StorageFormat' => 'applications/files/format/PhabricatorFileAES256StorageFormat.php', 'PhabricatorFileBundleLoader' => 'applications/files/query/PhabricatorFileBundleLoader.php', @@ -3205,8 +3205,6 @@ phutil_register_library_map(array( 'PhabricatorNamedQueryQuery' => 'applications/search/query/PhabricatorNamedQueryQuery.php', 'PhabricatorNavigationRemarkupRule' => 'infrastructure/markup/rule/PhabricatorNavigationRemarkupRule.php', 'PhabricatorNeverTriggerClock' => 'infrastructure/daemon/workers/clock/PhabricatorNeverTriggerClock.php', - 'PhabricatorNgramEngine' => 'applications/search/ngrams/PhabricatorNgramEngine.php', - 'PhabricatorNgramEngineTestCase' => 'applications/search/ngrams/__tests__/PhabricatorNgramEngineTestCase.php', 'PhabricatorNgramsIndexEngineExtension' => 'applications/search/engineextension/PhabricatorNgramsIndexEngineExtension.php', 'PhabricatorNgramsInterface' => 'applications/search/interface/PhabricatorNgramsInterface.php', 'PhabricatorNotificationBuilder' => 'applications/notification/builder/PhabricatorNotificationBuilder.php', @@ -3321,7 +3319,8 @@ phutil_register_library_map(array( 'PhabricatorOwnersPackageDescriptionTransaction' => 'applications/owners/xaction/PhabricatorOwnersPackageDescriptionTransaction.php', 'PhabricatorOwnersPackageDominionTransaction' => 'applications/owners/xaction/PhabricatorOwnersPackageDominionTransaction.php', 'PhabricatorOwnersPackageEditEngine' => 'applications/owners/editor/PhabricatorOwnersPackageEditEngine.php', - 'PhabricatorOwnersPackageFulltextEngine' => 'applications/owners/query/PhabricatorOwnersPackageFulltextEngine.php', + 'PhabricatorOwnersPackageFerretEngine' => 'applications/owners/search/PhabricatorOwnersPackageFerretEngine.php', + 'PhabricatorOwnersPackageFulltextEngine' => 'applications/owners/search/PhabricatorOwnersPackageFulltextEngine.php', 'PhabricatorOwnersPackageFunctionDatasource' => 'applications/owners/typeahead/PhabricatorOwnersPackageFunctionDatasource.php', 'PhabricatorOwnersPackageNameNgrams' => 'applications/owners/storage/PhabricatorOwnersPackageNameNgrams.php', 'PhabricatorOwnersPackageNameTransaction' => 'applications/owners/xaction/PhabricatorOwnersPackageNameTransaction.php', @@ -3669,6 +3668,7 @@ phutil_register_library_map(array( 'PhabricatorProjectEditController' => 'applications/project/controller/PhabricatorProjectEditController.php', 'PhabricatorProjectEditEngine' => 'applications/project/engine/PhabricatorProjectEditEngine.php', 'PhabricatorProjectEditPictureController' => 'applications/project/controller/PhabricatorProjectEditPictureController.php', + 'PhabricatorProjectFerretEngine' => 'applications/project/search/PhabricatorProjectFerretEngine.php', 'PhabricatorProjectFilterTransaction' => 'applications/project/xaction/PhabricatorProjectFilterTransaction.php', 'PhabricatorProjectFulltextEngine' => 'applications/project/search/PhabricatorProjectFulltextEngine.php', 'PhabricatorProjectHeraldAction' => 'applications/project/herald/PhabricatorProjectHeraldAction.php', @@ -3686,6 +3686,7 @@ phutil_register_library_map(array( 'PhabricatorProjectLockTransaction' => 'applications/project/xaction/PhabricatorProjectLockTransaction.php', 'PhabricatorProjectLogicalAncestorDatasource' => 'applications/project/typeahead/PhabricatorProjectLogicalAncestorDatasource.php', 'PhabricatorProjectLogicalDatasource' => 'applications/project/typeahead/PhabricatorProjectLogicalDatasource.php', + 'PhabricatorProjectLogicalOnlyDatasource' => 'applications/project/typeahead/PhabricatorProjectLogicalOnlyDatasource.php', 'PhabricatorProjectLogicalOrNotDatasource' => 'applications/project/typeahead/PhabricatorProjectLogicalOrNotDatasource.php', 'PhabricatorProjectLogicalUserDatasource' => 'applications/project/typeahead/PhabricatorProjectLogicalUserDatasource.php', 'PhabricatorProjectLogicalViewerDatasource' => 'applications/project/typeahead/PhabricatorProjectLogicalViewerDatasource.php', @@ -3807,6 +3808,7 @@ phutil_register_library_map(array( 'PhabricatorRepositoryDiscoveryEngine' => 'applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php', 'PhabricatorRepositoryEditor' => 'applications/repository/editor/PhabricatorRepositoryEditor.php', 'PhabricatorRepositoryEngine' => 'applications/repository/engine/PhabricatorRepositoryEngine.php', + 'PhabricatorRepositoryFerretEngine' => 'applications/repository/search/PhabricatorRepositoryFerretEngine.php', 'PhabricatorRepositoryFulltextEngine' => 'applications/repository/search/PhabricatorRepositoryFulltextEngine.php', 'PhabricatorRepositoryGitCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryGitCommitChangeParserWorker.php', 'PhabricatorRepositoryGitCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryGitCommitMessageParserWorker.php', @@ -4086,6 +4088,7 @@ phutil_register_library_map(array( 'PhabricatorStorageFixtureScopeGuard' => 'infrastructure/testing/fixture/PhabricatorStorageFixtureScopeGuard.php', 'PhabricatorStorageManagementAPI' => 'infrastructure/storage/management/PhabricatorStorageManagementAPI.php', 'PhabricatorStorageManagementAdjustWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementAdjustWorkflow.php', + 'PhabricatorStorageManagementAnalyzeWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementAnalyzeWorkflow.php', 'PhabricatorStorageManagementDatabasesWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDatabasesWorkflow.php', 'PhabricatorStorageManagementDestroyWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDestroyWorkflow.php', 'PhabricatorStorageManagementDumpWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php', @@ -4253,6 +4256,7 @@ phutil_register_library_map(array( 'PhabricatorUserEditorTestCase' => 'applications/people/editor/__tests__/PhabricatorUserEditorTestCase.php', 'PhabricatorUserEmail' => 'applications/people/storage/PhabricatorUserEmail.php', 'PhabricatorUserEmailTestCase' => 'applications/people/storage/__tests__/PhabricatorUserEmailTestCase.php', + 'PhabricatorUserFerretEngine' => 'applications/people/search/PhabricatorUserFerretEngine.php', 'PhabricatorUserFulltextEngine' => 'applications/people/search/PhabricatorUserFulltextEngine.php', 'PhabricatorUserIconField' => 'applications/people/customfield/PhabricatorUserIconField.php', 'PhabricatorUserLog' => 'applications/people/storage/PhabricatorUserLog.php', @@ -4372,6 +4376,7 @@ phutil_register_library_map(array( 'PhameBlogEditEngine' => 'applications/phame/editor/PhameBlogEditEngine.php', 'PhameBlogEditor' => 'applications/phame/editor/PhameBlogEditor.php', 'PhameBlogFeedController' => 'applications/phame/controller/blog/PhameBlogFeedController.php', + 'PhameBlogFerretEngine' => 'applications/phame/search/PhameBlogFerretEngine.php', 'PhameBlogFullDomainTransaction' => 'applications/phame/xaction/PhameBlogFullDomainTransaction.php', 'PhameBlogFulltextEngine' => 'applications/phame/search/PhameBlogFulltextEngine.php', 'PhameBlogHeaderImageTransaction' => 'applications/phame/xaction/PhameBlogHeaderImageTransaction.php', @@ -4412,6 +4417,7 @@ phutil_register_library_map(array( 'PhamePostEditController' => 'applications/phame/controller/post/PhamePostEditController.php', 'PhamePostEditEngine' => 'applications/phame/editor/PhamePostEditEngine.php', 'PhamePostEditor' => 'applications/phame/editor/PhamePostEditor.php', + 'PhamePostFerretEngine' => 'applications/phame/search/PhamePostFerretEngine.php', 'PhamePostFulltextEngine' => 'applications/phame/search/PhamePostFulltextEngine.php', 'PhamePostHeaderImageTransaction' => 'applications/phame/xaction/PhamePostHeaderImageTransaction.php', 'PhamePostHeaderPictureController' => 'applications/phame/controller/post/PhamePostHeaderPictureController.php', @@ -4472,6 +4478,7 @@ phutil_register_library_map(array( 'PholioMockEditController' => 'applications/pholio/controller/PholioMockEditController.php', 'PholioMockEditor' => 'applications/pholio/editor/PholioMockEditor.php', 'PholioMockEmbedView' => 'applications/pholio/view/PholioMockEmbedView.php', + 'PholioMockFerretEngine' => 'applications/pholio/search/PholioMockFerretEngine.php', 'PholioMockFulltextEngine' => 'applications/pholio/search/PholioMockFulltextEngine.php', 'PholioMockHasTaskEdgeType' => 'applications/pholio/edge/PholioMockHasTaskEdgeType.php', 'PholioMockHasTaskRelationship' => 'applications/pholio/relationships/PholioMockHasTaskRelationship.php', @@ -4692,6 +4699,7 @@ phutil_register_library_map(array( 'PhrictionDocumentContentTransaction' => 'applications/phriction/xaction/PhrictionDocumentContentTransaction.php', 'PhrictionDocumentController' => 'applications/phriction/controller/PhrictionDocumentController.php', 'PhrictionDocumentDeleteTransaction' => 'applications/phriction/xaction/PhrictionDocumentDeleteTransaction.php', + 'PhrictionDocumentFerretEngine' => 'applications/phriction/search/PhrictionDocumentFerretEngine.php', 'PhrictionDocumentFulltextEngine' => 'applications/phriction/search/PhrictionDocumentFulltextEngine.php', 'PhrictionDocumentHeraldAdapter' => 'applications/phriction/herald/PhrictionDocumentHeraldAdapter.php', 'PhrictionDocumentHeraldField' => 'applications/phriction/herald/PhrictionDocumentHeraldField.php', @@ -5524,6 +5532,7 @@ phutil_register_library_map(array( 'PhabricatorDestructibleInterface', 'PhabricatorProjectInterface', 'PhabricatorFulltextInterface', + 'PhabricatorFerretInterface', 'PhabricatorConduitResultInterface', 'PhabricatorDraftInterface', ), @@ -5547,6 +5556,7 @@ phutil_register_library_map(array( 'DifferentialRevisionEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod', 'DifferentialRevisionEditController' => 'DifferentialController', 'DifferentialRevisionEditEngine' => 'PhabricatorEditEngine', + 'DifferentialRevisionFerretEngine' => 'PhabricatorFerretEngine', 'DifferentialRevisionFulltextEngine' => 'PhabricatorFulltextEngine', 'DifferentialRevisionGraph' => 'PhabricatorObjectGraph', 'DifferentialRevisionHasChildRelationship' => 'DifferentialRevisionRelationship', @@ -5666,6 +5676,7 @@ phutil_register_library_map(array( 'DiffusionCommitEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod', 'DiffusionCommitEditController' => 'DiffusionController', 'DiffusionCommitEditEngine' => 'PhabricatorEditEngine', + 'DiffusionCommitFerretEngine' => 'PhabricatorFerretEngine', 'DiffusionCommitFulltextEngine' => 'PhabricatorFulltextEngine', 'DiffusionCommitHasPackageEdgeType' => 'PhabricatorEdgeType', 'DiffusionCommitHasRevisionEdgeType' => 'PhabricatorEdgeType', @@ -5856,7 +5867,6 @@ phutil_register_library_map(array( 'DiffusionRepositoryController' => 'DiffusionController', 'DiffusionRepositoryDatasource' => 'PhabricatorTypeaheadDatasource', 'DiffusionRepositoryDefaultController' => 'DiffusionController', - 'DiffusionRepositoryDocumentationManagementPanel' => 'DiffusionRepositoryManagementPanel', 'DiffusionRepositoryEditActivateController' => 'DiffusionRepositoryManageController', 'DiffusionRepositoryEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod', 'DiffusionRepositoryEditController' => 'DiffusionRepositoryManageController', @@ -5877,7 +5887,6 @@ phutil_register_library_map(array( 'DiffusionRepositoryRemarkupRule' => 'PhabricatorObjectRemarkupRule', 'DiffusionRepositorySearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod', 'DiffusionRepositoryStagingManagementPanel' => 'DiffusionRepositoryManagementPanel', - 'DiffusionRepositoryStatusManagementPanel' => 'DiffusionRepositoryManagementPanel', 'DiffusionRepositoryStorageManagementPanel' => 'DiffusionRepositoryManagementPanel', 'DiffusionRepositorySubversionManagementPanel' => 'DiffusionRepositoryManagementPanel', 'DiffusionRepositorySymbolsManagementPanel' => 'DiffusionRepositoryManagementPanel', @@ -6220,6 +6229,7 @@ phutil_register_library_map(array( 'PhabricatorTokenReceiverInterface', 'PhabricatorDestructibleInterface', 'PhabricatorFulltextInterface', + 'PhabricatorFerretInterface', ), 'FundInitiativeBackController' => 'FundController', 'FundInitiativeBackerTransaction' => 'FundInitiativeTransactionType', @@ -6228,6 +6238,7 @@ phutil_register_library_map(array( 'FundInitiativeEditController' => 'FundController', 'FundInitiativeEditEngine' => 'PhabricatorEditEngine', 'FundInitiativeEditor' => 'PhabricatorApplicationTransactionEditor', + 'FundInitiativeFerretEngine' => 'PhabricatorFerretEngine', 'FundInitiativeFulltextEngine' => 'PhabricatorFulltextEngine', 'FundInitiativeListController' => 'FundController', 'FundInitiativeMerchantTransaction' => 'FundInitiativeTransactionType', @@ -6695,10 +6706,7 @@ phutil_register_library_map(array( 'ManiphestTaskEditBulkJobType' => 'PhabricatorWorkerBulkJobType', 'ManiphestTaskEditController' => 'ManiphestController', 'ManiphestTaskEditEngineLock' => 'PhabricatorEditEngineLock', - 'ManiphestTaskFerretDocument' => 'PhabricatorFerretDocument', 'ManiphestTaskFerretEngine' => 'PhabricatorFerretEngine', - 'ManiphestTaskFerretField' => 'PhabricatorFerretField', - 'ManiphestTaskFerretNgrams' => 'PhabricatorFerretNgrams', 'ManiphestTaskFulltextEngine' => 'PhabricatorFulltextEngine', 'ManiphestTaskGraph' => 'PhabricatorObjectGraph', 'ManiphestTaskHasCommitEdgeType' => 'PhabricatorEdgeType', @@ -7014,6 +7022,7 @@ phutil_register_library_map(array( 'PhabricatorDestructibleInterface', 'PhabricatorSpacesInterface', 'PhabricatorFulltextInterface', + 'PhabricatorFerretInterface', ), 'PassphraseCredentialAuthorPolicyRule' => 'PhabricatorPolicyRule', 'PassphraseCredentialConduitController' => 'PassphraseController', @@ -7024,6 +7033,7 @@ phutil_register_library_map(array( 'PassphraseCredentialDestroyController' => 'PassphraseController', 'PassphraseCredentialDestroyTransaction' => 'PassphraseCredentialTransactionType', 'PassphraseCredentialEditController' => 'PassphraseController', + 'PassphraseCredentialFerretEngine' => 'PhabricatorFerretEngine', 'PassphraseCredentialFulltextEngine' => 'PhabricatorFulltextEngine', 'PassphraseCredentialListController' => 'PassphraseController', 'PassphraseCredentialLockController' => 'PassphraseController', @@ -7442,6 +7452,7 @@ phutil_register_library_map(array( 'PhabricatorFlaggableInterface', 'PhabricatorSpacesInterface', 'PhabricatorFulltextInterface', + 'PhabricatorFerretInterface', 'PhabricatorConduitResultInterface', ), 'PhabricatorCalendarEventAcceptTransaction' => 'PhabricatorCalendarEventReplyTransaction', @@ -7462,6 +7473,7 @@ phutil_register_library_map(array( 'PhabricatorCalendarEventEmailCommand' => 'MetaMTAEmailTransactionCommand', 'PhabricatorCalendarEventEndDateTransaction' => 'PhabricatorCalendarEventDateTransaction', 'PhabricatorCalendarEventExportController' => 'PhabricatorCalendarController', + 'PhabricatorCalendarEventFerretEngine' => 'PhabricatorFerretEngine', 'PhabricatorCalendarEventForkTransaction' => 'PhabricatorCalendarEventTransactionType', 'PhabricatorCalendarEventFrequencyTransaction' => 'PhabricatorCalendarEventTransactionType', 'PhabricatorCalendarEventFulltextEngine' => 'PhabricatorFulltextEngine', @@ -7735,7 +7747,6 @@ phutil_register_library_map(array( ), 'PhabricatorConfigOptionType' => 'Phobject', 'PhabricatorConfigPHIDModule' => 'PhabricatorConfigModule', - 'PhabricatorConfigPageView' => 'AphrontTagView', 'PhabricatorConfigProxySource' => 'PhabricatorConfigSource', 'PhabricatorConfigPurgeCacheController' => 'PhabricatorConfigController', 'PhabricatorConfigRegexOptionType' => 'PhabricatorConfigJSONOptionType', @@ -8164,11 +8175,12 @@ phutil_register_library_map(array( 'PhabricatorFeedStoryNotification' => 'PhabricatorFeedDAO', 'PhabricatorFeedStoryPublisher' => 'Phobject', 'PhabricatorFeedStoryReference' => 'PhabricatorFeedDAO', - 'PhabricatorFerretDocument' => 'PhabricatorSearchDAO', 'PhabricatorFerretEngine' => 'Phobject', - 'PhabricatorFerretField' => 'PhabricatorSearchDAO', + 'PhabricatorFerretEngineTestCase' => 'PhabricatorTestCase', 'PhabricatorFerretFulltextEngineExtension' => 'PhabricatorFulltextEngineExtension', - 'PhabricatorFerretNgrams' => 'PhabricatorSearchDAO', + 'PhabricatorFerretFulltextStorageEngine' => 'PhabricatorFulltextStorageEngine', + 'PhabricatorFerretMetadata' => 'Phobject', + 'PhabricatorFerretSearchEngineExtension' => 'PhabricatorSearchEngineExtension', 'PhabricatorFile' => array( 'PhabricatorFileDAO', 'PhabricatorApplicationTransactionInterface', @@ -8587,8 +8599,6 @@ phutil_register_library_map(array( 'PhabricatorNamedQueryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorNavigationRemarkupRule' => 'PhutilRemarkupRule', 'PhabricatorNeverTriggerClock' => 'PhabricatorTriggerClock', - 'PhabricatorNgramEngine' => 'Phobject', - 'PhabricatorNgramEngineTestCase' => 'PhabricatorTestCase', 'PhabricatorNgramsIndexEngineExtension' => 'PhabricatorIndexEngineExtension', 'PhabricatorNgramsInterface' => 'PhabricatorIndexableInterface', 'PhabricatorNotificationBuilder' => 'Phobject', @@ -8717,6 +8727,7 @@ phutil_register_library_map(array( 'PhabricatorDestructibleInterface', 'PhabricatorConduitResultInterface', 'PhabricatorFulltextInterface', + 'PhabricatorFerretInterface', 'PhabricatorNgramsInterface', ), 'PhabricatorOwnersPackageAuditingTransaction' => 'PhabricatorOwnersPackageTransactionType', @@ -8726,6 +8737,7 @@ phutil_register_library_map(array( 'PhabricatorOwnersPackageDescriptionTransaction' => 'PhabricatorOwnersPackageTransactionType', 'PhabricatorOwnersPackageDominionTransaction' => 'PhabricatorOwnersPackageTransactionType', 'PhabricatorOwnersPackageEditEngine' => 'PhabricatorEditEngine', + 'PhabricatorOwnersPackageFerretEngine' => 'PhabricatorFerretEngine', 'PhabricatorOwnersPackageFulltextEngine' => 'PhabricatorFulltextEngine', 'PhabricatorOwnersPackageFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 'PhabricatorOwnersPackageNameNgrams' => 'PhabricatorSearchNgrams', @@ -9103,6 +9115,7 @@ phutil_register_library_map(array( 'PhabricatorCustomFieldInterface', 'PhabricatorDestructibleInterface', 'PhabricatorFulltextInterface', + 'PhabricatorFerretInterface', 'PhabricatorConduitResultInterface', 'PhabricatorColumnProxyInterface', ), @@ -9162,6 +9175,7 @@ phutil_register_library_map(array( 'PhabricatorProjectEditController' => 'PhabricatorProjectController', 'PhabricatorProjectEditEngine' => 'PhabricatorEditEngine', 'PhabricatorProjectEditPictureController' => 'PhabricatorProjectController', + 'PhabricatorProjectFerretEngine' => 'PhabricatorFerretEngine', 'PhabricatorProjectFilterTransaction' => 'PhabricatorProjectTransactionType', 'PhabricatorProjectFulltextEngine' => 'PhabricatorFulltextEngine', 'PhabricatorProjectHeraldAction' => 'HeraldAction', @@ -9178,6 +9192,7 @@ phutil_register_library_map(array( 'PhabricatorProjectLockTransaction' => 'PhabricatorProjectTransactionType', 'PhabricatorProjectLogicalAncestorDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 'PhabricatorProjectLogicalDatasource' => 'PhabricatorTypeaheadCompositeDatasource', + 'PhabricatorProjectLogicalOnlyDatasource' => 'PhabricatorTypeaheadDatasource', 'PhabricatorProjectLogicalOrNotDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 'PhabricatorProjectLogicalUserDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 'PhabricatorProjectLogicalViewerDatasource' => 'PhabricatorTypeaheadDatasource', @@ -9297,6 +9312,7 @@ phutil_register_library_map(array( 'PhabricatorSpacesInterface', 'PhabricatorConduitResultInterface', 'PhabricatorFulltextInterface', + 'PhabricatorFerretInterface', ), 'PhabricatorRepositoryAuditRequest' => array( 'PhabricatorRepositoryDAO', @@ -9317,6 +9333,7 @@ phutil_register_library_map(array( 'PhabricatorCustomFieldInterface', 'PhabricatorApplicationTransactionInterface', 'PhabricatorFulltextInterface', + 'PhabricatorFerretInterface', 'PhabricatorConduitResultInterface', 'PhabricatorDraftInterface', ), @@ -9339,6 +9356,7 @@ phutil_register_library_map(array( 'PhabricatorRepositoryDiscoveryEngine' => 'PhabricatorRepositoryEngine', 'PhabricatorRepositoryEditor' => 'PhabricatorApplicationTransactionEditor', 'PhabricatorRepositoryEngine' => 'Phobject', + 'PhabricatorRepositoryFerretEngine' => 'PhabricatorFerretEngine', 'PhabricatorRepositoryFulltextEngine' => 'PhabricatorFulltextEngine', 'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker', 'PhabricatorRepositoryGitCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker', @@ -9662,6 +9680,7 @@ phutil_register_library_map(array( 'PhabricatorStorageFixtureScopeGuard' => 'Phobject', 'PhabricatorStorageManagementAPI' => 'Phobject', 'PhabricatorStorageManagementAdjustWorkflow' => 'PhabricatorStorageManagementWorkflow', + 'PhabricatorStorageManagementAnalyzeWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementDatabasesWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementDestroyWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementDumpWorkflow' => 'PhabricatorStorageManagementWorkflow', @@ -9831,6 +9850,7 @@ phutil_register_library_map(array( 'PhabricatorFlaggableInterface', 'PhabricatorApplicationTransactionInterface', 'PhabricatorFulltextInterface', + 'PhabricatorFerretInterface', 'PhabricatorConduitResultInterface', ), 'PhabricatorUserBadgesCacheType' => 'PhabricatorUserCacheType', @@ -9853,6 +9873,7 @@ phutil_register_library_map(array( 'PhabricatorUserEditorTestCase' => 'PhabricatorTestCase', 'PhabricatorUserEmail' => 'PhabricatorUserDAO', 'PhabricatorUserEmailTestCase' => 'PhabricatorTestCase', + 'PhabricatorUserFerretEngine' => 'PhabricatorFerretEngine', 'PhabricatorUserFulltextEngine' => 'PhabricatorFulltextEngine', 'PhabricatorUserIconField' => 'PhabricatorUserCustomField', 'PhabricatorUserLog' => array( @@ -9992,6 +10013,7 @@ phutil_register_library_map(array( 'PhabricatorApplicationTransactionInterface', 'PhabricatorConduitResultInterface', 'PhabricatorFulltextInterface', + 'PhabricatorFerretInterface', ), 'PhameBlog404Controller' => 'PhameLiveController', 'PhameBlogArchiveController' => 'PhameBlogController', @@ -10004,6 +10026,7 @@ phutil_register_library_map(array( 'PhameBlogEditEngine' => 'PhabricatorEditEngine', 'PhameBlogEditor' => 'PhabricatorApplicationTransactionEditor', 'PhameBlogFeedController' => 'PhameBlogController', + 'PhameBlogFerretEngine' => 'PhabricatorFerretEngine', 'PhameBlogFullDomainTransaction' => 'PhameBlogTransactionType', 'PhameBlogFulltextEngine' => 'PhabricatorFulltextEngine', 'PhameBlogHeaderImageTransaction' => 'PhameBlogTransactionType', @@ -10047,6 +10070,7 @@ phutil_register_library_map(array( 'PhabricatorTokenReceiverInterface', 'PhabricatorConduitResultInterface', 'PhabricatorFulltextInterface', + 'PhabricatorFerretInterface', ), 'PhamePostArchiveController' => 'PhamePostController', 'PhamePostBlogTransaction' => 'PhamePostTransactionType', @@ -10056,6 +10080,7 @@ phutil_register_library_map(array( 'PhamePostEditController' => 'PhamePostController', 'PhamePostEditEngine' => 'PhabricatorEditEngine', 'PhamePostEditor' => 'PhabricatorApplicationTransactionEditor', + 'PhamePostFerretEngine' => 'PhabricatorFerretEngine', 'PhamePostFulltextEngine' => 'PhabricatorFulltextEngine', 'PhamePostHeaderImageTransaction' => 'PhamePostTransactionType', 'PhamePostHeaderPictureController' => 'PhamePostController', @@ -10129,6 +10154,7 @@ phutil_register_library_map(array( 'PhabricatorSpacesInterface', 'PhabricatorMentionableInterface', 'PhabricatorFulltextInterface', + 'PhabricatorFerretInterface', ), 'PholioMockArchiveController' => 'PholioController', 'PholioMockAuthorHeraldField' => 'PholioMockHeraldField', @@ -10138,6 +10164,7 @@ phutil_register_library_map(array( 'PholioMockEditController' => 'PholioController', 'PholioMockEditor' => 'PhabricatorApplicationTransactionEditor', 'PholioMockEmbedView' => 'AphrontView', + 'PholioMockFerretEngine' => 'PhabricatorFerretEngine', 'PholioMockFulltextEngine' => 'PhabricatorFulltextEngine', 'PholioMockHasTaskEdgeType' => 'PhabricatorEdgeType', 'PholioMockHasTaskRelationship' => 'PholioMockRelationship', @@ -10408,6 +10435,7 @@ phutil_register_library_map(array( 'PhabricatorTokenReceiverInterface', 'PhabricatorDestructibleInterface', 'PhabricatorFulltextInterface', + 'PhabricatorFerretInterface', 'PhabricatorProjectInterface', 'PhabricatorApplicationTransactionInterface', ), @@ -10416,6 +10444,7 @@ phutil_register_library_map(array( 'PhrictionDocumentContentTransaction' => 'PhrictionDocumentTransactionType', 'PhrictionDocumentController' => 'PhrictionController', 'PhrictionDocumentDeleteTransaction' => 'PhrictionDocumentTransactionType', + 'PhrictionDocumentFerretEngine' => 'PhabricatorFerretEngine', 'PhrictionDocumentFulltextEngine' => 'PhabricatorFulltextEngine', 'PhrictionDocumentHeraldAdapter' => 'HeraldAdapter', 'PhrictionDocumentHeraldField' => 'HeraldField', diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php index f525d0ec97..72b577771f 100644 --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -57,6 +57,10 @@ abstract class PhabricatorApplication abstract public function getName(); + public function getMenuName() { + return $this->getName(); + } + public function getShortDescription() { return pht('%s Application', $this->getName()); } diff --git a/src/applications/calendar/search/PhabricatorCalendarEventFerretEngine.php b/src/applications/calendar/search/PhabricatorCalendarEventFerretEngine.php new file mode 100644 index 0000000000..70e456e034 --- /dev/null +++ b/src/applications/calendar/search/PhabricatorCalendarEventFerretEngine.php @@ -0,0 +1,18 @@ +setText(pht('Generate API Token')) + ->setText(pht('Generate Token')) ->setHref('/conduit/token/edit/?objectPHID='.$user->getPHID()) ->setTag('a') ->setWorkflow(true) ->setIcon('fa-plus'); $terminate_button = id(new PHUIButtonView()) - ->setText(pht('Terminate All Tokens')) + ->setText(pht('Terminate Tokens')) ->setHref('/conduit/token/terminate/?objectPHID='.$user->getPHID()) ->setTag('a') ->setWorkflow(true) - ->setIcon('fa-exclamation-triangle'); + ->setIcon('fa-exclamation-triangle') + ->setColor(PHUIButtonView::RED); $header = id(new PHUIHeaderView()) ->setHeader(pht('Active API Tokens')) @@ -108,8 +109,8 @@ final class PhabricatorConduitTokensSettingsPanel $panel = id(new PHUIObjectBoxView()) ->setHeader($header) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) + ->appendChild($table); return $panel; } diff --git a/src/applications/config/constants/PhabricatorConfigGroupConstants.php b/src/applications/config/constants/PhabricatorConfigGroupConstants.php index d3200abf2b..7dba1ca808 100644 --- a/src/applications/config/constants/PhabricatorConfigGroupConstants.php +++ b/src/applications/config/constants/PhabricatorConfigGroupConstants.php @@ -28,8 +28,17 @@ abstract class PhabricatorConfigGroupConstants public static function getGroupURI($group) { $map = array( self::GROUP_CORE => '/', - self::GROUP_APPLICATION => pht('application/'), - self::GROUP_DEVELOPER => pht('developer/'), + self::GROUP_APPLICATION => 'application/', + self::GROUP_DEVELOPER => 'developer/', + ); + return idx($map, $group, '#'); + } + + public static function getGroupFullURI($group) { + $map = array( + self::GROUP_CORE => '/config/', + self::GROUP_APPLICATION => '/config/application/', + self::GROUP_DEVELOPER => '/config/developer/', ); return idx($map, $group, '#'); } diff --git a/src/applications/config/controller/PhabricatorConfigAllController.php b/src/applications/config/controller/PhabricatorConfigAllController.php index 421e0078cf..3a19eff006 100644 --- a/src/applications/config/controller/PhabricatorConfigAllController.php +++ b/src/applications/config/controller/PhabricatorConfigAllController.php @@ -49,29 +49,29 @@ final class PhabricatorConfigAllController )); $title = pht('Current Settings'); - - $crumbs = $this - ->buildApplicationCrumbs() - ->addTextCrumb($title) - ->setBorder(true); - - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true); + $header = $this->buildHeaderView($title); $nav = $this->buildSideNavView(); $nav->selectFilter('all/'); - $content = id(new PhabricatorConfigPageView()) + $view = $this->buildConfigBoxView( + pht('All Settings'), + $table); + + $crumbs = $this->buildApplicationCrumbs() + ->addTextCrumb($title) + ->setBorder(true); + + $content = id(new PHUITwoColumnView()) ->setHeader($header) - ->setContent($table); + ->setNavigation($nav) + ->setFixed(true) + ->setMainColumn($view); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setNavigation($nav) - ->appendChild($content) - ->addClass('white-background'); + ->appendChild($content); } diff --git a/src/applications/config/controller/PhabricatorConfigApplicationController.php b/src/applications/config/controller/PhabricatorConfigApplicationController.php index 10f639adc7..b4f60982e7 100644 --- a/src/applications/config/controller/PhabricatorConfigApplicationController.php +++ b/src/applications/config/controller/PhabricatorConfigApplicationController.php @@ -11,28 +11,25 @@ final class PhabricatorConfigApplicationController $groups = PhabricatorApplicationConfigOptions::loadAll(); $apps_list = $this->buildConfigOptionsList($groups, 'apps'); + $apps_list = $this->buildConfigBoxView(pht('Applications'), $apps_list); $title = pht('Application Settings'); + $header = $this->buildHeaderView($title); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true); - - $crumbs = $this - ->buildApplicationCrumbs() - ->addTextCrumb(pht('Applications')) - ->setBorder(true); - - $content = id(new PhabricatorConfigPageView()) + $content = id(new PHUITwoColumnView()) ->setHeader($header) - ->setContent($apps_list); + ->setNavigation($nav) + ->setFixed(true) + ->setMainColumn($apps_list); + + $crumbs = $this->buildApplicationCrumbs() + ->addTextCrumb($title) + ->setBorder(true); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setNavigation($nav) - ->appendChild($content) - ->addClass('white-background'); + ->appendChild($content); } private function buildConfigOptionsList(array $groups, $type) { diff --git a/src/applications/config/controller/PhabricatorConfigCacheController.php b/src/applications/config/controller/PhabricatorConfigCacheController.php index 91b0be27cf..a23ab1f9c1 100644 --- a/src/applications/config/controller/PhabricatorConfigCacheController.php +++ b/src/applications/config/controller/PhabricatorConfigCacheController.php @@ -9,16 +9,15 @@ final class PhabricatorConfigCacheController $nav = $this->buildSideNavView(); $nav->selectFilter('cache/'); + $purge_button = id(new PHUIButtonView()) + ->setText(pht('Purge Caches')) + ->setHref('/config/cache/purge/') + ->setTag('a') + ->setWorkflow(true) + ->setIcon('fa-exclamation-triangle'); + $title = pht('Cache Status'); - - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true); - - $crumbs = $this - ->buildApplicationCrumbs() - ->addTextCrumb(pht('Cache Status')) - ->setBorder(true); + $header = $this->buildHeaderView($title, $purge_button); $code_box = $this->renderCodeBox(); $data_box = $this->renderDataBox(); @@ -28,40 +27,27 @@ final class PhabricatorConfigCacheController $data_box, ); - $content = id(new PhabricatorConfigPageView()) + $crumbs = $this->buildApplicationCrumbs() + ->addTextCrumb($title) + ->setBorder(true); + + $content = id(new PHUITwoColumnView()) ->setHeader($header) - ->setContent($page); + ->setNavigation($nav) + ->setFixed(true) + ->setMainColumn($page); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setNavigation($nav) - ->appendChild($content) - ->addClass('white-background'); + ->appendChild($content); } private function renderCodeBox() { $cache = PhabricatorOpcodeCacheSpec::getActiveCacheSpec(); - $properties = id(new PHUIPropertyListView()); - $this->renderCommonProperties($properties, $cache); - - $purge_button = id(new PHUIButtonView()) - ->setText(pht('Purge Caches')) - ->setHref('/config/cache/purge/') - ->setTag('a') - ->setWorkflow(true) - ->setIcon('fa-exclamation-triangle'); - - $header = id(new PHUIHeaderView()) - ->setHeader(pht('Opcode Cache')) - ->addActionLink($purge_button); - - return id(new PHUIObjectBoxView()) - ->setHeader($header) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($properties); + return $this->buildConfigBoxView(pht('Opcode Cache'), $properties); } private function renderDataBox() { @@ -109,11 +95,9 @@ final class PhabricatorConfigCacheController )); } - return id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Data Cache')) - ->addPropertyList($properties) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); + $properties = $this->buildConfigBoxView(pht('Data Cache'), $properties); + $table = $this->buildConfigBoxView(pht('Cache Storage'), $table); + return array($properties, $table); } private function renderCommonProperties( diff --git a/src/applications/config/controller/PhabricatorConfigClusterDatabasesController.php b/src/applications/config/controller/PhabricatorConfigClusterDatabasesController.php index 03dfa3f64c..43e5a15b9d 100644 --- a/src/applications/config/controller/PhabricatorConfigClusterDatabasesController.php +++ b/src/applications/config/controller/PhabricatorConfigClusterDatabasesController.php @@ -9,34 +9,31 @@ final class PhabricatorConfigClusterDatabasesController $title = pht('Cluster Database Status'); $doc_href = PhabricatorEnv::getDoclink('Cluster: Databases'); + $button = id(new PHUIButtonView()) + ->setIcon('fa-book') + ->setHref($doc_href) + ->setTag('a') + ->setText(pht('Documentation')); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true) - ->addActionLink( - id(new PHUIButtonView()) - ->setIcon('fa-book') - ->setHref($doc_href) - ->setTag('a') - ->setText(pht('Documentation'))); + $header = $this->buildHeaderView($title, $button); - $crumbs = $this - ->buildApplicationCrumbs() + $database_status = $this->buildClusterDatabaseStatus(); + $status = $this->buildConfigBoxView(pht('Status'), $database_status); + + $crumbs = $this->buildApplicationCrumbs() ->addTextCrumb($title) ->setBorder(true); - $database_status = $this->buildClusterDatabaseStatus(); - - $content = id(new PhabricatorConfigPageView()) + $content = id(new PHUITwoColumnView()) ->setHeader($header) - ->setContent($database_status); + ->setNavigation($nav) + ->setFixed(true) + ->setMainColumn($status); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setNavigation($nav) - ->appendChild($content) - ->addClass('white-background'); + ->appendChild($content); } private function buildClusterDatabaseStatus() { diff --git a/src/applications/config/controller/PhabricatorConfigClusterNotificationsController.php b/src/applications/config/controller/PhabricatorConfigClusterNotificationsController.php index cc0cc2bf45..443b51a903 100644 --- a/src/applications/config/controller/PhabricatorConfigClusterNotificationsController.php +++ b/src/applications/config/controller/PhabricatorConfigClusterNotificationsController.php @@ -9,34 +9,33 @@ final class PhabricatorConfigClusterNotificationsController $title = pht('Cluster Notifications'); $doc_href = PhabricatorEnv::getDoclink('Cluster: Notifications'); + $button = id(new PHUIButtonView()) + ->setIcon('fa-book') + ->setHref($doc_href) + ->setTag('a') + ->setText(pht('Documentation')); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true) - ->addActionLink( - id(new PHUIButtonView()) - ->setIcon('fa-book') - ->setHref($doc_href) - ->setTag('a') - ->setText(pht('Documentation'))); + $header = $this->buildHeaderView($title, $button); - $crumbs = $this - ->buildApplicationCrumbs() + $notification_status = $this->buildClusterNotificationStatus(); + $status = $this->buildConfigBoxView( + pht('Notifications Status'), + $notification_status); + + $crumbs = $this->buildApplicationCrumbs() ->addTextCrumb($title) ->setBorder(true); - $notification_status = $this->buildClusterNotificationStatus(); - - $content = id(new PhabricatorConfigPageView()) + $content = id(new PHUITwoColumnView()) ->setHeader($header) - ->setContent($notification_status); + ->setNavigation($nav) + ->setFixed(true) + ->setMainColumn($status); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setNavigation($nav) - ->appendChild($content) - ->addClass('white-background'); + ->appendChild($content); } private function buildClusterNotificationStatus() { diff --git a/src/applications/config/controller/PhabricatorConfigClusterRepositoriesController.php b/src/applications/config/controller/PhabricatorConfigClusterRepositoriesController.php index 3531c916a4..471c4cedf0 100644 --- a/src/applications/config/controller/PhabricatorConfigClusterRepositoriesController.php +++ b/src/applications/config/controller/PhabricatorConfigClusterRepositoriesController.php @@ -10,39 +10,39 @@ final class PhabricatorConfigClusterRepositoriesController $title = pht('Cluster Repository Status'); $doc_href = PhabricatorEnv::getDoclink('Cluster: Repositories'); + $button = id(new PHUIButtonView()) + ->setIcon('fa-book') + ->setHref($doc_href) + ->setTag('a') + ->setText(pht('Documentation')); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true) - ->addActionLink( - id(new PHUIButtonView()) - ->setIcon('fa-book') - ->setHref($doc_href) - ->setTag('a') - ->setText(pht('Documentation'))); - - $crumbs = $this - ->buildApplicationCrumbs() - ->addTextCrumb(pht('Repository Servers')) - ->setBorder(true); + $header = $this->buildHeaderView($title, $button); $repository_status = $this->buildClusterRepositoryStatus(); - $repository_errors = $this->buildClusterRepositoryErrors(); + $repo_status = $this->buildConfigBoxView( + pht('Repository Status'), $repository_status); - $content = id(new PhabricatorConfigPageView()) + $repository_errors = $this->buildClusterRepositoryErrors(); + $repo_errors = $this->buildConfigBoxView( + pht('Repository Errors'), $repository_errors); + + $crumbs = $this->buildApplicationCrumbs() + ->addTextCrumb($title) + ->setBorder(true); + + $content = id(new PHUITwoColumnView()) ->setHeader($header) - ->setContent( - array( - $repository_status, - $repository_errors, - )); + ->setNavigation($nav) + ->setFixed(true) + ->setMainColumn(array( + $repo_status, + $repo_errors, + )); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setNavigation($nav) - ->appendChild($content) - ->addClass('white-background'); + ->appendChild($content); } private function buildClusterRepositoryStatus() { diff --git a/src/applications/config/controller/PhabricatorConfigClusterSearchController.php b/src/applications/config/controller/PhabricatorConfigClusterSearchController.php index 4d3ce407ab..cd00ef73a0 100644 --- a/src/applications/config/controller/PhabricatorConfigClusterSearchController.php +++ b/src/applications/config/controller/PhabricatorConfigClusterSearchController.php @@ -10,33 +10,30 @@ final class PhabricatorConfigClusterSearchController $title = pht('Cluster Search'); $doc_href = PhabricatorEnv::getDoclink('Cluster: Search'); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true) - ->addActionLink( - id(new PHUIButtonView()) - ->setIcon('fa-book') - ->setHref($doc_href) - ->setTag('a') - ->setText(pht('Documentation'))); + $button = id(new PHUIButtonView()) + ->setIcon('fa-book') + ->setHref($doc_href) + ->setTag('a') + ->setText(pht('Documentation')); - $crumbs = $this - ->buildApplicationCrumbs($nav) - ->addTextCrumb($title) - ->setBorder(true); + $header = $this->buildHeaderView($title, $button); $search_status = $this->buildClusterSearchStatus(); - $content = id(new PhabricatorConfigPageView()) + $crumbs = $this->buildApplicationCrumbs() + ->addTextCrumb($title) + ->setBorder(true); + + $content = id(new PHUITwoColumnView()) ->setHeader($header) - ->setContent($search_status); + ->setNavigation($nav) + ->setFixed(true) + ->setMainColumn($search_status); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setNavigation($nav) - ->appendChild($content) - ->addClass('white-background'); + ->appendChild($content); } private function buildClusterSearchStatus() { @@ -105,15 +102,16 @@ final class PhabricatorConfigClusterSearchController ->setNoDataString(pht('No search servers are configured.')) ->setHeaders($head); - $view = id(new PHUIObjectBoxView()) - ->setHeaderText($service->getDisplayName()) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); + $view = $this->buildConfigBoxView(pht('Search Servers'), $table); - if ($stats_view) { - $view->addPropertyList($stats_view); + $stats = null; + if ($stats_view->hasAnyProperties()) { + $stats = $this->buildConfigBoxView( + pht('%s Stats', $service->getDisplayName()), + $stats_view); } - return $view; + + return array($stats, $view); } private function renderIndexStats($stats) { diff --git a/src/applications/config/controller/PhabricatorConfigController.php b/src/applications/config/controller/PhabricatorConfigController.php index 2abf2b3b31..ad5ea6cd27 100644 --- a/src/applications/config/controller/PhabricatorConfigController.php +++ b/src/applications/config/controller/PhabricatorConfigController.php @@ -8,10 +8,10 @@ abstract class PhabricatorConfigController extends PhabricatorController { public function buildSideNavView($filter = null, $for_app = false) { + $guide_href = new PhutilURI('/guides/'); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); - $nav->addLabel(pht('Configuration')); $nav->addFilter('/', pht('Core Settings'), null, 'fa-gear'); $nav->addFilter('application/', @@ -46,7 +46,6 @@ abstract class PhabricatorConfigController extends PhabricatorController { pht('Search Servers'), null, 'fa-search'); $nav->addLabel(pht('Modules')); - $modules = PhabricatorConfigModule::getAllModules(); foreach ($modules as $key => $module) { $nav->addFilter('module/'.$key.'/', @@ -60,4 +59,37 @@ abstract class PhabricatorConfigController extends PhabricatorController { return $this->buildSideNavView(null, true)->getMenu(); } + public function buildHeaderView($text, $action = null) { + $viewer = $this->getViewer(); + + $file = PhabricatorFile::loadBuiltin($viewer, 'projects/v3/manage.png'); + $image = $file->getBestURI($file); + $header = id(new PHUIHeaderView()) + ->setHeader($text) + ->setProfileHeader(true) + ->setImage($image); + + if ($action) { + $header->addActionLink($action); + } + + return $header; + } + + public function buildConfigBoxView($title, $content, $action = null) { + $header = id(new PHUIHeaderView()) + ->setHeader($title); + + if ($action) { + $header->addActionItem($action); + } + + $view = id(new PHUIObjectBoxView()) + ->setHeader($header) + ->appendChild($content) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG); + + return $view; + } + } diff --git a/src/applications/config/controller/PhabricatorConfigDatabaseIssueController.php b/src/applications/config/controller/PhabricatorConfigDatabaseIssueController.php index 7674d28f51..708a708043 100644 --- a/src/applications/config/controller/PhabricatorConfigDatabaseIssueController.php +++ b/src/applications/config/controller/PhabricatorConfigDatabaseIssueController.php @@ -12,10 +12,6 @@ final class PhabricatorConfigDatabaseIssueController $expect = $query->loadExpectedSchemata(); $comp_servers = $query->buildComparisonSchemata($expect, $actual); - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb(pht('Database Issues')); - $crumbs->setBorder(true); - // Collect all open issues. $issues = array(); foreach ($comp_servers as $ref_name => $comp) { @@ -158,24 +154,27 @@ final class PhabricatorConfigDatabaseIssueController } $title = pht('Database Issues'); - - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true); + $header = $this->buildHeaderView($title); $nav = $this->buildSideNavView(); $nav->selectFilter('dbissue/'); - $content = id(new PhabricatorConfigPageView()) + $view = $this->buildConfigBoxView(pht('Issues'), $table); + + $crumbs = $this->buildApplicationCrumbs() + ->addTextCrumb($title) + ->setBorder(true); + + $content = id(new PHUITwoColumnView()) ->setHeader($header) - ->setContent($table); + ->setNavigation($nav) + ->setFixed(true) + ->setMainColumn($view); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setNavigation($nav) - ->appendChild($content) - ->addClass('white-background'); + ->appendChild($content); } } diff --git a/src/applications/config/controller/PhabricatorConfigDatabaseStatusController.php b/src/applications/config/controller/PhabricatorConfigDatabaseStatusController.php index d49a546387..a67c57e6f9 100644 --- a/src/applications/config/controller/PhabricatorConfigDatabaseStatusController.php +++ b/src/applications/config/controller/PhabricatorConfigDatabaseStatusController.php @@ -132,27 +132,24 @@ final class PhabricatorConfigDatabaseStatusController } $doc_link = PhabricatorEnv::getDoclink('Managing Storage Adjustments'); + $button = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-book') + ->setHref($doc_link) + ->setText(pht('Documentation')); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true) - ->addActionLink( - id(new PHUIButtonView()) - ->setTag('a') - ->setIcon('fa-book') - ->setHref($doc_link) - ->setText(pht('Learn More'))); + $header = $this->buildHeaderView($title, $button); - $content = id(new PhabricatorConfigPageView()) + $content = id(new PHUITwoColumnView()) ->setHeader($header) - ->setContent($body); + ->setNavigation($nav) + ->setFixed(true) + ->setMainColumn($body); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setNavigation($nav) - ->appendChild($content) - ->addClass('white-background'); + ->appendChild($content); } @@ -221,11 +218,12 @@ final class PhabricatorConfigDatabaseStatusController )); $title = pht('Database Status'); - $properties = $this->buildProperties( array( ), $comp->getIssues()); + $properties = $this->buildConfigBoxView(pht('Properties'), $properties); + $table = $this->buildConfigBoxView(pht('Database'), $table); return $this->buildResponse($title, array($properties, $table)); } @@ -280,7 +278,7 @@ final class PhabricatorConfigDatabaseStatusController null, )); - $title = pht('Database: %s', $database_name); + $title = $database_name; $actual_database = $actual->getDatabase($database_name); if ($actual_database) { @@ -325,6 +323,9 @@ final class PhabricatorConfigDatabaseStatusController ), $database->getIssues()); + $properties = $this->buildConfigBoxView(pht('Properties'), $properties); + $table = $this->buildConfigBoxView(pht('Database'), $table); + return $this->buildResponse($title, array($properties, $table)); } @@ -503,7 +504,7 @@ final class PhabricatorConfigDatabaseStatusController null, )); - $title = pht('Database: %s.%s', $database_name, $table_name); + $title = pht('%s.%s', $database_name, $table_name); if ($actual_table) { $actual_collation = $actual_table->getCollation(); @@ -534,8 +535,14 @@ final class PhabricatorConfigDatabaseStatusController ), $table->getIssues()); + $box_header = pht('%s.%s', $database_name, $table_name); + + $properties = $this->buildConfigBoxView(pht('Properties'), $properties); + $table = $this->buildConfigBoxView(pht('Database'), $table_view); + $keys = $this->buildConfigBoxView(pht('Keys'), $keys_view); + return $this->buildResponse( - $title, array($properties, $table_view, $keys_view)); + $title, array($properties, $table, $keys)); } private function renderColumn( @@ -613,7 +620,7 @@ final class PhabricatorConfigDatabaseStatusController $title = pht( - 'Database Status: %s.%s.%s', + '%s.%s.%s', $database_name, $table_name, $column_name); @@ -671,6 +678,8 @@ final class PhabricatorConfigDatabaseStatusController ), $column->getIssues()); + $properties = $this->buildConfigBoxView(pht('Properties'), $properties); + return $this->buildResponse($title, $properties); } @@ -734,7 +743,7 @@ final class PhabricatorConfigDatabaseStatusController } $title = pht( - 'Database Status: %s.%s (%s)', + '%s.%s (%s)', $database_name, $table_name, $key_name); @@ -764,6 +773,8 @@ final class PhabricatorConfigDatabaseStatusController ), $key->getIssues()); + $properties = $this->buildConfigBoxView(pht('Properties'), $properties); + return $this->buildResponse($title, $properties); } diff --git a/src/applications/config/controller/PhabricatorConfigEditController.php b/src/applications/config/controller/PhabricatorConfigEditController.php index 783fcb4dd3..06df0de889 100644 --- a/src/applications/config/controller/PhabricatorConfigEditController.php +++ b/src/applications/config/controller/PhabricatorConfigEditController.php @@ -7,7 +7,6 @@ final class PhabricatorConfigEditController $viewer = $request->getViewer(); $key = $request->getURIData('key'); - $options = PhabricatorApplicationConfigOptions::loadAllOptions(); if (empty($options[$key])) { $ancient = PhabricatorExtraConfigSetupCheck::getAncientConfig(); @@ -104,44 +103,45 @@ final class PhabricatorConfigEditController $error_view = null; if ($errors) { $error_view = id(new PHUIInfoView()) + ->setSeverity(PHUIInfoView::SEVERITY_ERROR) ->setErrors($errors); } + $doc_href = PhabricatorEnv::getDoclink( + 'Configuration Guide: Locked and Hidden Configuration'); + + $doc_link = phutil_tag( + 'a', + array( + 'href' => $doc_href, + 'target' => '_blank', + ), + pht('Learn more about locked and hidden options.')); + $status_items = array(); + $tag = null; if ($option->getHidden()) { + $tag = id(new PHUITagView()) + ->setName(pht('Hidden')) + ->setColor(PHUITagView::COLOR_GREY) + ->setBorder(PHUITagView::BORDER_NONE) + ->setType(PHUITagView::TYPE_SHADE); + $message = pht( 'This configuration is hidden and can not be edited or viewed from '. 'the web interface.'); - - $status_items[] = id(new PHUIStatusItemView()) - ->setIcon('fa-eye-slash red') - ->setTarget(phutil_tag('strong', array(), pht('Configuration Hidden'))) - ->setNote($message); + $status_items[] = id(new PHUIInfoView()) + ->appendChild(array($message, ' ', $doc_link)); } else if ($option->getLocked()) { + $tag = id(new PHUITagView()) + ->setName(pht('Locked')) + ->setColor(PHUITagView::COLOR_RED) + ->setBorder(PHUITagView::BORDER_NONE) + ->setType(PHUITagView::TYPE_SHADE); + $message = $option->getLockedMessage(); - - $status_items[] = id(new PHUIStatusItemView()) - ->setIcon('fa-lock red') - ->setTarget(phutil_tag('strong', array(), pht('Configuration Locked'))) - ->setNote($message); - } - - if ($status_items) { - $doc_href = PhabricatorEnv::getDoclink( - 'Configuration Guide: Locked and Hidden Configuration'); - - $doc_link = phutil_tag( - 'a', - array( - 'href' => $doc_href, - 'target' => '_blank', - ), - pht('Configuration Guide: Locked and Hidden Configuration')); - - $status_items[] = id(new PHUIStatusItemView()) - ->setIcon('fa-book') - ->setTarget(phutil_tag('strong', array(), pht('Learn More'))) - ->setNote($doc_link); + $status_items[] = id(new PHUIInfoView()) + ->appendChild(array($message, ' ', $doc_link)); } if ($option->getHidden() || $option->getLocked()) { @@ -168,18 +168,6 @@ final class PhabricatorConfigEditController ->setUser($viewer) ->addHiddenInput('issue', $request->getStr('issue')); - if ($status_items) { - $status_view = id(new PHUIStatusListView()); - - foreach ($status_items as $status_item) { - $status_view->addItem($status_item); - } - - $form->appendControl( - id(new AphrontFormMarkupControl()) - ->setValue($status_view)); - } - $description = $option->getDescription(); if (strlen($description)) { $description_view = new PHUIRemarkupView($viewer, $description); @@ -213,56 +201,66 @@ final class PhabricatorConfigEditController ->setValue(pht('Save Config Entry'))); } + $current_config = null; if (!$option->getHidden()) { - $form->appendChild( - id(new AphrontFormMarkupControl()) - ->setLabel(pht('Current Configuration')) - ->setValue($this->renderDefaults($option, $config_entry))); + $current_config = $this->renderDefaults($option, $config_entry); + $current_config = $this->buildConfigBoxView( + pht('Current Configuration'), + $current_config); } $examples = $this->renderExamples($option); if ($examples) { - $form->appendChild( - id(new AphrontFormMarkupControl()) - ->setLabel(pht('Examples')) - ->setValue($examples)); + $examples = $this->buildConfigBoxView( + pht('Examples'), + $examples); } - $title = pht('Edit Option: %s', $key); - $header_icon = 'fa-pencil'; - $short = pht('Edit'); + $title = $key; - $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Config Option')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setForm($form); - - if ($error_view) { - $form_box->setInfoView($error_view); + $box_header = array(); + if ($group) { + $box_header[] = phutil_tag( + 'a', + array( + 'href' => $group_uri, + ), + $group->getName()); + $box_header[] = " \xC2\xBB "; } + $box_header[] = $key; $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Config'), $this->getApplicationURI()); - if ($group) { $crumbs->addTextCrumb($group->getName(), $group_uri); } - $crumbs->addTextCrumb($key, '/config/edit/'.$key); $crumbs->setBorder(true); + $form_box = $this->buildConfigBoxView($box_header, $form, $tag); + $timeline = $this->buildTransactionTimeline( $config_entry, new PhabricatorConfigTransactionQuery()); $timeline->setShouldTerminate(true); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon($header_icon); + $nav = $this->buildSideNavView(); + $nav->selectFilter($group_uri); + + $header = $this->buildHeaderView($title); $view = id(new PHUITwoColumnView()) ->setHeader($header) - ->setFooter($form_box); + ->setNavigation($nav) + ->setFixed(true) + ->setMainColumn(array( + $error_view, + $form_box, + $status_items, + $examples, + $current_config, + )); return $this->newPage() ->setTitle($title) @@ -426,7 +424,7 @@ final class PhabricatorConfigEditController } } - $table[] = phutil_tag('tr', array(), array( + $table[] = phutil_tag('tr', array('class' => 'column-labels'), array( phutil_tag('th', array(), $description), phutil_tag('td', array(), $value), )); @@ -438,6 +436,8 @@ final class PhabricatorConfigEditController 'table', array( 'class' => 'config-option-table', + 'cellspacing' => '0', + 'cellpadding' => '0', ), $table); } @@ -497,6 +497,8 @@ final class PhabricatorConfigEditController 'table', array( 'class' => 'config-option-table', + 'cellspacing' => '0', + 'cellpadding' => '0', ), $table); } diff --git a/src/applications/config/controller/PhabricatorConfigGroupController.php b/src/applications/config/controller/PhabricatorConfigGroupController.php index 6e713f7eab..920b2092ac 100644 --- a/src/applications/config/controller/PhabricatorConfigGroupController.php +++ b/src/applications/config/controller/PhabricatorConfigGroupController.php @@ -13,7 +13,7 @@ final class PhabricatorConfigGroupController return new Aphront404Response(); } - $group_uri = PhabricatorConfigGroupConstants::getGroupURI( + $group_uri = PhabricatorConfigGroupConstants::getGroupFullURI( $options->getGroup()); $group_name = PhabricatorConfigGroupConstants::getGroupShortName( $options->getGroup()); @@ -22,28 +22,28 @@ final class PhabricatorConfigGroupController $nav->selectFilter($group_uri); $title = pht('%s Configuration', $options->getName()); + $header = $this->buildHeaderView($title); $list = $this->buildOptionList($options->getOptions()); + $group_url = phutil_tag('a', array('href' => $group_uri), $group_name); - $crumbs = $this - ->buildApplicationCrumbs() + $box_header = pht("%s \xC2\xBB %s", $group_url, $options->getName()); + $view = $this->buildConfigBoxView($box_header, $list); + + $crumbs = $this->buildApplicationCrumbs() ->addTextCrumb($group_name, $this->getApplicationURI($group_uri)) ->addTextCrumb($options->getName()) ->setBorder(true); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true); - - $content = id(new PhabricatorConfigPageView()) + $content = id(new PHUITwoColumnView()) ->setHeader($header) - ->setContent($list); + ->setNavigation($nav) + ->setFixed(true) + ->setMainColumn($view); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setNavigation($nav) - ->appendChild($content) - ->addClass('white-background'); + ->appendChild($content); } private function buildOptionList(array $options) { @@ -77,13 +77,11 @@ final class PhabricatorConfigGroupController ->setHref('/config/edit/'.$option->getKey().'/') ->addAttribute($summary); - $label = pht('Current Value:'); $color = null; $db_value = idx($db_values, $option->getKey()); if ($db_value && !$db_value->getIsDeleted()) { $item->setEffect('visited'); $color = 'violet'; - $label = pht('Customized Value:'); } if ($option->getHidden()) { @@ -91,6 +89,8 @@ final class PhabricatorConfigGroupController $item->setDisabled(true); } else if ($option->getLocked()) { $item->setStatusIcon('fa-lock '.$color, pht('Locked')); + } else if ($color) { + $item->setStatusIcon('fa-pencil '.$color, pht('Editable')); } else { $item->setStatusIcon('fa-pencil-square-o '.$color, pht('Editable')); } @@ -102,14 +102,13 @@ final class PhabricatorConfigGroupController $current_value = phutil_tag( 'div', array( - 'class' => 'config-options-current-value', + 'class' => 'config-options-current-value '.$color, ), array( - phutil_tag('span', array(), $label), - ' '.$current_value, + $current_value, )); - $item->appendChild($current_value); + $item->setSideColumn($current_value); } $list->addItem($item); diff --git a/src/applications/config/controller/PhabricatorConfigHistoryController.php b/src/applications/config/controller/PhabricatorConfigHistoryController.php index eb7fbf607b..238d09234d 100644 --- a/src/applications/config/controller/PhabricatorConfigHistoryController.php +++ b/src/applications/config/controller/PhabricatorConfigHistoryController.php @@ -29,28 +29,25 @@ final class PhabricatorConfigHistoryController $object->willRenderTimeline($timeline, $this->getRequest()); $title = pht('Settings History'); - - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb($title); - $crumbs->setBorder(true); + $header = $this->buildHeaderView($title); $nav = $this->buildSideNavView(); $nav->selectFilter('history/'); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true); + $crumbs = $this->buildApplicationCrumbs() + ->addTextCrumb($title) + ->setBorder(true); - $content = id(new PhabricatorConfigPageView()) + $content = id(new PHUITwoColumnView()) ->setHeader($header) - ->setContent($timeline); + ->setNavigation($nav) + ->setFixed(true) + ->setMainColumn($timeline); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setNavigation($nav) - ->appendChild($content) - ->addClass('white-background'); + ->appendChild($content); } } diff --git a/src/applications/config/controller/PhabricatorConfigIssueListController.php b/src/applications/config/controller/PhabricatorConfigIssueListController.php index 869f53c223..770f79a9f2 100644 --- a/src/applications/config/controller/PhabricatorConfigIssueListController.php +++ b/src/applications/config/controller/PhabricatorConfigIssueListController.php @@ -43,34 +43,34 @@ final class PhabricatorConfigIssueListController } $title = pht('Setup Issues'); + $header = $this->buildHeaderView($title); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true); - - $crumbs = $this - ->buildApplicationCrumbs() - ->addTextCrumb(pht('Setup Issues')) - ->setBorder(true); - - $page = array( - $no_issues, + $issue_list = array( $important, $php, $mysql, $other, ); - $content = id(new PhabricatorConfigPageView()) + $issue_list = $this->buildConfigBoxView(pht('Issues'), $issue_list); + + $crumbs = $this->buildApplicationCrumbs() + ->addTextCrumb($title) + ->setBorder(true); + + $content = id(new PHUITwoColumnView()) ->setHeader($header) - ->setContent($page); + ->setNavigation($nav) + ->setFixed(true) + ->setMainColumn(array( + $no_issues, + $issue_list, + )); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setNavigation($nav) - ->appendChild($content) - ->addClass('white-background'); + ->appendChild($content); } private function buildIssueList(array $issues, $group, $fonticon) { diff --git a/src/applications/config/controller/PhabricatorConfigIssueViewController.php b/src/applications/config/controller/PhabricatorConfigIssueViewController.php index 43946a3e7b..29c9078413 100644 --- a/src/applications/config/controller/PhabricatorConfigIssueViewController.php +++ b/src/applications/config/controller/PhabricatorConfigIssueViewController.php @@ -36,6 +36,8 @@ final class PhabricatorConfigIssueViewController $title = $issue->getShortName(); } + $header = $this->buildHeaderView($title); + $crumbs = $this ->buildApplicationCrumbs() ->setBorder(true) @@ -43,12 +45,16 @@ final class PhabricatorConfigIssueViewController ->addTextCrumb($title, $request->getRequestURI()) ->setBorder(true); + $content = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setNavigation($nav) + ->setFixed(true) + ->setMainColumn($content); + return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setNavigation($nav) - ->appendChild($content) - ->addClass('white-background'); + ->appendChild($content); } private function renderIssue(PhabricatorSetupIssue $issue) { diff --git a/src/applications/config/controller/PhabricatorConfigListController.php b/src/applications/config/controller/PhabricatorConfigListController.php index 517fe014a9..1a136ea416 100644 --- a/src/applications/config/controller/PhabricatorConfigListController.php +++ b/src/applications/config/controller/PhabricatorConfigListController.php @@ -11,28 +11,25 @@ final class PhabricatorConfigListController $groups = PhabricatorApplicationConfigOptions::loadAll(); $core_list = $this->buildConfigOptionsList($groups, 'core'); + $core_list = $this->buildConfigBoxView(pht('Core'), $core_list); $title = pht('Core Settings'); + $header = $this->buildHeaderView($title); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true); - - $crumbs = $this - ->buildApplicationCrumbs() - ->addTextCrumb(pht('Core')) + $crumbs = $this->buildApplicationCrumbs() + ->addTextCrumb($title) ->setBorder(true); - $content = id(new PhabricatorConfigPageView()) + $content = id(new PHUITwoColumnView()) ->setHeader($header) - ->setContent($core_list); + ->setNavigation($nav) + ->setFixed(true) + ->setMainColumn($core_list); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setNavigation($nav) - ->appendChild($content) - ->addClass('white-background'); + ->appendChild($content); } private function buildConfigOptionsList(array $groups, $type) { diff --git a/src/applications/config/controller/PhabricatorConfigModuleController.php b/src/applications/config/controller/PhabricatorConfigModuleController.php index e10d70561b..63cc5b3843 100644 --- a/src/applications/config/controller/PhabricatorConfigModuleController.php +++ b/src/applications/config/controller/PhabricatorConfigModuleController.php @@ -16,27 +16,26 @@ final class PhabricatorConfigModuleController $content = $module->renderModuleStatus($request); $title = $module->getModuleName(); - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb($title); - $crumbs->setBorder(true); - $nav = $this->buildSideNavView(); $nav->selectFilter('module/'.$key.'/'); + $header = $this->buildHeaderView($title); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true); + $view = $this->buildConfigBoxView($title, $content); - $content = id(new PhabricatorConfigPageView()) + $crumbs = $this->buildApplicationCrumbs() + ->addTextCrumb($title) + ->setBorder(true); + + $content = id(new PHUITwoColumnView()) ->setHeader($header) - ->setContent($content); + ->setNavigation($nav) + ->setFixed(true) + ->setMainColumn($view); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setNavigation($nav) - ->appendChild($content) - ->addClass('white-background'); + ->appendChild($content); } } diff --git a/src/applications/config/controller/PhabricatorConfigVersionController.php b/src/applications/config/controller/PhabricatorConfigVersionController.php index ca638051e4..8a87dec5cc 100644 --- a/src/applications/config/controller/PhabricatorConfigVersionController.php +++ b/src/applications/config/controller/PhabricatorConfigVersionController.php @@ -7,31 +7,30 @@ final class PhabricatorConfigVersionController $viewer = $request->getViewer(); $title = pht('Version Information'); - - $crumbs = $this - ->buildApplicationCrumbs() - ->addTextCrumb($title) - ->setBorder(true); - $versions = $this->renderModuleStatus($viewer); $nav = $this->buildSideNavView(); $nav->selectFilter('version/'); + $header = $this->buildHeaderView($title); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setProfileHeader(true); + $view = $this->buildConfigBoxView( + pht('Installed Versions'), + $versions); - $content = id(new PhabricatorConfigPageView()) + $crumbs = $this->buildApplicationCrumbs() + ->addTextCrumb($title) + ->setBorder(true); + + $content = id(new PHUITwoColumnView()) ->setHeader($header) - ->setContent($versions); + ->setNavigation($nav) + ->setFixed(true) + ->setMainColumn($view); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setNavigation($nav) - ->appendChild($content) - ->addClass('white-background'); + ->appendChild($content); } diff --git a/src/applications/config/schema/PhabricatorConfigCoreSchemaSpec.php b/src/applications/config/schema/PhabricatorConfigCoreSchemaSpec.php index 4219ad2cb4..0d8d743649 100644 --- a/src/applications/config/schema/PhabricatorConfigCoreSchemaSpec.php +++ b/src/applications/config/schema/PhabricatorConfigCoreSchemaSpec.php @@ -42,5 +42,13 @@ final class PhabricatorConfigCoreSchemaSpec )); } + $ferret_objects = id(new PhutilClassMapQuery()) + ->setAncestorClass('PhabricatorFerretInterface') + ->execute(); + + foreach ($ferret_objects as $ferret_object) { + $engine = $ferret_object->newFerretEngine(); + $this->buildFerretIndexSchema($engine); + } } } diff --git a/src/applications/config/schema/PhabricatorConfigSchemaSpec.php b/src/applications/config/schema/PhabricatorConfigSchemaSpec.php index 49a99ab03a..b24adf27cd 100644 --- a/src/applications/config/schema/PhabricatorConfigSchemaSpec.php +++ b/src/applications/config/schema/PhabricatorConfigSchemaSpec.php @@ -55,6 +55,26 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject { $object->getSchemaKeys()); } + protected function buildFerretIndexSchema(PhabricatorFerretEngine $engine) { + $this->buildRawSchema( + $engine->getApplicationName(), + $engine->getDocumentTableName(), + $engine->getDocumentSchemaColumns(), + $engine->getDocumentSchemaKeys()); + + $this->buildRawSchema( + $engine->getApplicationName(), + $engine->getFieldTableName(), + $engine->getFieldSchemaColumns(), + $engine->getFieldSchemaKeys()); + + $this->buildRawSchema( + $engine->getApplicationName(), + $engine->getNgramsTableName(), + $engine->getNgramsSchemaColumns(), + $engine->getNgramsSchemaKeys()); + } + protected function buildRawSchema( $database_name, $table_name, diff --git a/src/applications/config/view/PhabricatorConfigPageView.php b/src/applications/config/view/PhabricatorConfigPageView.php deleted file mode 100644 index 9fed2d4f47..0000000000 --- a/src/applications/config/view/PhabricatorConfigPageView.php +++ /dev/null @@ -1,60 +0,0 @@ -header = $header; - return $this; - } - - public function setContent($content) { - $this->content = $content; - return $this; - } - - public function setFooter($footer) { - $this->footer = $footer; - return $this; - } - - protected function getTagName() { - return 'div'; - } - - protected function getTagAttributes() { - require_celerity_resource('config-page-css'); - - $classes = array(); - $classes[] = 'config-page'; - - return array( - 'class' => implode(' ', $classes), - ); - } - - protected function getTagContent() { - - $header = null; - if ($this->header) { - $header = phutil_tag_div('config-page-header', $this->header); - } - - $content = null; - if ($this->content) { - $content = phutil_tag_div('config-page-content', $this->content); - } - - $footer = null; - if ($this->footer) { - $footer = phutil_tag_div('config-page-footer', $this->footer); - } - - return array($header, $content, $footer); - - } - -} diff --git a/src/applications/config/view/PhabricatorSetupIssueView.php b/src/applications/config/view/PhabricatorSetupIssueView.php index 71bdb9d8dc..6fd75568ac 100644 --- a/src/applications/config/view/PhabricatorSetupIssueView.php +++ b/src/applications/config/view/PhabricatorSetupIssueView.php @@ -148,7 +148,6 @@ final class PhabricatorSetupIssueView extends AphrontView { array( 'href' => '/config/issue/'.$issue->getIssueKey().'/', 'class' => 'button button-grey', - 'style' => 'float: right', ), pht('Reload Page')); } @@ -194,14 +193,24 @@ final class PhabricatorSetupIssueView extends AphrontView { array( 'class' => 'setup-issue-head', ), - array($name, $status)); + $name); + + $body = phutil_tag( + 'div', + array( + 'class' => 'setup-issue-body', + ), + array( + $status, + $description, + )); $tail = phutil_tag( 'div', array( 'class' => 'setup-issue-tail', ), - array($actions)); + $actions); $issue = phutil_tag( 'div', @@ -210,7 +219,7 @@ final class PhabricatorSetupIssueView extends AphrontView { ), array( $head, - $description, + $body, $tail, )); diff --git a/src/applications/dashboard/controller/PhabricatorDashboardEditController.php b/src/applications/dashboard/controller/PhabricatorDashboardEditController.php index 0edda37102..6b3a96d80c 100644 --- a/src/applications/dashboard/controller/PhabricatorDashboardEditController.php +++ b/src/applications/dashboard/controller/PhabricatorDashboardEditController.php @@ -184,19 +184,14 @@ final class PhabricatorDashboardEditController ->addCancelButton($cancel_uri)); $box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Dashboard')) + ->setHeaderText($title) ->setForm($form) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setValidationException($validation_exception); $crumbs->setBorder(true); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon($header_icon); - $view = id(new PHUITwoColumnView()) - ->setHeader($header) ->setFooter($box); return $this->newPage() diff --git a/src/applications/differential/application/PhabricatorDifferentialApplication.php b/src/applications/differential/application/PhabricatorDifferentialApplication.php index e259c2f112..1c8926f585 100644 --- a/src/applications/differential/application/PhabricatorDifferentialApplication.php +++ b/src/applications/differential/application/PhabricatorDifferentialApplication.php @@ -10,8 +10,12 @@ final class PhabricatorDifferentialApplication extends PhabricatorApplication { return pht('Differential'); } + public function getMenuName() { + return pht('Code Review'); + } + public function getShortDescription() { - return pht('Review Code'); + return pht('Pre-Commit Review'); } public function getIcon() { diff --git a/src/applications/differential/controller/DifferentialDiffCreateController.php b/src/applications/differential/controller/DifferentialDiffCreateController.php index 0e13ea08fd..36f0b86202 100644 --- a/src/applications/differential/controller/DifferentialDiffCreateController.php +++ b/src/applications/differential/controller/DifferentialDiffCreateController.php @@ -182,10 +182,10 @@ final class DifferentialDiffCreateController extends DifferentialController { ->setValue($button)); $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Diff')) + ->setHeaderText($title) ->setValidationException($validation_exception) ->setForm($form) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setFormErrors($errors); $crumbs = $this->buildApplicationCrumbs(); @@ -197,15 +197,10 @@ final class DifferentialDiffCreateController extends DifferentialController { $crumbs->addTextCrumb($title); $crumbs->setBorder(true); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon($header_icon); - $view = id(new PHUITwoColumnView()) - ->setHeader($header) ->setFooter(array( - $info_view, $form_box, + $info_view, )); return $this->newPage() diff --git a/src/applications/differential/query/DifferentialRevisionQuery.php b/src/applications/differential/query/DifferentialRevisionQuery.php index 8e6e23776a..8fd91cbd7e 100644 --- a/src/applications/differential/query/DifferentialRevisionQuery.php +++ b/src/applications/differential/query/DifferentialRevisionQuery.php @@ -320,7 +320,7 @@ final class DifferentialRevisionQuery */ protected function loadPage() { $data = $this->loadData(); - + $data = $this->didLoadRawRows($data); $table = $this->newResultObject(); return $table->loadAllFromArray($data); } @@ -772,7 +772,7 @@ final class DifferentialRevisionQuery 'column' => 'dateModified', 'type' => 'int', ), - ); + ) + parent::getOrderableColumns(); } protected function getPagingValueMap($cursor, array $keys) { diff --git a/src/applications/differential/search/DifferentialRevisionFerretEngine.php b/src/applications/differential/search/DifferentialRevisionFerretEngine.php new file mode 100644 index 0000000000..2fc7d5905e --- /dev/null +++ b/src/applications/differential/search/DifferentialRevisionFerretEngine.php @@ -0,0 +1,26 @@ +getTransactionType()) { + case DifferentialRevisionReviewersTransaction::TRANSACTIONTYPE: + // Don't hide the initial "X added reviewers: ..." transaction during + // object creation from mail. See T12118 and PHI54. + return false; + } + + return parent::shouldHideForMail($xactions); + } + + public function isInlineCommentTransaction() { switch ($this->getTransactionType()) { case self::TYPE_INLINE: diff --git a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php index b00fcce77f..cf9c14aa8b 100644 --- a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php +++ b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php @@ -6,6 +6,10 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication { return pht('Diffusion'); } + public function getMenuName() { + return pht('Repositories'); + } + public function getShortDescription() { return pht('Host and Browse Repositories'); } diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditUpdateController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditUpdateController.php index 4cb6ffda67..dd95654302 100644 --- a/src/applications/diffusion/controller/DiffusionRepositoryEditUpdateController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryEditUpdateController.php @@ -13,7 +13,7 @@ final class DiffusionRepositoryEditUpdateController $drequest = $this->getDiffusionRequest(); $repository = $drequest->getRepository(); - $panel_uri = id(new DiffusionRepositoryStatusManagementPanel()) + $panel_uri = id(new DiffusionRepositoryBasicsManagementPanel()) ->setRepository($repository) ->getPanelURI(); diff --git a/src/applications/diffusion/controller/DiffusionRepositoryManageController.php b/src/applications/diffusion/controller/DiffusionRepositoryManageController.php index 8b0740c540..b04e72960b 100644 --- a/src/applications/diffusion/controller/DiffusionRepositoryManageController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryManageController.php @@ -22,4 +22,20 @@ abstract class DiffusionRepositoryManageController return $crumbs; } + public function newBox($title, $content, $action = null) { + $header = id(new PHUIHeaderView()) + ->setHeader($title); + + if ($action) { + $header->addActionItem($action); + } + + $view = id(new PHUIObjectBoxView()) + ->setHeader($header) + ->appendChild($content) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG); + + return $view; + } + } diff --git a/src/applications/diffusion/controller/DiffusionRepositoryManagePanelsController.php b/src/applications/diffusion/controller/DiffusionRepositoryManagePanelsController.php index 12faa6799d..7871c5192a 100644 --- a/src/applications/diffusion/controller/DiffusionRepositoryManagePanelsController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryManagePanelsController.php @@ -53,6 +53,10 @@ final class DiffusionRepositoryManagePanelsController $panel = $panels[$selected]; + $crumbs = $this->buildApplicationCrumbs(); + $crumbs->addTextCrumb($panel->getManagementPanelLabel()); + $crumbs->setBorder(true); + $content = $panel->buildManagementPanelContent(); $title = array( @@ -60,45 +64,17 @@ final class DiffusionRepositoryManagePanelsController $repository->getDisplayName(), ); - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb($panel->getManagementPanelLabel()); - $crumbs->setBorder(true); - - $header_text = pht( - '%s: %s', - $repository->getDisplayName(), - $panel->getManagementPanelLabel()); - - $header = id(new PHUIHeaderView()) - ->setHeader($header_text) - ->setHeaderIcon('fa-pencil'); - if ($repository->isTracked()) { - $header->setStatus('fa-check', 'bluegrey', pht('Active')); - } else { - $header->setStatus('fa-ban', 'dark', pht('Inactive')); - } - - $header->addActionLink( - id(new PHUIButtonView()) - ->setTag('a') - ->setText(pht('View Repository')) - ->setHref($repository->getURI()) - ->setIcon('fa-code') - ->setColor(PHUIButtonView::GREEN)); + $header = $this->buildHeaderView($repository->getDisplayName()); $view = id(new PHUITwoColumnView()) ->setHeader($header) + ->setNavigation($nav) + ->setFixed(true) ->setMainColumn($content); - $curtain = $panel->buildManagementPanelCurtain(); - if ($curtain) { - $view->setCurtain($curtain); - } - return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setNavigation($nav) ->appendChild($view); } @@ -113,12 +89,6 @@ final class DiffusionRepositoryManagePanelsController $nav = id(new AphrontSideNavFilterView()) ->setBaseURI($base_uri); - $item = id(new PHUIListItemView()) - ->setName(pht('manage')) - ->setType(PHUIListItemView::TYPE_LABEL); - - $nav->addMenuItem($item); - foreach ($panels as $panel) { $key = $panel->getManagementPanelKey(); $label = $panel->getManagementPanelLabel(); @@ -140,6 +110,46 @@ final class DiffusionRepositoryManagePanelsController return $nav; } + public function buildHeaderView($title) { + $viewer = $this->getViewer(); + + $drequest = $this->getDiffusionRequest(); + $repository = $drequest->getRepository(); + + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->setProfileHeader(true) + ->setHref($repository->getURI()) + ->setImage($repository->getProfileImageURI()); + + if ($repository->isTracked()) { + $header->setStatus('fa-check', 'bluegrey', pht('Active')); + } else { + $header->setStatus('fa-ban', 'dark', pht('Inactive')); + } + + $doc_href = PhabricatorEnv::getDoclink( + 'Diffusion User Guide: Managing Repositories'); + + $header->addActionLink( + id(new PHUIButtonView()) + ->setTag('a') + ->setText(pht('View Repository')) + ->setHref($repository->getURI()) + ->setIcon('fa-code') + ->setColor(PHUIButtonView::GREY)); + + $header->addActionLink( + id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-book') + ->setHref($doc_href) + ->setText(pht('Help')) + ->setColor(PHUIButtonView::GREY)); + + return $header; + } + public function newTimeline(PhabricatorRepository $repository) { $timeline = $this->buildTransactionTimeline( $repository, diff --git a/src/applications/diffusion/controller/DiffusionRepositoryURIViewController.php b/src/applications/diffusion/controller/DiffusionRepositoryURIViewController.php index 308df8f0d2..91ffbb473f 100644 --- a/src/applications/diffusion/controller/DiffusionRepositoryURIViewController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryURIViewController.php @@ -45,6 +45,7 @@ final class DiffusionRepositoryURIViewController ); $crumbs = $this->buildApplicationCrumbs(); + $crumbs->setBorder(true); $crumbs->addTextCrumb( $repository->getDisplayName(), $repository->getURI()); diff --git a/src/applications/diffusion/management/DiffusionRepositoryActionsManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryActionsManagementPanel.php index 83697e52e3..a5805fd0cc 100644 --- a/src/applications/diffusion/management/DiffusionRepositoryActionsManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositoryActionsManagementPanel.php @@ -14,20 +14,7 @@ final class DiffusionRepositoryActionsManagementPanel } public function getManagementPanelIcon() { - $repository = $this->getRepository(); - - $has_any = - $repository->getDetail('herald-disabled') || - $repository->getDetail('disable-autoclose'); - - // NOTE: Any value here really means something is disabled, so try to - // hint that a little bit with the icon. - - if ($has_any) { - return 'fa-comment-o'; - } else { - return 'fa-commenting grey'; - } + return 'fa-flash'; } protected function getEditEngineFieldKeys() { @@ -37,29 +24,6 @@ final class DiffusionRepositoryActionsManagementPanel ); } - public function buildManagementPanelCurtain() { - $repository = $this->getRepository(); - $viewer = $this->getViewer(); - $action_list = $this->getNewActionList(); - - $can_edit = PhabricatorPolicyFilter::hasCapability( - $viewer, - $repository, - PhabricatorPolicyCapability::CAN_EDIT); - - $actions_uri = $this->getEditPageURI(); - - $action_list->addAction( - id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Actions')) - ->setHref($actions_uri) - ->setDisabled(!$can_edit) - ->setWorkflow(!$can_edit)); - - return $this->getNewCurtainView($action_list); - } - public function buildManagementPanelContent() { $repository = $this->getRepository(); $viewer = $this->getViewer(); @@ -79,7 +43,22 @@ final class DiffusionRepositoryActionsManagementPanel $autoclose = phutil_tag('em', array(), $autoclose); $view->addProperty(pht('Autoclose'), $autoclose); - return $this->newBox(pht('Actions'), $view); + $can_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $repository, + PhabricatorPolicyCapability::CAN_EDIT); + + $actions_uri = $this->getEditPageURI(); + + $button = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-pencil') + ->setText(pht('Edit')) + ->setHref($actions_uri) + ->setDisabled(!$can_edit) + ->setWorkflow(!$can_edit); + + return $this->newBox(pht('Actions'), $view, array($button)); } } diff --git a/src/applications/diffusion/management/DiffusionRepositoryAutomationManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryAutomationManagementPanel.php index b37aa05ecf..22afd5a53b 100644 --- a/src/applications/diffusion/management/DiffusionRepositoryAutomationManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositoryAutomationManagementPanel.php @@ -27,59 +27,18 @@ final class DiffusionRepositoryAutomationManagementPanel public function getManagementPanelIcon() { $repository = $this->getRepository(); - if (!$repository->canPerformAutomation()) { - return 'fa-truck grey'; - } - $blueprint_phids = $repository->getAutomationBlueprintPHIDs(); - if (!$blueprint_phids) { - return 'fa-truck grey'; - } $is_authorized = DrydockAuthorizationQuery::isFullyAuthorized( $repository->getPHID(), $blueprint_phids); if (!$is_authorized) { - return 'fa-exclamation-triangle yellow'; + return 'fa-exclamation-triangle'; } return 'fa-truck'; } - public function buildManagementPanelCurtain() { - $repository = $this->getRepository(); - $viewer = $this->getViewer(); - $action_list = $this->getNewActionList(); - - $can_edit = PhabricatorPolicyFilter::hasCapability( - $viewer, - $repository, - PhabricatorPolicyCapability::CAN_EDIT); - - $can_test = $can_edit && $repository->canPerformAutomation(); - - $automation_uri = $this->getEditPageURI(); - $test_uri = $repository->getPathURI('edit/testautomation/'); - - $action_list->addAction( - id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Automation')) - ->setHref($automation_uri) - ->setDisabled(!$can_edit) - ->setWorkflow(!$can_edit)); - - $action_list->addAction( - id(new PhabricatorActionView()) - ->setIcon('fa-gamepad') - ->setName(pht('Test Configuration')) - ->setWorkflow(true) - ->setDisabled(!$can_test) - ->setHref($test_uri)); - - return $this->getNewCurtainView($action_list); - } - public function buildManagementPanelContent() { $repository = $this->getRepository(); $viewer = $this->getViewer(); @@ -99,7 +58,33 @@ final class DiffusionRepositoryAutomationManagementPanel $view->addProperty(pht('Automation'), $blueprint_view); - return $this->newBox(pht('Automation'), $view); + $can_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $repository, + PhabricatorPolicyCapability::CAN_EDIT); + + $can_test = $can_edit && $repository->canPerformAutomation(); + + $automation_uri = $this->getEditPageURI(); + $test_uri = $repository->getPathURI('edit/testautomation/'); + + $edit = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-pencil') + ->setText(pht('Edit')) + ->setHref($automation_uri) + ->setDisabled(!$can_edit) + ->setWorkflow(!$can_edit); + + $test = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-gamepad') + ->setText(pht('Test Config')) + ->setWorkflow(true) + ->setDisabled(!$can_test) + ->setHref($test_uri); + + return $this->newBox(pht('Automation'), $view, array($edit, $test)); } } diff --git a/src/applications/diffusion/management/DiffusionRepositoryBasicsManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryBasicsManagementPanel.php index a5e09e40d3..6e527e81b5 100644 --- a/src/applications/diffusion/management/DiffusionRepositoryBasicsManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositoryBasicsManagementPanel.php @@ -14,13 +14,7 @@ final class DiffusionRepositoryBasicsManagementPanel } public function getManagementPanelIcon() { - $repository = $this->getRepository(); - - if (!$repository->isTracked()) { - return 'fa-ban indigo'; - } else { - return 'fa-code'; - } + return 'fa-code'; } protected function getEditEngineFieldKeys() { @@ -33,10 +27,11 @@ final class DiffusionRepositoryBasicsManagementPanel ); } - public function buildManagementPanelCurtain() { + private function buildActionMenu() { $repository = $this->getRepository(); $viewer = $this->getViewer(); - $action_list = $this->getNewActionList(); + $action_list = id(new PhabricatorActionListView()) + ->setViewer($viewer); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, @@ -50,27 +45,22 @@ final class DiffusionRepositoryBasicsManagementPanel $dangerous_uri = $repository->getPathURI('edit/dangerous/'); if ($repository->isTracked()) { - $activate_icon = 'fa-pause'; $activate_label = pht('Deactivate Repository'); } else { - $activate_icon = 'fa-play'; $activate_label = pht('Activate Repository'); } $should_dangerous = $repository->shouldAllowDangerousChanges(); if ($should_dangerous) { - $dangerous_icon = 'fa-shield'; $dangerous_name = pht('Prevent Dangerous Changes'); $can_dangerous = $can_edit; } else { - $dangerous_icon = 'fa-bullseye'; $dangerous_name = pht('Allow Dangerous Changes'); $can_dangerous = ($can_edit && $repository->canAllowDangerousChanges()); } $action_list->addAction( id(new PhabricatorActionView()) - ->setIcon('fa-pencil') ->setName(pht('Edit Basic Information')) ->setHref($edit_uri) ->setDisabled(!$can_edit) @@ -78,7 +68,6 @@ final class DiffusionRepositoryBasicsManagementPanel $action_list->addAction( id(new PhabricatorActionView()) - ->setIcon('fa-text-width') ->setName(pht('Edit Text Encoding')) ->setHref($encoding_uri) ->setDisabled(!$can_edit) @@ -86,7 +75,6 @@ final class DiffusionRepositoryBasicsManagementPanel $action_list->addAction( id(new PhabricatorActionView()) - ->setIcon($dangerous_icon) ->setName($dangerous_name) ->setHref($dangerous_uri) ->setDisabled(!$can_dangerous) @@ -95,26 +83,37 @@ final class DiffusionRepositoryBasicsManagementPanel $action_list->addAction( id(new PhabricatorActionView()) ->setHref($activate_uri) - ->setIcon($activate_icon) ->setName($activate_label) ->setDisabled(!$can_edit) ->setWorkflow(true)); + $action_list->addAction( + id(new PhabricatorActionView()) + ->setType(PhabricatorActionView::TYPE_DIVIDER)); + $action_list->addAction( id(new PhabricatorActionView()) ->setName(pht('Delete Repository')) - ->setIcon('fa-times') ->setHref($delete_uri) + ->setColor(PhabricatorActionView::RED) ->setDisabled(true) ->setWorkflow(true)); - return $this->getNewCurtainView($action_list); + return $action_list; } public function buildManagementPanelContent() { - $result = array(); - $basics = $this->newBox(pht('Repository Basics'), $this->buildBasics()); + $button = id(new PHUIButtonView()) + ->setTag('a') + ->setText(pht('Actions')) + ->setHref('#') + ->setIcon('fa-bars') + ->addClass('phui-mobile-menu') + ->setDropdownMenu($this->buildActionMenu()); + + $basics = $this->buildBasics(); + $basics = $this->newBox(pht('Properties'), $basics, array($button)); $repository = $this->getRepository(); $is_new = $repository->isNewlyInitialized(); @@ -144,14 +143,13 @@ final class DiffusionRepositoryBasicsManagementPanel ->setErrors($messages); } - $result[] = $basics; - $description = $this->buildDescription(); if ($description) { - $result[] = $this->newBox(pht('Description'), $description); + $description = $this->newBox(pht('Description'), $description); } + $status = $this->buildStatus(); - return array($info_view, $result); + return array($info_view, $basics, $description, $status); } private function buildBasics() { @@ -213,7 +211,7 @@ final class DiffusionRepositoryBasicsManagementPanel $view = id(new PHUIPropertyListView()) ->setViewer($viewer); if (!strlen($description)) { - $description = phutil_tag('em', array(), pht('No description provided.')); + return null; } else { $description = new PHUIRemarkupView($viewer, $description); } @@ -222,4 +220,471 @@ final class DiffusionRepositoryBasicsManagementPanel return $view; } + private function buildStatus() { + $repository = $this->getRepository(); + $viewer = $this->getViewer(); + $update_uri = $repository->getPathURI('edit/update/'); + + $view = id(new PHUIPropertyListView()) + ->setViewer($viewer); + + $view->addProperty( + pht('Update Frequency'), + $this->buildRepositoryUpdateInterval($repository)); + + $messages = $this->loadStatusMessages($repository); + + $status = $this->buildRepositoryStatus($repository, $messages); + $raw_error = $this->buildRepositoryRawError($repository, $messages); + + $view->addProperty(pht('Status'), $status); + if ($raw_error) { + $view->addSectionHeader(pht('Raw Error')); + $view->addTextContent($raw_error); + } + + $can_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $repository, + PhabricatorPolicyCapability::CAN_EDIT); + + $button = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-refresh') + ->setText(pht('Update Now')) + ->setWorkflow(true) + ->setDisabled(!$can_edit) + ->setHref($update_uri); + + return $this->newBox(pht('Status'), $view, array($button)); + } + + private function buildRepositoryUpdateInterval( + PhabricatorRepository $repository) { + + $smart_wait = $repository->loadUpdateInterval(); + + $doc_href = PhabricatorEnv::getDoclink( + 'Diffusion User Guide: Repository Updates'); + + return array( + phutil_format_relative_time_detailed($smart_wait), + " \xC2\xB7 ", + phutil_tag( + 'a', + array( + 'href' => $doc_href, + 'target' => '_blank', + ), + pht('Learn More')), + ); + } + + private function buildRepositoryStatus( + PhabricatorRepository $repository, + array $messages) { + + $viewer = $this->getViewer(); + $is_cluster = $repository->getAlmanacServicePHID(); + + $view = new PHUIStatusListView(); + + if ($repository->isTracked()) { + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') + ->setTarget(pht('Repository Active'))); + } else { + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_WARNING, 'bluegrey') + ->setTarget(pht('Repository Inactive')) + ->setNote( + pht('Activate this repository to begin or resume import.'))); + return $view; + } + + $binaries = array(); + $svnlook_check = false; + switch ($repository->getVersionControlSystem()) { + case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: + $binaries[] = 'git'; + break; + case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: + $binaries[] = 'svn'; + break; + case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: + $binaries[] = 'hg'; + break; + } + + if ($repository->isHosted()) { + $proto_https = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTPS; + $proto_http = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTP; + $can_http = $repository->canServeProtocol($proto_http, false) || + $repository->canServeProtocol($proto_https, false); + + if ($can_http) { + switch ($repository->getVersionControlSystem()) { + case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: + $binaries[] = 'git-http-backend'; + break; + case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: + $binaries[] = 'svnserve'; + $binaries[] = 'svnadmin'; + $binaries[] = 'svnlook'; + $svnlook_check = true; + break; + case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: + $binaries[] = 'hg'; + break; + } + } + + + $proto_ssh = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH; + $can_ssh = $repository->canServeProtocol($proto_ssh, false); + + if ($can_ssh) { + switch ($repository->getVersionControlSystem()) { + case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: + $binaries[] = 'git-receive-pack'; + $binaries[] = 'git-upload-pack'; + break; + case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: + $binaries[] = 'svnserve'; + $binaries[] = 'svnadmin'; + $binaries[] = 'svnlook'; + $svnlook_check = true; + break; + case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: + $binaries[] = 'hg'; + break; + } + } + } + + $binaries = array_unique($binaries); + if (!$is_cluster) { + // We're only checking for binaries if we aren't running with a cluster + // configuration. In theory, we could check for binaries on the + // repository host machine, but we'd need to make this more complicated + // to do that. + + foreach ($binaries as $binary) { + $where = Filesystem::resolveBinary($binary); + if (!$where) { + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') + ->setTarget( + pht('Missing Binary %s', phutil_tag('tt', array(), $binary))) + ->setNote(pht( + "Unable to find this binary in the webserver's PATH. You may ". + "need to configure %s.", + $this->getEnvConfigLink()))); + } else { + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') + ->setTarget( + pht('Found Binary %s', phutil_tag('tt', array(), $binary))) + ->setNote(phutil_tag('tt', array(), $where))); + } + } + + // This gets checked generically above. However, for svn commit hooks, we + // need this to be in environment.append-paths because subversion strips + // PATH. + if ($svnlook_check) { + $where = Filesystem::resolveBinary('svnlook'); + if ($where) { + $path = substr($where, 0, strlen($where) - strlen('svnlook')); + $dirs = PhabricatorEnv::getEnvConfig('environment.append-paths'); + $in_path = false; + foreach ($dirs as $dir) { + if (Filesystem::isDescendant($path, $dir)) { + $in_path = true; + break; + } + } + if (!$in_path) { + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') + ->setTarget( + pht('Missing Binary %s', phutil_tag('tt', array(), $binary))) + ->setNote(pht( + 'Unable to find this binary in `%s`. '. + 'You need to configure %s and include %s.', + 'environment.append-paths', + $this->getEnvConfigLink(), + $path))); + } + } + } + } + + $doc_href = PhabricatorEnv::getDoclink('Managing Daemons with phd'); + + $daemon_instructions = pht( + 'Use %s to start daemons. See %s.', + phutil_tag('tt', array(), 'bin/phd start'), + phutil_tag( + 'a', + array( + 'href' => $doc_href, + ), + pht('Managing Daemons with phd'))); + + + $pull_daemon = id(new PhabricatorDaemonLogQuery()) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE) + ->withDaemonClasses(array('PhabricatorRepositoryPullLocalDaemon')) + ->setLimit(1) + ->execute(); + + if ($pull_daemon) { + + // TODO: In a cluster environment, we need a daemon on this repository's + // host, specifically, and we aren't checking for that right now. This + // is a reasonable proxy for things being more-or-less correctly set up, + // though. + + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') + ->setTarget(pht('Pull Daemon Running'))); + } else { + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') + ->setTarget(pht('Pull Daemon Not Running')) + ->setNote($daemon_instructions)); + } + + + $task_daemon = id(new PhabricatorDaemonLogQuery()) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE) + ->withDaemonClasses(array('PhabricatorTaskmasterDaemon')) + ->setLimit(1) + ->execute(); + if ($task_daemon) { + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') + ->setTarget(pht('Task Daemon Running'))); + } else { + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') + ->setTarget(pht('Task Daemon Not Running')) + ->setNote($daemon_instructions)); + } + + + if ($is_cluster) { + // Just omit this status check for now in cluster environments. We + // could make a service call and pull it from the repository host + // eventually. + } else if ($repository->usesLocalWorkingCopy()) { + $local_parent = dirname($repository->getLocalPath()); + if (Filesystem::pathExists($local_parent)) { + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') + ->setTarget(pht('Storage Directory OK')) + ->setNote(phutil_tag('tt', array(), $local_parent))); + } else { + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') + ->setTarget(pht('No Storage Directory')) + ->setNote( + pht( + 'Storage directory %s does not exist, or is not readable by '. + 'the webserver. Create this directory or make it readable.', + phutil_tag('tt', array(), $local_parent)))); + return $view; + } + + $local_path = $repository->getLocalPath(); + $message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_INIT); + if ($message) { + switch ($message->getStatusCode()) { + case PhabricatorRepositoryStatusMessage::CODE_ERROR: + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') + ->setTarget(pht('Initialization Error')) + ->setNote($message->getParameter('message'))); + return $view; + case PhabricatorRepositoryStatusMessage::CODE_OKAY: + if (Filesystem::pathExists($local_path)) { + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') + ->setTarget(pht('Working Copy OK')) + ->setNote(phutil_tag('tt', array(), $local_path))); + } else { + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') + ->setTarget(pht('Working Copy Error')) + ->setNote( + pht( + 'Working copy %s has been deleted, or is not '. + 'readable by the webserver. Make this directory '. + 'readable. If it has been deleted, the daemons should '. + 'restore it automatically.', + phutil_tag('tt', array(), $local_path)))); + return $view; + } + break; + default: + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green') + ->setTarget(pht('Initializing Working Copy')) + ->setNote(pht('Daemons are initializing the working copy.'))); + return $view; + } + } else { + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange') + ->setTarget(pht('No Working Copy Yet')) + ->setNote( + pht('Waiting for daemons to build a working copy.'))); + return $view; + } + } + + $message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_FETCH); + if ($message) { + switch ($message->getStatusCode()) { + case PhabricatorRepositoryStatusMessage::CODE_ERROR: + $message = $message->getParameter('message'); + + $suggestion = null; + if (preg_match('/Permission denied \(publickey\)./', $message)) { + $suggestion = pht( + 'Public Key Error: This error usually indicates that the '. + 'keypair you have configured does not have permission to '. + 'access the repository.'); + } + + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') + ->setTarget(pht('Update Error')) + ->setNote($suggestion)); + return $view; + case PhabricatorRepositoryStatusMessage::CODE_OKAY: + $ago = (PhabricatorTime::getNow() - $message->getEpoch()); + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') + ->setTarget(pht('Updates OK')) + ->setNote( + pht( + 'Last updated %s (%s ago).', + phabricator_datetime($message->getEpoch(), $viewer), + phutil_format_relative_time_detailed($ago)))); + break; + } + } else { + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange') + ->setTarget(pht('Waiting For Update')) + ->setNote( + pht('Waiting for daemons to read updates.'))); + } + + if ($repository->isImporting()) { + $ratio = $repository->loadImportProgress(); + $percentage = sprintf('%.2f%%', 100 * $ratio); + + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green') + ->setTarget(pht('Importing')) + ->setNote( + pht('%s Complete', $percentage))); + } else { + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') + ->setTarget(pht('Fully Imported'))); + } + + if (idx($messages, PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE)) { + $view->addItem( + id(new PHUIStatusItemView()) + ->setIcon(PHUIStatusItemView::ICON_UP, 'indigo') + ->setTarget(pht('Prioritized')) + ->setNote(pht('This repository will be updated soon!'))); + } + + return $view; + } + + private function buildRepositoryRawError( + PhabricatorRepository $repository, + array $messages) { + $viewer = $this->getViewer(); + + $can_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $repository, + PhabricatorPolicyCapability::CAN_EDIT); + + $raw_error = null; + + $message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_FETCH); + if ($message) { + switch ($message->getStatusCode()) { + case PhabricatorRepositoryStatusMessage::CODE_ERROR: + $raw_error = $message->getParameter('message'); + break; + } + } + + if ($raw_error !== null) { + if (!$can_edit) { + $raw_message = pht( + 'You must be able to edit a repository to see raw error messages '. + 'because they sometimes disclose sensitive information.'); + $raw_message = phutil_tag('em', array(), $raw_message); + } else { + $raw_message = phutil_escape_html_newlines($raw_error); + } + } else { + $raw_message = null; + } + + return $raw_message; + } + + private function loadStatusMessages(PhabricatorRepository $repository) { + $messages = id(new PhabricatorRepositoryStatusMessage()) + ->loadAllWhere('repositoryID = %d', $repository->getID()); + $messages = mpull($messages, null, 'getStatusType'); + + return $messages; + } + + private function getEnvConfigLink() { + $config_href = '/config/edit/environment.append-paths/'; + return phutil_tag( + 'a', + array( + 'href' => $config_href, + ), + 'environment.append-paths'); + } + } diff --git a/src/applications/diffusion/management/DiffusionRepositoryBranchesManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryBranchesManagementPanel.php index 90b646c3f9..7c7f4bcf63 100644 --- a/src/applications/diffusion/management/DiffusionRepositoryBranchesManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositoryBranchesManagementPanel.php @@ -19,18 +19,7 @@ final class DiffusionRepositoryBranchesManagementPanel } public function getManagementPanelIcon() { - $repository = $this->getRepository(); - - $has_any = - $repository->getDetail('default-branch') || - $repository->getDetail('branch-filter') || - $repository->getDetail('close-commits-filter'); - - if ($has_any) { - return 'fa-code-fork'; - } else { - return 'fa-code-fork grey'; - } + return 'fa-code-fork'; } protected function getEditEngineFieldKeys() { @@ -41,29 +30,6 @@ final class DiffusionRepositoryBranchesManagementPanel ); } - public function buildManagementPanelCurtain() { - $repository = $this->getRepository(); - $viewer = $this->getViewer(); - $action_list = $this->getNewActionList(); - - $can_edit = PhabricatorPolicyFilter::hasCapability( - $viewer, - $repository, - PhabricatorPolicyCapability::CAN_EDIT); - - $branches_uri = $this->getEditPageURI(); - - $action_list->addAction( - id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Branches')) - ->setHref($branches_uri) - ->setDisabled(!$can_edit) - ->setWorkflow(!$can_edit)); - - return $this->getNewCurtainView($action_list); - } - public function buildManagementPanelContent() { $repository = $this->getRepository(); $viewer = $this->getViewer(); @@ -94,7 +60,23 @@ final class DiffusionRepositoryBranchesManagementPanel } $view->addProperty(pht('Autoclose Only'), $autoclose_only); - $content[] = $this->newBox(pht('Branches'), $view); + + $can_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $repository, + PhabricatorPolicyCapability::CAN_EDIT); + + $branches_uri = $this->getEditPageURI(); + + $button = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-pencil') + ->setText(pht('Edit')) + ->setHref($branches_uri) + ->setDisabled(!$can_edit) + ->setWorkflow(!$can_edit); + + $content[] = $this->newBox(pht('Branches'), $view, array($button)); // Branch Autoclose Table if (!$repository->isImporting()) { @@ -176,11 +158,8 @@ final class DiffusionRepositoryBranchesManagementPanel true, )); - $box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Branch Status')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($branch_table) - ->setPager($pager); + $box = $this->newBox(pht('Branch Status'), $branch_table); + $box->setPager($pager); $content[] = $box; } else { $content[] = id(new PHUIInfoView()) diff --git a/src/applications/diffusion/management/DiffusionRepositoryDocumentationManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryDocumentationManagementPanel.php deleted file mode 100644 index 9d067cd90b..0000000000 --- a/src/applications/diffusion/management/DiffusionRepositoryDocumentationManagementPanel.php +++ /dev/null @@ -1,33 +0,0 @@ -newTimeline(); } - public function buildManagementPanelCurtain() { - return null; - } - } diff --git a/src/applications/diffusion/management/DiffusionRepositoryManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryManagementPanel.php index f9e76eb523..282fa1b7b1 100644 --- a/src/applications/diffusion/management/DiffusionRepositoryManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositoryManagementPanel.php @@ -41,7 +41,6 @@ abstract class DiffusionRepositoryManagementPanel abstract public function getManagementPanelLabel(); abstract public function getManagementPanelOrder(); abstract public function buildManagementPanelContent(); - abstract public function buildManagementPanelCurtain(); public function getManagementPanelIcon() { return 'fa-pencil'; @@ -56,22 +55,6 @@ abstract class DiffusionRepositoryManagementPanel return true; } - public function getNewActionList() { - $viewer = $this->getViewer(); - $action_id = celerity_generate_unique_node_id(); - - return id(new PhabricatorActionListView()) - ->setViewer($viewer) - ->setID($action_id); - } - - public function getNewCurtainView(PhabricatorActionListView $action_list) { - $viewer = $this->getViewer(); - return id(new PHUICurtainView()) - ->setViewer($viewer) - ->setActionList($action_list); - } - public static function getAllPanels() { return id(new PhutilClassMapQuery()) ->setAncestorClass(__CLASS__) @@ -80,11 +63,20 @@ abstract class DiffusionRepositoryManagementPanel ->execute(); } - final protected function newBox($header_text, $body) { - return id(new PHUIObjectBoxView()) - ->setHeaderText($header_text) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + final protected function newBox($header_text, $body, $button = array()) { + $header = id(new PHUIHeaderView()) + ->setHeader($header_text); + + foreach ($button as $link) { + $header->addActionLink($link); + } + + $view = id(new PHUIObjectBoxView()) + ->setHeader($header) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->appendChild($body); + + return $view; } final protected function newTimeline() { diff --git a/src/applications/diffusion/management/DiffusionRepositoryPoliciesManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryPoliciesManagementPanel.php index 6b2972e30c..3da6ea80dc 100644 --- a/src/applications/diffusion/management/DiffusionRepositoryPoliciesManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositoryPoliciesManagementPanel.php @@ -14,35 +14,7 @@ final class DiffusionRepositoryPoliciesManagementPanel } public function getManagementPanelIcon() { - $viewer = $this->getViewer(); - $repository = $this->getRepository(); - - $can_view = PhabricatorPolicyCapability::CAN_VIEW; - $can_edit = PhabricatorPolicyCapability::CAN_EDIT; - $can_push = DiffusionPushCapability::CAPABILITY; - - $actual_values = array( - 'spacePHID' => $repository->getSpacePHID(), - 'view' => $repository->getPolicy($can_view), - 'edit' => $repository->getPolicy($can_edit), - 'push' => $repository->getPolicy($can_push), - ); - - $default = PhabricatorRepository::initializeNewRepository( - $viewer); - - $default_values = array( - 'spacePHID' => $default->getSpacePHID(), - 'view' => $default->getPolicy($can_view), - 'edit' => $default->getPolicy($can_edit), - 'push' => $default->getPolicy($can_push), - ); - - if ($actual_values === $default_values) { - return 'fa-lock grey'; - } else { - return 'fa-lock'; - } + return 'fa-lock'; } protected function getEditEngineFieldKeys() { @@ -54,29 +26,6 @@ final class DiffusionRepositoryPoliciesManagementPanel ); } - public function buildManagementPanelCurtain() { - $repository = $this->getRepository(); - $viewer = $this->getViewer(); - $action_list = $this->getNewActionList(); - - $can_edit = PhabricatorPolicyFilter::hasCapability( - $viewer, - $repository, - PhabricatorPolicyCapability::CAN_EDIT); - - $edit_uri = $this->getEditPageURI(); - - $action_list->addAction( - id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Policies')) - ->setHref($edit_uri) - ->setDisabled(!$can_edit) - ->setWorkflow(!$can_edit)); - - return $this->getNewCurtainView($action_list); - } - public function buildManagementPanelContent() { $repository = $this->getRepository(); $viewer = $this->getViewer(); @@ -109,7 +58,22 @@ final class DiffusionRepositoryPoliciesManagementPanel : phutil_tag('em', array(), pht('Not a Hosted Repository')); $view->addProperty(pht('Pushable By'), $pushable); - return $this->newBox(pht('Policies'), $view); + $can_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $repository, + PhabricatorPolicyCapability::CAN_EDIT); + + $edit_uri = $this->getEditPageURI(); + + $button = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-pencil') + ->setText(pht('Edit')) + ->setHref($edit_uri) + ->setDisabled(!$can_edit) + ->setWorkflow(!$can_edit); + + return $this->newBox(pht('Policies'), $view, array($button)); } } diff --git a/src/applications/diffusion/management/DiffusionRepositoryStagingManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryStagingManagementPanel.php index bab7e72857..ebd970f032 100644 --- a/src/applications/diffusion/management/DiffusionRepositoryStagingManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositoryStagingManagementPanel.php @@ -20,15 +20,7 @@ final class DiffusionRepositoryStagingManagementPanel public function getManagementPanelIcon() { - $repository = $this->getRepository(); - - $staging_uri = $repository->getStagingURI(); - - if ($staging_uri) { - return 'fa-upload'; - } else { - return 'fa-upload grey'; - } + return 'fa-upload'; } protected function getEditEngineFieldKeys() { @@ -37,29 +29,6 @@ final class DiffusionRepositoryStagingManagementPanel ); } - public function buildManagementPanelCurtain() { - $repository = $this->getRepository(); - $viewer = $this->getViewer(); - $action_list = $this->getNewActionList(); - - $can_edit = PhabricatorPolicyFilter::hasCapability( - $viewer, - $repository, - PhabricatorPolicyCapability::CAN_EDIT); - - $staging_uri = $this->getEditPageURI(); - - $action_list->addAction( - id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Staging')) - ->setHref($staging_uri) - ->setDisabled(!$can_edit) - ->setWorkflow(!$can_edit)); - - return $this->getNewCurtainView($action_list); - } - public function buildManagementPanelContent() { $repository = $this->getRepository(); $viewer = $this->getViewer(); @@ -74,7 +43,22 @@ final class DiffusionRepositoryStagingManagementPanel $view->addProperty(pht('Staging Area URI'), $staging_uri); - return $this->newBox(pht('Staging Area'), $view); + $can_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $repository, + PhabricatorPolicyCapability::CAN_EDIT); + + $staging_uri = $this->getEditPageURI(); + + $button = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-pencil') + ->setText(pht('Edit')) + ->setHref($staging_uri) + ->setDisabled(!$can_edit) + ->setWorkflow(!$can_edit); + + return $this->newBox(pht('Staging Area'), $view, array($button)); } } diff --git a/src/applications/diffusion/management/DiffusionRepositoryStatusManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryStatusManagementPanel.php deleted file mode 100644 index 23b2cd1684..0000000000 --- a/src/applications/diffusion/management/DiffusionRepositoryStatusManagementPanel.php +++ /dev/null @@ -1,507 +0,0 @@ -getRepository(); - - // TODO: We could try to show a warning icon in more cases, but just - // raise in the most serious cases for now. - $messages = $this->loadStatusMessages($repository); - - $raw_error = $this->buildRepositoryRawError($repository, $messages); - if ($raw_error) { - return 'fa-exclamation-triangle red'; - } - - return 'fa-check grey'; - } - - public function buildManagementPanelCurtain() { - $repository = $this->getRepository(); - $viewer = $this->getViewer(); - $action_list = $this->getNewActionList(); - - $can_edit = PhabricatorPolicyFilter::hasCapability( - $viewer, - $repository, - PhabricatorPolicyCapability::CAN_EDIT); - - $update_uri = $repository->getPathURI('edit/update/'); - - $action_list->addAction( - id(new PhabricatorActionView()) - ->setIcon('fa-refresh') - ->setName(pht('Update Now')) - ->setWorkflow(true) - ->setDisabled(!$can_edit) - ->setHref($update_uri)); - - return $this->getNewCurtainView($action_list); - } - - public function buildManagementPanelContent() { - $repository = $this->getRepository(); - $viewer = $this->getViewer(); - - $view = id(new PHUIPropertyListView()) - ->setViewer($viewer); - - $view->addProperty( - pht('Update Frequency'), - $this->buildRepositoryUpdateInterval($repository)); - - $messages = $this->loadStatusMessages($repository); - - $status = $this->buildRepositoryStatus($repository, $messages); - $raw_error = $this->buildRepositoryRawError($repository, $messages); - - $view->addProperty(pht('Status'), $status); - if ($raw_error) { - $view->addSectionHeader(pht('Raw Error')); - $view->addTextContent($raw_error); - } - - return $this->newBox(pht('Status'), $view); - } - - private function buildRepositoryUpdateInterval( - PhabricatorRepository $repository) { - - $smart_wait = $repository->loadUpdateInterval(); - - $doc_href = PhabricatorEnv::getDoclink( - 'Diffusion User Guide: Repository Updates'); - - return array( - phutil_format_relative_time_detailed($smart_wait), - " \xC2\xB7 ", - phutil_tag( - 'a', - array( - 'href' => $doc_href, - 'target' => '_blank', - ), - pht('Learn More')), - ); - } - - private function buildRepositoryStatus( - PhabricatorRepository $repository, - array $messages) { - - $viewer = $this->getViewer(); - $is_cluster = $repository->getAlmanacServicePHID(); - - $view = new PHUIStatusListView(); - - if ($repository->isTracked()) { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') - ->setTarget(pht('Repository Active'))); - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'bluegrey') - ->setTarget(pht('Repository Inactive')) - ->setNote( - pht('Activate this repository to begin or resume import.'))); - return $view; - } - - $binaries = array(); - $svnlook_check = false; - switch ($repository->getVersionControlSystem()) { - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: - $binaries[] = 'git'; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: - $binaries[] = 'svn'; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: - $binaries[] = 'hg'; - break; - } - - if ($repository->isHosted()) { - $proto_https = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTPS; - $proto_http = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTP; - $can_http = $repository->canServeProtocol($proto_http, false) || - $repository->canServeProtocol($proto_https, false); - - if ($can_http) { - switch ($repository->getVersionControlSystem()) { - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: - $binaries[] = 'git-http-backend'; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: - $binaries[] = 'svnserve'; - $binaries[] = 'svnadmin'; - $binaries[] = 'svnlook'; - $svnlook_check = true; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: - $binaries[] = 'hg'; - break; - } - } - - - $proto_ssh = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH; - $can_ssh = $repository->canServeProtocol($proto_ssh, false); - - if ($can_ssh) { - switch ($repository->getVersionControlSystem()) { - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: - $binaries[] = 'git-receive-pack'; - $binaries[] = 'git-upload-pack'; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: - $binaries[] = 'svnserve'; - $binaries[] = 'svnadmin'; - $binaries[] = 'svnlook'; - $svnlook_check = true; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: - $binaries[] = 'hg'; - break; - } - } - } - - $binaries = array_unique($binaries); - if (!$is_cluster) { - // We're only checking for binaries if we aren't running with a cluster - // configuration. In theory, we could check for binaries on the - // repository host machine, but we'd need to make this more complicated - // to do that. - - foreach ($binaries as $binary) { - $where = Filesystem::resolveBinary($binary); - if (!$where) { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') - ->setTarget( - pht('Missing Binary %s', phutil_tag('tt', array(), $binary))) - ->setNote(pht( - "Unable to find this binary in the webserver's PATH. You may ". - "need to configure %s.", - $this->getEnvConfigLink()))); - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') - ->setTarget( - pht('Found Binary %s', phutil_tag('tt', array(), $binary))) - ->setNote(phutil_tag('tt', array(), $where))); - } - } - - // This gets checked generically above. However, for svn commit hooks, we - // need this to be in environment.append-paths because subversion strips - // PATH. - if ($svnlook_check) { - $where = Filesystem::resolveBinary('svnlook'); - if ($where) { - $path = substr($where, 0, strlen($where) - strlen('svnlook')); - $dirs = PhabricatorEnv::getEnvConfig('environment.append-paths'); - $in_path = false; - foreach ($dirs as $dir) { - if (Filesystem::isDescendant($path, $dir)) { - $in_path = true; - break; - } - } - if (!$in_path) { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') - ->setTarget( - pht('Missing Binary %s', phutil_tag('tt', array(), $binary))) - ->setNote(pht( - 'Unable to find this binary in `%s`. '. - 'You need to configure %s and include %s.', - 'environment.append-paths', - $this->getEnvConfigLink(), - $path))); - } - } - } - } - - $doc_href = PhabricatorEnv::getDoclink('Managing Daemons with phd'); - - $daemon_instructions = pht( - 'Use %s to start daemons. See %s.', - phutil_tag('tt', array(), 'bin/phd start'), - phutil_tag( - 'a', - array( - 'href' => $doc_href, - ), - pht('Managing Daemons with phd'))); - - - $pull_daemon = id(new PhabricatorDaemonLogQuery()) - ->setViewer(PhabricatorUser::getOmnipotentUser()) - ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE) - ->withDaemonClasses(array('PhabricatorRepositoryPullLocalDaemon')) - ->setLimit(1) - ->execute(); - - if ($pull_daemon) { - - // TODO: In a cluster environment, we need a daemon on this repository's - // host, specifically, and we aren't checking for that right now. This - // is a reasonable proxy for things being more-or-less correctly set up, - // though. - - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') - ->setTarget(pht('Pull Daemon Running'))); - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') - ->setTarget(pht('Pull Daemon Not Running')) - ->setNote($daemon_instructions)); - } - - - $task_daemon = id(new PhabricatorDaemonLogQuery()) - ->setViewer(PhabricatorUser::getOmnipotentUser()) - ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE) - ->withDaemonClasses(array('PhabricatorTaskmasterDaemon')) - ->setLimit(1) - ->execute(); - if ($task_daemon) { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') - ->setTarget(pht('Task Daemon Running'))); - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') - ->setTarget(pht('Task Daemon Not Running')) - ->setNote($daemon_instructions)); - } - - - if ($is_cluster) { - // Just omit this status check for now in cluster environments. We - // could make a service call and pull it from the repository host - // eventually. - } else if ($repository->usesLocalWorkingCopy()) { - $local_parent = dirname($repository->getLocalPath()); - if (Filesystem::pathExists($local_parent)) { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') - ->setTarget(pht('Storage Directory OK')) - ->setNote(phutil_tag('tt', array(), $local_parent))); - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') - ->setTarget(pht('No Storage Directory')) - ->setNote( - pht( - 'Storage directory %s does not exist, or is not readable by '. - 'the webserver. Create this directory or make it readable.', - phutil_tag('tt', array(), $local_parent)))); - return $view; - } - - $local_path = $repository->getLocalPath(); - $message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_INIT); - if ($message) { - switch ($message->getStatusCode()) { - case PhabricatorRepositoryStatusMessage::CODE_ERROR: - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') - ->setTarget(pht('Initialization Error')) - ->setNote($message->getParameter('message'))); - return $view; - case PhabricatorRepositoryStatusMessage::CODE_OKAY: - if (Filesystem::pathExists($local_path)) { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') - ->setTarget(pht('Working Copy OK')) - ->setNote(phutil_tag('tt', array(), $local_path))); - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') - ->setTarget(pht('Working Copy Error')) - ->setNote( - pht( - 'Working copy %s has been deleted, or is not '. - 'readable by the webserver. Make this directory '. - 'readable. If it has been deleted, the daemons should '. - 'restore it automatically.', - phutil_tag('tt', array(), $local_path)))); - return $view; - } - break; - default: - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green') - ->setTarget(pht('Initializing Working Copy')) - ->setNote(pht('Daemons are initializing the working copy.'))); - return $view; - } - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange') - ->setTarget(pht('No Working Copy Yet')) - ->setNote( - pht('Waiting for daemons to build a working copy.'))); - return $view; - } - } - - $message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_FETCH); - if ($message) { - switch ($message->getStatusCode()) { - case PhabricatorRepositoryStatusMessage::CODE_ERROR: - $message = $message->getParameter('message'); - - $suggestion = null; - if (preg_match('/Permission denied \(publickey\)./', $message)) { - $suggestion = pht( - 'Public Key Error: This error usually indicates that the '. - 'keypair you have configured does not have permission to '. - 'access the repository.'); - } - - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') - ->setTarget(pht('Update Error')) - ->setNote($suggestion)); - return $view; - case PhabricatorRepositoryStatusMessage::CODE_OKAY: - $ago = (PhabricatorTime::getNow() - $message->getEpoch()); - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') - ->setTarget(pht('Updates OK')) - ->setNote( - pht( - 'Last updated %s (%s ago).', - phabricator_datetime($message->getEpoch(), $viewer), - phutil_format_relative_time_detailed($ago)))); - break; - } - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange') - ->setTarget(pht('Waiting For Update')) - ->setNote( - pht('Waiting for daemons to read updates.'))); - } - - if ($repository->isImporting()) { - $ratio = $repository->loadImportProgress(); - $percentage = sprintf('%.2f%%', 100 * $ratio); - - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green') - ->setTarget(pht('Importing')) - ->setNote( - pht('%s Complete', $percentage))); - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') - ->setTarget(pht('Fully Imported'))); - } - - if (idx($messages, PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE)) { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_UP, 'indigo') - ->setTarget(pht('Prioritized')) - ->setNote(pht('This repository will be updated soon!'))); - } - - return $view; - } - - private function buildRepositoryRawError( - PhabricatorRepository $repository, - array $messages) { - $viewer = $this->getViewer(); - - $can_edit = PhabricatorPolicyFilter::hasCapability( - $viewer, - $repository, - PhabricatorPolicyCapability::CAN_EDIT); - - $raw_error = null; - - $message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_FETCH); - if ($message) { - switch ($message->getStatusCode()) { - case PhabricatorRepositoryStatusMessage::CODE_ERROR: - $raw_error = $message->getParameter('message'); - break; - } - } - - if ($raw_error !== null) { - if (!$can_edit) { - $raw_message = pht( - 'You must be able to edit a repository to see raw error messages '. - 'because they sometimes disclose sensitive information.'); - $raw_message = phutil_tag('em', array(), $raw_message); - } else { - $raw_message = phutil_escape_html_newlines($raw_error); - } - } else { - $raw_message = null; - } - - return $raw_message; - } - - private function loadStatusMessages(PhabricatorRepository $repository) { - $messages = id(new PhabricatorRepositoryStatusMessage()) - ->loadAllWhere('repositoryID = %d', $repository->getID()); - $messages = mpull($messages, null, 'getStatusType'); - - return $messages; - } - - private function getEnvConfigLink() { - $config_href = '/config/edit/environment.append-paths/'; - return phutil_tag( - 'a', - array( - 'href' => $config_href, - ), - 'environment.append-paths'); - } - -} diff --git a/src/applications/diffusion/management/DiffusionRepositoryStorageManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryStorageManagementPanel.php index 3d6733d5d3..a39dfaa632 100644 --- a/src/applications/diffusion/management/DiffusionRepositoryStorageManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositoryStorageManagementPanel.php @@ -14,31 +14,7 @@ final class DiffusionRepositoryStorageManagementPanel } public function getManagementPanelIcon() { - $repository = $this->getRepository(); - - if ($repository->getAlmanacServicePHID()) { - return 'fa-sitemap'; - } else if ($repository->isHosted()) { - return 'fa-folder'; - } else { - return 'fa-download'; - } - } - - public function buildManagementPanelCurtain() { - $repository = $this->getRepository(); - $viewer = $this->getViewer(); - $action_list = $this->getNewActionList(); - - $doc_href = PhabricatorEnv::getDoclink('Cluster: Repositories'); - - $action_list->addAction( - id(new PhabricatorActionView()) - ->setIcon('fa-book') - ->setHref($doc_href) - ->setName(pht('Cluster Documentation'))); - - return $this->getNewCurtainView($action_list); + return 'fa-database'; } public function buildManagementPanelContent() { @@ -71,9 +47,15 @@ final class DiffusionRepositoryStorageManagementPanel $view->addProperty(pht('Storage Path'), $storage_path); $view->addProperty(pht('Storage Cluster'), $storage_service); - $box = $this->newBox(pht('Storage'), null); - $box->addPropertyList($view); - return $box; + $doc_href = PhabricatorEnv::getDoclink('Cluster: Repositories'); + + $button = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-book') + ->setHref($doc_href) + ->setText(pht('Help')); + + return $this->newBox(pht('Storage'), $view, array($button)); } private function buildClusterStatusPanel() { @@ -243,9 +225,7 @@ final class DiffusionRepositoryStorageManagementPanel 'date', )); - $box = $this->newBox(pht('Cluster Status'), null); - $box->setTable($table); - return $box; + return $this->newBox(pht('Cluster Status'), $table); } } diff --git a/src/applications/diffusion/management/DiffusionRepositorySubversionManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositorySubversionManagementPanel.php index 5b9384d195..cd6e2c5be0 100644 --- a/src/applications/diffusion/management/DiffusionRepositorySubversionManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositorySubversionManagementPanel.php @@ -19,15 +19,7 @@ final class DiffusionRepositorySubversionManagementPanel } public function getManagementPanelIcon() { - $repository = $this->getRepository(); - - $has_any = (bool)$repository->getDetail('svn-subpath'); - - if ($has_any) { - return 'fa-database'; - } else { - return 'fa-database grey'; - } + return 'fa-folder'; } protected function getEditEngineFieldKeys() { @@ -36,29 +28,6 @@ final class DiffusionRepositorySubversionManagementPanel ); } - public function buildManagementPanelCurtain() { - $repository = $this->getRepository(); - $viewer = $this->getViewer(); - $action_list = $this->getNewActionList(); - - $can_edit = PhabricatorPolicyFilter::hasCapability( - $viewer, - $repository, - PhabricatorPolicyCapability::CAN_EDIT); - - $subversion_uri = $this->getEditPageURI(); - - $action_list->addAction( - id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Properties')) - ->setHref($subversion_uri) - ->setDisabled(!$can_edit) - ->setWorkflow(!$can_edit)); - - return $this->getNewCurtainView($action_list); - } - public function buildManagementPanelContent() { $repository = $this->getRepository(); $viewer = $this->getViewer(); @@ -71,8 +40,22 @@ final class DiffusionRepositorySubversionManagementPanel phutil_tag('em', array(), pht('Import Entire Repository'))); $view->addProperty(pht('Import Only'), $default_branch); + $can_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $repository, + PhabricatorPolicyCapability::CAN_EDIT); - return $this->newBox(pht('Subversion'), $view); + $subversion_uri = $this->getEditPageURI(); + + $button = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-pencil') + ->setText(pht('Edit')) + ->setHref($subversion_uri) + ->setDisabled(!$can_edit) + ->setWorkflow(!$can_edit); + + return $this->newBox(pht('Subversion'), $view, array($button)); } } diff --git a/src/applications/diffusion/management/DiffusionRepositorySymbolsManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositorySymbolsManagementPanel.php index 22d8780077..f64fbf8d6e 100644 --- a/src/applications/diffusion/management/DiffusionRepositorySymbolsManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositorySymbolsManagementPanel.php @@ -14,17 +14,7 @@ final class DiffusionRepositorySymbolsManagementPanel } public function getManagementPanelIcon() { - $repository = $this->getRepository(); - - $has_any = - $repository->getSymbolLanguages() || - $repository->getSymbolSources(); - - if ($has_any) { - return 'fa-link'; - } else { - return 'fa-link grey'; - } + return 'fa-bullseye'; } protected function getEditEngineFieldKeys() { @@ -34,29 +24,6 @@ final class DiffusionRepositorySymbolsManagementPanel ); } - public function buildManagementPanelCurtain() { - $repository = $this->getRepository(); - $viewer = $this->getViewer(); - $action_list = $this->getNewActionList(); - - $can_edit = PhabricatorPolicyFilter::hasCapability( - $viewer, - $repository, - PhabricatorPolicyCapability::CAN_EDIT); - - $symbols_uri = $this->getEditPageURI(); - - $action_list->addAction( - id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Symbols')) - ->setHref($symbols_uri) - ->setDisabled(!$can_edit) - ->setWorkflow(!$can_edit)); - - return $this->getNewCurtainView($action_list); - } - public function buildManagementPanelContent() { $repository = $this->getRepository(); $viewer = $this->getViewer(); @@ -80,7 +47,22 @@ final class DiffusionRepositorySymbolsManagementPanel } $view->addProperty(pht('Uses Symbols From'), $sources); - return $this->newBox(pht('Symbols'), $view); + $can_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $repository, + PhabricatorPolicyCapability::CAN_EDIT); + + $symbols_uri = $this->getEditPageURI(); + + $button = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-pencil') + ->setText(pht('Edit')) + ->setHref($symbols_uri) + ->setDisabled(!$can_edit) + ->setWorkflow(!$can_edit); + + return $this->newBox(pht('Symbols'), $view, array($button)); } } diff --git a/src/applications/diffusion/management/DiffusionRepositoryURIsManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryURIsManagementPanel.php index 4fe9e00475..220bf4e2c1 100644 --- a/src/applications/diffusion/management/DiffusionRepositoryURIsManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositoryURIsManagementPanel.php @@ -10,42 +10,13 @@ final class DiffusionRepositoryURIsManagementPanel } public function getManagementPanelIcon() { - return 'fa-cogs'; + return 'fa-globe'; } public function getManagementPanelOrder() { return 400; } - public function buildManagementPanelCurtain() { - $repository = $this->getRepository(); - $viewer = $this->getViewer(); - $action_list = $this->getNewActionList(); - - $can_edit = PhabricatorPolicyFilter::hasCapability( - $viewer, - $repository, - PhabricatorPolicyCapability::CAN_EDIT); - - $doc_href = PhabricatorEnv::getDoclink('Diffusion User Guide: URIs'); - $add_href = $repository->getPathURI('uri/edit/'); - - $action_list->addAction( - id(new PhabricatorActionView()) - ->setIcon('fa-plus') - ->setHref($add_href) - ->setDisabled(!$can_edit) - ->setName(pht('Add New URI'))); - - $action_list->addAction( - id(new PhabricatorActionView()) - ->setIcon('fa-book') - ->setHref($doc_href) - ->setName(pht('URI Documentation'))); - - return $this->getNewCurtainView($action_list); - } - public function buildManagementPanelContent() { $repository = $this->getRepository(); $viewer = $this->getViewer(); @@ -151,10 +122,30 @@ final class DiffusionRepositoryURIsManagementPanel ->setSeverity(PHUIInfoView::SEVERITY_NOTICE) ->setErrors($messages); - $box = $this->newBox(pht('Repository URIs'), null); - $box->setTable($table); + $can_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $repository, + PhabricatorPolicyCapability::CAN_EDIT); - return array($info_view, $box); + $doc_href = PhabricatorEnv::getDoclink('Diffusion User Guide: URIs'); + $add_href = $repository->getPathURI('uri/edit/'); + + $add = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-plus') + ->setHref($add_href) + ->setDisabled(!$can_edit) + ->setText(pht('New URI')); + + $help = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-book') + ->setHref($doc_href) + ->setText(pht('Help')); + + $box = $this->newBox(pht('Repository URIs'), $table, array($add, $help)); + + return array($box, $info_view); } } diff --git a/src/applications/diffusion/panel/DiffusionSetPasswordSettingsPanel.php b/src/applications/diffusion/panel/DiffusionSetPasswordSettingsPanel.php index a41f322a3d..ccfa0df4a4 100644 --- a/src/applications/diffusion/panel/DiffusionSetPasswordSettingsPanel.php +++ b/src/applications/diffusion/panel/DiffusionSetPasswordSettingsPanel.php @@ -233,7 +233,7 @@ final class DiffusionSetPasswordSettingsPanel extends PhabricatorSettingsPanel { $object_box = id(new PHUIObjectBoxView()) ->setHeaderText($title) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setForm($form) ->setFormErrors($errors); @@ -259,7 +259,7 @@ final class DiffusionSetPasswordSettingsPanel extends PhabricatorSettingsPanel { $remove_box = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Remove VCS Password')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setForm($remove_form); $saved = null; diff --git a/src/applications/drydock/controller/DrydockBlueprintEditController.php b/src/applications/drydock/controller/DrydockBlueprintEditController.php index f25dc01bff..8f066c708b 100644 --- a/src/applications/drydock/controller/DrydockBlueprintEditController.php +++ b/src/applications/drydock/controller/DrydockBlueprintEditController.php @@ -74,6 +74,7 @@ final class DrydockBlueprintEditController extends DrydockBlueprintController { $title = pht('Create New Blueprint'); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('New Blueprint')); + $crumbs->setBorder(true); $form = id(new AphrontFormView()) ->setUser($viewer) @@ -86,12 +87,16 @@ final class DrydockBlueprintEditController extends DrydockBlueprintController { $box = id(new PHUIObjectBoxView()) ->setFormErrors($errors) ->setHeaderText($title) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setForm($form); + $view = id(new PHUITwoColumnView()) + ->setFooter($box); + return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->appendChild($box); + ->appendChild($view); } } diff --git a/src/applications/drydock/controller/DrydockConsoleController.php b/src/applications/drydock/controller/DrydockConsoleController.php index ac524cb8a5..54adcf5ca5 100644 --- a/src/applications/drydock/controller/DrydockConsoleController.php +++ b/src/applications/drydock/controller/DrydockConsoleController.php @@ -26,7 +26,8 @@ final class DrydockConsoleController extends DrydockController { $viewer = $request->getViewer(); $menu = id(new PHUIObjectItemListView()) - ->setUser($viewer); + ->setUser($viewer) + ->setBig(true); $menu->addItem( id(new PHUIObjectItemView()) @@ -64,17 +65,15 @@ final class DrydockConsoleController extends DrydockController { $crumbs->addTextCrumb(pht('Console')); $crumbs->setBorder(true); - $box = id(new PHUIObjectBoxView()) - ->setObjectList($menu); - $title = pht('Drydock Console'); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-truck'); + $box = id(new PHUIObjectBoxView()) + ->setHeaderText($title) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) + ->setObjectList($menu); $view = id(new PHUITwoColumnView()) - ->setHeader($header) + ->setFixed(true) ->setFooter($box); return $this->newPage() diff --git a/src/applications/files/controller/PhabricatorFileUploadController.php b/src/applications/files/controller/PhabricatorFileUploadController.php index 3be0ca3968..c06e0e6d89 100644 --- a/src/applications/files/controller/PhabricatorFileUploadController.php +++ b/src/applications/files/controller/PhabricatorFileUploadController.php @@ -90,17 +90,12 @@ final class PhabricatorFileUploadController extends PhabricatorFileController { ->setShowIfSupportedID($support_id); $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('File')) + ->setHeaderText($title) ->setFormErrors($errors) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setForm($form); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-upload'); - $view = id(new PHUITwoColumnView()) - ->setHeader($header) ->setFooter(array( $form_box, $global_upload, diff --git a/src/applications/fund/query/FundInitiativeQuery.php b/src/applications/fund/query/FundInitiativeQuery.php index 66f87a883c..bbb4ef2746 100644 --- a/src/applications/fund/query/FundInitiativeQuery.php +++ b/src/applications/fund/query/FundInitiativeQuery.php @@ -8,8 +8,6 @@ final class FundInitiativeQuery private $ownerPHIDs; private $statuses; - private $needProjectPHIDs; - public function withIDs(array $ids) { $this->ids = $ids; return $this; @@ -30,87 +28,54 @@ final class FundInitiativeQuery return $this; } - public function needProjectPHIDs($need) { - $this->needProjectPHIDs = $need; - return $this; + public function newResultObject() { + return new FundInitiative(); } protected function loadPage() { - $table = new FundInitiative(); - $conn_r = $table->establishConnection('r'); - - $rows = 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($rows); + return $this->loadStandardPage($this->newResultObject()); } - protected function didFilterPage(array $initiatives) { - - if ($this->needProjectPHIDs) { - $edge_query = id(new PhabricatorEdgeQuery()) - ->withSourcePHIDs(mpull($initiatives, 'getPHID')) - ->withEdgeTypes( - array( - PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, - )); - $edge_query->execute(); - - foreach ($initiatives as $initiative) { - $phids = $edge_query->getDestinationPHIDs( - array( - $initiative->getPHID(), - )); - $initiative->attachProjectPHIDs($phids); - } - } - - return $initiatives; - } - - protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { - $where = array(); - - $where[] = $this->buildPagingClause($conn_r); + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { + $where = parent::buildWhereClauseParts($conn); if ($this->ids !== null) { $where[] = qsprintf( - $conn_r, - 'id IN (%Ld)', + $conn, + 'i.id IN (%Ld)', $this->ids); } if ($this->phids !== null) { $where[] = qsprintf( - $conn_r, - 'phid IN (%Ls)', + $conn, + 'i.phid IN (%Ls)', $this->phids); } if ($this->ownerPHIDs !== null) { $where[] = qsprintf( - $conn_r, - 'ownerPHID IN (%Ls)', + $conn, + 'i.ownerPHID IN (%Ls)', $this->ownerPHIDs); } if ($this->statuses !== null) { $where[] = qsprintf( - $conn_r, - 'status IN (%Ls)', + $conn, + 'i.status IN (%Ls)', $this->statuses); } - return $this->formatWhereClause($where); + return $where; } public function getQueryApplicationClass() { return 'PhabricatorFundApplication'; } + protected function getPrimaryTableAlias() { + return 'i'; + } + } diff --git a/src/applications/fund/query/FundInitiativeSearchEngine.php b/src/applications/fund/query/FundInitiativeSearchEngine.php index 3c339c1a64..e075fe5063 100644 --- a/src/applications/fund/query/FundInitiativeSearchEngine.php +++ b/src/applications/fund/query/FundInitiativeSearchEngine.php @@ -11,67 +11,37 @@ final class FundInitiativeSearchEngine return 'PhabricatorFundApplication'; } - public function buildSavedQueryFromRequest(AphrontRequest $request) { - $saved = new PhabricatorSavedQuery(); - - $saved->setParameter( - 'ownerPHIDs', - $this->readUsersFromRequest($request, 'owners')); - - $saved->setParameter( - 'statuses', - $this->readListFromRequest($request, 'statuses')); - - return $saved; + public function newQuery() { + return new FundInitiativeQuery(); } - public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { - $query = id(new FundInitiativeQuery()) - ->needProjectPHIDs(true); + protected function buildCustomSearchFields() { + return array( + id(new PhabricatorUsersSearchField()) + ->setKey('ownerPHIDs') + ->setAliases(array('owner', 'ownerPHID', 'owners')) + ->setLabel(pht('Owners')), + id(new PhabricatorSearchCheckboxesField()) + ->setKey('statuses') + ->setLabel(pht('Statuses')) + ->setOptions(FundInitiative::getStatusNameMap()), + ); + } - $owner_phids = $saved->getParameter('ownerPHIDs'); - if ($owner_phids) { - $query->withOwnerPHIDs($owner_phids); + protected function buildQueryFromParameters(array $map) { + $query = $this->newQuery(); + + if ($map['ownerPHIDs']) { + $query->withOwnerPHIDs($map['ownerPHIDs']); } - $statuses = $saved->getParameter('statuses'); - if ($statuses) { - $query->withStatuses($statuses); + if ($map['statuses']) { + $query->withStatuses($map['statuses']); } return $query; } - public function buildSearchForm( - AphrontFormView $form, - PhabricatorSavedQuery $saved) { - - $statuses = $saved->getParameter('statuses', array()); - $statuses = array_fuse($statuses); - - $owner_phids = $saved->getParameter('ownerPHIDs', array()); - - $status_map = FundInitiative::getStatusNameMap(); - $status_control = id(new AphrontFormCheckboxControl()) - ->setLabel(pht('Statuses')); - foreach ($status_map as $status => $name) { - $status_control->addCheckbox( - 'statuses[]', - $status, - $name, - isset($statuses[$status])); - } - - $form - ->appendControl( - id(new AphrontFormTokenizerControl()) - ->setLabel(pht('Owners')) - ->setName('owners') - ->setDatasource(new PhabricatorPeopleDatasource()) - ->setValue($owner_phids)) - ->appendChild($status_control); - } - protected function getURI($path) { return '/fund/'.$path; } @@ -112,21 +82,6 @@ final class FundInitiativeSearchEngine return parent::buildSavedQueryFromBuiltin($query_key); } - protected function getRequiredHandlePHIDsForResultList( - array $initiatives, - PhabricatorSavedQuery $query) { - - $phids = array(); - foreach ($initiatives as $initiative) { - $phids[] = $initiative->getOwnerPHID(); - foreach ($initiative->getProjectPHIDs() as $project_phid) { - $phids[] = $project_phid; - } - } - - return $phids; - } - protected function renderResultList( array $initiatives, PhabricatorSavedQuery $query, @@ -135,7 +90,30 @@ final class FundInitiativeSearchEngine $viewer = $this->requireViewer(); - $list = id(new PHUIObjectItemListView()); + $load_phids = array(); + foreach ($initiatives as $initiative) { + $load_phids[] = $initiative->getOwnerPHID(); + } + + if ($initiatives) { + $edge_query = id(new PhabricatorEdgeQuery()) + ->withSourcePHIDs(mpull($initiatives, 'getPHID')) + ->withEdgeTypes( + array( + PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, + )); + + $edge_query->execute(); + + foreach ($edge_query->getDestinationPHIDs() as $phid) { + $load_phids[] = $phid; + } + } + + $handles = $viewer->loadHandles($load_phids); + $handles = iterator_to_array($handles); + + $list = new PHUIObjectItemListView(); foreach ($initiatives as $initiative) { $owner_handle = $handles[$initiative->getOwnerPHID()]; @@ -149,9 +127,12 @@ final class FundInitiativeSearchEngine $item->setDisabled(true); } - $project_handles = array_select_keys( - $handles, - $initiative->getProjectPHIDs()); + $project_phids = $edge_query->getDestinationPHIDs( + array( + $initiative->getPHID(), + )); + + $project_handles = array_select_keys($handles, $project_phids); if ($project_handles) { $item->addAttribute( id(new PHUIHandleTagListView()) @@ -168,9 +149,6 @@ final class FundInitiativeSearchEngine $result->setNoDataString(pht('No initiatives found.')); return $result; - - - return $list; } } diff --git a/src/applications/fund/search/FundInitiativeFerretEngine.php b/src/applications/fund/search/FundInitiativeFerretEngine.php new file mode 100644 index 0000000000..785b40b06f --- /dev/null +++ b/src/applications/fund/search/FundInitiativeFerretEngine.php @@ -0,0 +1,18 @@ +addCancelButton($cancel_uri, $cancel_text)); $form_box = id(new PHUIObjectBoxView()) + ->setHeaderText($title) ->setFormErrors($errors) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setForm($form); $crumbs = $this @@ -203,12 +204,7 @@ final class HeraldNewController extends HeraldController { ->addTextCrumb(pht('Create Rule')) ->setBorder(true); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-plus-square'); - $view = id(new PHUITwoColumnView()) - ->setHeader($header) ->setFooter($form_box); return $this->newPage() diff --git a/src/applications/herald/controller/HeraldRuleController.php b/src/applications/herald/controller/HeraldRuleController.php index 0e7f6b0aa5..eaf352a0a7 100644 --- a/src/applications/herald/controller/HeraldRuleController.php +++ b/src/applications/herald/controller/HeraldRuleController.php @@ -238,9 +238,9 @@ final class HeraldRuleController extends HeraldController { ? pht('Edit Herald Rule: %s', $rule->getName()) : pht('Create Herald Rule: %s', idx($content_type_map, $content_type)); - $icon = $rule->getID() ? 'fa-pencil' : 'fa-plus-square'; - $form_box = id(new PHUIObjectBoxView()) + ->setHeaderText($title) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setFormErrors($errors) ->setForm($form); @@ -249,12 +249,7 @@ final class HeraldRuleController extends HeraldController { ->addTextCrumb($title) ->setBorder(true); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-plus-square'); - $view = id(new PHUITwoColumnView()) - ->setHeader($header) ->setFooter($form_box); return $this->newPage() diff --git a/src/applications/home/engine/PhabricatorHomeProfileMenuEngine.php b/src/applications/home/engine/PhabricatorHomeProfileMenuEngine.php index cbfe62aaa6..e380af2b6a 100644 --- a/src/applications/home/engine/PhabricatorHomeProfileMenuEngine.php +++ b/src/applications/home/engine/PhabricatorHomeProfileMenuEngine.php @@ -49,7 +49,7 @@ final class PhabricatorHomeProfileMenuEngine $items[] = $this->newItem() ->setBuiltinKey(PhabricatorHomeConstants::ITEM_APPS_LABEL) ->setMenuItemKey(PhabricatorLabelProfileMenuItem::MENUITEMKEY) - ->setMenuItemProperties(array('name' => pht('Applications'))); + ->setMenuItemProperties(array('name' => pht('Favorites'))); foreach ($applications as $application) { if (!$application->isPinnedByDefault($viewer)) { diff --git a/src/applications/maniphest/application/PhabricatorManiphestApplication.php b/src/applications/maniphest/application/PhabricatorManiphestApplication.php index 6cb9626d5a..3076354599 100644 --- a/src/applications/maniphest/application/PhabricatorManiphestApplication.php +++ b/src/applications/maniphest/application/PhabricatorManiphestApplication.php @@ -6,6 +6,10 @@ final class PhabricatorManiphestApplication extends PhabricatorApplication { return pht('Maniphest'); } + public function getMenuName() { + return pht('Tasks'); + } + public function getShortDescription() { return pht('Tasks and Bugs'); } diff --git a/src/applications/maniphest/query/ManiphestTaskQuery.php b/src/applications/maniphest/query/ManiphestTaskQuery.php index 704a67f548..f009e5c2ef 100644 --- a/src/applications/maniphest/query/ManiphestTaskQuery.php +++ b/src/applications/maniphest/query/ManiphestTaskQuery.php @@ -247,6 +247,7 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery { break; } + $data = $this->didLoadRawRows($data); $tasks = $task_dao->loadAllFromArray($data); switch ($this->groupBy) { diff --git a/src/applications/maniphest/query/ManiphestTaskSearchEngine.php b/src/applications/maniphest/query/ManiphestTaskSearchEngine.php index 0e3e0db69f..150ec81def 100644 --- a/src/applications/maniphest/query/ManiphestTaskSearchEngine.php +++ b/src/applications/maniphest/query/ManiphestTaskSearchEngine.php @@ -49,8 +49,6 @@ final class ManiphestTaskSearchEngine $subtype_map = id(new ManiphestTask())->newEditEngineSubtypeMap(); $hide_subtypes = (count($subtype_map) == 1); - $hide_ferret = !PhabricatorEnv::getEnvConfig('phabricator.show-prototypes'); - return array( id(new PhabricatorOwnersSearchField()) ->setLabel(pht('Assigned To')) @@ -91,10 +89,6 @@ final class ManiphestTaskSearchEngine id(new PhabricatorSearchTextField()) ->setLabel(pht('Contains Words')) ->setKey('fulltext'), - id(new PhabricatorSearchTextField()) - ->setLabel(pht('Query (Prototype)')) - ->setKey('query') - ->setIsHidden($hide_ferret), id(new PhabricatorSearchThreeStateField()) ->setLabel(pht('Open Parents')) ->setKey('hasParents') @@ -150,7 +144,6 @@ final class ManiphestTaskSearchEngine 'statuses', 'priorities', 'subtypes', - 'query', 'fulltext', 'hasParents', 'hasSubtasks', @@ -231,27 +224,6 @@ final class ManiphestTaskSearchEngine $query->withFullTextSearch($map['fulltext']); } - if (strlen($map['query'])) { - $raw_query = $map['query']; - - $compiler = id(new PhutilSearchQueryCompiler()) - ->setEnableFunctions(true); - - $raw_tokens = $compiler->newTokens($raw_query); - - $fulltext_tokens = array(); - foreach ($raw_tokens as $raw_token) { - $fulltext_token = id(new PhabricatorFulltextToken()) - ->setToken($raw_token); - - $fulltext_tokens[] = $fulltext_token; - } - - $query->withFerretConstraint( - id(new ManiphestTask())->newFerretEngine(), - $fulltext_tokens); - } - if ($map['parentIDs']) { $query->withParentTaskIDs($map['parentIDs']); } diff --git a/src/applications/maniphest/search/ManiphestTaskFerretEngine.php b/src/applications/maniphest/search/ManiphestTaskFerretEngine.php index 7232d0251f..45b90471ea 100644 --- a/src/applications/maniphest/search/ManiphestTaskFerretEngine.php +++ b/src/applications/maniphest/search/ManiphestTaskFerretEngine.php @@ -3,16 +3,25 @@ final class ManiphestTaskFerretEngine extends PhabricatorFerretEngine { - public function newNgramsObject() { - return new ManiphestTaskFerretNgrams(); + public function getApplicationName() { + return 'maniphest'; } - public function newDocumentObject() { - return new ManiphestTaskFerretDocument(); + public function getScopeName() { + return 'task'; } - public function newFieldObject() { - return new ManiphestTaskFerretField(); + public function newSearchEngine() { + return new ManiphestTaskSearchEngine(); + } + + protected function getFunctionMap() { + $map = parent::getFunctionMap(); + + $map['body']['aliases'][] = 'desc'; + $map['body']['aliases'][] = 'description'; + + return $map; } } diff --git a/src/applications/maniphest/storage/ManiphestTaskFerretDocument.php b/src/applications/maniphest/storage/ManiphestTaskFerretDocument.php deleted file mode 100644 index 240523a85a..0000000000 --- a/src/applications/maniphest/storage/ManiphestTaskFerretDocument.php +++ /dev/null @@ -1,14 +0,0 @@ -setHeader($header) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) + ->appendChild($table); return $panel; } diff --git a/src/applications/owners/search/PhabricatorOwnersPackageFerretEngine.php b/src/applications/owners/search/PhabricatorOwnersPackageFerretEngine.php new file mode 100644 index 0000000000..684fe10969 --- /dev/null +++ b/src/applications/owners/search/PhabricatorOwnersPackageFerretEngine.php @@ -0,0 +1,18 @@ +setBorder(true); $box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Credential')) + ->setHeaderText($title) ->setFormErrors($errors) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setForm($form); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-plus-square'); - $view = id(new PHUITwoColumnView()) - ->setHeader($header) ->setFooter($box); return $this->newPage() diff --git a/src/applications/passphrase/controller/PassphraseCredentialEditController.php b/src/applications/passphrase/controller/PassphraseCredentialEditController.php index a35bd3479e..91c8d93883 100644 --- a/src/applications/passphrase/controller/PassphraseCredentialEditController.php +++ b/src/applications/passphrase/controller/PassphraseCredentialEditController.php @@ -249,10 +249,6 @@ final class PassphraseCredentialEditController extends PassphraseController { ->setName('description') ->setLabel(pht('Description')) ->setValue($v_desc)) - ->appendChild( - id(new AphrontFormMarkupControl()) - ->setLabel(pht('Credential Type')) - ->setValue($type->getCredentialTypeName())) ->appendChild( id(new AphrontFormDividerControl())) ->appendControl( @@ -322,10 +318,9 @@ final class PassphraseCredentialEditController extends PassphraseController { $crumbs->setBorder(true); if ($is_new) { - $title = pht('Create New Credential'); + $title = pht('New Credential: %s', $type->getCredentialTypeName()); $crumbs->addTextCrumb(pht('Create')); $cancel_uri = $this->getApplicationURI(); - $header_icon = 'fa-plus-square'; } else { $title = pht('Edit Credential: %s', $credential->getName()); $crumbs->addTextCrumb( @@ -333,7 +328,6 @@ final class PassphraseCredentialEditController extends PassphraseController { '/K'.$credential->getID()); $crumbs->addTextCrumb(pht('Edit')); $cancel_uri = '/K'.$credential->getID(); - $header_icon = 'fa-pencil'; } if ($request->isAjax()) { @@ -356,18 +350,13 @@ final class PassphraseCredentialEditController extends PassphraseController { ->addCancelButton($cancel_uri)); $box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Credential')) + ->setHeaderText($title) ->setFormErrors($errors) ->setValidationException($validation_exception) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setForm($form); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon($header_icon); - $view = id(new PHUITwoColumnView()) - ->setHeader($header) ->setFooter(array( $box, )); diff --git a/src/applications/passphrase/query/PassphraseCredentialQuery.php b/src/applications/passphrase/query/PassphraseCredentialQuery.php index 3a78ac0d13..2518ad44e5 100644 --- a/src/applications/passphrase/query/PassphraseCredentialQuery.php +++ b/src/applications/passphrase/query/PassphraseCredentialQuery.php @@ -109,49 +109,49 @@ final class PassphraseCredentialQuery if ($this->ids !== null) { $where[] = qsprintf( $conn, - 'id IN (%Ld)', + 'c.id IN (%Ld)', $this->ids); } if ($this->phids !== null) { $where[] = qsprintf( $conn, - 'phid IN (%Ls)', + 'c.phid IN (%Ls)', $this->phids); } if ($this->credentialTypes !== null) { $where[] = qsprintf( $conn, - 'credentialType in (%Ls)', + 'c.credentialType in (%Ls)', $this->credentialTypes); } if ($this->providesTypes !== null) { $where[] = qsprintf( $conn, - 'providesType IN (%Ls)', + 'c.providesType IN (%Ls)', $this->providesTypes); } if ($this->isDestroyed !== null) { $where[] = qsprintf( $conn, - 'isDestroyed = %d', + 'c.isDestroyed = %d', (int)$this->isDestroyed); } if ($this->allowConduit !== null) { $where[] = qsprintf( $conn, - 'allowConduit = %d', + 'c.allowConduit = %d', (int)$this->allowConduit); } if (strlen($this->nameContains)) { $where[] = qsprintf( $conn, - 'LOWER(name) LIKE %~', + 'LOWER(c.name) LIKE %~', phutil_utf8_strtolower($this->nameContains)); } @@ -162,4 +162,8 @@ final class PassphraseCredentialQuery return 'PhabricatorPassphraseApplication'; } + protected function getPrimaryTableAlias() { + return 'c'; + } + } diff --git a/src/applications/passphrase/search/PassphraseCredentialFerretEngine.php b/src/applications/passphrase/search/PassphraseCredentialFerretEngine.php new file mode 100644 index 0000000000..cb9aa99abb --- /dev/null +++ b/src/applications/passphrase/search/PassphraseCredentialFerretEngine.php @@ -0,0 +1,18 @@ +addTextCrumb($title); $crumbs->setBorder(true); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-user'); - $box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('User')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setHeaderText($title) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setForm($form); $guidance_context = new PhabricatorPeopleCreateGuidanceContext(); @@ -109,7 +105,6 @@ final class PhabricatorPeopleCreateController ->newInfoView(); $view = id(new PHUITwoColumnView()) - ->setHeader($header) ->setFooter( array( $guidance, diff --git a/src/applications/people/controller/PhabricatorPeopleNewController.php b/src/applications/people/controller/PhabricatorPeopleNewController.php index 60f9f47b5d..9f52cf567a 100644 --- a/src/applications/people/controller/PhabricatorPeopleNewController.php +++ b/src/applications/people/controller/PhabricatorPeopleNewController.php @@ -132,12 +132,15 @@ final class PhabricatorPeopleNewController ->setUser($admin); if ($is_bot) { + $title = pht('Create New Bot'); $form->appendRemarkupInstructions( pht('You are creating a new **bot** user account.')); } else if ($is_list) { + $title = pht('Create New Mailing List'); $form->appendRemarkupInstructions( pht('You are creating a new **mailing list** user account.')); } else { + $title = pht('Create New User'); $form->appendRemarkupInstructions( pht('You are creating a new **standard** user account.')); } @@ -205,25 +208,17 @@ final class PhabricatorPeopleNewController "`bot@yourcompany.com` if you prefer.")); } - - $title = pht('Create New User'); - $box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('User')) + ->setHeaderText($title) ->setFormErrors($errors) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setForm($form); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($title); $crumbs->setBorder(true); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-user'); - $view = id(new PHUITwoColumnView()) - ->setHeader($header) ->setFooter($box); return $this->newPage() diff --git a/src/applications/people/search/PhabricatorUserFerretEngine.php b/src/applications/people/search/PhabricatorUserFerretEngine.php new file mode 100644 index 0000000000..c29d4001db --- /dev/null +++ b/src/applications/people/search/PhabricatorUserFerretEngine.php @@ -0,0 +1,25 @@ +statuses !== null) { $where[] = qsprintf( $conn, - 'status IN (%Ls)', + 'b.status IN (%Ls)', $this->statuses); } if ($this->ids !== null) { $where[] = qsprintf( $conn, - 'id IN (%Ls)', + 'b.id IN (%Ls)', $this->ids); } if ($this->phids !== null) { $where[] = qsprintf( $conn, - 'phid IN (%Ls)', + 'b.phid IN (%Ls)', $this->phids); } if ($this->domain !== null) { $where[] = qsprintf( $conn, - 'domain = %s', + 'b.domain = %s', $this->domain); } @@ -143,4 +143,8 @@ final class PhameBlogQuery extends PhabricatorCursorPagedPolicyAwareQuery { return null; } + protected function getPrimaryTableAlias() { + return 'b'; + } + } diff --git a/src/applications/phame/query/PhamePostQuery.php b/src/applications/phame/query/PhamePostQuery.php index 357418cfb3..85ef470cea 100644 --- a/src/applications/phame/query/PhamePostQuery.php +++ b/src/applications/phame/query/PhamePostQuery.php @@ -106,45 +106,45 @@ final class PhamePostQuery extends PhabricatorCursorPagedPolicyAwareQuery { protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { $where = parent::buildWhereClauseParts($conn); - if ($this->ids) { + if ($this->ids !== null) { $where[] = qsprintf( $conn, - 'id IN (%Ld)', + 'p.id IN (%Ld)', $this->ids); } - if ($this->phids) { + if ($this->phids !== null) { $where[] = qsprintf( $conn, - 'phid IN (%Ls)', + 'p.phid IN (%Ls)', $this->phids); } - if ($this->bloggerPHIDs) { + if ($this->bloggerPHIDs !== null) { $where[] = qsprintf( $conn, - 'bloggerPHID IN (%Ls)', + 'p.bloggerPHID IN (%Ls)', $this->bloggerPHIDs); } - if ($this->visibility) { + if ($this->visibility !== null) { $where[] = qsprintf( $conn, - 'visibility IN (%Ld)', + 'p.visibility IN (%Ld)', $this->visibility); } if ($this->publishedAfter !== null) { $where[] = qsprintf( $conn, - 'datePublished > %d', + 'p.datePublished > %d', $this->publishedAfter); } if ($this->blogPHIDs !== null) { $where[] = qsprintf( $conn, - 'blogPHID in (%Ls)', + 'p.blogPHID in (%Ls)', $this->blogPHIDs); } @@ -163,6 +163,7 @@ final class PhamePostQuery extends PhabricatorCursorPagedPolicyAwareQuery { public function getOrderableColumns() { return parent::getOrderableColumns() + array( 'datePublished' => array( + 'table' => $this->getPrimaryTableAlias(), 'column' => 'datePublished', 'type' => 'int', 'reverse' => false, @@ -186,4 +187,8 @@ final class PhamePostQuery extends PhabricatorCursorPagedPolicyAwareQuery { return null; } + protected function getPrimaryTableAlias() { + return 'p'; + } + } diff --git a/src/applications/phame/search/PhameBlogFerretEngine.php b/src/applications/phame/search/PhameBlogFerretEngine.php new file mode 100644 index 0000000000..76901f915c --- /dev/null +++ b/src/applications/phame/search/PhameBlogFerretEngine.php @@ -0,0 +1,18 @@ +addTextCrumb($title, $request->getRequestURI()); - $header_icon = 'fa-plus-square'; } else { $title = pht('Edit Variable: %s', $key); - $header_icon = 'fa-pencil'; $crumbs->addTextCrumb($title, $request->getRequestURI()); } $crumbs->setBorder(true); $box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Variable')) + ->setHeaderText($title) ->setFormErrors($errors) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setForm($form); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon($header_icon); - $view = id(new PHUITwoColumnView()) - ->setHeader($header) ->setFooter(array( $box, )); diff --git a/src/applications/pholio/application/PhabricatorPholioApplication.php b/src/applications/pholio/application/PhabricatorPholioApplication.php index 4d80dd12ae..4afaeba263 100644 --- a/src/applications/pholio/application/PhabricatorPholioApplication.php +++ b/src/applications/pholio/application/PhabricatorPholioApplication.php @@ -6,6 +6,10 @@ final class PhabricatorPholioApplication extends PhabricatorApplication { return pht('Pholio'); } + public function getMenuName() { + return pht('Design Review'); + } + public function getBaseURI() { return '/pholio/'; } diff --git a/src/applications/pholio/controller/PholioMockEditController.php b/src/applications/pholio/controller/PholioMockEditController.php index 2d477c70aa..89d1fe2a50 100644 --- a/src/applications/pholio/controller/PholioMockEditController.php +++ b/src/applications/pholio/controller/PholioMockEditController.php @@ -23,7 +23,6 @@ final class PholioMockEditController extends PholioController { } $title = pht('Edit Mock: %s', $mock->getName()); - $header_icon = 'fa-pencil'; $is_new = false; $mock_images = $mock->getImages(); @@ -33,7 +32,6 @@ final class PholioMockEditController extends PholioController { $mock = PholioMock::initializeNewMock($viewer); $title = pht('Create Mock'); - $header_icon = 'fa-plus-square'; $is_new = true; $files = array(); @@ -347,9 +345,9 @@ final class PholioMockEditController extends PholioController { ->appendChild($submit); $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Mock')) + ->setHeaderText($title) ->setFormErrors($errors) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setForm($form); $crumbs = $this->buildApplicationCrumbs(); @@ -359,12 +357,7 @@ final class PholioMockEditController extends PholioController { $crumbs->addTextCrumb($title); $crumbs->setBorder(true); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon($header_icon); - $view = id(new PHUITwoColumnView()) - ->setHeader($header) ->setFooter($form_box); return $this->newPage() diff --git a/src/applications/pholio/search/PholioMockFerretEngine.php b/src/applications/pholio/search/PholioMockFerretEngine.php new file mode 100644 index 0000000000..f4f9b4610f --- /dev/null +++ b/src/applications/pholio/search/PholioMockFerretEngine.php @@ -0,0 +1,18 @@ +getID()) { - $panel_header = pht('Edit Document: %s', $content->getTitle()); - $page_title = pht('Edit Document'); - $header_icon = 'fa-pencil'; + $page_title = pht('Edit Document: %s', $content->getTitle()); if ($overwrite) { $submit_button = pht('Overwrite Changes'); } else { $submit_button = pht('Save Changes'); } } else { - $panel_header = pht('Create New Phriction Document'); $submit_button = pht('Create Document'); $page_title = pht('Create Document'); - $header_icon = 'fa-plus-square'; } $uri = $document->getSlug(); @@ -289,9 +285,9 @@ final class PhrictionEditController ->setValue($submit_button)); $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Document')) + ->setHeaderText($page_title) ->setValidationException($validation_exception) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setForm($form); $preview = id(new PHUIRemarkupPreviewPanel()) @@ -311,12 +307,7 @@ final class PhrictionEditController } $crumbs->setBorder(true); - $header = id(new PHUIHeaderView()) - ->setHeader($panel_header) - ->setHeaderIcon($header_icon); - $view = id(new PHUITwoColumnView()) - ->setHeader($header) ->setFooter(array( $draft_note, $form_box, diff --git a/src/applications/phriction/search/PhrictionDocumentFerretEngine.php b/src/applications/phriction/search/PhrictionDocumentFerretEngine.php new file mode 100644 index 0000000000..76802391e7 --- /dev/null +++ b/src/applications/phriction/search/PhrictionDocumentFerretEngine.php @@ -0,0 +1,18 @@ + array( + 'name' => pht('Only Match Other Constraints'), + 'summary' => pht( + 'Find results with only the specified tags.'), + 'description' => pht( + "This function is used with other tags, and causes the query to ". + "match only results with exactly those tags. For example, to find ". + "tasks tagged only iOS:". + "\n\n". + "> ios, only()". + "\n\n". + "This will omit results with any other project tag."), + ), + ); + } + + public function loadResults() { + $results = array( + $this->renderOnlyFunctionToken(), + ); + return $this->filterResultsAgainstTokens($results); + } + + protected function evaluateFunction($function, array $argv_list) { + $results = array(); + + $results[] = new PhabricatorQueryConstraint( + PhabricatorQueryConstraint::OPERATOR_ONLY, + null); + + return $results; + } + + public function renderFunctionTokens( + $function, + array $argv_list) { + + $tokens = array(); + foreach ($argv_list as $argv) { + $tokens[] = PhabricatorTypeaheadTokenView::newFromTypeaheadResult( + $this->renderOnlyFunctionToken()); + } + + return $tokens; + } + + private function renderOnlyFunctionToken() { + return $this->newFunctionResult() + ->setName(pht('Only')) + ->setPHID('only()') + ->setIcon('fa-asterisk') + ->setUnique(true) + ->addAttribute( + pht('Select only results with exactly the other specified tags.')); + } + +} diff --git a/src/applications/project/typeahead/PhabricatorProjectLogicalViewerDatasource.php b/src/applications/project/typeahead/PhabricatorProjectLogicalViewerDatasource.php index 9bb15ed180..807986457a 100644 --- a/src/applications/project/typeahead/PhabricatorProjectLogicalViewerDatasource.php +++ b/src/applications/project/typeahead/PhabricatorProjectLogicalViewerDatasource.php @@ -29,7 +29,7 @@ final class PhabricatorProjectLogicalViewerDatasource "\n\n". "This normally means //your// projects, but if you save a query ". "using this function and send it to someone else, it will mean ". - "//their// projects when they run it (they become the currnet ". + "//their// projects when they run it (they become the current ". "viewer). This can be useful for building dashboard panels."), ), ); diff --git a/src/applications/repository/search/DiffusionCommitFerretEngine.php b/src/applications/repository/search/DiffusionCommitFerretEngine.php new file mode 100644 index 0000000000..a6c5ce42c8 --- /dev/null +++ b/src/applications/repository/search/DiffusionCommitFerretEngine.php @@ -0,0 +1,18 @@ +getPHID(); $engine = $object->newFerretEngine(); - $ferret_document = $engine->newDocumentObject() - ->setObjectPHID($phid) - ->setIsClosed(0) - ->setEpochCreated(0) - ->setEpochModified(0); + $is_closed = 0; + $author_phid = null; + $owner_phid = null; + foreach ($document->getRelationshipData() as $relationship) { + list($related_type, $related_phid) = $relationship; + switch ($related_type) { + case PhabricatorSearchRelationship::RELATIONSHIP_OPEN: + $is_closed = 0; + break; + case PhabricatorSearchRelationship::RELATIONSHIP_CLOSED: + $is_closed = 1; + break; + case PhabricatorSearchRelationship::RELATIONSHIP_OWNER: + $owner_phid = $related_phid; + break; + case PhabricatorSearchRelationship::RELATIONSHIP_UNOWNED: + $owner_phid = null; + break; + case PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR: + $author_phid = $related_phid; + break; + } + } - $stemmer = new PhutilSearchStemmer(); - $ngram_engine = id(new PhabricatorNgramEngine()); + $stemmer = $engine->newStemmer(); // Copy all of the "title" and "body" fields to create new "core" fields. // This allows users to search "in title or body" with the "core:" prefix. @@ -49,9 +66,12 @@ final class PhabricatorFerretFulltextEngineExtension ); break; } - } - $key_all = PhabricatorSearchDocumentFieldType::FIELD_ALL; + $virtual_fields[] = array( + PhabricatorSearchDocumentFieldType::FIELD_ALL, + $raw_corpus, + ); + } $empty_template = array( 'raw' => array(), @@ -59,9 +79,7 @@ final class PhabricatorFerretFulltextEngineExtension 'normal' => array(), ); - $ferret_corpus_map = array( - $key_all => $empty_template, - ); + $ferret_corpus_map = array(); foreach ($virtual_fields as $field) { list($key, $raw_corpus) = $field; @@ -69,10 +87,10 @@ final class PhabricatorFerretFulltextEngineExtension continue; } - $term_corpus = $ngram_engine->newTermsCorpus($raw_corpus); + $term_corpus = $engine->newTermsCorpus($raw_corpus); $normal_corpus = $stemmer->stemCorpus($raw_corpus); - $normal_coprus = $ngram_engine->newTermsCorpus($normal_corpus); + $normal_corpus = $engine->newTermsCorpus($normal_corpus); if (!isset($ferret_corpus_map[$key])) { $ferret_corpus_map[$key] = $empty_template; @@ -81,10 +99,6 @@ final class PhabricatorFerretFulltextEngineExtension $ferret_corpus_map[$key]['raw'][] = $raw_corpus; $ferret_corpus_map[$key]['term'][] = $term_corpus; $ferret_corpus_map[$key]['normal'][] = $normal_corpus; - - $ferret_corpus_map[$key_all]['raw'][] = $raw_corpus; - $ferret_corpus_map[$key_all]['term'][] = $term_corpus; - $ferret_corpus_map[$key_all]['normal'][] = $normal_corpus; } $ferret_fields = array(); @@ -92,49 +106,65 @@ final class PhabricatorFerretFulltextEngineExtension foreach ($ferret_corpus_map as $key => $fields) { $raw_corpus = $fields['raw']; $raw_corpus = implode("\n", $raw_corpus); - $ngrams_source[] = $raw_corpus; + if (strlen($raw_corpus)) { + $ngrams_source[] = $raw_corpus; + } $normal_corpus = $fields['normal']; - $normal_corpus = implode(' ', $normal_corpus); + $normal_corpus = implode("\n", $normal_corpus); if (strlen($normal_corpus)) { $ngrams_source[] = $normal_corpus; - $normal_corpus = ' '.$normal_corpus.' '; } $term_corpus = $fields['term']; - $term_corpus = implode(' ', $term_corpus); + $term_corpus = implode("\n", $term_corpus); if (strlen($term_corpus)) { $ngrams_source[] = $term_corpus; - $term_corpus = ' '.$term_corpus.' '; } - $ferret_fields[] = $engine->newFieldObject() - ->setFieldKey($key) - ->setRawCorpus($raw_corpus) - ->setTermCorpus($term_corpus) - ->setNormalCorpus($normal_corpus); + $ferret_fields[] = array( + 'fieldKey' => $key, + 'rawCorpus' => $raw_corpus, + 'termCorpus' => $term_corpus, + 'normalCorpus' => $normal_corpus, + ); } - $ngrams_source = implode(' ', $ngrams_source); + $ngrams_source = implode("\n", $ngrams_source); - $ngrams = $ngram_engine->getNgramsFromString($ngrams_source, 'index'); + $ngrams = $engine->getTermNgramsFromString($ngrams_source); - $ferret_document->openTransaction(); + $object->openTransaction(); try { + $conn = $object->establishConnection('w'); $this->deleteOldDocument($engine, $object, $document); - $ferret_document->save(); + queryfx( + $conn, + 'INSERT INTO %T (objectPHID, isClosed, epochCreated, epochModified, + authorPHID, ownerPHID) VALUES (%s, %d, %d, %d, %ns, %ns)', + $engine->getDocumentTableName(), + $object->getPHID(), + $is_closed, + $document->getDocumentCreated(), + $document->getDocumentModified(), + $author_phid, + $owner_phid); - $document_id = $ferret_document->getID(); + $document_id = $conn->getInsertID(); foreach ($ferret_fields as $ferret_field) { - $ferret_field - ->setDocumentID($document_id) - ->save(); + queryfx( + $conn, + 'INSERT INTO %T (documentID, fieldKey, rawCorpus, termCorpus, + normalCorpus) VALUES (%d, %s, %s, %s, %s)', + $engine->getFieldTableName(), + $document_id, + $ferret_field['fieldKey'], + $ferret_field['rawCorpus'], + $ferret_field['termCorpus'], + $ferret_field['normalCorpus']); } - $ferret_ngrams = $engine->newNgramsObject(); - $conn = $ferret_ngrams->establishConnection('w'); - $sql = array(); foreach ($ngrams as $ngram) { $sql[] = qsprintf( @@ -148,15 +178,15 @@ final class PhabricatorFerretFulltextEngineExtension queryfx( $conn, 'INSERT INTO %T (documentID, ngram) VALUES %Q', - $ferret_ngrams->getTableName(), + $engine->getNgramsTableName(), $chunk); } } catch (Exception $ex) { - $ferret_document->killTransaction(); + $object->killTransaction(); throw $ex; } - $ferret_document->saveTransaction(); + $object->saveTransaction(); } @@ -165,32 +195,35 @@ final class PhabricatorFerretFulltextEngineExtension $object, PhabricatorSearchAbstractDocument $document) { - $old_document = $engine->newDocumentObject()->loadOneWhere( - 'objectPHID = %s', - $document->getPHID()); + $conn = $object->establishConnection('w'); + + $old_document = queryfx_one( + $conn, + 'SELECT * FROM %T WHERE objectPHID = %s', + $engine->getDocumentTableName(), + $object->getPHID()); if (!$old_document) { return; } - $conn = $old_document->establishConnection('w'); - $old_id = $old_document->getID(); + $old_id = $old_document['id']; queryfx( $conn, 'DELETE FROM %T WHERE id = %d', - $engine->newDocumentObject()->getTableName(), + $engine->getDocumentTableName(), $old_id); queryfx( $conn, 'DELETE FROM %T WHERE documentID = %d', - $engine->newFieldObject()->getTableName(), + $engine->getFieldTableName(), $old_id); queryfx( $conn, 'DELETE FROM %T WHERE documentID = %d', - $engine->newNgramsObject()->getTableName(), + $engine->getNgramsTableName(), $old_id); } diff --git a/src/applications/search/engineextension/PhabricatorFerretSearchEngineExtension.php b/src/applications/search/engineextension/PhabricatorFerretSearchEngineExtension.php new file mode 100644 index 0000000000..02aadf7336 --- /dev/null +++ b/src/applications/search/engineextension/PhabricatorFerretSearchEngineExtension.php @@ -0,0 +1,70 @@ +newFerretEngine(); + + $raw_query = $map['query']; + + $compiler = id(new PhutilSearchQueryCompiler()) + ->setEnableFunctions(true); + + $raw_tokens = $compiler->newTokens($raw_query); + + $fulltext_tokens = array(); + foreach ($raw_tokens as $raw_token) { + $fulltext_token = id(new PhabricatorFulltextToken()) + ->setToken($raw_token); + + $fulltext_tokens[] = $fulltext_token; + } + + $query->withFerretConstraint($engine, $fulltext_tokens); + } + + public function getSearchFields($object) { + $fields = array(); + + $fields[] = id(new PhabricatorSearchTextField()) + ->setKey('query') + ->setLabel(pht('Query (Prototype)')) + ->setDescription(pht('Fulltext search.')); + + return $fields; + } + + public function getSearchAttachments($object) { + return array(); + } + + +} diff --git a/src/applications/search/ferret/PhabricatorFerretDocument.php b/src/applications/search/ferret/PhabricatorFerretDocument.php deleted file mode 100644 index fa816c8d17..0000000000 --- a/src/applications/search/ferret/PhabricatorFerretDocument.php +++ /dev/null @@ -1,40 +0,0 @@ - false, - self::CONFIG_COLUMN_SCHEMA => array( - 'isClosed' => 'bool', - 'authorPHID' => 'phid?', - 'ownerPHID' => 'phid?', - 'epochCreated' => 'epoch', - 'epochModified' => 'epoch', - ), - self::CONFIG_KEY_SCHEMA => array( - 'key_object' => array( - 'columns' => array('objectPHID'), - 'unique' => true, - ), - ), - ) + parent::getConfiguration(); - } - - public function getTableName() { - $application = $this->getApplicationName(); - $key = $this->getIndexKey(); - return "{$application}_{$key}_fdocument"; - } - -} diff --git a/src/applications/search/ferret/PhabricatorFerretEngine.php b/src/applications/search/ferret/PhabricatorFerretEngine.php index e816ef3f59..3c8098c54f 100644 --- a/src/applications/search/ferret/PhabricatorFerretEngine.php +++ b/src/applications/search/ferret/PhabricatorFerretEngine.php @@ -2,8 +2,276 @@ abstract class PhabricatorFerretEngine extends Phobject { - abstract public function newNgramsObject(); - abstract public function newDocumentObject(); - abstract public function newFieldObject(); + abstract public function getApplicationName(); + abstract public function getScopeName(); + abstract public function newSearchEngine(); + + public function getDefaultFunctionKey() { + return 'all'; + } + + public function getObjectTypeRelevance() { + return 1000; + } + + public function getFieldForFunction($function) { + $function = phutil_utf8_strtolower($function); + + $map = $this->getFunctionMap(); + if (!isset($map[$function])) { + throw new PhutilSearchQueryCompilerSyntaxException( + pht( + 'Unknown search function "%s". Supported functions are: %s.', + $function, + implode(', ', array_keys($map)))); + } + + return $map[$function]['field']; + } + + public function getAllFunctionFields() { + $map = $this->getFunctionMap(); + + $fields = array(); + foreach ($map as $key => $spec) { + $fields[] = $spec['field']; + } + + return $fields; + } + + protected function getFunctionMap() { + return array( + 'all' => array( + 'field' => PhabricatorSearchDocumentFieldType::FIELD_ALL, + 'aliases' => array( + 'any', + ), + ), + 'title' => array( + 'field' => PhabricatorSearchDocumentFieldType::FIELD_TITLE, + 'aliases' => array(), + ), + 'body' => array( + 'field' => PhabricatorSearchDocumentFieldType::FIELD_BODY, + 'aliases' => array(), + ), + 'core' => array( + 'field' => PhabricatorSearchDocumentFieldType::FIELD_CORE, + 'aliases' => array(), + ), + 'comment' => array( + 'field' => PhabricatorSearchDocumentFieldType::FIELD_COMMENT, + 'aliases' => array( + 'comments', + ), + ), + ); + } + + public function newStemmer() { + return new PhutilSearchStemmer(); + } + + public function tokenizeString($value) { + $value = trim($value, ' '); + $value = preg_split('/\s+/u', $value); + return $value; + } + + public function getTermNgramsFromString($string) { + return $this->getNgramsFromString($string, true); + } + + public function getSubstringNgramsFromString($string) { + return $this->getNgramsFromString($string, false); + } + + private function getNgramsFromString($value, $as_term) { + $tokens = $this->tokenizeString($value); + + $ngrams = array(); + foreach ($tokens as $token) { + $token = phutil_utf8_strtolower($token); + + if ($as_term) { + $token = ' '.$token.' '; + } + + $token_v = phutil_utf8v($token); + $len = (count($token_v) - 2); + for ($ii = 0; $ii < $len; $ii++) { + $ngram = array_slice($token_v, $ii, 3); + $ngram = implode('', $ngram); + $ngrams[$ngram] = $ngram; + } + } + + ksort($ngrams); + + return array_keys($ngrams); + } + + public function newTermsCorpus($raw_corpus) { + $term_corpus = strtr( + $raw_corpus, + array( + '!' => ' ', + '"' => ' ', + '#' => ' ', + '$' => ' ', + '%' => ' ', + '&' => ' ', + '(' => ' ', + ')' => ' ', + '*' => ' ', + '+' => ' ', + ',' => ' ', + '-' => ' ', + '/' => ' ', + ':' => ' ', + ';' => ' ', + '<' => ' ', + '=' => ' ', + '>' => ' ', + '?' => ' ', + '@' => ' ', + '[' => ' ', + '\\' => ' ', + ']' => ' ', + '^' => ' ', + '`' => ' ', + '{' => ' ', + '|' => ' ', + '}' => ' ', + '~' => ' ', + '.' => ' ', + '_' => ' ', + "\n" => ' ', + "\r" => ' ', + "\t" => ' ', + )); + + // NOTE: Single quotes divide terms only if they're at a word boundary. + // In contractions, like "whom'st've", the entire word is a single term. + $term_corpus = preg_replace('/(^| )[\']+/', ' ', $term_corpus); + $term_corpus = preg_replace('/[\']+( |$)/', ' ', $term_corpus); + + $term_corpus = preg_replace('/\s+/u', ' ', $term_corpus); + $term_corpus = trim($term_corpus, ' '); + + if (strlen($term_corpus)) { + $term_corpus = ' '.$term_corpus.' '; + } + + return $term_corpus; + } + +/* -( Schema )------------------------------------------------------------- */ + + public function getDocumentTableName() { + $application = $this->getApplicationName(); + $scope = $this->getScopeName(); + + return "{$application}_{$scope}_fdocument"; + } + + public function getDocumentSchemaColumns() { + return array( + 'id' => 'auto', + 'objectPHID' => 'phid', + 'isClosed' => 'bool', + 'authorPHID' => 'phid?', + 'ownerPHID' => 'phid?', + 'epochCreated' => 'epoch', + 'epochModified' => 'epoch', + ); + } + + public function getDocumentSchemaKeys() { + return array( + 'PRIMARY' => array( + 'columns' => array('id'), + 'unique' => true, + ), + 'key_object' => array( + 'columns' => array('objectPHID'), + 'unique' => true, + ), + 'key_author' => array( + 'columns' => array('authorPHID'), + ), + 'key_owner' => array( + 'columns' => array('ownerPHID'), + ), + 'key_created' => array( + 'columns' => array('epochCreated'), + ), + 'key_modified' => array( + 'columns' => array('epochModified'), + ), + ); + } + + public function getFieldTableName() { + $application = $this->getApplicationName(); + $scope = $this->getScopeName(); + + return "{$application}_{$scope}_ffield"; + } + + public function getFieldSchemaColumns() { + return array( + 'id' => 'auto', + 'documentID' => 'uint32', + 'fieldKey' => 'text4', + 'rawCorpus' => 'sort', + 'termCorpus' => 'sort', + 'normalCorpus' => 'sort', + ); + } + + public function getFieldSchemaKeys() { + return array( + 'PRIMARY' => array( + 'columns' => array('id'), + 'unique' => true, + ), + 'key_documentfield' => array( + 'columns' => array('documentID', 'fieldKey'), + 'unique' => true, + ), + ); + } + + public function getNgramsTableName() { + $application = $this->getApplicationName(); + $scope = $this->getScopeName(); + + return "{$application}_{$scope}_fngrams"; + } + + public function getNgramsSchemaColumns() { + return array( + 'id' => 'auto', + 'documentID' => 'uint32', + 'ngram' => 'char3', + ); + } + + public function getNgramsSchemaKeys() { + return array( + 'PRIMARY' => array( + 'columns' => array('id'), + 'unique' => true, + ), + 'key_ngram' => array( + 'columns' => array('ngram', 'documentID'), + ), + 'key_object' => array( + 'columns' => array('documentID'), + ), + ); + } } diff --git a/src/applications/search/ferret/PhabricatorFerretField.php b/src/applications/search/ferret/PhabricatorFerretField.php deleted file mode 100644 index be39e745ed..0000000000 --- a/src/applications/search/ferret/PhabricatorFerretField.php +++ /dev/null @@ -1,39 +0,0 @@ - false, - self::CONFIG_COLUMN_SCHEMA => array( - 'documentID' => 'uint32', - 'fieldKey' => 'text4', - 'rawCorpus' => 'sort', - 'termCorpus' => 'sort', - 'normalCorpus' => 'sort', - ), - self::CONFIG_KEY_SCHEMA => array( - 'key_documentfield' => array( - 'columns' => array('documentID', 'fieldKey'), - 'unique' => true, - ), - ), - ) + parent::getConfiguration(); - } - - public function getTableName() { - $application = $this->getApplicationName(); - $key = $this->getIndexKey(); - return "{$application}_{$key}_ffield"; - } - -} diff --git a/src/applications/search/ferret/PhabricatorFerretMetadata.php b/src/applications/search/ferret/PhabricatorFerretMetadata.php new file mode 100644 index 0000000000..0f9337ce32 --- /dev/null +++ b/src/applications/search/ferret/PhabricatorFerretMetadata.php @@ -0,0 +1,44 @@ +engine = $engine; + return $this; + } + + public function getEngine() { + return $this->engine; + } + + public function setPHID($phid) { + $this->phid = $phid; + return $this; + } + + public function getPHID() { + return $this->phid; + } + + public function setRelevance($relevance) { + $this->relevance = $relevance; + return $this; + } + + public function getRelevance() { + return $this->relevance; + } + + public function getRelevanceSortVector() { + $engine = $this->getEngine(); + + return id(new PhutilSortVector()) + ->addInt($engine->getObjectTypeRelevance()) + ->addInt(-$this->getRelevance()); + } + +} diff --git a/src/applications/search/ferret/PhabricatorFerretNgrams.php b/src/applications/search/ferret/PhabricatorFerretNgrams.php deleted file mode 100644 index 9e28f96cb6..0000000000 --- a/src/applications/search/ferret/PhabricatorFerretNgrams.php +++ /dev/null @@ -1,35 +0,0 @@ - false, - self::CONFIG_COLUMN_SCHEMA => array( - 'documentID' => 'uint32', - 'ngram' => 'char3', - ), - self::CONFIG_KEY_SCHEMA => array( - 'key_ngram' => array( - 'columns' => array('ngram', 'documentID'), - ), - 'key_object' => array( - 'columns' => array('documentID'), - ), - ), - ) + parent::getConfiguration(); - } - - public function getTableName() { - $application = $this->getApplicationName(); - $key = $this->getIndexKey(); - return "{$application}_{$key}_fngrams"; - } - -} diff --git a/src/applications/search/ngrams/__tests__/PhabricatorNgramEngineTestCase.php b/src/applications/search/ferret/__tests__/PhabricatorFerretEngineTestCase.php similarity index 52% rename from src/applications/search/ngrams/__tests__/PhabricatorNgramEngineTestCase.php rename to src/applications/search/ferret/__tests__/PhabricatorFerretEngineTestCase.php index fccb6fb324..a8690f1d8b 100644 --- a/src/applications/search/ngrams/__tests__/PhabricatorNgramEngineTestCase.php +++ b/src/applications/search/ferret/__tests__/PhabricatorFerretEngineTestCase.php @@ -1,18 +1,19 @@ 'Hear ye hear ye', - "Thou whom'st've art worthy." => "Thou whom'st've art worthy", - 'Guaranteed to contain "food".' => 'Guaranteed to contain food', + 'Hear ye, hear ye!' => ' Hear ye hear ye ', + "Thou whom'st've art worthy." => " Thou whom'st've art worthy ", + 'Guaranteed to contain "food".' => ' Guaranteed to contain food ', 'http://example.org/path/to/file.jpg' => - 'http example org path to file jpg', + ' http example org path to file jpg ', ); - $engine = new PhabricatorNgramEngine(); + $engine = new ManiphestTaskFerretEngine(); + foreach ($map as $input => $expect) { $actual = $engine->newTermsCorpus($input); diff --git a/src/applications/search/fulltextstorage/PhabricatorElasticFulltextStorageEngine.php b/src/applications/search/fulltextstorage/PhabricatorElasticFulltextStorageEngine.php index 8c75c17e36..f6aead3759 100644 --- a/src/applications/search/fulltextstorage/PhabricatorElasticFulltextStorageEngine.php +++ b/src/applications/search/fulltextstorage/PhabricatorElasticFulltextStorageEngine.php @@ -105,42 +105,6 @@ class PhabricatorElasticFulltextStorageEngine $this->executeRequest($host, "/{$type}/{$phid}/", $spec, 'PUT'); } - public function reconstructDocument($phid) { - $type = phid_get_type($phid); - $host = $this->getHostForRead(); - $response = $this->executeRequest($host, "/{$type}/{$phid}", array()); - - if (empty($response['exists'])) { - return null; - } - - $hit = $response['_source']; - - $doc = new PhabricatorSearchAbstractDocument(); - $doc->setPHID($phid); - $doc->setDocumentType($response['_type']); - $doc->setDocumentTitle($hit['title']); - $doc->setDocumentCreated($hit['dateCreated']); - $doc->setDocumentModified($hit[$this->getTimestampField()]); - - foreach ($hit['field'] as $fdef) { - $field_type = $fdef['type']; - $doc->addField($field_type, $hit[$field_type], $fdef['aux']); - } - - foreach ($hit['relationship'] as $rtype => $rships) { - foreach ($rships as $rship) { - $doc->addRelationship( - $rtype, - $rship['phid'], - $rship['phidType'], - $rship['when']); - } - } - - return $doc; - } - private function buildSpec(PhabricatorSavedQuery $query) { $q = new PhabricatorElasticsearchQueryBuilder('bool'); $query_string = $query->getParameter('query'); diff --git a/src/applications/search/fulltextstorage/PhabricatorFerretFulltextStorageEngine.php b/src/applications/search/fulltextstorage/PhabricatorFerretFulltextStorageEngine.php new file mode 100644 index 0000000000..74e8771de7 --- /dev/null +++ b/src/applications/search/fulltextstorage/PhabricatorFerretFulltextStorageEngine.php @@ -0,0 +1,123 @@ +setAncestorClass('PhabricatorFerretInterface') + ->execute(); + + $type_map = array(); + foreach ($all_objects as $object) { + $phid_type = phid_get_type($object->generatePHID()); + + $type_map[$phid_type] = array( + 'object' => $object, + 'engine' => $object->newFerretEngine(), + ); + } + + $types = $query->getParameter('types'); + if ($types) { + $type_map = array_select_keys($type_map, $types); + } + + $offset = (int)$query->getParameter('offset', 0); + $limit = (int)$query->getParameter('limit', 25); + + // NOTE: For now, it's okay to query with the omnipotent viewer here + // because we're just returning PHIDs which we'll filter later. + $viewer = PhabricatorUser::getOmnipotentUser(); + + $type_results = array(); + $metadata = array(); + foreach ($type_map as $type => $spec) { + $engine = $spec['engine']; + $object = $spec['object']; + + $local_query = new PhabricatorSavedQuery(); + $local_query->setParameter('query', $query->getParameter('query')); + + $project_phids = $query->getParameter('projectPHIDs'); + if ($project_phids) { + $local_query->setParameter('projectPHIDs', $project_phids); + } + + $subscriber_phids = $query->getParameter('subscriberPHIDs'); + if ($subscriber_phids) { + $local_query->setParameter('subscriberPHIDs', $subscriber_phids); + } + + $search_engine = $engine->newSearchEngine() + ->setViewer($viewer); + + $engine_query = $search_engine->buildQueryFromSavedQuery($local_query) + ->setViewer($viewer); + + $engine_query + ->withFerretQuery($engine, $query) + ->setOrder('relevance') + ->setLimit($offset + $limit); + + $results = $engine_query->execute(); + $results = mpull($results, null, 'getPHID'); + $type_results[$type] = $results; + + $metadata += $engine_query->getFerretMetadata(); + } + + $list = array(); + foreach ($type_results as $type => $results) { + $list += $results; + } + + // Currently, the list is grouped by object type. For example, all the + // tasks might be first, then all the revisions, and so on. In each group, + // the results are ordered properly. + + // Reorder the results so that the highest-ranking results come first, + // no matter which object types they belong to. + + $metadata = msort($metadata, 'getRelevanceSortVector'); + $list = array_select_keys($list, array_keys($metadata)) + $list; + + $result_slice = array_slice($list, $offset, $limit, true); + return array_keys($result_slice); + } + + public function indexExists() { + return true; + } + + public function getIndexStats() { + return false; + } + + public function getFulltextTokens() { + return $this->fulltextTokens; + } + + +} diff --git a/src/applications/search/fulltextstorage/PhabricatorFulltextStorageEngine.php b/src/applications/search/fulltextstorage/PhabricatorFulltextStorageEngine.php index 588ccc3e5e..ba019ea593 100644 --- a/src/applications/search/fulltextstorage/PhabricatorFulltextStorageEngine.php +++ b/src/applications/search/fulltextstorage/PhabricatorFulltextStorageEngine.php @@ -53,15 +53,6 @@ abstract class PhabricatorFulltextStorageEngine extends Phobject { abstract public function reindexAbstractDocument( PhabricatorSearchAbstractDocument $document); - /** - * Reconstruct the document for a given PHID. This is used for debugging - * and does not need to be perfect if it is unreasonable to implement it. - * - * @param phid Document PHID to reconstruct. - * @return PhabricatorSearchAbstractDocument Abstract document. - */ - abstract public function reconstructDocument($phid); - /** * Execute a search query. * diff --git a/src/applications/search/fulltextstorage/PhabricatorMySQLFulltextStorageEngine.php b/src/applications/search/fulltextstorage/PhabricatorMySQLFulltextStorageEngine.php index fe526a8133..c2e38d2db7 100644 --- a/src/applications/search/fulltextstorage/PhabricatorMySQLFulltextStorageEngine.php +++ b/src/applications/search/fulltextstorage/PhabricatorMySQLFulltextStorageEngine.php @@ -91,73 +91,6 @@ final class PhabricatorMySQLFulltextStorageEngine } - /** - * Rebuild the PhabricatorSearchAbstractDocument that was used to index - * an object out of the index itself. This is primarily useful for debugging, - * as it allows you to inspect the search index representation of a - * document. - * - * @param phid PHID of a document which exists in the search index. - * @return null|PhabricatorSearchAbstractDocument Abstract document object - * which corresponds to the original abstract document used to - * build the document index. - */ - public function reconstructDocument($phid) { - $dao_doc = new PhabricatorSearchDocument(); - $dao_field = new PhabricatorSearchDocumentField(); - $dao_relationship = new PhabricatorSearchDocumentRelationship(); - - $t_doc = $dao_doc->getTableName(); - $t_field = $dao_field->getTableName(); - $t_relationship = $dao_relationship->getTableName(); - - $doc = queryfx_one( - $dao_doc->establishConnection('r'), - 'SELECT * FROM %T WHERE phid = %s', - $t_doc, - $phid); - - if (!$doc) { - return null; - } - - $fields = queryfx_all( - $dao_field->establishConnection('r'), - 'SELECT * FROM %T WHERE phid = %s', - $t_field, - $phid); - - $relationships = queryfx_all( - $dao_relationship->establishConnection('r'), - 'SELECT * FROM %T WHERE phid = %s', - $t_relationship, - $phid); - - $adoc = id(new PhabricatorSearchAbstractDocument()) - ->setPHID($phid) - ->setDocumentType($doc['documentType']) - ->setDocumentTitle($doc['documentTitle']) - ->setDocumentCreated($doc['documentCreated']) - ->setDocumentModified($doc['documentModified']); - - foreach ($fields as $field) { - $adoc->addField( - $field['field'], - $field['corpus'], - $field['auxPHID']); - } - - foreach ($relationships as $relationship) { - $adoc->addRelationship( - $relationship['relation'], - $relationship['relatedPHID'], - $relationship['relatedType'], - $relationship['relatedTime']); - } - - return $adoc; - } - public function executeSearch(PhabricatorSavedQuery $query) { $table = new PhabricatorSearchDocument(); $document_table = $table->getTableName(); diff --git a/src/applications/search/menuitem/PhabricatorApplicationProfileMenuItem.php b/src/applications/search/menuitem/PhabricatorApplicationProfileMenuItem.php index aa42d56cfb..40275a8d7a 100644 --- a/src/applications/search/menuitem/PhabricatorApplicationProfileMenuItem.php +++ b/src/applications/search/menuitem/PhabricatorApplicationProfileMenuItem.php @@ -31,7 +31,7 @@ final class PhabricatorApplicationProfileMenuItem return $name; } - return $application->getName(); + return $application->getMenuName(); } public function buildEditEngineFields( diff --git a/src/applications/search/ngrams/PhabricatorNgramEngine.php b/src/applications/search/ngrams/PhabricatorNgramEngine.php deleted file mode 100644 index f8f55d8757..0000000000 --- a/src/applications/search/ngrams/PhabricatorNgramEngine.php +++ /dev/null @@ -1,95 +0,0 @@ -tokenizeString($value); - - $ngrams = array(); - foreach ($tokens as $token) { - $token = phutil_utf8_strtolower($token); - - switch ($mode) { - case 'query': - break; - case 'index': - $token = ' '.$token.' '; - break; - case 'prefix': - $token = ' '.$token; - break; - } - - $token_v = phutil_utf8v($token); - $len = (count($token_v) - 2); - for ($ii = 0; $ii < $len; $ii++) { - $ngram = array_slice($token_v, $ii, 3); - $ngram = implode('', $ngram); - $ngrams[$ngram] = $ngram; - } - } - - ksort($ngrams); - - return array_keys($ngrams); - } - - public function newTermsCorpus($raw_corpus) { - $term_corpus = strtr( - $raw_corpus, - array( - '!' => ' ', - '"' => ' ', - '#' => ' ', - '$' => ' ', - '%' => ' ', - '&' => ' ', - '(' => ' ', - ')' => ' ', - '*' => ' ', - '+' => ' ', - ',' => ' ', - '-' => ' ', - '/' => ' ', - ':' => ' ', - ';' => ' ', - '<' => ' ', - '=' => ' ', - '>' => ' ', - '?' => ' ', - '@' => ' ', - '[' => ' ', - '\\' => ' ', - ']' => ' ', - '^' => ' ', - '`' => ' ', - '{' => ' ', - '|' => ' ', - '}' => ' ', - '~' => ' ', - '.' => ' ', - '_' => ' ', - "\n" => ' ', - "\r" => ' ', - "\t" => ' ', - )); - - // NOTE: Single quotes divide terms only if they're at a word boundary. - // In contractions, like "whom'st've", the entire word is a single term. - $term_corpus = preg_replace('/(^| )[\']+/', ' ', $term_corpus); - $term_corpus = preg_replace('/[\']+( |$)/', ' ', $term_corpus); - - $term_corpus = preg_replace('/\s+/u', ' ', $term_corpus); - $term_corpus = trim($term_corpus, ' '); - - return $term_corpus; - } - - -} diff --git a/src/applications/settings/editor/PhabricatorSettingsEditEngine.php b/src/applications/settings/editor/PhabricatorSettingsEditEngine.php index e12654e1a4..30e831543d 100644 --- a/src/applications/settings/editor/PhabricatorSettingsEditEngine.php +++ b/src/applications/settings/editor/PhabricatorSettingsEditEngine.php @@ -63,12 +63,13 @@ final class PhabricatorSettingsEditEngine } protected function getObjectEditTitleText($object) { - $user = $object->getUser(); - if ($user) { - return pht('Edit Settings (%s)', $user->getUserName()); - } else { - return pht('Edit Global Settings'); + $page = $this->getSelectedPage(); + + if ($page) { + return $page->getLabel(); } + + return pht('Settings'); } protected function getObjectEditShortText($object) { @@ -97,6 +98,20 @@ final class PhabricatorSettingsEditEngine return pht('Settings'); } + protected function getPageHeader($object) { + $user = $object->getUser(); + if ($user) { + $text = pht('Edit Settings (%s)', $user->getUserName()); + } else { + $text = pht('Edit Global Settings'); + } + + $header = id(new PHUIHeaderView()) + ->setHeader($text); + + return $header; + } + protected function getEditorURI() { throw new PhutilMethodNotImplementedException(); } diff --git a/src/applications/settings/panel/PhabricatorActivitySettingsPanel.php b/src/applications/settings/panel/PhabricatorActivitySettingsPanel.php index 0b3533f287..50f951d661 100644 --- a/src/applications/settings/panel/PhabricatorActivitySettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorActivitySettingsPanel.php @@ -46,10 +46,7 @@ final class PhabricatorActivitySettingsPanel extends PhabricatorSettingsPanel { ->setLogs($logs) ->setHandles($handles); - $panel = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Account Activity Logs')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); + $panel = $this->newBox(pht('Account Activity Logs'), $table); $pager_box = id(new PHUIBoxView()) ->addMargin(PHUI::MARGIN_LARGE) diff --git a/src/applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php b/src/applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php index 66fd0396ad..1bdb95f568 100644 --- a/src/applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php @@ -138,24 +138,18 @@ final class PhabricatorEmailAddressesSettingsPanel $editable, )); - $view = new PHUIObjectBoxView(); - $header = new PHUIHeaderView(); - $header->setHeader(pht('Email Addresses')); - + $button = null; if ($editable) { - $button = new PHUIButtonView(); - $button->setText(pht('Add New Address')); - $button->setTag('a'); - $button->setHref($uri->alter('new', 'true')); - $button->setIcon('fa-plus'); - $button->addSigil('workflow'); - $header->addActionLink($button); + $button = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-plus') + ->setText(pht('Add New Address')) + ->setHref($uri->alter('new', 'true')) + ->addSigil('workflow') + ->setColor(PHUIButtonView::GREY); } - $view->setHeader($header); - $view->setTable($table); - $view->setBackground(PHUIObjectBoxView::BLUE_PROPERTY); - return $view; + return $this->newBox(pht('Email Addresses'), $table, array($button)); } private function returnNewAddressResponse( diff --git a/src/applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php b/src/applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php index 77364e0aa0..faa79889ed 100644 --- a/src/applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php @@ -136,7 +136,7 @@ final class PhabricatorEmailPreferencesSettingsPanel ->setHeaderText(pht('Email Preferences')) ->setFormSaved($request->getStr('saved')) ->setFormErrors($errors) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setForm($form); return $form_box; diff --git a/src/applications/settings/panel/PhabricatorExternalAccountsSettingsPanel.php b/src/applications/settings/panel/PhabricatorExternalAccountsSettingsPanel.php index 068c58d549..e380248a83 100644 --- a/src/applications/settings/panel/PhabricatorExternalAccountsSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorExternalAccountsSettingsPanel.php @@ -31,12 +31,10 @@ final class PhabricatorExternalAccountsSettingsPanel )) ->execute(); - $linked_head = id(new PHUIHeaderView()) - ->setHeader(pht('Linked Accounts and Authentication')); + $linked_head = pht('Linked Accounts and Authentication'); $linked = id(new PHUIObjectItemListView()) ->setUser($viewer) - ->setFlush(true) ->setNoDataString(pht('You have no linked accounts.')); $login_accounts = 0; @@ -47,7 +45,7 @@ final class PhabricatorExternalAccountsSettingsPanel } foreach ($accounts as $account) { - $item = id(new PHUIObjectItemView()); + $item = new PHUIObjectItemView(); $provider = idx($providers, $account->getProviderKey()); if ($provider) { @@ -94,12 +92,10 @@ final class PhabricatorExternalAccountsSettingsPanel $linked->addItem($item); } - $linkable_head = id(new PHUIHeaderView()) - ->setHeader(pht('Add External Account')); + $linkable_head = pht('Add External Account'); $linkable = id(new PHUIObjectItemListView()) ->setUser($viewer) - ->setFlush(true) ->setNoDataString( pht('Your account is linked with all available providers.')); @@ -118,26 +114,19 @@ final class PhabricatorExternalAccountsSettingsPanel $link_uri = '/auth/link/'.$provider->getProviderKey().'/'; - $item = id(new PHUIObjectItemView()); - $item->setHeader($provider->getProviderName()); - $item->setHref($link_uri); - $item->addAction( - id(new PHUIListItemView()) - ->setIcon('fa-link') - ->setHref($link_uri)); + $item = id(new PHUIObjectItemView()) + ->setHeader($provider->getProviderName()) + ->setHref($link_uri) + ->addAction( + id(new PHUIListItemView()) + ->setIcon('fa-link') + ->setHref($link_uri)); $linkable->addItem($item); } - $linked_box = id(new PHUIObjectBoxView()) - ->setHeader($linked_head) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setObjectList($linked); - - $linkable_box = id(new PHUIObjectBoxView()) - ->setHeader($linkable_head) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setObjectList($linkable); + $linked_box = $this->newBox($linked_head, $linked); + $linkable_box = $this->newBox($linkable_head, $linkable); return array( $linked_box, diff --git a/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php b/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php index 68d1812616..ae653e0f70 100644 --- a/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php @@ -101,34 +101,27 @@ final class PhabricatorMultiFactorSettingsPanel true, )); - $panel = new PHUIObjectBoxView(); - $header = new PHUIHeaderView(); - $help_uri = PhabricatorEnv::getDoclink( 'User Guide: Multi-Factor Authentication'); - $help_button = id(new PHUIButtonView()) + $buttons = array(); + + $buttons[] = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-plus') + ->setText(pht('Add Auth Factor')) + ->setHref($this->getPanelURI('?new=true')) + ->setWorkflow(true) + ->setColor(PHUIButtonView::GREY); + + $buttons[] = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-book') ->setText(pht('Help')) ->setHref($help_uri) - ->setTag('a') - ->setIcon('fa-info-circle'); + ->setColor(PHUIButtonView::GREY); - $create_button = id(new PHUIButtonView()) - ->setText(pht('Add Authentication Factor')) - ->setHref($this->getPanelURI('?new=true')) - ->setTag('a') - ->setWorkflow(true) - ->setIcon('fa-plus'); - - $header->setHeader(pht('Authentication Factors')); - $header->addActionLink($help_button); - $header->addActionLink($create_button); - - $panel->setHeader($header); - $panel->setTable($table); - $panel->setBackground(PHUIObjectBoxView::BLUE_PROPERTY); - - return $panel; + return $this->newBox(pht('Authentication Factors'), $table, $buttons); } private function processNew(AphrontRequest $request) { diff --git a/src/applications/settings/panel/PhabricatorNotificationsSettingsPanel.php b/src/applications/settings/panel/PhabricatorNotificationsSettingsPanel.php index d61ece6da5..e75c2b99ee 100644 --- a/src/applications/settings/panel/PhabricatorNotificationsSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorNotificationsSettingsPanel.php @@ -152,24 +152,17 @@ final class PhabricatorNotificationsSettingsPanel id(new AphrontFormSubmitControl()) ->setValue(pht('Save Preference'))); - $test_button = id(new PHUIButtonView()) + $button = id(new PHUIButtonView()) ->setTag('a') + ->setIcon('fa-send-o') ->setWorkflow(true) ->setText(pht('Send Test Notification')) ->setHref('/notification/test/') - ->setIcon('fa-exclamation-triangle'); + ->setColor(PHUIButtonView::GREY); - $form_box = id(new PHUIObjectBoxView()) - ->setHeader( - id(new PHUIHeaderView()) - ->setHeader(pht('Notifications')) - ->addActionLink($test_button)) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->appendChild(array( - $saved_box, - $status_box, - $form, - )); + $form_content = array($saved_box, $status_box, $form); + $form_box = $this->newBox( + pht('Notifications'), $form_content, array($button)); $browser_status_box = id(new PHUIInfoView()) ->setID($browser_status_id) diff --git a/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php b/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php index 2a1b482c80..c1250fca23 100644 --- a/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php @@ -91,7 +91,7 @@ final class PhabricatorPasswordSettingsPanel extends PhabricatorSettingsPanel { // is changed here the CSRF token check will fail. $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); - $envelope = new PhutilOpaqueEnvelope($pass); + $envelope = new PhutilOpaqueEnvelope($pass); id(new PhabricatorUserEditor()) ->setActor($user) ->changePassword($user, $envelope); @@ -172,45 +172,47 @@ final class PhabricatorPasswordSettingsPanel extends PhabricatorSettingsPanel { ->setDisableAutocomplete(true) ->setLabel(pht('New Password')) ->setError($e_new) - ->setName('new_pw')); - $form + ->setName('new_pw')) ->appendChild( id(new AphrontFormPasswordControl()) ->setDisableAutocomplete(true) ->setLabel(pht('Confirm Password')) ->setCaption($len_caption) ->setError($e_conf) - ->setName('conf_pw')); - $form + ->setName('conf_pw')) ->appendChild( id(new AphrontFormSubmitControl()) ->setValue(pht('Change Password'))); - $form->appendChild( - id(new AphrontFormStaticControl()) - ->setLabel(pht('Current Algorithm')) - ->setValue(PhabricatorPasswordHasher::getCurrentAlgorithmName( - new PhutilOpaqueEnvelope($user->getPasswordHash())))); + $properties = id(new PHUIPropertyListView()); - $form->appendChild( - id(new AphrontFormStaticControl()) - ->setLabel(pht('Best Available Algorithm')) - ->setValue(PhabricatorPasswordHasher::getBestAlgorithmName())); + $properties->addProperty( + pht('Current Algorithm'), + PhabricatorPasswordHasher::getCurrentAlgorithmName( + new PhutilOpaqueEnvelope($user->getPasswordHash()))); - $form->appendRemarkupInstructions( - pht( - 'NOTE: Changing your password will terminate any other outstanding '. - 'login sessions.')); + $properties->addProperty( + pht('Best Available Algorithm'), + PhabricatorPasswordHasher::getBestAlgorithmName()); + $info_view = id(new PHUIInfoView()) + ->setSeverity(PHUIInfoView::SEVERITY_NOTICE) + ->appendChild( + pht('Changing your password will terminate any other outstanding '. + 'login sessions.')); + + $algo_box = $this->newBox(pht('Password Algorithms'), $properties); $form_box = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Change Password')) ->setFormSaved($request->getStr('saved')) ->setFormErrors($errors) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setForm($form); return array( $form_box, + $algo_box, + $info_view, ); } diff --git a/src/applications/settings/panel/PhabricatorSSHKeysSettingsPanel.php b/src/applications/settings/panel/PhabricatorSSHKeysSettingsPanel.php index 3e339e9145..13944411ed 100644 --- a/src/applications/settings/panel/PhabricatorSSHKeysSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorSSHKeysSettingsPanel.php @@ -45,14 +45,7 @@ final class PhabricatorSSHKeysSettingsPanel extends PhabricatorSettingsPanel { $viewer, $user); - $header->setHeader(pht('SSH Public Keys')); - $header->addActionLink($ssh_actions); - - $panel->setHeader($header); - $panel->setTable($table); - $panel->setBackground(PHUIObjectBoxView::BLUE_PROPERTY); - - return $panel; + return $this->newBox(pht('SSH Public Keys'), $table, array($ssh_actions)); } } diff --git a/src/applications/settings/panel/PhabricatorSessionsSettingsPanel.php b/src/applications/settings/panel/PhabricatorSessionsSettingsPanel.php index fb60e40d81..eab18002a1 100644 --- a/src/applications/settings/panel/PhabricatorSessionsSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorSessionsSettingsPanel.php @@ -112,34 +112,27 @@ final class PhabricatorSessionsSettingsPanel extends PhabricatorSettingsPanel { 'action', )); - $terminate_button = id(new PHUIButtonView()) + $buttons = array(); + $buttons[] = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-warning') ->setText(pht('Terminate All Sessions')) ->setHref('/auth/session/terminate/all/') - ->setTag('a') ->setWorkflow(true) - ->setIcon('fa-exclamation-triangle'); - - $header = id(new PHUIHeaderView()) - ->setHeader(pht('Active Login Sessions')) - ->addActionLink($terminate_button); + ->setColor(PHUIButtonView::RED); $hisec = ($viewer->getSession()->getHighSecurityUntil() - time()); if ($hisec > 0) { - $hisec_button = id(new PHUIButtonView()) + $buttons[] = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-lock') ->setText(pht('Leave High Security')) ->setHref('/auth/session/downgrade/') - ->setTag('a') ->setWorkflow(true) - ->setIcon('fa-lock'); - $header->addActionLink($hisec_button); + ->setColor(PHUIButtonView::RED); } - $panel = id(new PHUIObjectBoxView()) - ->setHeader($header) - ->setTable($table) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY); - - return $panel; + return $this->newBox(pht('Active Login Sessions'), $table, $buttons); } } diff --git a/src/applications/settings/panel/PhabricatorSettingsPanel.php b/src/applications/settings/panel/PhabricatorSettingsPanel.php index eea48e540f..d2008f8857 100644 --- a/src/applications/settings/panel/PhabricatorSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorSettingsPanel.php @@ -281,4 +281,21 @@ abstract class PhabricatorSettingsPanel extends Phobject { $editor->applyTransactions($preferences, $xactions); } + + public function newBox($title, $content, $actions = array()) { + $header = id(new PHUIHeaderView()) + ->setHeader($title); + + foreach ($actions as $action) { + $header->addActionLink($action); + } + + $view = id(new PHUIObjectBoxView()) + ->setHeader($header) + ->appendChild($content) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG); + + return $view; + } + } diff --git a/src/applications/settings/panel/PhabricatorTokensSettingsPanel.php b/src/applications/settings/panel/PhabricatorTokensSettingsPanel.php index d2cc0dedb6..f2021bafa5 100644 --- a/src/applications/settings/panel/PhabricatorTokensSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorTokensSettingsPanel.php @@ -71,23 +71,15 @@ final class PhabricatorTokensSettingsPanel extends PhabricatorSettingsPanel { 'action', )); - $terminate_button = id(new PHUIButtonView()) + $button = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-warning') ->setText(pht('Revoke All')) ->setHref('/auth/token/revoke/all/') - ->setTag('a') ->setWorkflow(true) - ->setIcon('fa-exclamation-triangle'); + ->setColor(PHUIButtonView::RED); - $header = id(new PHUIHeaderView()) - ->setHeader(pht('Temporary Tokens')) - ->addActionLink($terminate_button); - - $panel = id(new PHUIObjectBoxView()) - ->setHeader($header) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); - - return $panel; + return $this->newBox(pht('Temporary Tokens'), $table, array($button)); } } diff --git a/src/applications/slowvote/controller/PhabricatorSlowvoteEditController.php b/src/applications/slowvote/controller/PhabricatorSlowvoteEditController.php index ebf09ec929..44927fedea 100644 --- a/src/applications/slowvote/controller/PhabricatorSlowvoteEditController.php +++ b/src/applications/slowvote/controller/PhabricatorSlowvoteEditController.php @@ -269,17 +269,12 @@ final class PhabricatorSlowvoteEditController $crumbs->setBorder(true); $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Poll')) + ->setHeaderText($title) ->setFormErrors($errors) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setForm($form); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon($header_icon); - $view = id(new PHUITwoColumnView()) - ->setHeader($header) ->setFooter($form_box); return $this->newPage() diff --git a/src/applications/spaces/controller/PhabricatorSpacesEditController.php b/src/applications/spaces/controller/PhabricatorSpacesEditController.php index faca39d634..cf3b6578b6 100644 --- a/src/applications/spaces/controller/PhabricatorSpacesEditController.php +++ b/src/applications/spaces/controller/PhabricatorSpacesEditController.php @@ -165,8 +165,8 @@ final class PhabricatorSpacesEditController ->addCancelButton($cancel_uri)); $box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Space')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setHeaderText($title) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->setValidationException($validation_exception) ->appendChild($form); @@ -179,12 +179,7 @@ final class PhabricatorSpacesEditController $crumbs->addTextCrumb($title); $crumbs->setBorder(true); - $header = id(new PHUIHeaderView()) - ->setHeader($header_text) - ->setHeaderIcon('fa-pencil'); - $view = id(new PHUITwoColumnView()) - ->setHeader($header) ->setFooter(array( $box, )); diff --git a/src/applications/transactions/editengine/PhabricatorEditEngine.php b/src/applications/transactions/editengine/PhabricatorEditEngine.php index d09e2450a1..e1d6812778 100644 --- a/src/applications/transactions/editengine/PhabricatorEditEngine.php +++ b/src/applications/transactions/editengine/PhabricatorEditEngine.php @@ -312,6 +312,15 @@ abstract class PhabricatorEditEngine } + /** + * @task text + */ + protected function getPageHeader($object) { + return null; + } + + + /** * Return a human-readable header describing what this engine is used to do, * like "Configure Maniphest Task Forms". @@ -1169,6 +1178,9 @@ abstract class PhabricatorEditEngine $form = $this->buildEditForm($object, $fields); + $crumbs = $this->buildCrumbs($object, $final = true); + $crumbs->setBorder(true); + if ($request->isAjax()) { return $this->getController() ->newDialog() @@ -1180,21 +1192,18 @@ abstract class PhabricatorEditEngine ->addSubmitButton($submit_button); } - $crumbs = $this->buildCrumbs($object, $final = true); - - $header = id(new PHUIHeaderView()) + $box_header = id(new PHUIHeaderView()) ->setHeader($header_text); - $crumbs->setBorder(true); if ($action_button) { - $header->addActionLink($action_button); + $box_header->addActionLink($action_button); } $box = id(new PHUIObjectBoxView()) ->setUser($viewer) - ->setHeaderText($this->getObjectName()) + ->setHeader($box_header) ->setValidationException($validation_exception) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setBackground(PHUIObjectBoxView::WHITE_CONFIG) ->appendChild($form); // This is fairly questionable, but in use by Settings. @@ -1209,8 +1218,9 @@ abstract class PhabricatorEditEngine $view = new PHUITwoColumnView(); - if ($header) { - $view->setHeader($header); + $page_header = $this->getPageHeader($object); + if ($page_header) { + $view->setHeader($page_header); } $page = $controller->newPage() diff --git a/src/infrastructure/query/constraint/PhabricatorQueryConstraint.php b/src/infrastructure/query/constraint/PhabricatorQueryConstraint.php index 74b3830676..54cd7ae51f 100644 --- a/src/infrastructure/query/constraint/PhabricatorQueryConstraint.php +++ b/src/infrastructure/query/constraint/PhabricatorQueryConstraint.php @@ -8,6 +8,7 @@ final class PhabricatorQueryConstraint extends Phobject { const OPERATOR_NULL = 'null'; const OPERATOR_ANCESTOR = 'ancestor'; const OPERATOR_EMPTY = 'empty'; + const OPERATOR_ONLY = 'only'; private $operator; private $value; diff --git a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php index 03d56bc1d2..0488ba6133 100644 --- a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php +++ b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php @@ -28,8 +28,10 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery private $spaceIsArchived; private $ngrams = array(); private $ferretEngine; - private $ferretTokens; - private $ferretTables; + private $ferretTokens = array(); + private $ferretTables = array(); + private $ferretQuery; + private $ferretMetadata = array(); protected function getPageCursors(array $page) { return array( @@ -81,6 +83,18 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery return $this->beforeID; } + final public function getFerretMetadata() { + if (!$this->supportsFerretEngine()) { + throw new Exception( + pht( + 'Unable to retrieve Ferret engine metadata, this class ("%s") does '. + 'not support the Ferret engine.', + get_class($this))); + } + + return $this->ferretMetadata; + } + protected function loadStandardPage(PhabricatorLiskDAO $table) { $rows = $this->loadStandardPageRows($table); return $table->loadAllFromArray($rows); @@ -110,6 +124,27 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery $this->buildOrderClause($conn), $this->buildLimitClause($conn)); + $rows = $this->didLoadRawRows($rows); + + return $rows; + } + + protected function didLoadRawRows(array $rows) { + if ($this->ferretEngine) { + foreach ($rows as $row) { + $phid = $row['phid']; + + $metadata = id(new PhabricatorFerretMetadata()) + ->setPHID($phid) + ->setEngine($this->ferretEngine) + ->setRelevance(idx($row, '_ft_rank')); + + $this->ferretMetadata[$phid] = $metadata; + + unset($row['_ft_rank']); + } + } + return $rows; } @@ -171,6 +206,7 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery if ($this->beforeID) { $results = array_reverse($results, $preserve_keys = true); } + return $results; } @@ -251,6 +287,7 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery } $select[] = $this->buildEdgeLogicSelectClause($conn); + $select[] = $this->buildFerretSelectClause($conn); return $select; } @@ -769,6 +806,13 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery } } + if ($this->supportsFerretEngine()) { + $orders['relevance'] = array( + 'vector' => array('rank', 'fulltext-modified', 'id'), + 'name' => pht('Relevence'), + ); + } + return $orders; } @@ -961,6 +1005,24 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery } } + if ($this->supportsFerretEngine()) { + $columns['rank'] = array( + 'table' => null, + 'column' => '_ft_rank', + 'type' => 'int', + ); + $columns['fulltext-created'] = array( + 'table' => 'ft_doc', + 'column' => 'epochCreated', + 'type' => 'int', + ); + $columns['fulltext-modified'] = array( + 'table' => 'ft_doc', + 'column' => 'epochModified', + 'type' => 'int', + ); + } + $cache->setKey($cache_key, $columns); return $columns; @@ -1385,10 +1447,39 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery /* -( Ferret )------------------------------------------------------------- */ + public function supportsFerretEngine() { + $object = $this->newResultObject(); + return ($object instanceof PhabricatorFerretInterface); + } + + public function withFerretQuery( + PhabricatorFerretEngine $engine, + PhabricatorSavedQuery $query) { + + if (!$this->supportsFerretEngine()) { + throw new Exception( + pht( + 'Query ("%s") does not support the Ferret fulltext engine.', + get_class($this))); + } + + $this->ferretEngine = $engine; + $this->ferretQuery = $query; + + return $this; + } + public function withFerretConstraint( PhabricatorFerretEngine $engine, array $fulltext_tokens) { + if (!$this->supportsFerretEngine()) { + throw new Exception( + pht( + 'Query ("%s") does not support the Ferret fulltext engine.', + get_class($this))); + } + if ($this->ferretEngine) { throw new Exception( pht( @@ -1402,15 +1493,7 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery $this->ferretEngine = $engine; $this->ferretTokens = $fulltext_tokens; - - $function_map = array( - 'all' => PhabricatorSearchDocumentFieldType::FIELD_ALL, - 'title' => PhabricatorSearchDocumentFieldType::FIELD_TITLE, - 'body' => PhabricatorSearchDocumentFieldType::FIELD_BODY, - 'core' => PhabricatorSearchDocumentFieldType::FIELD_CORE, - ); - - $current_function = 'all'; + $current_function = $engine->getDefaultFunctionKey(); $table_map = array(); $idx = 1; foreach ($this->ferretTokens as $fulltext_token) { @@ -1421,29 +1504,114 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery $function = $current_function; } - if (!isset($function_map[$function])) { - throw new PhutilSearchQueryCompilerSyntaxException( - pht( - 'Unknown search function "%s".', - $function)); - } + $raw_field = $engine->getFieldForFunction($function); if (!isset($table_map[$function])) { - $alias = 'ftfield'.$idx++; + $alias = 'ftfield_'.$idx++; $table_map[$function] = array( 'alias' => $alias, - 'key' => $function_map[$function], + 'key' => $raw_field, ); } $current_function = $function; } + // Join the title field separately so we can rank results. + $table_map['rank'] = array( + 'alias' => 'ft_rank', + 'key' => PhabricatorSearchDocumentFieldType::FIELD_TITLE, + ); + $this->ferretTables = $table_map; return $this; } + protected function buildFerretSelectClause(AphrontDatabaseConnection $conn) { + $select = array(); + + if (!$this->supportsFerretEngine()) { + return $select; + } + + if (!$this->ferretEngine) { + $select[] = '0 _ft_rank'; + return $select; + } + + $engine = $this->ferretEngine; + $stemmer = $engine->newStemmer(); + + $op_sub = PhutilSearchQueryCompiler::OPERATOR_SUBSTRING; + $op_not = PhutilSearchQueryCompiler::OPERATOR_NOT; + $table_alias = 'ft_rank'; + + $parts = array(); + foreach ($this->ferretTokens as $fulltext_token) { + $raw_token = $fulltext_token->getToken(); + $value = $raw_token->getValue(); + + if ($raw_token->getOperator() == $op_not) { + // Ignore "not" terms when ranking, since they aren't useful. + continue; + } + + if ($raw_token->getOperator() == $op_sub) { + $is_substring = true; + } else { + $is_substring = false; + } + + if ($is_substring) { + $parts[] = qsprintf( + $conn, + 'IF(%T.rawCorpus LIKE %~, 2, 0)', + $table_alias, + $value); + continue; + } + + if ($raw_token->isQuoted()) { + $is_quoted = true; + $is_stemmed = false; + } else { + $is_quoted = false; + $is_stemmed = true; + } + + $term_constraints = array(); + + $term_value = $engine->newTermsCorpus($value); + + $parts[] = qsprintf( + $conn, + 'IF(%T.termCorpus LIKE %~, 2, 0)', + $table_alias, + $term_value); + + if ($is_stemmed) { + $stem_value = $stemmer->stemToken($value); + $stem_value = $engine->newTermsCorpus($stem_value); + + $parts[] = qsprintf( + $conn, + 'IF(%T.normalCorpus LIKE %~, 1, 0)', + $table_alias, + $stem_value); + } + } + + $parts[] = '0'; + + $select[] = qsprintf( + $conn, + '%Q _ft_rank', + implode(' + ', $parts)); + + return $select; + } + protected function buildFerretJoinClause(AphrontDatabaseConnection $conn) { if (!$this->ferretEngine) { return array(); @@ -1453,11 +1621,9 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery $op_not = PhutilSearchQueryCompiler::OPERATOR_NOT; $engine = $this->ferretEngine; - $ngram_engine = new PhabricatorNgramEngine(); - $stemmer = new PhutilSearchStemmer(); + $stemmer = $engine->newStemmer(); - $ngram_table = $engine->newNgramsObject(); - $ngram_table_name = $ngram_table->getTableName(); + $ngram_table = $engine->getNgramsTableName(); $flat = array(); foreach ($this->ferretTokens as $fulltext_token) { @@ -1498,25 +1664,23 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery } if ($is_substring) { - $ngrams = $ngram_engine->getNgramsFromString($value, 'query'); + $ngrams = $engine->getSubstringNgramsFromString($value); } else { - $ngrams = $ngram_engine->getNgramsFromString($value, 'index'); + $terms_value = $engine->newTermsCorpus($value); + $ngrams = $engine->getTermNgramsFromString($terms_value); // If this is a stemmed term, only look for ngrams present in both the // unstemmed and stemmed variations. if ($is_stemmed) { - $stem_value = $stemmer->stemToken($value); - $stem_ngrams = $ngram_engine->getNgramsFromString( - $stem_value, - 'index'); - + $stem_value = $stemmer->stemToken($terms_value); + $stem_ngrams = $engine->getTermNgramsFromString($stem_value); $ngrams = array_intersect($ngrams, $stem_ngrams); } } foreach ($ngrams as $ngram) { $flat[] = array( - 'table' => $ngram_table_name, + 'table' => $ngram_table, 'ngram' => $ngram, ); } @@ -1538,14 +1702,14 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery $phid_column = qsprintf($conn, '%T', 'phid'); } - $document_table = $engine->newDocumentObject(); - $field_table = $engine->newFieldObject(); + $document_table = $engine->getDocumentTableName(); + $field_table = $engine->getFieldTableName(); $joins = array(); $joins[] = qsprintf( $conn, - 'JOIN %T ftdoc ON ftdoc.objectPHID = %Q', - $document_table->getTableName(), + 'JOIN %T ft_doc ON ft_doc.objectPHID = %Q', + $document_table, $phid_column); $idx = 1; @@ -1553,11 +1717,11 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery $table = $spec['table']; $ngram = $spec['ngram']; - $alias = 'ft'.$idx++; + $alias = 'ftngram_'.$idx++; $joins[] = qsprintf( $conn, - 'JOIN %T %T ON %T.documentID = ftdoc.id AND %T.ngram = %s', + 'JOIN %T %T ON %T.documentID = ft_doc.id AND %T.ngram = %s', $table, $alias, $alias, @@ -1570,9 +1734,9 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery $joins[] = qsprintf( $conn, - 'JOIN %T %T ON ftdoc.id = %T.documentID + 'JOIN %T %T ON ft_doc.id = %T.documentID AND %T.fieldKey = %s', - $field_table->getTableName(), + $field_table, $alias, $alias, $alias, @@ -1587,8 +1751,8 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery return array(); } - $ngram_engine = new PhabricatorNgramEngine(); - $stemmer = new PhutilSearchStemmer(); + $engine = $this->ferretEngine; + $stemmer = $engine->newStemmer(); $table_map = $this->ferretTables; $op_sub = PhutilSearchQueryCompiler::OPERATOR_SUBSTRING; @@ -1653,7 +1817,7 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery $term_constraints = array(); - $term_value = ' '.$ngram_engine->newTermsCorpus($value).' '; + $term_value = $engine->newTermsCorpus($value); if ($is_not) { $term_constraints[] = qsprintf( $conn, @@ -1670,8 +1834,7 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery if ($is_stemmed) { $stem_value = $stemmer->stemToken($value); - $stem_value = $ngram_engine->newTermsCorpus($stem_value); - $stem_value = ' '.$stem_value.' '; + $stem_value = $engine->newTermsCorpus($stem_value); $term_constraints[] = qsprintf( $conn, @@ -1700,6 +1863,75 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery } } + if ($this->ferretQuery) { + $query = $this->ferretQuery; + + $author_phids = $query->getParameter('authorPHIDs'); + if ($author_phids) { + $where[] = qsprintf( + $conn, + 'ft_doc.authorPHID IN (%Ls)', + $author_phids); + } + + $with_unowned = $query->getParameter('withUnowned'); + $with_any = $query->getParameter('withAnyOwner'); + + if ($with_any && $with_unowned) { + throw new PhabricatorEmptyQueryException( + pht( + 'This query matches only unowned documents owned by anyone, '. + 'which is impossible.')); + } + + $owner_phids = $query->getParameter('ownerPHIDs'); + if ($owner_phids && !$with_any) { + if ($with_unowned) { + $where[] = qsprintf( + $conn, + 'ft_doc.ownerPHID IN (%Ls) OR ft_doc.ownerPHID IS NULL', + $owner_phids); + } else { + $where[] = qsprintf( + $conn, + 'ft_doc.ownerPHID IN (%Ls)', + $owner_phids); + } + } else if ($with_unowned) { + $where[] = qsprintf( + $conn, + 'ft_doc.ownerPHID IS NULL'); + } + + if ($with_any) { + $where[] = qsprintf( + $conn, + 'ft_doc.ownerPHID IS NOT NULL'); + } + + $rel_open = PhabricatorSearchRelationship::RELATIONSHIP_OPEN; + + $statuses = $query->getParameter('statuses'); + $is_closed = null; + if ($statuses) { + $statuses = array_fuse($statuses); + if (count($statuses) == 1) { + if (isset($statuses[$rel_open])) { + $is_closed = 0; + } else { + $is_closed = 1; + } + } + } + + if ($is_closed !== null) { + $where[] = qsprintf( + $conn, + 'ft_doc.isClosed = %d', + $is_closed); + } + } + return $where; } @@ -1968,6 +2200,27 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery $op_null = PhabricatorQueryConstraint::OPERATOR_NULL; $has_null = isset($constraints[$op_null]); + // If we're going to process an only() operator, build a list of the + // acceptable set of PHIDs first. We'll only match results which have + // no edges to any other PHIDs. + $all_phids = array(); + if (isset($constraints[PhabricatorQueryConstraint::OPERATOR_ONLY])) { + foreach ($constraints as $operator => $list) { + switch ($operator) { + case PhabricatorQueryConstraint::OPERATOR_ANCESTOR: + case PhabricatorQueryConstraint::OPERATOR_AND: + case PhabricatorQueryConstraint::OPERATOR_OR: + foreach ($list as $constraint) { + $value = (array)$constraint->getValue(); + foreach ($value as $v) { + $all_phids[$v] = $v; + } + } + break; + } + } + } + foreach ($constraints as $operator => $list) { $alias = $this->getEdgeLogicTableAlias($operator, $type); @@ -2032,6 +2285,20 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery $alias, $type); break; + case PhabricatorQueryConstraint::OPERATOR_ONLY: + $joins[] = qsprintf( + $conn, + 'LEFT JOIN %T %T ON %Q = %T.src AND %T.type = %d + AND %T.dst NOT IN (%Ls)', + $edge_table, + $alias, + $phid_column, + $alias, + $alias, + $type, + $alias, + $all_phids); + break; } } } @@ -2058,6 +2325,7 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery $alias = $this->getEdgeLogicTableAlias($operator, $type); switch ($operator) { case PhabricatorQueryConstraint::OPERATOR_NOT: + case PhabricatorQueryConstraint::OPERATOR_ONLY: $full[] = qsprintf( $conn, '%T.dst IS NULL', @@ -2157,6 +2425,7 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery // discussion, see T12753. return true; case PhabricatorQueryConstraint::OPERATOR_NULL: + case PhabricatorQueryConstraint::OPERATOR_ONLY: return true; } } @@ -2274,6 +2543,34 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery } } + $op_and = PhabricatorQueryConstraint::OPERATOR_AND; + $op_or = PhabricatorQueryConstraint::OPERATOR_OR; + $op_ancestor = PhabricatorQueryConstraint::OPERATOR_ANCESTOR; + + foreach ($this->edgeLogicConstraints as $type => $constraints) { + foreach ($constraints as $operator => $list) { + switch ($operator) { + case PhabricatorQueryConstraint::OPERATOR_ONLY: + if (count($list) > 1) { + throw new PhabricatorEmptyQueryException( + pht( + 'This query specifies only() more than once.')); + } + + $have_and = idx($constraints, $op_and); + $have_or = idx($constraints, $op_or); + $have_ancestor = idx($constraints, $op_ancestor); + if (!$have_and && !$have_or && !$have_ancestor) { + throw new PhabricatorEmptyQueryException( + pht( + 'This query specifies only(), but no other constraints '. + 'which it can apply to.')); + } + break; + } + } + } + $this->edgeLogicConstraintsAreValid = true; return $this; diff --git a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementAnalyzeWorkflow.php b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementAnalyzeWorkflow.php new file mode 100644 index 0000000000..6fe3e60926 --- /dev/null +++ b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementAnalyzeWorkflow.php @@ -0,0 +1,20 @@ +setName('analyze') + ->setExamples('**analyze**') + ->setSynopsis( + pht('Run "ANALYZE TABLE" on tables to improve performance.')); + } + + public function didExecute(PhutilArgumentParser $args) { + $api = $this->getSingleAPI(); + $this->analyzeTables($api); + return 0; + } + +} diff --git a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php index 48d753781d..a03ef41c4d 100644 --- a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php +++ b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php @@ -137,6 +137,15 @@ abstract class PhabricatorStorageManagementWorkflow try { $err = $this->doAdjustSchemata($api, $unsafe); + + // Analyze tables if we're not doing a dry run and adjustments are either + // all clear or have minor errors like surplus tables. + if (!$this->dryRun) { + $should_analyze = (($err == 0) || ($err == 2)); + if ($should_analyze) { + $this->analyzeTables($api); + } + } } catch (Exception $ex) { $lock->unlock(); throw $ex; @@ -1163,4 +1172,54 @@ abstract class PhabricatorStorageManagementWorkflow ->lock(); } + final protected function analyzeTables( + PhabricatorStorageManagementAPI $api) { + + // Analyzing tables can sometimes have a significant effect on query + // performance, particularly for the fulltext ngrams tables. See T12819 + // for some specific examples. + + $conn = $api->getConn(null); + + $patches = $this->getPatches(); + $databases = $api->getDatabaseList($patches, true); + + $this->logInfo( + pht('ANALYZE'), + pht('Analyzing tables...')); + + $targets = array(); + foreach ($databases as $database) { + queryfx($conn, 'USE %C', $database); + $tables = queryfx_all($conn, 'SHOW TABLE STATUS'); + foreach ($tables as $table) { + $table_name = $table['Name']; + + $targets[] = array( + 'database' => $database, + 'table' => $table_name, + ); + } + } + + $bar = id(new PhutilConsoleProgressBar()) + ->setTotal(count($targets)); + foreach ($targets as $target) { + queryfx( + $conn, + 'ANALYZE TABLE %T.%T', + $target['database'], + $target['table']); + + $bar->update(1); + } + $bar->done(); + + $this->logOkay( + pht('ANALYZED'), + pht( + 'Analyzed %d table(s).', + count($targets))); + } + } diff --git a/src/view/phui/PHUIInfoView.php b/src/view/phui/PHUIInfoView.php index 18f5af3374..161e49108b 100644 --- a/src/view/phui/PHUIInfoView.php +++ b/src/view/phui/PHUIInfoView.php @@ -59,6 +59,7 @@ final class PHUIInfoView extends AphrontTagView { } else { $icon = id(new PHUIIconView()) ->setIcon($icon); + $this->icon = $icon; } return $this; diff --git a/src/view/phui/PHUIObjectBoxView.php b/src/view/phui/PHUIObjectBoxView.php index 0089e8e26e..f5fdbfffc4 100644 --- a/src/view/phui/PHUIObjectBoxView.php +++ b/src/view/phui/PHUIObjectBoxView.php @@ -35,6 +35,7 @@ final class PHUIObjectBoxView extends AphrontTagView { const BLUE = 'phui-box-blue'; const BLUE_PROPERTY = 'phui-box-blue-property'; + const WHITE_CONFIG = 'phui-box-white-config'; const GREY = 'phui-box-grey'; public function addPropertyList(PHUIPropertyListView $property_list) { diff --git a/src/view/phui/PHUITwoColumnView.php b/src/view/phui/PHUITwoColumnView.php index 6e261ffeeb..9240887f4b 100644 --- a/src/view/phui/PHUITwoColumnView.php +++ b/src/view/phui/PHUITwoColumnView.php @@ -106,6 +106,10 @@ final class PHUITwoColumnView extends AphrontTagView { $classes[] = 'with-subheader'; } + if (!$this->header) { + $classes[] = 'without-header'; + } + return array( 'class' => implode(' ', $classes), ); diff --git a/webroot/rsrc/css/application/config/config-options.css b/webroot/rsrc/css/application/config/config-options.css index d8a6af6012..0c80e31b5e 100644 --- a/webroot/rsrc/css/application/config/config-options.css +++ b/webroot/rsrc/css/application/config/config-options.css @@ -5,20 +5,20 @@ .config-option-table { width: 100%; border-collapse: collapse; - border: 1px solid {$thinblueborder}; + border: none; background: {$page.content}; } .config-option-table th, .config-option-table td { - padding: 4px 12px; - border: 1px solid {$lightgreyborder}; + padding: 8px 12px; + border-bottom: 1px solid {$thinblueborder}; } .config-option-table th { background: {$lightgreybackground}; color: {$bluetext}; - text-align: right; + text-align: left; white-space: nowrap; } @@ -37,17 +37,19 @@ .config-option-table .column-labels th { font-weight: bold; color: {$bluetext}; - text-align: center; - background: {$greybackground}; + background: {$lightgreybackground}; + border-right: 1px solid {$thinblueborder}; } .config-options-current-value { - padding: 0 8px 6px; - white-space: pre-wrap; + white-space: nowrap; + width: 200px; + text-overflow: ellipsis; + overflow: hidden; } -.config-options-current-value span { - color: {$greytext}; +.config-options-current-value.violet { + color: {$violet}; } .config-options-effective-value, diff --git a/webroot/rsrc/css/application/config/config-page.css b/webroot/rsrc/css/application/config/config-page.css deleted file mode 100644 index 82cb9642d2..0000000000 --- a/webroot/rsrc/css/application/config/config-page.css +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @provides config-page-css - */ - -.config-page-header { - margin: 28px 24px 0; - padding-bottom: 28px; - border-bottom: 1px solid {$thinblueborder}; -} - -.device-phone .config-page-header { - margin: 4px 12px 0; - padding-bottom: 4px; -} - -.config-page-header .phui-profile-header { - padding: 0; -} - -.device-phone .config-page-header .phui-profile-header { - padding-left: 4px; - padding-right: 4px; -} - -.config-page-header .phui-profile-header.phui-header-shell .phui-header-header { - font-size: 20px; -} - -.device-phone .config-page-header .phui-profile-header.phui-header-shell - .phui-header-header { - font-size: 16px; -} - -.config-page-content { - margin: 0 24px; -} - -.device-phone .config-page-content { - margin: 0 4px; -} - -.device-desktop .config-page-content .phui-oi-list-view { - padding-left: 0; - padding-right: 0; -} - -.device-desktop .config-page-content .phui-document-fluid .phui-document-view { - padding: 16px 0; - margin: 0; -} - -.config-page-content .aphront-table-view { - border: none; -} - -.config-page-property { - padding-top: 4px; - border-bottom: 1px solid {$thinblueborder}; -} - -.config-page-content .aphront-table-notice { - padding: 0; -} - -.config-page-content .aphront-table-notice .phui-info-view { - margin-left: 0; - margin-right: 0; -} - -.config-page-content .aphront-table-wrap + .aphront-table-wrap { - margin-top: 20px; - border-top: 1px solid {$thinblueborder}; -} - -.config-page-content .phui-box.phui-box-blue-property { - margin-top: 16px; -} diff --git a/webroot/rsrc/css/application/config/setup-issue.css b/webroot/rsrc/css/application/config/setup-issue.css index ae54394b4c..7ba033d9c2 100644 --- a/webroot/rsrc/css/application/config/setup-issue.css +++ b/webroot/rsrc/css/application/config/setup-issue.css @@ -6,15 +6,15 @@ } .setup-issue-shell { - max-width: 760px; + max-width: 880px; margin: 16px auto; } .setup-issue { background: #fff; - border: 1px solid #BFCFDA; - padding: 8px; - border-radius: 3px; + border: 1px solid #e4e5e6; + padding: 0; + border-radius: 5px; } .setup-issue p { @@ -24,29 +24,30 @@ .setup-issue table { width: 100%; border-collapse: collapse; - border: 1px solid #BFCFDA; + border: 1px solid #e2e2e2; } .setup-issue table th { text-align: right; width: 30%; background: #F8F9FC; - border: 1px solid #BFCFDA; + border: 1px solid #e2e2e2; padding: 8px; } .setup-issue table td { - border: 1px solid #BFCFDA; + border: 1px solid #e2e2e2; padding: 8px; word-break: break-word; } .setup-issue pre { width: auto; - border: 1px solid #BFCFDA; - padding: 10px 2%; + border: 1px solid #e2e2e2; + padding: 12px; background: #F8F9FC; overflow-x: auto; + border-radius: 3px; } .setup-issue tt { @@ -60,51 +61,51 @@ } .setup-issue-instructions { - font-size: 14px; - padding: 12px 0; + font-size: 13px; + padding: 16px; line-height: 20px; - background: #fff; - border-bottom: 1px solid #BFCFDA; - margin: 0 12px; + background: rgba(71,87,120,0.08); + border-radius: 3px; } .setup-fatal .setup-issue-instructions { - color: #c0392b; + color: #af1404; background: #f4dddb; - padding: 12px; - margin: 0 0 12px; - border-bottom: 1px solid #c0392b; } .setup-issue-name { - color: #464C5C; - padding: 4px 8px 12px; - border-bottom: 1px solid #BFCFDA; font-size: 15px; font-weight: bold; + color: #6B748C; + border-bottom: 1px solid #e2e2e2; + overflow: hidden; + padding: 16px; + line-height: 24px; } -.setup-issue-tail { - margin-top: 12px; +.setup-issue-body { + padding: 16px 16px 0 16px; } .setup-issue-status { - margin: 12px 4px 0; + margin: 0 0 16px 0; padding: 12px; background: #FDF5D4; - color: #bc7837; - border: 1px solid #bc7837; + color: #ab8206; border-radius: 3px; } .setup-issue-actions { - padding: 8px 12px; - border-top: 1px solid #dfdfdf; - background-color: #f7f7f7; - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px; + padding: 12px; + background-color: #f5f5f5; + border-bottom-right-radius: 5px; + border-bottom-left-radius: 5px; overflow: hidden; - margin: 0 -8px -8px -8px; + text-align: right; +} + +.setup-issue-actions .button { + margin-left: 8px; } .setup-issue-next { @@ -112,14 +113,17 @@ border: 1px solid #BFCFDA; background: #daeaf3; text-align: center; - font-size: 16px; margin: 12px 0; color: #2980b9; border-radius: 3px; } .setup-issue-config { - padding: 8px 12px; + padding: 12px 0; +} + +.setup-issue-config + .setup-issue-config { + padding-top: 0; } .setup-issue ul { @@ -134,3 +138,12 @@ text-align: right; color: #74777D; } + +.phui-two-column-view .setup-issue-background { + padding: 0; +} + +.phui-two-column-view .setup-issue-shell { + width: auto; + margin: 0; +} diff --git a/webroot/rsrc/css/phui/object-item/phui-oi-big-ui.css b/webroot/rsrc/css/phui/object-item/phui-oi-big-ui.css index e4d636cf46..67ce566733 100644 --- a/webroot/rsrc/css/phui/object-item/phui-oi-big-ui.css +++ b/webroot/rsrc/css/phui/object-item/phui-oi-big-ui.css @@ -31,7 +31,7 @@ } .device-desktop .phui-oi-list-big .phui-oi { - margin-bottom: 8px; + margin-bottom: 4px; } .phui-oi-list-big .phui-oi-col0 { @@ -46,3 +46,16 @@ .phui-oi-list-big .phui-oi-visited a.phui-oi-link { color: {$violet}; } + +.phui-box-white-config .phui-oi-list-big.phui-oi-list-view { + padding: 8px 8px 4px; +} + +.phui-box-white-config .phui-oi-frame { + padding: 4px 8px 0; +} + +.device-desktop .phui-box-white-config .phui-oi:hover .phui-oi-frame { + background-color: {$hoverblue}; + border-radius: 3px; +} diff --git a/webroot/rsrc/css/phui/phui-box.css b/webroot/rsrc/css/phui/phui-box.css index 4c44fa04d6..278f1365e8 100644 --- a/webroot/rsrc/css/phui/phui-box.css +++ b/webroot/rsrc/css/phui/phui-box.css @@ -115,3 +115,29 @@ body .phui-box-blue-property .phui-header-shell + .phui-object-box { .phui-header-shell { background: {$page.content}; } + +/* Config Boxes */ + +.phui-box-white-config.phui-box-border { + border-color: #e2e2e2; + border-radius: 5px; +} + +.phui-box-white-config.phui-object-box { + padding: 16px 0 0 0; +} + +.phui-box-white-config .phui-header-shell { + border-bottom: 1px solid #e2e2e2; + overflow: hidden; + padding: 0 16px 16px; +} + +.phui-box-white-config .phui-header-header { + color: {$bluetext}; +} + +.phui-box-white-config .phui-header-action-links .button { + margin-top: 0; + margin-bottom: 0; +} diff --git a/webroot/rsrc/css/phui/phui-header-view.css b/webroot/rsrc/css/phui/phui-header-view.css index 8aefcee31c..18b1464e53 100644 --- a/webroot/rsrc/css/phui/phui-header-view.css +++ b/webroot/rsrc/css/phui/phui-header-view.css @@ -34,10 +34,6 @@ vertical-align: middle; } -.device-phone .phui-header-col3 { - vertical-align: top; -} - body .phui-header-shell.phui-header-no-backgound { background-color: transparent; border: none; @@ -341,8 +337,8 @@ body .phui-header-shell.phui-bleed-header color: {$blacktext}; } -.phui-profile-header .phui-header-col3 { - vertical-align: top; +.phui-profile-header.phui-header-shell .phui-header-header a { + color: {$blacktext}; } .phui-header-view .phui-tag-indigo a { diff --git a/webroot/rsrc/css/phui/phui-info-view.css b/webroot/rsrc/css/phui/phui-info-view.css index 268385edec..55400956e4 100644 --- a/webroot/rsrc/css/phui/phui-info-view.css +++ b/webroot/rsrc/css/phui/phui-info-view.css @@ -46,8 +46,11 @@ div.phui-info-view.phui-info-severity-plain { } .phui-info-view-body tt { - padding: 0 2px; - background-color: rgba({$alphagrey},.1); + color: {$blacktext}; + background: rgba({$alphablue},0.1); + padding: 1px 4px; + border-radius: 3px; + white-space: pre-wrap; } .phui-info-view-actions { @@ -136,3 +139,7 @@ h1.phui-info-view-head { div.phui-object-box .phui-header-shell + .phui-info-view { margin: 16px 0 8px; } + +div.phui-object-box.phui-box-white-config .phui-header-shell + .phui-info-view { + margin: 20px 16px 8px; +} diff --git a/webroot/rsrc/css/phui/phui-two-column-view.css b/webroot/rsrc/css/phui/phui-two-column-view.css index 73926be92a..2fb0eccee2 100644 --- a/webroot/rsrc/css/phui/phui-two-column-view.css +++ b/webroot/rsrc/css/phui/phui-two-column-view.css @@ -13,6 +13,10 @@ margin-bottom: 24px; } +.phui-two-column-view.without-header { + margin-top: 24px; +} + .device .phui-two-column-view .phui-two-column-header { margin-bottom: 12px; }