1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-28 09:42:41 +01:00

(stable) Promote 2016 Week 35

This commit is contained in:
epriestley 2016-08-26 17:30:23 -07:00
commit be84c051e5
79 changed files with 1180 additions and 616 deletions

View file

@ -42,7 +42,7 @@ return array(
'rsrc/css/application/config/config-options.css' => '0ede4c9b', 'rsrc/css/application/config/config-options.css' => '0ede4c9b',
'rsrc/css/application/config/config-template.css' => '8e6c6fcd', 'rsrc/css/application/config/config-template.css' => '8e6c6fcd',
'rsrc/css/application/config/config-welcome.css' => '035aa483', 'rsrc/css/application/config/config-welcome.css' => '035aa483',
'rsrc/css/application/config/setup-issue.css' => 'db7e9c40', 'rsrc/css/application/config/setup-issue.css' => 'f794cfc3',
'rsrc/css/application/config/unhandled-exception.css' => '4c96257a', 'rsrc/css/application/config/unhandled-exception.css' => '4c96257a',
'rsrc/css/application/conpherence/durable-column.css' => '86396117', 'rsrc/css/application/conpherence/durable-column.css' => '86396117',
'rsrc/css/application/conpherence/menu.css' => 'f99fee4c', 'rsrc/css/application/conpherence/menu.css' => 'f99fee4c',
@ -891,7 +891,7 @@ return array(
'releeph-preview-branch' => 'b7a6f4a5', 'releeph-preview-branch' => 'b7a6f4a5',
'releeph-request-differential-create-dialog' => '8d8b92cd', 'releeph-request-differential-create-dialog' => '8d8b92cd',
'releeph-request-typeahead-css' => '667a48ae', 'releeph-request-typeahead-css' => '667a48ae',
'setup-issue-css' => 'db7e9c40', 'setup-issue-css' => 'f794cfc3',
'sprite-login-css' => '60e8560e', 'sprite-login-css' => '60e8560e',
'sprite-tokens-css' => '9cdfd599', 'sprite-tokens-css' => '9cdfd599',
'syntax-default-css' => '9923583c', 'syntax-default-css' => '9923583c',

View file

@ -15,8 +15,7 @@
], ],
"conduit.uri" : null, "conduit.uri" : null,
"conduit.user" : null, "conduit.token" : null,
"conduit.cert" : null,
"macro.size" : 48, "macro.size" : 48,
"macro.aspect" : 0.66, "macro.aspect" : 0.66,

View file

@ -0,0 +1 @@
DROP TABLE {$NAMESPACE}_conduit.conduit_connectionlog;

View file

@ -0,0 +1,8 @@
CREATE TABLE {$NAMESPACE}_repository.repository_commithint (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
repositoryPHID VARBINARY(64) NOT NULL,
oldCommitIdentifier VARCHAR(40) NOT NULL COLLATE {$COLLATE_TEXT},
newCommitIdentifier VARCHAR(40) COLLATE {$COLLATE_TEXT},
hintType VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT},
UNIQUE KEY `key_old` (repositoryPHID, oldCommitIdentifier)
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};

View file

@ -0,0 +1,39 @@
<?php
$table = new PhabricatorRepositoryCommit();
$conn = $table->establishConnection('w');
$rows = queryfx_all(
$conn,
'SELECT fullCommitName FROM repository_badcommit');
$viewer = PhabricatorUser::getOmnipotentUser();
foreach ($rows as $row) {
$identifier = $row['fullCommitName'];
$commit = id(new DiffusionCommitQuery())
->setViewer($viewer)
->withIdentifiers(array($identifier))
->executeOne();
if (!$commit) {
echo tsprintf(
"%s\n",
pht(
'Skipped hint for "%s", this is not a valid commit.',
$identifier));
} else {
PhabricatorRepositoryCommitHint::updateHint(
$commit->getRepository()->getPHID(),
$commit->getCommitIdentifier(),
null,
PhabricatorRepositoryCommitHint::HINT_UNREADABLE);
echo tsprintf(
"%s\n",
pht(
'Updated commit hint for "%s".',
$identifier));
}
}

View file

@ -0,0 +1 @@
DROP TABLE {$NAMESPACE}_repository.repository_badcommit;

View file

@ -0,0 +1,7 @@
/* Removes Ponder vote data. */
DELETE FROM {$NAMESPACE}_ponder.edge
WHERE type IN (17, 18, 19, 20);
DELETE FROM {$NAMESPACE}_user.edge
WHERE type IN (17, 18, 19, 20);

View file

@ -612,6 +612,7 @@ phutil_register_library_map(array(
'DiffusionCommitHash' => 'applications/diffusion/data/DiffusionCommitHash.php', 'DiffusionCommitHash' => 'applications/diffusion/data/DiffusionCommitHash.php',
'DiffusionCommitHeraldField' => 'applications/diffusion/herald/DiffusionCommitHeraldField.php', 'DiffusionCommitHeraldField' => 'applications/diffusion/herald/DiffusionCommitHeraldField.php',
'DiffusionCommitHeraldFieldGroup' => 'applications/diffusion/herald/DiffusionCommitHeraldFieldGroup.php', 'DiffusionCommitHeraldFieldGroup' => 'applications/diffusion/herald/DiffusionCommitHeraldFieldGroup.php',
'DiffusionCommitHintQuery' => 'applications/diffusion/query/DiffusionCommitHintQuery.php',
'DiffusionCommitHookEngine' => 'applications/diffusion/engine/DiffusionCommitHookEngine.php', 'DiffusionCommitHookEngine' => 'applications/diffusion/engine/DiffusionCommitHookEngine.php',
'DiffusionCommitHookRejectException' => 'applications/diffusion/exception/DiffusionCommitHookRejectException.php', 'DiffusionCommitHookRejectException' => 'applications/diffusion/exception/DiffusionCommitHookRejectException.php',
'DiffusionCommitMergeHeraldField' => 'applications/diffusion/herald/DiffusionCommitMergeHeraldField.php', 'DiffusionCommitMergeHeraldField' => 'applications/diffusion/herald/DiffusionCommitMergeHeraldField.php',
@ -2114,7 +2115,6 @@ phutil_register_library_map(array(
'PhabricatorConduitAPIController' => 'applications/conduit/controller/PhabricatorConduitAPIController.php', 'PhabricatorConduitAPIController' => 'applications/conduit/controller/PhabricatorConduitAPIController.php',
'PhabricatorConduitApplication' => 'applications/conduit/application/PhabricatorConduitApplication.php', 'PhabricatorConduitApplication' => 'applications/conduit/application/PhabricatorConduitApplication.php',
'PhabricatorConduitCertificateToken' => 'applications/conduit/storage/PhabricatorConduitCertificateToken.php', 'PhabricatorConduitCertificateToken' => 'applications/conduit/storage/PhabricatorConduitCertificateToken.php',
'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/PhabricatorConduitConnectionLog.php',
'PhabricatorConduitConsoleController' => 'applications/conduit/controller/PhabricatorConduitConsoleController.php', 'PhabricatorConduitConsoleController' => 'applications/conduit/controller/PhabricatorConduitConsoleController.php',
'PhabricatorConduitContentSource' => 'infrastructure/contentsource/PhabricatorConduitContentSource.php', 'PhabricatorConduitContentSource' => 'infrastructure/contentsource/PhabricatorConduitContentSource.php',
'PhabricatorConduitController' => 'applications/conduit/controller/PhabricatorConduitController.php', 'PhabricatorConduitController' => 'applications/conduit/controller/PhabricatorConduitController.php',
@ -2140,6 +2140,7 @@ phutil_register_library_map(array(
'PhabricatorConduitTokensSettingsPanel' => 'applications/conduit/settings/PhabricatorConduitTokensSettingsPanel.php', 'PhabricatorConduitTokensSettingsPanel' => 'applications/conduit/settings/PhabricatorConduitTokensSettingsPanel.php',
'PhabricatorConfigAllController' => 'applications/config/controller/PhabricatorConfigAllController.php', 'PhabricatorConfigAllController' => 'applications/config/controller/PhabricatorConfigAllController.php',
'PhabricatorConfigApplication' => 'applications/config/application/PhabricatorConfigApplication.php', 'PhabricatorConfigApplication' => 'applications/config/application/PhabricatorConfigApplication.php',
'PhabricatorConfigApplicationController' => 'applications/config/controller/PhabricatorConfigApplicationController.php',
'PhabricatorConfigCacheController' => 'applications/config/controller/PhabricatorConfigCacheController.php', 'PhabricatorConfigCacheController' => 'applications/config/controller/PhabricatorConfigCacheController.php',
'PhabricatorConfigClusterDatabasesController' => 'applications/config/controller/PhabricatorConfigClusterDatabasesController.php', 'PhabricatorConfigClusterDatabasesController' => 'applications/config/controller/PhabricatorConfigClusterDatabasesController.php',
'PhabricatorConfigClusterNotificationsController' => 'applications/config/controller/PhabricatorConfigClusterNotificationsController.php', 'PhabricatorConfigClusterNotificationsController' => 'applications/config/controller/PhabricatorConfigClusterNotificationsController.php',
@ -2201,7 +2202,7 @@ phutil_register_library_map(array(
'PhabricatorConfigTransaction' => 'applications/config/storage/PhabricatorConfigTransaction.php', 'PhabricatorConfigTransaction' => 'applications/config/storage/PhabricatorConfigTransaction.php',
'PhabricatorConfigTransactionQuery' => 'applications/config/query/PhabricatorConfigTransactionQuery.php', 'PhabricatorConfigTransactionQuery' => 'applications/config/query/PhabricatorConfigTransactionQuery.php',
'PhabricatorConfigValidationException' => 'applications/config/exception/PhabricatorConfigValidationException.php', 'PhabricatorConfigValidationException' => 'applications/config/exception/PhabricatorConfigValidationException.php',
'PhabricatorConfigVersionsModule' => 'applications/config/module/PhabricatorConfigVersionsModule.php', 'PhabricatorConfigVersionController' => 'applications/config/controller/PhabricatorConfigVersionController.php',
'PhabricatorConfigWelcomeController' => 'applications/config/controller/PhabricatorConfigWelcomeController.php', 'PhabricatorConfigWelcomeController' => 'applications/config/controller/PhabricatorConfigWelcomeController.php',
'PhabricatorConpherenceApplication' => 'applications/conpherence/application/PhabricatorConpherenceApplication.php', 'PhabricatorConpherenceApplication' => 'applications/conpherence/application/PhabricatorConpherenceApplication.php',
'PhabricatorConpherenceColumnVisibleSetting' => 'applications/settings/setting/PhabricatorConpherenceColumnVisibleSetting.php', 'PhabricatorConpherenceColumnVisibleSetting' => 'applications/settings/setting/PhabricatorConpherenceColumnVisibleSetting.php',
@ -3383,6 +3384,7 @@ phutil_register_library_map(array(
'PhabricatorRepositoryCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryCommitChangeParserWorker.php', 'PhabricatorRepositoryCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryCommitChangeParserWorker.php',
'PhabricatorRepositoryCommitData' => 'applications/repository/storage/PhabricatorRepositoryCommitData.php', 'PhabricatorRepositoryCommitData' => 'applications/repository/storage/PhabricatorRepositoryCommitData.php',
'PhabricatorRepositoryCommitHeraldWorker' => 'applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php', 'PhabricatorRepositoryCommitHeraldWorker' => 'applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php',
'PhabricatorRepositoryCommitHint' => 'applications/repository/storage/PhabricatorRepositoryCommitHint.php',
'PhabricatorRepositoryCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php', 'PhabricatorRepositoryCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php',
'PhabricatorRepositoryCommitOwnersWorker' => 'applications/repository/worker/PhabricatorRepositoryCommitOwnersWorker.php', 'PhabricatorRepositoryCommitOwnersWorker' => 'applications/repository/worker/PhabricatorRepositoryCommitOwnersWorker.php',
'PhabricatorRepositoryCommitPHIDType' => 'applications/repository/phid/PhabricatorRepositoryCommitPHIDType.php', 'PhabricatorRepositoryCommitPHIDType' => 'applications/repository/phid/PhabricatorRepositoryCommitPHIDType.php',
@ -3403,6 +3405,7 @@ phutil_register_library_map(array(
'PhabricatorRepositoryManagementCacheWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementCacheWorkflow.php', 'PhabricatorRepositoryManagementCacheWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementCacheWorkflow.php',
'PhabricatorRepositoryManagementClusterizeWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementClusterizeWorkflow.php', 'PhabricatorRepositoryManagementClusterizeWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementClusterizeWorkflow.php',
'PhabricatorRepositoryManagementDiscoverWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementDiscoverWorkflow.php', 'PhabricatorRepositoryManagementDiscoverWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementDiscoverWorkflow.php',
'PhabricatorRepositoryManagementHintWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementHintWorkflow.php',
'PhabricatorRepositoryManagementImportingWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementImportingWorkflow.php', 'PhabricatorRepositoryManagementImportingWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementImportingWorkflow.php',
'PhabricatorRepositoryManagementListPathsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementListPathsWorkflow.php', 'PhabricatorRepositoryManagementListPathsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementListPathsWorkflow.php',
'PhabricatorRepositoryManagementListWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementListWorkflow.php', 'PhabricatorRepositoryManagementListWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementListWorkflow.php',
@ -5104,6 +5107,7 @@ phutil_register_library_map(array(
'DiffusionCommitHash' => 'Phobject', 'DiffusionCommitHash' => 'Phobject',
'DiffusionCommitHeraldField' => 'HeraldField', 'DiffusionCommitHeraldField' => 'HeraldField',
'DiffusionCommitHeraldFieldGroup' => 'HeraldFieldGroup', 'DiffusionCommitHeraldFieldGroup' => 'HeraldFieldGroup',
'DiffusionCommitHintQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'DiffusionCommitHookEngine' => 'Phobject', 'DiffusionCommitHookEngine' => 'Phobject',
'DiffusionCommitHookRejectException' => 'Exception', 'DiffusionCommitHookRejectException' => 'Exception',
'DiffusionCommitMergeHeraldField' => 'DiffusionCommitHeraldField', 'DiffusionCommitMergeHeraldField' => 'DiffusionCommitHeraldField',
@ -6845,7 +6849,6 @@ phutil_register_library_map(array(
'PhabricatorConduitAPIController' => 'PhabricatorConduitController', 'PhabricatorConduitAPIController' => 'PhabricatorConduitController',
'PhabricatorConduitApplication' => 'PhabricatorApplication', 'PhabricatorConduitApplication' => 'PhabricatorApplication',
'PhabricatorConduitCertificateToken' => 'PhabricatorConduitDAO', 'PhabricatorConduitCertificateToken' => 'PhabricatorConduitDAO',
'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO',
'PhabricatorConduitConsoleController' => 'PhabricatorConduitController', 'PhabricatorConduitConsoleController' => 'PhabricatorConduitController',
'PhabricatorConduitContentSource' => 'PhabricatorContentSource', 'PhabricatorConduitContentSource' => 'PhabricatorContentSource',
'PhabricatorConduitController' => 'PhabricatorController', 'PhabricatorConduitController' => 'PhabricatorController',
@ -6877,6 +6880,7 @@ phutil_register_library_map(array(
'PhabricatorConduitTokensSettingsPanel' => 'PhabricatorSettingsPanel', 'PhabricatorConduitTokensSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorConfigAllController' => 'PhabricatorConfigController', 'PhabricatorConfigAllController' => 'PhabricatorConfigController',
'PhabricatorConfigApplication' => 'PhabricatorApplication', 'PhabricatorConfigApplication' => 'PhabricatorApplication',
'PhabricatorConfigApplicationController' => 'PhabricatorConfigController',
'PhabricatorConfigCacheController' => 'PhabricatorConfigController', 'PhabricatorConfigCacheController' => 'PhabricatorConfigController',
'PhabricatorConfigClusterDatabasesController' => 'PhabricatorConfigController', 'PhabricatorConfigClusterDatabasesController' => 'PhabricatorConfigController',
'PhabricatorConfigClusterNotificationsController' => 'PhabricatorConfigController', 'PhabricatorConfigClusterNotificationsController' => 'PhabricatorConfigController',
@ -6945,7 +6949,7 @@ phutil_register_library_map(array(
'PhabricatorConfigTransaction' => 'PhabricatorApplicationTransaction', 'PhabricatorConfigTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorConfigTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorConfigTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorConfigValidationException' => 'Exception', 'PhabricatorConfigValidationException' => 'Exception',
'PhabricatorConfigVersionsModule' => 'PhabricatorConfigModule', 'PhabricatorConfigVersionController' => 'PhabricatorConfigController',
'PhabricatorConfigWelcomeController' => 'PhabricatorConfigController', 'PhabricatorConfigWelcomeController' => 'PhabricatorConfigController',
'PhabricatorConpherenceApplication' => 'PhabricatorApplication', 'PhabricatorConpherenceApplication' => 'PhabricatorApplication',
'PhabricatorConpherenceColumnVisibleSetting' => 'PhabricatorInternalSetting', 'PhabricatorConpherenceColumnVisibleSetting' => 'PhabricatorInternalSetting',
@ -8348,6 +8352,10 @@ phutil_register_library_map(array(
'PhabricatorRepositoryCommitChangeParserWorker' => 'PhabricatorRepositoryCommitParserWorker', 'PhabricatorRepositoryCommitChangeParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitData' => 'PhabricatorRepositoryDAO', 'PhabricatorRepositoryCommitData' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryCommitHeraldWorker' => 'PhabricatorRepositoryCommitParserWorker', 'PhabricatorRepositoryCommitHeraldWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitHint' => array(
'PhabricatorRepositoryDAO',
'PhabricatorPolicyInterface',
),
'PhabricatorRepositoryCommitMessageParserWorker' => 'PhabricatorRepositoryCommitParserWorker', 'PhabricatorRepositoryCommitMessageParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitOwnersWorker' => 'PhabricatorRepositoryCommitParserWorker', 'PhabricatorRepositoryCommitOwnersWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitPHIDType' => 'PhabricatorPHIDType', 'PhabricatorRepositoryCommitPHIDType' => 'PhabricatorPHIDType',
@ -8372,6 +8380,7 @@ phutil_register_library_map(array(
'PhabricatorRepositoryManagementCacheWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 'PhabricatorRepositoryManagementCacheWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementClusterizeWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 'PhabricatorRepositoryManagementClusterizeWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementDiscoverWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 'PhabricatorRepositoryManagementDiscoverWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementHintWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementImportingWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 'PhabricatorRepositoryManagementImportingWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementListPathsWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 'PhabricatorRepositoryManagementListPathsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementListWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 'PhabricatorRepositoryManagementListWorkflow' => 'PhabricatorRepositoryManagementWorkflow',

View file

@ -162,7 +162,7 @@ abstract class AphrontResponse extends Phobject {
$object, $object,
array(__CLASS__, 'processValueForJSONEncoding')); array(__CLASS__, 'processValueForJSONEncoding'));
$response = json_encode($object); $response = phutil_json_encode($object);
// Prevent content sniffing attacks by encoding "<" and ">", so browsers // Prevent content sniffing attacks by encoding "<" and ">", so browsers
// won't try to execute the document as HTML even if they ignore // won't try to execute the document as HTML even if they ignore

View file

@ -43,6 +43,7 @@ final class PhabricatorAuthSessionEngineExtensionModule
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeaderText(pht('SessionEngine Extensions')) ->setHeaderText(pht('SessionEngine Extensions'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -41,6 +41,7 @@ final class PhabricatorAuthTemporaryTokenTypeModule
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeaderText(pht('Temporary Token Types')) ->setHeaderText(pht('Temporary Token Types'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -575,44 +575,4 @@ abstract class PhabricatorController extends AphrontController {
return $page->produceAphrontResponse(); return $page->produceAphrontResponse();
} }
/**
* DEPRECATED. Use @{method:newPage}.
*/
public function buildApplicationPage($view, array $options) {
$page = $this->newPage();
$title = PhabricatorEnv::getEnvConfig('phabricator.serious-business') ?
'Phabricator' :
pht('Bacon Ice Cream for Breakfast');
$page->setTitle(idx($options, 'title', $title));
if (idx($options, 'class')) {
$page->addClass($options['class']);
}
if (!($view instanceof AphrontSideNavFilterView)) {
$nav = new AphrontSideNavFilterView();
$nav->appendChild($view);
$view = $nav;
}
$page->appendChild($view);
$object_phids = idx($options, 'pageObjects', array());
if ($object_phids) {
$page->setPageObjectPHIDs($object_phids);
}
if (!idx($options, 'device', true)) {
$page->setDeviceReady(false);
}
$page->setShowFooter(idx($options, 'showFooter', true));
$page->setShowChrome(idx($options, 'chrome', true));
return $page->produceAphrontResponse();
}
} }

View file

@ -232,11 +232,8 @@ EOFILE;
list($description, $metadata) = $parser->parse($matches[0]); list($description, $metadata) = $parser->parse($matches[0]);
$provides = preg_split('/\s+/', trim(idx($metadata, 'provides'))); $provides = $this->parseResourceSymbolList(idx($metadata, 'provides'));
$requires = preg_split('/\s+/', trim(idx($metadata, 'requires'))); $requires = $this->parseResourceSymbolList(idx($metadata, 'requires'));
$provides = array_filter($provides);
$requires = array_filter($requires);
if (!$provides) { if (!$provides) {
// Tests and documentation-only JS is permitted to @provide no targets. // Tests and documentation-only JS is permitted to @provide no targets.
return array(null, null); return array(null, null);
@ -364,4 +361,37 @@ EOFILE;
return $result; return $result;
} }
private function parseResourceSymbolList($list) {
if (!$list) {
return array();
}
// This is valid:
//
// @requires x y
//
// But so is this:
//
// @requires x
// @requires y
//
// Accept either form and produce a list of symbols.
$list = (array)$list;
// We can get `true` values if there was a bare `@requires` in the input.
foreach ($list as $key => $item) {
if ($item === true) {
unset($list[$key]);
}
}
$list = implode(' ', $list);
$list = trim($list);
$list = preg_split('/\s+/', $list);
$list = array_filter($list);
return $list;
}
} }

View file

@ -1,26 +0,0 @@
<?php
final class PhabricatorConduitConnectionLog extends PhabricatorConduitDAO {
protected $client;
protected $clientVersion;
protected $clientDescription;
protected $username;
protected function getConfiguration() {
return array(
self::CONFIG_COLUMN_SCHEMA => array(
'client' => 'text255?',
'clientVersion' => 'text255?',
'clientDescription' => 'text255?',
'username' => 'text255?',
),
self::CONFIG_KEY_SCHEMA => array(
'key_created' => array(
'columns' => array('dateCreated'),
),
),
) + parent::getConfiguration();
}
}

View file

@ -38,10 +38,12 @@ final class PhabricatorConfigApplication extends PhabricatorApplication {
return array( return array(
'/config/' => array( '/config/' => array(
'' => 'PhabricatorConfigListController', '' => 'PhabricatorConfigListController',
'application/' => 'PhabricatorConfigApplicationController',
'all/' => 'PhabricatorConfigAllController', 'all/' => 'PhabricatorConfigAllController',
'history/' => 'PhabricatorConfigHistoryController', 'history/' => 'PhabricatorConfigHistoryController',
'edit/(?P<key>[\w\.\-]+)/' => 'PhabricatorConfigEditController', 'edit/(?P<key>[\w\.\-]+)/' => 'PhabricatorConfigEditController',
'group/(?P<key>[^/]+)/' => 'PhabricatorConfigGroupController', 'group/(?P<key>[^/]+)/' => 'PhabricatorConfigGroupController',
'version/' => 'PhabricatorConfigVersionController',
'welcome/' => 'PhabricatorConfigWelcomeController', 'welcome/' => 'PhabricatorConfigWelcomeController',
'database/'. 'database/'.
'(?:(?P<database>[^/]+)/'. '(?:(?P<database>[^/]+)/'.

View file

@ -143,6 +143,9 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck {
'phabricator.auth-permanent', 'phabricator.auth-permanent',
'phabricator.application-id', 'phabricator.application-id',
'phabricator.application-secret', 'phabricator.application-secret',
'maniphest.priorities.unbreak-now',
'maniphest.priorities.needs-triage',
'welcome.html',
); );
$ancient_config = array_fill_keys($auth_config, $reason_auth); $ancient_config = array_fill_keys($auth_config, $reason_auth);
@ -332,6 +335,19 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck {
'ui.custom-header' => pht( 'ui.custom-header' => pht(
'This option has been replaced with `ui.logo`, which provides more '. 'This option has been replaced with `ui.logo`, which provides more '.
'flexible configuration options.'), 'flexible configuration options.'),
'welcome.html' => pht(
'This option has been removed, you can use Dashboards to provide '.
'homepage customization. See T11533 for more details.'),
'maniphest.priorities.unbreak-now' => pht(
'This option has been removed, you can use Dashboards to provide '.
'homepage customization. See T11533 for more details.'),
'maniphest.priorities.needs-triage' => pht(
'This option has been removed, you can use Dashboards to provide '.
'homepage customization. See T11533 for more details.'),
); );
return $ancient_config; return $ancient_config;

View file

@ -197,5 +197,53 @@ final class PhabricatorPHPConfigSetupCheck extends PhabricatorSetupCheck {
->setMessage($message); ->setMessage($message);
} }
} }
if (empty($_SERVER['REMOTE_ADDR'])) {
$doc_href = PhabricatorEnv::getDocLink('Configuring a Preamble Script');
$summary = pht(
'You likely need to fix your preamble script so '.
'REMOTE_ADDR is no longer empty.');
$message = pht(
'No REMOTE_ADDR is available, so Phabricator cannot determine the '.
'origin address for requests. This will prevent Phabricator from '.
'performing important security checks. This most often means you '.
'have a mistake in your preamble script. Consult the documentation '.
'(%s) and double-check that the script is written correctly.',
phutil_tag(
'a',
array(
'href' => $doc_href,
'target' => '_blank',
),
pht('Configuring a Preamble Script')));
$this->newIssue('php.remote_addr')
->setName(pht('No REMOTE_ADDR available'))
->setSummary($summary)
->setMessage($message);
}
$raw_post_data = (int)ini_get('always_populate_raw_post_data');
if ($raw_post_data != -1) {
$summary = pht(
'PHP setting "%s" should be set to "-1" to avoid deprecation '.
'warnings.',
'always_populate_raw_post_data');
$message = pht(
'The "%s" key is set to some value other than "-1" in your PHP '.
'configuration. This can cause PHP to raise deprecation warnings '.
'during process startup. Set this option to "-1" to prevent these '.
'warnings from appearing.',
'always_populate_raw_post_data');
$this->newIssue('php.always_populate_raw_post_data')
->setName(pht('Disable PHP %s', 'always_populate_raw_post_data'))
->setSummary($summary)
->setMessage($message)
->addPHPConfig('always_populate_raw_post_data');
}
} }
} }

View file

@ -52,11 +52,13 @@ final class PhabricatorConfigAllController
$crumbs = $this $crumbs = $this
->buildApplicationCrumbs() ->buildApplicationCrumbs()
->addTextCrumb(pht('Configuration'), $this->getApplicationURI())
->addTextCrumb($title); ->addTextCrumb($title);
$panel = new PHUIObjectBoxView(); $panel = id(new PHUIObjectBoxView())
$panel->setHeaderText(pht('Current Settings')); ->setHeaderText(pht('Current Settings'))
$panel->setTable($table); ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table);
$nav = $this->buildSideNavView(); $nav = $this->buildSideNavView();
$nav->selectFilter('all/'); $nav->selectFilter('all/');

View file

@ -0,0 +1,58 @@
<?php
final class PhabricatorConfigApplicationController
extends PhabricatorConfigController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$nav = $this->buildSideNavView();
$nav->selectFilter('application/');
$groups = PhabricatorApplicationConfigOptions::loadAll();
$apps_list = $this->buildConfigOptionsList($groups, 'apps');
$title = pht('Application Configuration');
$apps = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setObjectList($apps_list);
$crumbs = $this
->buildApplicationCrumbs()
->addTextCrumb(pht('Configuration'), $this->getApplicationURI())
->addTextCrumb(pht('Applications'));
$view = id(new PHUITwoColumnView())
->setNavigation($nav)
->setMainColumn(array(
$apps,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function buildConfigOptionsList(array $groups, $type) {
assert_instances_of($groups, 'PhabricatorApplicationConfigOptions');
$list = new PHUIObjectItemListView();
$groups = msort($groups, 'getName');
foreach ($groups as $group) {
if ($group->getGroup() == $type) {
$item = id(new PHUIObjectItemView())
->setHeader($group->getName())
->setHref('/config/group/'.$group->getKey().'/')
->addAttribute($group->getDescription())
->setImageIcon($group->getIcon());
$list->addItem($item);
}
}
return $list;
}
}

View file

@ -51,6 +51,7 @@ final class PhabricatorConfigCacheController
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeader($header) ->setHeader($header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->addPropertyList($properties); ->addPropertyList($properties);
} }
@ -102,6 +103,7 @@ final class PhabricatorConfigCacheController
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeaderText(pht('Data Cache')) ->setHeaderText(pht('Data Cache'))
->addPropertyList($properties) ->addPropertyList($properties)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -207,6 +207,7 @@ final class PhabricatorConfigClusterDatabasesController
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeader($header) ->setHeader($header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -157,6 +157,7 @@ final class PhabricatorConfigClusterNotificationsController
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeader($header) ->setHeader($header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -253,6 +253,7 @@ final class PhabricatorConfigClusterRepositoriesController
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeader($header) ->setHeader($header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -12,11 +12,14 @@ abstract class PhabricatorConfigController extends PhabricatorController {
$nav = new AphrontSideNavFilterView(); $nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI())); $nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
$nav->addLabel(pht('Configuration')); $nav->addLabel(pht('Configuration'));
$nav->addFilter('/', pht('Browse Settings')); $nav->addFilter('/', pht('Core Settings'));
$nav->addFilter('all/', pht('All Settings')); $nav->addFilter('application/', pht('Application Settings'));
$nav->addFilter('history/', pht('Settings History')); $nav->addFilter('history/', pht('Settings History'));
$nav->addFilter('version/', pht('Version Information'));
$nav->addFilter('all/', pht('All Settings'));
$nav->addLabel(pht('Setup')); $nav->addLabel(pht('Setup'));
$nav->addFilter('issue/', pht('Setup Issues')); $nav->addFilter('issue/', pht('Setup Issues'));
$nav->addFilter('welcome/', pht('Installation Guide'));
$nav->addLabel(pht('Database')); $nav->addLabel(pht('Database'));
$nav->addFilter('database/', pht('Database Status')); $nav->addFilter('database/', pht('Database Status'));
$nav->addFilter('dbissue/', pht('Database Issues')); $nav->addFilter('dbissue/', pht('Database Issues'));
@ -26,8 +29,6 @@ abstract class PhabricatorConfigController extends PhabricatorController {
$nav->addFilter('cluster/databases/', pht('Database Servers')); $nav->addFilter('cluster/databases/', pht('Database Servers'));
$nav->addFilter('cluster/notifications/', pht('Notification Servers')); $nav->addFilter('cluster/notifications/', pht('Notification Servers'));
$nav->addFilter('cluster/repositories/', pht('Repository Servers')); $nav->addFilter('cluster/repositories/', pht('Repository Servers'));
$nav->addLabel(pht('Welcome'));
$nav->addFilter('welcome/', pht('Welcome Screen'));
$nav->addLabel(pht('Modules')); $nav->addLabel(pht('Modules'));
$modules = PhabricatorConfigModule::getAllModules(); $modules = PhabricatorConfigModule::getAllModules();

View file

@ -149,6 +149,7 @@ final class PhabricatorConfigDatabaseIssueController
$table_box = id(new PHUIObjectBoxView()) $table_box = id(new PHUIObjectBoxView())
->setHeader($this->buildHeaderWithDocumentationLink($title)) ->setHeader($this->buildHeaderWithDocumentationLink($title))
->setFormErrors($errors) ->setFormErrors($errors)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
$nav = $this->buildSideNavView(); $nav = $this->buildSideNavView();

View file

@ -165,10 +165,12 @@ final class PhabricatorConfigDatabaseStatusController
$prop_box = id(new PHUIObjectBoxView()) $prop_box = id(new PHUIObjectBoxView())
->setHeader($this->buildHeaderWithDocumentationLink($title)) ->setHeader($this->buildHeaderWithDocumentationLink($title))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->addPropertyList($properties); ->addPropertyList($properties);
$table_box = id(new PHUIObjectBoxView()) $table_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Databases')) ->setHeaderText(pht('Databases'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
return $this->buildResponse($title, array($prop_box, $table_box)); return $this->buildResponse($title, array($prop_box, $table_box));
@ -263,10 +265,12 @@ final class PhabricatorConfigDatabaseStatusController
$prop_box = id(new PHUIObjectBoxView()) $prop_box = id(new PHUIObjectBoxView())
->setHeader($this->buildHeaderWithDocumentationLink($title)) ->setHeader($this->buildHeaderWithDocumentationLink($title))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->addPropertyList($properties); ->addPropertyList($properties);
$table_box = id(new PHUIObjectBoxView()) $table_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Database Status')) ->setHeaderText(pht('Database Status'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
return $this->buildResponse($title, array($prop_box, $table_box)); return $this->buildResponse($title, array($prop_box, $table_box));
@ -476,14 +480,17 @@ final class PhabricatorConfigDatabaseStatusController
$prop_box = id(new PHUIObjectBoxView()) $prop_box = id(new PHUIObjectBoxView())
->setHeader($this->buildHeaderWithDocumentationLink($title)) ->setHeader($this->buildHeaderWithDocumentationLink($title))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->addPropertyList($properties); ->addPropertyList($properties);
$table_box = id(new PHUIObjectBoxView()) $table_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Database')) ->setHeaderText(pht('Database'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table_view); ->setTable($table_view);
$key_box = id(new PHUIObjectBoxView()) $key_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Keys')) ->setHeaderText(pht('Keys'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($keys_view); ->setTable($keys_view);
return $this->buildResponse($title, array($prop_box, $table_box, $key_box)); return $this->buildResponse($title, array($prop_box, $table_box, $key_box));
@ -620,6 +627,7 @@ final class PhabricatorConfigDatabaseStatusController
$box = id(new PHUIObjectBoxView()) $box = id(new PHUIObjectBoxView())
->setHeader($this->buildHeaderWithDocumentationLink($title)) ->setHeader($this->buildHeaderWithDocumentationLink($title))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->addPropertyList($properties); ->addPropertyList($properties);
return $this->buildResponse($title, $box); return $this->buildResponse($title, $box);
@ -713,6 +721,7 @@ final class PhabricatorConfigDatabaseStatusController
$box = id(new PHUIObjectBoxView()) $box = id(new PHUIObjectBoxView())
->setHeader($this->buildHeaderWithDocumentationLink($title)) ->setHeader($this->buildHeaderWithDocumentationLink($title))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->addPropertyList($properties); ->addPropertyList($properties);
return $this->buildResponse($title, $box); return $this->buildResponse($title, $box);

View file

@ -17,6 +17,7 @@ final class PhabricatorConfigGroupController
$list = $this->buildOptionList($options->getOptions()); $list = $this->buildOptionList($options->getOptions());
$box = id(new PHUIObjectBoxView()) $box = id(new PHUIObjectBoxView())
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setObjectList($list); ->setObjectList($list);
$crumbs = $this $crumbs = $this

View file

@ -31,7 +31,7 @@ final class PhabricatorConfigHistoryController
$title = pht('Settings History'); $title = pht('Settings History');
$crumbs = $this->buildApplicationCrumbs(); $crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb('Config', $this->getApplicationURI()); $crumbs->addTextCrumb('Configuration', $this->getApplicationURI());
$crumbs->addTextCrumb($title, '/config/history/'); $crumbs->addTextCrumb($title, '/config/history/');
$nav = $this->buildSideNavView(); $nav = $this->buildSideNavView();

View file

@ -27,25 +27,28 @@ final class PhabricatorConfigIssueListController
if ($important) { if ($important) {
$setup_issues[] = id(new PHUIObjectBoxView()) $setup_issues[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Important Setup Issues')) ->setHeaderText(pht('Important Setup Issues'))
->setColor(PHUIObjectBoxView::COLOR_RED) ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setObjectList($important); ->setObjectList($important);
} }
if ($php) { if ($php) {
$setup_issues[] = id(new PHUIObjectBoxView()) $setup_issues[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('PHP Setup Issues')) ->setHeaderText(pht('PHP Setup Issues'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setObjectList($php); ->setObjectList($php);
} }
if ($mysql) { if ($mysql) {
$setup_issues[] = id(new PHUIObjectBoxView()) $setup_issues[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('MySQL Setup Issues')) ->setHeaderText(pht('MySQL Setup Issues'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setObjectList($mysql); ->setObjectList($mysql);
} }
if ($other) { if ($other) {
$setup_issues[] = id(new PHUIObjectBoxView()) $setup_issues[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Other Setup Issues')) ->setHeaderText(pht('Other Setup Issues'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setObjectList($other); ->setObjectList($other);
} }

View file

@ -11,27 +11,23 @@ final class PhabricatorConfigListController
$groups = PhabricatorApplicationConfigOptions::loadAll(); $groups = PhabricatorApplicationConfigOptions::loadAll();
$core_list = $this->buildConfigOptionsList($groups, 'core'); $core_list = $this->buildConfigOptionsList($groups, 'core');
$apps_list = $this->buildConfigOptionsList($groups, 'apps');
$title = pht('Phabricator Configuration'); $title = pht('Core Configuration');
$core = id(new PHUIObjectBoxView()) $core = id(new PHUIObjectBoxView())
->setHeaderText($title) ->setHeaderText($title)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setObjectList($core_list); ->setObjectList($core_list);
$apps = id(new PHUIObjectBoxView())
->setHeaderText(pht('Applications Configuration'))
->setObjectList($apps_list);
$crumbs = $this $crumbs = $this
->buildApplicationCrumbs() ->buildApplicationCrumbs()
->addTextCrumb(pht('Config'), $this->getApplicationURI()); ->addTextCrumb(pht('Configuration'), $this->getApplicationURI())
->addTextCrumb($title);
$view = id(new PHUITwoColumnView()) $view = id(new PHUITwoColumnView())
->setNavigation($nav) ->setNavigation($nav)
->setMainColumn(array( ->setMainColumn(array(
$core, $core,
$apps,
)); ));
return $this->newPage() return $this->newPage()

View file

@ -1,19 +1,37 @@
<?php <?php
final class PhabricatorConfigVersionsModule final class PhabricatorConfigVersionController
extends PhabricatorConfigModule { extends PhabricatorConfigController {
public function getModuleKey() { public function handleRequest(AphrontRequest $request) {
return 'versions';
}
public function getModuleName() {
return pht('Versions');
}
public function renderModuleStatus(AphrontRequest $request) {
$viewer = $request->getViewer(); $viewer = $request->getViewer();
$title = pht('Version Information');
$crumbs = $this
->buildApplicationCrumbs()
->addTextCrumb(pht('Configuration'), $this->getApplicationURI())
->addTextCrumb($title);
$versions = $this->renderModuleStatus($viewer);
$nav = $this->buildSideNavView();
$nav->selectFilter('version/');
$view = id(new PHUITwoColumnView())
->setNavigation($nav)
->setMainColumn(array(
$versions,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
public function renderModuleStatus($viewer) {
$versions = $this->loadVersions($viewer); $versions = $this->loadVersions($viewer);
$version_property_list = id(new PHUIPropertyListView()); $version_property_list = id(new PHUIPropertyListView());
@ -22,7 +40,8 @@ final class PhabricatorConfigVersionsModule
} }
$object_box = id(new PHUIObjectBoxView()) $object_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Current Versions')) ->setHeaderText(pht('Version Information'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->addPropertyList($version_property_list); ->addPropertyList($version_property_list);
$phabricator_root = dirname(phutil_get_library_root('phabricator')); $phabricator_root = dirname(phutil_get_library_root('phabricator'));

View file

@ -9,11 +9,11 @@ final class PhabricatorConfigWelcomeController
$nav = $this->buildSideNavView(); $nav = $this->buildSideNavView();
$nav->selectFilter('welcome/'); $nav->selectFilter('welcome/');
$title = pht('Welcome'); $title = pht('Installation Guide');
$crumbs = $this $crumbs = $this
->buildApplicationCrumbs() ->buildApplicationCrumbs()
->addTextCrumb(pht('Welcome')); ->addTextCrumb($title);
$view = id(new PHUITwoColumnView()) $view = id(new PHUITwoColumnView())
->setNavigation($nav) ->setNavigation($nav)

View file

@ -73,6 +73,7 @@ final class PhabricatorConfigCollectorsModule extends PhabricatorConfigModule {
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeader($header) ->setHeader($header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -41,6 +41,7 @@ final class PhabricatorConfigEdgeModule extends PhabricatorConfigModule {
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeaderText(pht('Edge Types')) ->setHeaderText(pht('Edge Types'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -21,6 +21,7 @@ final class PhabricatorConfigHTTPParameterTypesModule
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeaderText(pht('HTTP Parameter Types')) ->setHeaderText(pht('HTTP Parameter Types'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -73,6 +73,7 @@ final class PhabricatorConfigPHIDModule extends PhabricatorConfigModule {
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeaderText(pht('PHID Types')) ->setHeaderText(pht('PHID Types'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -41,6 +41,7 @@ final class PhabricatorConfigRequestExceptionHandlerModule
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeaderText(pht('Exception Handlers')) ->setHeaderText(pht('Exception Handlers'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -40,6 +40,7 @@ final class PhabricatorConfigSiteModule extends PhabricatorConfigModule {
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeaderText(pht('Sites')) ->setHeaderText(pht('Sites'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -213,10 +213,6 @@ final class PhabricatorCoreConfigOptions
->setLocked(true) ->setLocked(true)
->setDescription( ->setDescription(
pht('Customized settings for Phabricator applications.')), pht('Customized settings for Phabricator applications.')),
$this->newOption('welcome.html', 'string', null)
->setLocked(true)
->setDescription(
pht('Custom HTML to show on the main Phabricator dashboard.')),
$this->newOption('phabricator.cache-namespace', 'string', 'phabricator') $this->newOption('phabricator.cache-namespace', 'string', 'phabricator')
->setLocked(true) ->setLocked(true)
->setDescription(pht('Cache namespace.')), ->setDescription(pht('Cache namespace.')),

View file

@ -7,7 +7,6 @@ final class DifferentialRevisionListView extends AphrontView {
private $revisions; private $revisions;
private $handles; private $handles;
private $highlightAge;
private $header; private $header;
private $noDataString; private $noDataString;
private $noBox; private $noBox;
@ -39,11 +38,6 @@ final class DifferentialRevisionListView extends AphrontView {
return $this; return $this;
} }
public function setHighlightAge($bool) {
$this->highlightAge = $bool;
return $this;
}
public function setNoBox($box) { public function setNoBox($box) {
$this->noBox = $box; $this->noBox = $box;
return $this; return $this;

View file

@ -73,6 +73,38 @@ final class DiffusionCommitController extends DiffusionController {
$commit_data = $commit->getCommitData(); $commit_data = $commit->getCommitData();
$is_foreign = $commit_data->getCommitDetail('foreign-svn-stub'); $is_foreign = $commit_data->getCommitDetail('foreign-svn-stub');
$error_panel = null; $error_panel = null;
$hard_limit = 1000;
if ($commit->isImported()) {
$change_query = DiffusionPathChangeQuery::newFromDiffusionRequest(
$drequest);
$change_query->setLimit($hard_limit + 1);
$changes = $change_query->loadChanges();
} else {
$changes = array();
}
$was_limited = (count($changes) > $hard_limit);
if ($was_limited) {
$changes = array_slice($changes, 0, $hard_limit);
}
$count = count($changes);
$is_unreadable = false;
$hint = null;
if (!$count || $commit->isUnreachable()) {
$hint = id(new DiffusionCommitHintQuery())
->setViewer($viewer)
->withRepositoryPHIDs(array($repository->getPHID()))
->withOldCommitIdentifiers(array($commit->getCommitIdentifier()))
->executeOne();
if ($hint) {
$is_unreadable = $hint->isUnreadable();
}
}
if ($is_foreign) { if ($is_foreign) {
$subpath = $commit_data->getCommitDetail('svn-subpath'); $subpath = $commit_data->getCommitDetail('svn-subpath');
@ -130,10 +162,42 @@ final class DiffusionCommitController extends DiffusionController {
$message)); $message));
if ($commit->isUnreachable()) { if ($commit->isUnreachable()) {
$did_rewrite = false;
if ($hint) {
if ($hint->isRewritten()) {
$rewritten = id(new DiffusionCommitQuery())
->setViewer($viewer)
->withRepository($repository)
->withIdentifiers(array($hint->getNewCommitIdentifier()))
->executeOne();
if ($rewritten) {
$did_rewrite = true;
$rewritten_uri = $rewritten->getURI();
$rewritten_name = $rewritten->getLocalName();
$rewritten_link = phutil_tag(
'a',
array(
'href' => $rewritten_uri,
),
$rewritten_name);
$this->commitErrors[] = pht(
'This commit was rewritten after it was published, which '.
'changed the commit hash. This old version of the commit is '.
'no longer reachable from any branch, tag or ref. The new '.
'version of this commit is %s.',
$rewritten_link);
}
}
}
if (!$did_rewrite) {
$this->commitErrors[] = pht( $this->commitErrors[] = pht(
'This commit has been deleted in the repository: it is no longer '. 'This commit has been deleted in the repository: it is no longer '.
'reachable from any branch, tag, or ref.'); 'reachable from any branch, tag, or ref.');
} }
}
if ($this->getCommitErrors()) { if ($this->getCommitErrors()) {
$error_panel = id(new PHUIInfoView()) $error_panel = id(new PHUIInfoView())
@ -143,47 +207,23 @@ final class DiffusionCommitController extends DiffusionController {
} }
$timeline = $this->buildComments($commit); $timeline = $this->buildComments($commit);
$hard_limit = 1000;
if ($commit->isImported()) {
$change_query = DiffusionPathChangeQuery::newFromDiffusionRequest(
$drequest);
$change_query->setLimit($hard_limit + 1);
$changes = $change_query->loadChanges();
} else {
$changes = array();
}
$was_limited = (count($changes) > $hard_limit);
if ($was_limited) {
$changes = array_slice($changes, 0, $hard_limit);
}
$merge_table = $this->buildMergesTable($commit); $merge_table = $this->buildMergesTable($commit);
$highlighted_audits = $commit->getAuthorityAudits( $highlighted_audits = $commit->getAuthorityAudits(
$viewer, $viewer,
$this->auditAuthorityPHIDs); $this->auditAuthorityPHIDs);
$count = count($changes);
$bad_commit = null;
if ($count == 0) {
$bad_commit = queryfx_one(
id(new PhabricatorRepository())->establishConnection('r'),
'SELECT * FROM %T WHERE fullCommitName = %s',
PhabricatorRepository::TABLE_BADCOMMIT,
$commit->getMonogram());
}
$show_changesets = false; $show_changesets = false;
$info_panel = null; $info_panel = null;
$change_list = null; $change_list = null;
$change_table = null; $change_table = null;
if ($bad_commit) { if ($is_unreadable) {
$info_panel = $this->renderStatusMessage( $info_panel = $this->renderStatusMessage(
pht('Bad Commit'), pht('Unreadable Commit'),
$bad_commit['description']); pht(
'This commit has been marked as unreadable by an administrator. '.
'It may have been corrupted or created improperly by an external '.
'tool.'));
} else if ($is_foreign) { } else if ($is_foreign) {
// Don't render anything else. // Don't render anything else.
} else if (!$commit->isImported()) { } else if (!$commit->isImported()) {

View file

@ -0,0 +1,116 @@
<?php
final class DiffusionCommitHintQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $repositoryPHIDs;
private $oldCommitIdentifiers;
private $commits;
private $commitMap;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withRepositoryPHIDs(array $phids) {
$this->repositoryPHIDs = $phids;
return $this;
}
public function withOldCommitIdentifiers(array $identifiers) {
$this->oldCommitIdentifiers = $identifiers;
return $this;
}
public function withCommits(array $commits) {
assert_instances_of($commits, 'PhabricatorRepositoryCommit');
$repository_phids = array();
foreach ($commits as $commit) {
$repository_phids[] = $commit->getRepository()->getPHID();
}
$this->repositoryPHIDs = $repository_phids;
$this->oldCommitIdentifiers = mpull($commits, 'getCommitIdentifier');
$this->commits = $commits;
return $this;
}
public function getCommitMap() {
if ($this->commitMap === null) {
throw new PhutilInvalidStateException('execute');
}
return $this->commitMap;
}
public function newResultObject() {
return new PhabricatorRepositoryCommitHint();
}
protected function willExecute() {
$this->commitMap = array();
}
protected function loadPage() {
return $this->loadStandardPage($this->newResultObject());
}
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
$where = parent::buildWhereClauseParts($conn);
if ($this->ids !== null) {
$where[] = qsprintf(
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->repositoryPHIDs !== null) {
$where[] = qsprintf(
$conn,
'repositoryPHID IN (%Ls)',
$this->repositoryPHIDs);
}
if ($this->oldCommitIdentifiers !== null) {
$where[] = qsprintf(
$conn,
'oldCommitIdentifier IN (%Ls)',
$this->oldCommitIdentifiers);
}
return $where;
}
protected function didFilterPage(array $hints) {
if ($this->commits) {
$map = array();
foreach ($this->commits as $commit) {
$repository_phid = $commit->getRepository()->getPHID();
$identifier = $commit->getCommitIdentifier();
$map[$repository_phid][$identifier] = $commit->getPHID();
}
foreach ($hints as $hint) {
$repository_phid = $hint->getRepositoryPHID();
$identifier = $hint->getOldCommitIdentifier();
if (isset($map[$repository_phid][$identifier])) {
$commit_phid = $map[$repository_phid][$identifier];
$this->commitMap[$commit_phid] = $hint;
}
}
}
return $hints;
}
public function getQueryApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
}

View file

@ -14,6 +14,25 @@ final class DiffusionCommitRemarkupRule extends PhabricatorObjectRemarkupRule {
return PhabricatorRepositoryCommitPHIDType::getCommitObjectNamePattern(); return PhabricatorRepositoryCommitPHIDType::getCommitObjectNamePattern();
} }
protected function getObjectNameText(
$object,
PhabricatorObjectHandle $handle,
$id) {
// If this commit is unreachable, return the handle name instead of the
// normal text because it may be able to tell the user that the commit
// was rewritten and where to find the new one.
// By default, we try to preserve what the user actually typed as
// faithfully as possible, but if they're referencing a deleted commit
// it's more valuable to try to pick up any rewrite. See T11522.
if ($object->isUnreachable()) {
return $handle->getName();
}
return parent::getObjectNameText($object, $handle, $id);
}
protected function loadObjects(array $ids) { protected function loadObjects(array $ids) {
$viewer = $this->getEngine()->getConfig('viewer'); $viewer = $this->getEngine()->getConfig('viewer');

View file

@ -2,8 +2,6 @@
final class PhabricatorHomeMainController extends PhabricatorHomeController { final class PhabricatorHomeMainController extends PhabricatorHomeController {
private $minipanels = array();
public function shouldAllowPublic() { public function shouldAllowPublic() {
return true; return true;
} }
@ -13,32 +11,27 @@ final class PhabricatorHomeMainController extends PhabricatorHomeController {
} }
public function handleRequest(AphrontRequest $request) { public function handleRequest(AphrontRequest $request) {
$user = $request->getUser(); $viewer = $request->getViewer();
$dashboard = PhabricatorDashboardInstall::getDashboard( $dashboard = PhabricatorDashboardInstall::getDashboard(
$user, $viewer,
$user->getPHID(), $viewer->getPHID(),
get_class($this->getCurrentApplication())); get_class($this->getCurrentApplication()));
if (!$dashboard) { if (!$dashboard) {
$dashboard = PhabricatorDashboardInstall::getDashboard( $dashboard = PhabricatorDashboardInstall::getDashboard(
$user, $viewer,
PhabricatorHomeApplication::DASHBOARD_DEFAULT, PhabricatorHomeApplication::DASHBOARD_DEFAULT,
get_class($this->getCurrentApplication())); get_class($this->getCurrentApplication()));
} }
if ($dashboard) { if ($dashboard) {
$content = id(new PhabricatorDashboardRenderingEngine()) $content = id(new PhabricatorDashboardRenderingEngine())
->setViewer($user) ->setViewer($viewer)
->setDashboard($dashboard) ->setDashboard($dashboard)
->renderDashboard(); ->renderDashboard();
} else { } else {
$project_query = new PhabricatorProjectQuery(); $content = $this->buildMainResponse();
$project_query->setViewer($user);
$project_query->withMemberPHIDs(array($user->getPHID()));
$projects = $project_query->execute();
$content = $this->buildMainResponse($projects);
} }
if (!$request->getURIData('only')) { if (!$request->getURIData('only')) {
@ -46,7 +39,7 @@ final class PhabricatorHomeMainController extends PhabricatorHomeController {
$nav->appendChild( $nav->appendChild(
array( array(
$content, $content,
id(new PhabricatorGlobalUploadTargetView())->setUser($user), id(new PhabricatorGlobalUploadTargetView())->setUser($viewer),
)); ));
$content = $nav; $content = $nav;
} }
@ -58,354 +51,180 @@ final class PhabricatorHomeMainController extends PhabricatorHomeController {
} }
private function buildMainResponse(array $projects) { private function buildMainResponse() {
assert_instances_of($projects, 'PhabricatorProject'); require_celerity_resource('phabricator-dashboard-css');
$viewer = $this->getRequest()->getUser(); $viewer = $this->getViewer();
$has_maniphest = PhabricatorApplication::isClassInstalledForViewer( $has_maniphest = PhabricatorApplication::isClassInstalledForViewer(
'PhabricatorManiphestApplication', 'PhabricatorManiphestApplication',
$viewer); $viewer);
$has_audit = PhabricatorApplication::isClassInstalledForViewer( $has_diffusion = PhabricatorApplication::isClassInstalledForViewer(
'PhabricatorAuditApplication', 'PhabricatorDiffusionApplication',
$viewer); $viewer);
$has_differential = PhabricatorApplication::isClassInstalledForViewer( $has_differential = PhabricatorApplication::isClassInstalledForViewer(
'PhabricatorDifferentialApplication', 'PhabricatorDifferentialApplication',
$viewer); $viewer);
if ($has_maniphest) { $revision_panel = null;
$unbreak_panel = $this->buildUnbreakNowPanel();
$triage_panel = $this->buildNeedsTriagePanel($projects);
$tasks_panel = $this->buildTasksPanel();
} else {
$unbreak_panel = null;
$triage_panel = null;
$tasks_panel = null;
}
if ($has_audit) {
$audit_panel = $this->buildAuditPanel();
$commit_panel = $this->buildCommitPanel();
} else {
$audit_panel = null;
$commit_panel = null;
}
if (PhabricatorEnv::getEnvConfig('welcome.html') !== null) {
$welcome_panel = $this->buildWelcomePanel();
} else {
$welcome_panel = null;
}
if ($has_differential) { if ($has_differential) {
$revision_panel = $this->buildRevisionPanel(); $revision_panel = $this->buildRevisionPanel();
} else {
$revision_panel = null;
} }
$home = phutil_tag( $tasks_panel = null;
if ($has_maniphest) {
$tasks_panel = $this->buildTasksPanel();
}
$repository_panel = null;
if ($has_diffusion) {
$repository_panel = $this->buildRepositoryPanel();
}
$feed_panel = $this->buildFeedPanel();
$dashboard = id(new AphrontMultiColumnView())
->setFluidlayout(true)
->setGutter(AphrontMultiColumnView::GUTTER_LARGE);
$main_panel = phutil_tag(
'div', 'div',
array( array(
'class' => 'homepage-panel', 'class' => 'homepage-panel',
), ),
array( array(
$welcome_panel,
$unbreak_panel,
$triage_panel,
$revision_panel, $revision_panel,
$tasks_panel, $tasks_panel,
$audit_panel, $repository_panel,
$commit_panel,
$this->minipanels,
)); ));
return $home; $dashboard->addColumn($main_panel, 'thirds');
}
private function buildUnbreakNowPanel() { $side_panel = phutil_tag(
$unbreak_now = PhabricatorEnv::getEnvConfig( 'div',
'maniphest.priorities.unbreak-now'); array(
if (!$unbreak_now) { 'class' => 'homepage-side-panel',
return null; ),
} array(
$feed_panel,
));
$dashboard->addColumn($side_panel, 'third');
$user = $this->getRequest()->getUser(); $view = id(new PHUIBoxView())
->addClass('dashboard-view')
$task_query = id(new ManiphestTaskQuery()) ->appendChild($dashboard);
->setViewer($user)
->withStatuses(ManiphestTaskStatus::getOpenStatusConstants())
->withPriorities(array($unbreak_now))
->needProjectPHIDs(true)
->setLimit(10);
$tasks = $task_query->execute();
if (!$tasks) {
return $this->renderMiniPanel(
pht('No "Unbreak Now!" Tasks'),
pht('Nothing appears to be critically broken right now.'));
}
$href = urisprintf(
'/maniphest/?statuses=open()&priorities=%s#R',
$unbreak_now);
$title = pht('Unbreak Now!');
$panel = new PHUIObjectBoxView();
$panel->setHeader($this->renderSectionHeader($title, $href));
$panel->setObjectList($this->buildTaskListView($tasks));
return $panel;
}
private function buildNeedsTriagePanel(array $projects) {
assert_instances_of($projects, 'PhabricatorProject');
$needs_triage = PhabricatorEnv::getEnvConfig(
'maniphest.priorities.needs-triage');
if (!$needs_triage) {
return null;
}
$user = $this->getRequest()->getUser();
if (!$user->isLoggedIn()) {
return null;
}
if ($projects) {
$task_query = id(new ManiphestTaskQuery())
->setViewer($user)
->withStatuses(ManiphestTaskStatus::getOpenStatusConstants())
->withPriorities(array($needs_triage))
->withEdgeLogicPHIDs(
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
PhabricatorQueryConstraint::OPERATOR_OR,
mpull($projects, 'getPHID'))
->needProjectPHIDs(true)
->setLimit(10);
$tasks = $task_query->execute();
} else {
$tasks = array();
}
if (!$tasks) {
return $this->renderMiniPanel(
pht('No "Needs Triage" Tasks'),
pht('No tasks tagged with projects you are a member of need triage.'));
}
$title = pht('Needs Triage');
$href = urisprintf(
'/maniphest/?statuses=open()&priorities=%s&projects=projects(%s)#R',
$needs_triage,
$user->getPHID());
$panel = new PHUIObjectBoxView();
$panel->setHeader($this->renderSectionHeader($title, $href));
$panel->setObjectList($this->buildTaskListView($tasks));
return $panel;
}
private function buildRevisionPanel() {
$viewer = $this->getViewer();
$revisions = PhabricatorDifferentialApplication::loadNeedAttentionRevisions(
$viewer);
if (!$revisions) {
return $this->renderMiniPanel(
pht('No Waiting Revisions'),
pht('No revisions are waiting on you.'));
}
$title = pht('Revisions Waiting on You');
$href = '/differential/';
$panel = new PHUIObjectBoxView();
$panel->setHeader($this->renderSectionHeader($title, $href));
$revision_view = id(new DifferentialRevisionListView())
->setHighlightAge(true)
->setRevisions($revisions)
->setUser($viewer);
$phids = array_merge(
array($viewer->getPHID()),
$revision_view->getRequiredHandlePHIDs());
$handles = $this->loadViewerHandles($phids);
$revision_view->setHandles($handles);
$list_view = $revision_view->render();
$panel->setObjectList($list_view);
return $panel;
}
private function buildWelcomePanel() {
$panel = new PHUIObjectBoxView();
$panel->setHeaderText(pht('Welcome'));
$panel->appendChild(
phutil_safe_html(
PhabricatorEnv::getEnvConfig('welcome.html')));
return $panel;
}
private function buildTasksPanel() {
$user = $this->getRequest()->getUser();
$user_phid = $user->getPHID();
$task_query = id(new ManiphestTaskQuery())
->setViewer($user)
->withStatuses(ManiphestTaskStatus::getOpenStatusConstants())
->setGroupBy(ManiphestTaskQuery::GROUP_PRIORITY)
->withOwners(array($user_phid))
->needProjectPHIDs(true)
->setLimit(10);
$tasks = $task_query->execute();
if (!$tasks) {
return $this->renderMiniPanel(
pht('No Assigned Tasks'),
pht('You have no assigned tasks.'));
}
$title = pht('Assigned Tasks');
$href = '/maniphest/query/assigned/';
$panel = new PHUIObjectBoxView();
$panel->setHeader($this->renderSectionHeader($title, $href));
$panel->setObjectList($this->buildTaskListView($tasks));
return $panel;
}
private function buildTaskListView(array $tasks) {
assert_instances_of($tasks, 'ManiphestTask');
$user = $this->getRequest()->getUser();
$phids = array_merge(
array_filter(mpull($tasks, 'getOwnerPHID')),
array_mergev(mpull($tasks, 'getProjectPHIDs')));
$handles = $this->loadViewerHandles($phids);
$view = new ManiphestTaskListView();
$view->setTasks($tasks);
$view->setUser($user);
$view->setHandles($handles);
return $view; return $view;
} }
private function renderSectionHeader($title, $href) { private function buildHomepagePanel($title, $href, $view) {
$title = phutil_tag( $title = phutil_tag(
'a', 'a',
array( array(
'href' => $href, 'href' => $href,
), ),
$title); $title);
$icon = id(new PHUIIconView()) $icon = id(new PHUIIconView())
->setIcon('fa-search') ->setIcon('fa-search')
->setHref($href); ->setHref($href);
$header = id(new PHUIHeaderView()) $header = id(new PHUIHeaderView())
->setHeader($title) ->setHeader($title)
->addActionItem($icon); ->addActionItem($icon);
return $header;
$box = id(new PHUIObjectBoxView())
->setHeader($header);
if ($view->getObjectList()) {
$box->setObjectList($view->getObjectList());
}
if ($view->getContent()) {
$box->appendChild($view->getContent());
} }
private function renderMiniPanel($title, $body) { return $box;
$panel = new PHUIInfoView();
$panel->setSeverity(PHUIInfoView::SEVERITY_NODATA);
$panel->appendChild(
phutil_tag(
'p',
array(
),
array(
phutil_tag('strong', array(), $title.': '),
$body,
)));
$this->minipanels[] = $panel;
} }
public function buildAuditPanel() { private function buildRevisionPanel() {
$request = $this->getRequest(); $viewer = $this->getViewer();
$user = $request->getUser(); if (!$viewer->isLoggedIn()) {
return null;
$phids = PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($user);
$query = id(new DiffusionCommitQuery())
->setViewer($user)
->withNeedsAuditByPHIDs($phids)
->withAuditStatus(DiffusionCommitQuery::AUDIT_STATUS_OPEN)
->needAuditRequests(true)
->needCommitData(true)
->setLimit(10);
$commits = $query->execute();
if (!$commits) {
return $this->renderMinipanel(
pht('No Audits'),
pht('No commits are waiting for you to audit them.'));
} }
$view = id(new PhabricatorAuditListView()) $engine = new DifferentialRevisionSearchEngine();
->setCommits($commits) $engine->setViewer($viewer);
->setUser($user); $saved = $engine->buildSavedQueryFromBuiltin('active');
$query = $engine->buildQueryFromSavedQuery($saved);
$pager = $engine->newPagerForSavedQuery($saved);
$pager->setPageSize(15);
$results = $engine->executeQuery($query, $pager);
$view = $engine->renderResults($results, $saved);
$phids = $view->getRequiredHandlePHIDs(); $title = pht('Active Revisions');
$handles = $this->loadViewerHandles($phids); $href = '/differential/query/active/';
$view->setHandles($handles);
$title = pht('Audits'); return $this->buildHomepagePanel($title, $href, $view);
$href = '/audit/';
$panel = new PHUIObjectBoxView();
$panel->setHeader($this->renderSectionHeader($title, $href));
$panel->setObjectList($view);
return $panel;
} }
public function buildCommitPanel() { private function buildTasksPanel() {
$request = $this->getRequest(); $viewer = $this->getViewer();
$user = $request->getUser();
$phids = array($user->getPHID()); $query = 'assigned';
$title = pht('Assigned Tasks');
$query = id(new DiffusionCommitQuery()) $href = '/maniphest/query/assigned/';
->setViewer($user) if (!$viewer->isLoggedIn()) {
->withAuthorPHIDs($phids) $query = 'open';
->withAuditStatus(DiffusionCommitQuery::AUDIT_STATUS_CONCERN) $title = pht('Open Tasks');
->needCommitData(true) $href = '/maniphest/query/open/';
->needAuditRequests(true)
->setLimit(10);
$commits = $query->execute();
if (!$commits) {
return $this->renderMinipanel(
pht('No Problem Commits'),
pht('No one has raised concerns with your commits.'));
} }
$view = id(new PhabricatorAuditListView()) $engine = new ManiphestTaskSearchEngine();
->setCommits($commits) $engine->setViewer($viewer);
->setUser($user); $saved = $engine->buildSavedQueryFromBuiltin($query);
$query = $engine->buildQueryFromSavedQuery($saved);
$pager = $engine->newPagerForSavedQuery($saved);
$pager->setPageSize(15);
$results = $engine->executeQuery($query, $pager);
$view = $engine->renderResults($results, $saved);
$phids = $view->getRequiredHandlePHIDs(); return $this->buildHomepagePanel($title, $href, $view);
$handles = $this->loadViewerHandles($phids); }
$view->setHandles($handles);
$title = pht('Problem Commits'); public function buildFeedPanel() {
$href = '/audit/'; $viewer = $this->getViewer();
$panel = new PHUIObjectBoxView();
$panel->setHeader($this->renderSectionHeader($title, $href));
$panel->setObjectList($view);
return $panel; $engine = new PhabricatorFeedSearchEngine();
$engine->setViewer($viewer);
$saved = $engine->buildSavedQueryFromBuiltin('all');
$query = $engine->buildQueryFromSavedQuery($saved);
$pager = $engine->newPagerForSavedQuery($saved);
$pager->setPageSize(40);
$results = $engine->executeQuery($query, $pager);
$view = $engine->renderResults($results, $saved);
$title = pht('Recent Activity');
$href = '/feed/';
return $this->buildHomepagePanel($title, $href, $view);
}
public function buildRepositoryPanel() {
$viewer = $this->getViewer();
$engine = new PhabricatorRepositorySearchEngine();
$engine->setViewer($viewer);
$saved = $engine->buildSavedQueryFromBuiltin('active');
$query = $engine->buildQueryFromSavedQuery($saved);
$pager = $engine->newPagerForSavedQuery($saved);
$pager->setPageSize(5);
$results = $engine->executeQuery($query, $pager);
$view = $engine->renderResults($results, $saved);
$title = pht('Active Repositories');
$href = '/diffusion/';
return $this->buildHomepagePanel($title, $href, $view);
} }
} }

View file

@ -356,28 +356,6 @@ EOTEXT
'string', 'string',
'[Maniphest]') '[Maniphest]')
->setDescription(pht('Subject prefix for Maniphest mail.')), ->setDescription(pht('Subject prefix for Maniphest mail.')),
$this->newOption(
'maniphest.priorities.unbreak-now',
'int',
100)
->setSummary(pht('Priority used to populate "Unbreak Now" on home.'))
->setDescription(
pht(
'Temporary setting. If set, this priority is used to populate the '.
'"Unbreak Now" panel on the home page. You should adjust this if '.
'you adjust priorities using `%s`.',
'maniphest.priorities')),
$this->newOption(
'maniphest.priorities.needs-triage',
'int',
90)
->setSummary(pht('Priority used to populate "Needs Triage" on home.'))
->setDescription(
pht(
'Temporary setting. If set, this priority is used to populate the '.
'"Needs Triage" panel on the home page. You should adjust this if '.
'you adjust priorities using `%s`.',
'maniphest.priorities')),
$this->newOption('maniphest.points', $points_type, array()) $this->newOption('maniphest.points', $points_type, array())
->setSummary(pht('Configure point values for tasks.')) ->setSummary(pht('Configure point values for tasks.'))
->setDescription($points_description) ->setDescription($points_description)

View file

@ -41,7 +41,8 @@ final class ManiphestTaskResultListView extends ManiphestView {
// If we didn't match anything, just pick up the default empty state. // If we didn't match anything, just pick up the default empty state.
if (!$tasks) { if (!$tasks) {
return id(new PHUIObjectItemListView()) return id(new PHUIObjectItemListView())
->setUser($viewer); ->setUser($viewer)
->setNoDataString(pht('No tasks found.'));
} }
$group_parameter = nonempty($query->getParameter('group'), 'priority'); $group_parameter = nonempty($query->getParameter('group'), 'priority');

View file

@ -38,7 +38,9 @@ final class PhabricatorApplicationDatasource
->setDisplayType($application->getShortDescription()) ->setDisplayType($application->getShortDescription())
->setImageuRI($application->getIconURI()) ->setImageuRI($application->getIconURI())
->setPriorityType('apps') ->setPriorityType('apps')
->setImageSprite('phabricator-search-icon '.$img); ->setImageSprite('phabricator-search-icon '.$img)
->setIcon($application->getIcon())
->addAttribute($application->getShortDescription());
} }
return $this->filterResultsAgainstTokens($results); return $this->filterResultsAgainstTokens($results);

View file

@ -3,20 +3,12 @@
final class PhabricatorPeopleApproveController final class PhabricatorPeopleApproveController
extends PhabricatorPeopleController { extends PhabricatorPeopleController {
private $id; public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
public function willProcessRequest(array $data) {
$this->id = idx($data, 'id');
}
public function processRequest() {
$request = $this->getRequest();
$admin = $request->getUser();
$user = id(new PhabricatorPeopleQuery()) $user = id(new PhabricatorPeopleQuery())
->setViewer($admin) ->setViewer($viewer)
->withIDs(array($this->id)) ->withIDs(array($request->getURIData('id')))
->executeOne(); ->executeOne();
if (!$user) { if (!$user) {
return new Aphront404Response(); return new Aphront404Response();
@ -26,7 +18,7 @@ final class PhabricatorPeopleApproveController
if ($request->isFormPost()) { if ($request->isFormPost()) {
id(new PhabricatorUserEditor()) id(new PhabricatorUserEditor())
->setActor($admin) ->setActor($viewer)
->approveUser($user, true); ->approveUser($user, true);
$title = pht( $title = pht(
@ -39,12 +31,12 @@ final class PhabricatorPeopleApproveController
'Your Phabricator account (%s) has been approved by %s. You can '. 'Your Phabricator account (%s) has been approved by %s. You can '.
'login here:', 'login here:',
$user->getUsername(), $user->getUsername(),
$admin->getUsername()), $viewer->getUsername()),
PhabricatorEnv::getProductionURI('/')); PhabricatorEnv::getProductionURI('/'));
$mail = id(new PhabricatorMetaMTAMail()) $mail = id(new PhabricatorMetaMTAMail())
->addTos(array($user->getPHID())) ->addTos(array($user->getPHID()))
->addCCs(array($admin->getPHID())) ->addCCs(array($viewer->getPHID()))
->setSubject('[Phabricator] '.$title) ->setSubject('[Phabricator] '.$title)
->setForceDelivery(true) ->setForceDelivery(true)
->setBody($body) ->setBody($body)

View file

@ -3,8 +3,6 @@
final class PhabricatorPeopleListController final class PhabricatorPeopleListController
extends PhabricatorPeopleController { extends PhabricatorPeopleController {
private $key;
public function shouldAllowPublic() { public function shouldAllowPublic() {
return true; return true;
} }
@ -13,16 +11,12 @@ final class PhabricatorPeopleListController
return false; return false;
} }
public function willProcessRequest(array $data) { public function handleRequest(AphrontRequest $request) {
$this->key = idx($data, 'key');
}
public function processRequest() {
$this->requireApplicationCapability( $this->requireApplicationCapability(
PeopleBrowseUserDirectoryCapability::CAPABILITY); PeopleBrowseUserDirectoryCapability::CAPABILITY);
$controller = id(new PhabricatorApplicationSearchController()) $controller = id(new PhabricatorApplicationSearchController())
->setQueryKey($this->key) ->setQueryKey($request->getURIData('key'))
->setSearchEngine(new PhabricatorPeopleSearchEngine()) ->setSearchEngine(new PhabricatorPeopleSearchEngine())
->setNavigation($this->buildSideNavView()); ->setNavigation($this->buildSideNavView());

View file

@ -3,15 +3,9 @@
final class PhabricatorPeopleLogsController final class PhabricatorPeopleLogsController
extends PhabricatorPeopleController { extends PhabricatorPeopleController {
private $queryKey; public function handleRequest(AphrontRequest $request) {
public function willProcessRequest(array $data) {
$this->queryKey = idx($data, 'queryKey');
}
public function processRequest() {
$controller = id(new PhabricatorApplicationSearchController()) $controller = id(new PhabricatorApplicationSearchController())
->setQueryKey($this->queryKey) ->setQueryKey($request->getURIData('queryKey'))
->setSearchEngine(new PhabricatorPeopleLogSearchEngine()) ->setSearchEngine(new PhabricatorPeopleLogSearchEngine())
->setNavigation($this->buildSideNavView()); ->setNavigation($this->buildSideNavView());

View file

@ -108,7 +108,7 @@ final class PhabricatorUserLog extends PhabricatorUserDAO
$log->setUserPHID((string)$object_phid); $log->setUserPHID((string)$object_phid);
$log->setAction($action); $log->setAction($action);
$log->remoteAddr = idx($_SERVER, 'REMOTE_ADDR', ''); $log->remoteAddr = (string)idx($_SERVER, 'REMOTE_ADDR', '');
return $log; return $log;
} }

View file

@ -406,9 +406,17 @@ final class PhabricatorRepositoryDiscoveryEngine
$refs = array(); $refs = array();
foreach ($commits as $commit) { foreach ($commits as $commit) {
$epoch = $stream->getCommitDate($commit);
// If the epoch doesn't fit into a uint32, treat it as though it stores
// the current time. For discussion, see T11537.
if ($epoch > 0xFFFFFFFF) {
$epoch = PhabricatorTime::getNow();
}
$refs[] = id(new PhabricatorRepositoryCommitRef()) $refs[] = id(new PhabricatorRepositoryCommitRef())
->setIdentifier($commit) ->setIdentifier($commit)
->setEpoch($stream->getCommitDate($commit)) ->setEpoch($epoch)
->setCanCloseImmediately($close_immediately) ->setCanCloseImmediately($close_immediately)
->setParents($stream->getParents($commit)); ->setParents($stream->getParents($commit));
} }

View file

@ -0,0 +1,97 @@
<?php
final class PhabricatorRepositoryManagementHintWorkflow
extends PhabricatorRepositoryManagementWorkflow {
protected function didConstruct() {
$this
->setName('hint')
->setExamples('**hint** [options] ...')
->setSynopsis(
pht(
'Write hints about unusual (rewritten or unreadable) commits.'))
->setArguments(array());
}
public function execute(PhutilArgumentParser $args) {
$viewer = $this->getViewer();
echo tsprintf(
"%s\n",
pht('Reading list of hints from stdin...'));
$hints = file_get_contents('php://stdin');
if ($hints === false) {
throw new PhutilArgumentUsageException(pht('Failed to read stdin.'));
}
try {
$hints = phutil_json_decode($hints);
} catch (Exception $ex) {
throw new PhutilArgumentUsageException(
pht(
'Expected a list of hints in JSON format: %s',
$ex->getMessage()));
}
$repositories = array();
foreach ($hints as $idx => $hint) {
if (!is_array($hint)) {
throw new PhutilArgumentUsageException(
pht(
'Each item in the list of hints should be a JSON object, but '.
'the item at index "%s" is not.',
$idx));
}
try {
PhutilTypeSpec::checkMap(
$hint,
array(
'repository' => 'string|int',
'old' => 'string',
'new' => 'optional string|null',
'hint' => 'string',
));
} catch (Exception $ex) {
throw new PhutilArgumentUsageException(
pht(
'Unexpected hint format at index "%s": %s',
$idx,
$ex->getMessage()));
}
$repository_identifier = $hint['repository'];
$repository = idx($repositories, $repository_identifier);
if (!$repository) {
$repository = id(new PhabricatorRepositoryQuery())
->setViewer($viewer)
->withIdentifiers(array($repository_identifier))
->executeOne();
if (!$repository) {
throw new PhutilArgumentUsageException(
pht(
'Repository identifier "%s" (in hint at index "%s") does not '.
'identify a valid repository.',
$repository_identifier,
$idx));
}
$repositories[$repository_identifier] = $repository;
}
PhabricatorRepositoryCommitHint::updateHint(
$repository->getPHID(),
$hint['old'],
idx($hint, 'new'),
$hint['hint']);
echo tsprintf(
"%s\n",
pht(
'Updated hint for "%s".',
$hint['old']));
}
}
}

View file

@ -29,12 +29,47 @@ final class PhabricatorRepositoryCommitPHIDType extends PhabricatorPHIDType {
array $handles, array $handles,
array $objects) { array $objects) {
$unreachable = array();
foreach ($handles as $phid => $handle) {
$commit = $objects[$phid];
if ($commit->isUnreachable()) {
$unreachable[$phid] = $commit;
}
}
if ($unreachable) {
$query = id(new DiffusionCommitHintQuery())
->setViewer($query->getViewer())
->withCommits($unreachable);
$query->execute();
$hints = $query->getCommitMap();
} else {
$hints = array();
}
foreach ($handles as $phid => $handle) { foreach ($handles as $phid => $handle) {
$commit = $objects[$phid]; $commit = $objects[$phid];
$repository = $commit->getRepository(); $repository = $commit->getRepository();
$commit_identifier = $commit->getCommitIdentifier(); $commit_identifier = $commit->getCommitIdentifier();
$name = $repository->formatCommitName($commit_identifier); $name = $repository->formatCommitName($commit_identifier);
if ($commit->isUnreachable()) {
$handle->setStatus(PhabricatorObjectHandle::STATUS_CLOSED);
// If we have a hint about this commit being rewritten, add the
// rewrite target to the handle name. This reduces the chance users
// will be caught offguard by the rewrite.
$hint = idx($hints, $phid);
if ($hint && $hint->isRewritten()) {
$new_name = $hint->getNewCommitIdentifier();
$new_name = $repository->formatCommitName($new_name);
$name = pht("%s \xE2\x99\xBB %s", $name, $new_name);
}
}
$summary = $commit->getSummary(); $summary = $commit->getSummary();
if (strlen($summary)) { if (strlen($summary)) {
$full_name = $name.': '.$summary; $full_name = $name.': '.$summary;
@ -46,10 +81,6 @@ final class PhabricatorRepositoryCommitPHIDType extends PhabricatorPHIDType {
$handle->setFullName($full_name); $handle->setFullName($full_name);
$handle->setURI($commit->getURI()); $handle->setURI($commit->getURI());
$handle->setTimestamp($commit->getEpoch()); $handle->setTimestamp($commit->getEpoch());
if ($commit->isUnreachable()) {
$handle->setStatus(PhabricatorObjectHandle::STATUS_CLOSED);
}
} }
} }

View file

@ -35,7 +35,6 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
const TABLE_PATHCHANGE = 'repository_pathchange'; const TABLE_PATHCHANGE = 'repository_pathchange';
const TABLE_FILESYSTEM = 'repository_filesystem'; const TABLE_FILESYSTEM = 'repository_filesystem';
const TABLE_SUMMARY = 'repository_summary'; const TABLE_SUMMARY = 'repository_summary';
const TABLE_BADCOMMIT = 'repository_badcommit';
const TABLE_LINTMESSAGE = 'repository_lintmessage'; const TABLE_LINTMESSAGE = 'repository_lintmessage';
const TABLE_PARENTS = 'repository_parents'; const TABLE_PARENTS = 'repository_parents';
const TABLE_COVERAGE = 'repository_coverage'; const TABLE_COVERAGE = 'repository_coverage';

View file

@ -0,0 +1,137 @@
<?php
final class PhabricatorRepositoryCommitHint
extends PhabricatorRepositoryDAO
implements PhabricatorPolicyInterface {
protected $repositoryPHID;
protected $oldCommitIdentifier;
protected $newCommitIdentifier;
protected $hintType;
const HINT_NONE = 'none';
const HINT_REWRITTEN = 'rewritten';
const HINT_UNREADABLE = 'unreadable';
protected function getConfiguration() {
return array(
self::CONFIG_TIMESTAMPS => false,
self::CONFIG_COLUMN_SCHEMA => array(
'oldCommitIdentifier' => 'text40',
'newCommitIdentifier' => 'text40?',
'hintType' => 'text32',
),
self::CONFIG_KEY_SCHEMA => array(
'key_old' => array(
'columns' => array('repositoryPHID', 'oldCommitIdentifier'),
'unique' => true,
),
),
) + parent::getConfiguration();
}
public static function getAllHintTypes() {
return array(
self::HINT_NONE,
self::HINT_REWRITTEN,
self::HINT_UNREADABLE,
);
}
public static function updateHint($repository_phid, $old, $new, $type) {
switch ($type) {
case self::HINT_NONE:
break;
case self::HINT_REWRITTEN:
if (!$new) {
throw new Exception(
pht(
'When hinting a commit ("%s") as rewritten, you must provide '.
'the commit it was rewritten into.',
$old));
}
break;
case self::HINT_UNREADABLE:
if ($new) {
throw new Exception(
pht(
'When hinting a commit ("%s") as unreadable, you must not '.
'provide a new commit ("%s").',
$old,
$new));
}
break;
default:
$all_types = self::getAllHintTypes();
throw new Exception(
pht(
'Hint type ("%s") for commit ("%s") is not valid. Valid hints '.
'are: %s.',
$type,
$old,
implode(', ', $all_types)));
}
$table = new self();
$table_name = $table->getTableName();
$conn = $table->establishConnection('w');
if ($type == self::HINT_NONE) {
queryfx(
$conn,
'DELETE FROM %T WHERE repositoryPHID = %s AND oldCommitIdentifier = %s',
$table_name,
$repository_phid,
$old);
} else {
queryfx(
$conn,
'INSERT INTO %T
(repositoryPHID, oldCommitIdentifier, newCommitIdentifier, hintType)
VALUES (%s, %s, %ns, %s)
ON DUPLICATE KEY UPDATE
newCommitIdentifier = VALUES(newCommitIdentifier),
hintType = VALUES(hintType)',
$table_name,
$repository_phid,
$old,
$new,
$type);
}
}
public function isUnreadable() {
return ($this->getHintType() == self::HINT_UNREADABLE);
}
public function isRewritten() {
return ($this->getHintType() == self::HINT_REWRITTEN);
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
);
}
public function getPolicy($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return PhabricatorPolicies::getMostOpenPolicy();
}
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
}

View file

@ -6,20 +6,6 @@ final class PhabricatorRepositorySchemaSpec
public function buildSchemata() { public function buildSchemata() {
$this->buildEdgeSchemata(new PhabricatorRepository()); $this->buildEdgeSchemata(new PhabricatorRepository());
$this->buildRawSchema(
id(new PhabricatorRepository())->getApplicationName(),
PhabricatorRepository::TABLE_BADCOMMIT,
array(
'fullCommitName' => 'text64',
'description' => 'text',
),
array(
'PRIMARY' => array(
'columns' => array('fullCommitName'),
'unique' => true,
),
));
$this->buildRawSchema( $this->buildRawSchema(
id(new PhabricatorRepository())->getApplicationName(), id(new PhabricatorRepository())->getApplicationName(),
PhabricatorRepository::TABLE_COVERAGE, PhabricatorRepository::TABLE_COVERAGE,

View file

@ -95,16 +95,16 @@ abstract class PhabricatorRepositoryCommitParserWorker
PhabricatorRepository $repository, PhabricatorRepository $repository,
PhabricatorRepositoryCommit $commit); PhabricatorRepositoryCommit $commit);
protected function isBadCommit(PhabricatorRepositoryCommit $commit) { protected function loadCommitHint(PhabricatorRepositoryCommit $commit) {
$repository = new PhabricatorRepository(); $viewer = PhabricatorUser::getOmnipotentUser();
$bad_commit = queryfx_one( $repository = $commit->getRepository();
$repository->establishConnection('w'),
'SELECT * FROM %T WHERE fullCommitName = %s',
PhabricatorRepository::TABLE_BADCOMMIT,
$commit->getMonogram());
return (bool)$bad_commit; return id(new DiffusionCommitHintQuery())
->setViewer($viewer)
->withRepositoryPHIDs(array($repository->getPHID()))
->withOldCommitIdentifiers(array($commit->getCommitIdentifier()))
->executeOne();
} }
public function renderForDisplay(PhabricatorUser $viewer) { public function renderForDisplay(PhabricatorUser $viewer) {

View file

@ -22,8 +22,13 @@ abstract class PhabricatorRepositoryCommitChangeParserWorker
PhabricatorRepositoryCommit $commit) { PhabricatorRepositoryCommit $commit) {
$this->log("%s\n", pht('Parsing "%s"...', $commit->getMonogram())); $this->log("%s\n", pht('Parsing "%s"...', $commit->getMonogram()));
if ($this->isBadCommit($commit)) {
$this->log(pht('This commit is marked bad!')); $hint = $this->loadCommitHint($commit);
if ($hint && $hint->isUnreadable()) {
$this->log(
pht(
'This commit is marked as unreadable, so changes will not be '.
'parsed.'));
return; return;
} }

View file

@ -49,6 +49,7 @@ final class PhabricatorHovercardEngineExtensionModule
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeaderText(pht('HovercardEngine Extensions')) ->setHeaderText(pht('HovercardEngine Extensions'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -49,6 +49,7 @@ final class PhabricatorSearchEngineExtensionModule
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeaderText(pht('SearchEngine Extensions')) ->setHeaderText(pht('SearchEngine Extensions'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -38,6 +38,7 @@ final class PhabricatorFulltextEngineExtensionModule
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeaderText(pht('FulltextEngine Extensions')) ->setHeaderText(pht('FulltextEngine Extensions'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -38,6 +38,7 @@ final class PhabricatorIndexEngineExtensionModule
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeaderText(pht('IndexEngine Extensions')) ->setHeaderText(pht('IndexEngine Extensions'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -143,6 +143,7 @@ final class PhabricatorMotivatorProfilePanel
pht( pht(
'Cats will often bring you their prey because they feel sorry '. 'Cats will often bring you their prey because they feel sorry '.
'for your inability to hunt.'), 'for your inability to hunt.'),
pht('Cats spend most of their time plotting to kill their owner.'),
); );
} }

View file

@ -25,20 +25,30 @@ final class PhabricatorSearchDocumentTypeDatasource
} }
private function buildResults() { private function buildResults() {
$viewer = $this->getViewer();
$types = $types =
PhabricatorSearchApplicationSearchEngine::getIndexableDocumentTypes(); PhabricatorSearchApplicationSearchEngine::getIndexableDocumentTypes(
$viewer);
$icons = mpull( $phid_types = mpull(PhabricatorPHIDType::getAllTypes(),
PhabricatorPHIDType::getAllTypes(), null,
'getTypeIcon',
'getTypeConstant'); 'getTypeConstant');
$results = array(); $results = array();
foreach ($types as $type => $name) { foreach ($types as $type => $name) {
$type_object = idx($phid_types, $type);
if (!$type_object) {
continue;
}
$application_class = $type_object->getPHIDTypeApplicationClass();
$application = PhabricatorApplication::getByClass($application_class);
$application_name = $application->getName();
$results[$type] = id(new PhabricatorTypeaheadResult()) $results[$type] = id(new PhabricatorTypeaheadResult())
->setPHID($type) ->setPHID($type)
->setName($name) ->setName($name)
->setIcon(idx($icons, $type)); ->addAttribute($application_name)
->setIcon($type_object->getTypeIcon());
} }
return $results; return $results;

View file

@ -165,6 +165,11 @@ final class PhabricatorEmailAddressesSettingsPanel
$user = $this->getUser(); $user = $this->getUser();
$viewer = $this->getViewer(); $viewer = $this->getViewer();
$token = id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
$viewer,
$request,
$this->getPanelURI());
$e_email = true; $e_email = true;
$email = null; $email = null;
$errors = array(); $errors = array();
@ -276,6 +281,11 @@ final class PhabricatorEmailAddressesSettingsPanel
$user = $this->getUser(); $user = $this->getUser();
$viewer = $this->getViewer(); $viewer = $this->getViewer();
$token = id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
$viewer,
$request,
$this->getPanelURI());
// NOTE: You can only delete your own email addresses, and you can not // NOTE: You can only delete your own email addresses, and you can not
// delete your primary address. // delete your primary address.
$email = id(new PhabricatorUserEmail())->loadOneWhere( $email = id(new PhabricatorUserEmail())->loadOneWhere(

View file

@ -67,7 +67,19 @@ final class PhabricatorHomePreferencesSettingsPanel
unset($options['PhabricatorApplicationsApplication']); unset($options['PhabricatorApplicationsApplication']);
if ($request->isFormPost()) { if ($request->isFormPost()) {
$pin = $request->getStr('pin'); $pins = $request->getArr('pin');
$phid = head($pins);
$app = id(new PhabricatorApplicationQuery())
->setViewer($viewer)
->withPHIDs(array($phid))
->executeOne();
if ($app) {
$pin = get_class($app);
} else {
// This likely means the user submitted an empty form
// which will cause nothing to happen.
$pin = '';
}
if (isset($options[$pin]) && !in_array($pin, $pinned)) { if (isset($options[$pin]) && !in_array($pin, $pinned)) {
$pinned[] = $pin; $pinned[] = $pin;
@ -78,18 +90,18 @@ final class PhabricatorHomePreferencesSettingsPanel
} }
} }
$options_control = id(new AphrontFormSelectControl()) $options_control = id(new AphrontFormTokenizerControl())
->setName('pin') ->setName('pin')
->setLabel(pht('Application')) ->setLabel(pht('Application'))
->setOptions($options) ->setDatasource(new PhabricatorApplicationDatasource())
->setDisabledOptions(array_keys($app_list)); ->setLimit(1);
$form = id(new AphrontFormView()) $form = id(new AphrontFormView())
->setViewer($viewer) ->setViewer($viewer)
->addHiddenInput('add', 'true') ->addHiddenInput('add', 'true')
->appendRemarkupInstructions( ->appendRemarkupInstructions(
pht('Choose an application to pin to your home page.')) pht('Choose an application to pin to your home page.'))
->appendChild($options_control); ->appendControl($options_control);
return $this->newDialog() return $this->newDialog()
->setWidth(AphrontDialogView::WIDTH_FORM) ->setWidth(AphrontDialogView::WIDTH_FORM)
@ -152,20 +164,12 @@ final class PhabricatorHomePreferencesSettingsPanel
$icon = $application->getIcon(); $icon = $application->getIcon();
if (!$icon) { if (!$icon) {
$icon = 'application'; $icon = 'fa-globe';
} }
$icon_view = javelin_tag(
'span',
array(
'class' => 'phui-icon-view phui-font-fa '.$icon,
'aural' => false,
),
'');
$item = id(new PHUIObjectItemView()) $item = id(new PHUIObjectItemView())
->setHeader($application->getName()) ->setHeader($application->getName())
->setImageIcon($icon_view) ->setImageIcon($icon)
->addAttribute($application->getShortDescription()) ->addAttribute($application->getShortDescription())
->setGrippable(true); ->setGrippable(true);

View file

@ -38,6 +38,7 @@ final class PhabricatorDestructionEngineExtensionModule
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeaderText(pht('DestructionEngine Extensions')) ->setHeaderText(pht('DestructionEngine Extensions'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -46,6 +46,7 @@ final class PhabricatorEditEngineExtensionModule
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeaderText(pht('EditEngine Extensions')) ->setHeaderText(pht('EditEngine Extensions'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -2,26 +2,4 @@
abstract class PhabricatorXHProfController extends PhabricatorController { abstract class PhabricatorXHProfController extends PhabricatorController {
public function buildStandardPageResponse($view, array $data) {
$page = $this->buildStandardPageView();
$page->setApplicationName(pht('XHProf'));
$page->setBaseURI('/xhprof/');
$page->setTitle(idx($data, 'title'));
$page->setGlyph("\xE2\x98\x84");
$page->appendChild($view);
$page->setDeviceReady(true);
$response = new AphrontWebpageResponse();
if (isset($data['frame'])) {
$response->setFrameable(true);
$page->setFrameable(true);
$page->setShowChrome(false);
$page->setDisableConsole(true);
}
return $response->setContent($page->render());
}
} }

View file

@ -47,11 +47,14 @@ final class PhabricatorXHProfProfileController
$crumbs = $this->buildApplicationCrumbs(); $crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('%s Profile', $symbol)); $crumbs->addTextCrumb(pht('%s Profile', $symbol));
return $this->buildStandardPageResponse( $title = pht('Profile');
array($crumbs, $view),
array( return $this->newPage()
'title' => pht('Profile'), ->setTitle($title)
'frame' => $is_framed, ->setCrumbs($crumbs)
)); ->setFrameable(true)
->setShowChrome(false)
->setDisableConsole(true)
->appendChild($view);
} }
} }

View file

@ -32,7 +32,7 @@ These are the configuration values it reads:
- `join` Array, list of channels to join. - `join` Array, list of channels to join.
- `handlers` Array, list of handlers to run. These are like plugins for the - `handlers` Array, list of handlers to run. These are like plugins for the
bot. bot.
- `conduit.uri`, `conduit.user`, `conduit.cert` Conduit configuration, - `conduit.uri`, `conduit.token` Conduit configuration,
see below. see below.
- `notification.channels` Notification configuration, see below. - `notification.channels` Notification configuration, see below.
@ -72,10 +72,8 @@ with. To do this, login to Phabricator as an administrator and go to
- `conduit.uri` The URI for your Phabricator install, like - `conduit.uri` The URI for your Phabricator install, like
`http://phabricator.example.com/` `http://phabricator.example.com/`
- `conduit.user` The username your bot should login to Phabricator with -- - `conduit.token` The user's conduit API token, from the "Conduit API Tokens"
whatever you selected above, like `phabot`. tab in the user's administrative view.
- `conduit.cert` The user's certificate, from the "Conduit Certificate" tab
in the user's administrative view.
Now the bot should be able to connect to Phabricator via Conduit. Now the bot should be able to connect to Phabricator via Conduit.

View file

@ -0,0 +1,134 @@
@title Repository Hints and Rewriting Commits
@group fieldmanual
Dealing with rewrites of published repositories and other unusual problems.
Overview
========
Some repositories have unusual commits. You can provide "hints" to Phabricator
about these commits to improve behavior.
Supported hints are:
- **Rewritten Commits**: If you have rewritten the history of a published
repository, you can provide hints about the mapping from old commits to
new commits so it can redirect users who visit old pages to the proper
new pages.
- **Unreadable Commits**: If some commits are not readable (which is rare,
but can happen in some cases if they are generated with an external tool)
you can provide hints so that Phabricator doesn't try to read them.
The remainder of this document explains how to create and remove hints, and how
to specify each type of hint.
Creating Hints
==============
To create hints, pipe a JSON list of hints to `bin/repository hint`:
```
phabricator/ $ cat hints.json | ./bin/repository hint
```
The hints should be a list of objects like this:
```lang=json
[
...
{
"repository": "XYZ",
"hint": "...",
"old": "abcdef1234abcdef1234abcdef1234abcdef1234",
"new": "..."
}
...
]
```
Each hint may have these keys:
- `repository`: A repository identifier (ID, PHID, callsign or short name).
- `hint`: The hint type, see below.
- `old`: The full identifier or commit hash of the commit you want to
provide a hint for.
- `new`: For hints which specify a new commit, the full identifier or commit
hash of the new commit.
See below for exactly how to specify each type of hint.
Removing Hints
==============
To remove a hint, create a hint of type `"none"`. This will remove any existing
hint.
For example, use a hint specification like this:
```lang=json
[
{
"repository": "XYZ",
"hint": "none",
"old": "abcdef1234abcdef1234abcdef1234abcdef1234"
}
]
```
Phabricator won't treat commits without any hint specially.
Hint: Rewritten Commits
=======================
The `"rewritten"` hint allows you to redirect old commits to new commits after
a rewrite of published history. You should normally avoid rewriting published
commits, but sometimes this is necessary: for example, if a repository has
become unwieldy because it contains large binaries, you may strip them from
history.
To provide this kind of hint, pass the `"old"` commit hash (from before the
rewrite) and the `"new"` commit hash (from after the rewrite).
For example, a hint might look like this:
```lang=json
[
{
"repository": "XYZ",
"hint": "rewritten",
"old": "abcdef1234abcdef1234abcdef1234abcdef1234",
"new": "098765ffaabbccdd4680098765ffaabbccdd4680"
}
]
```
Phabricator will show users that the commit was rewritten in the web UI.
Hint: Unreadable Commits
========================
The `"unreadable"` hint allows you to tell Phabricator that it should not
bother trying to read the changes associated with a particular commit. In
some rare cases, repositories can contain commits which aren't readable
(for example, if they were created by external tools during an import or
merge process).
To provide this kind of hint, pass the `"old"` commit which is affected.
For example, a hint might look like this:
```lang=json
[
{
"repository": "XYZ",
"hint": "unreadable",
"old": "abcdef1234abcdef1234abcdef1234abcdef1234"
}
]
```
Phabricator won't try to read, parse, import, or display the changes associated
with this commit.

View file

@ -45,6 +45,7 @@ final class PhabricatorContentSourceModule
return id(new PHUIObjectBoxView()) return id(new PHUIObjectBoxView())
->setHeaderText(pht('Content Sources')) ->setHeaderText(pht('Content Sources'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($table); ->setTable($table);
} }

View file

@ -159,11 +159,10 @@ final class PhabricatorBot extends PhabricatorDaemon {
if (empty($this->conduit)) { if (empty($this->conduit)) {
throw new Exception( throw new Exception(
pht( pht(
"This bot is not configured with a Conduit uplink. Set '%s', ". "This bot is not configured with a Conduit uplink. Set '%s' and ".
"'%s' and '%s' in the configuration to connect.", "'%s' in the configuration to connect.",
'conduit.uri', 'conduit.uri',
'conduit.user', 'conduit.token'));
'conduit.cert'));
} }
return $this->conduit; return $this->conduit;
} }

View file

@ -50,8 +50,14 @@ final class PhabricatorBotObjectNameHandler extends PhabricatorBotHandler {
'(?:\b|$)'. '(?:\b|$)'.
'@'; '@';
$regex = trim(
PhabricatorEnv::getEnvConfig('remarkup.ignored-object-names'));
if (preg_match_all($pattern, $message, $matches, PREG_SET_ORDER)) { if (preg_match_all($pattern, $message, $matches, PREG_SET_ORDER)) {
foreach ($matches as $match) { foreach ($matches as $match) {
if ($regex && preg_match($regex, $match[0])) {
continue;
}
switch ($match[1]) { switch ($match[1]) {
case 'P': case 'P':
$paste_ids[] = $match[2]; $paste_ids[] = $match[2];

View file

@ -25,6 +25,13 @@ abstract class PhabricatorObjectRemarkupRule extends PhutilRemarkupRule {
return true; return true;
} }
protected function getObjectNameText(
$object,
PhabricatorObjectHandle $handle,
$id) {
return $this->getObjectNamePrefix().$id;
}
protected function loadHandles(array $objects) { protected function loadHandles(array $objects) {
$phids = mpull($objects, 'getPHID'); $phids = mpull($objects, 'getPHID');
@ -60,7 +67,7 @@ abstract class PhabricatorObjectRemarkupRule extends PhutilRemarkupRule {
$id) { $id) {
$href = $this->getObjectHref($object, $handle, $id); $href = $this->getObjectHref($object, $handle, $id);
$text = $this->getObjectNamePrefix().$id; $text = $this->getObjectNameText($object, $handle, $id);
if ($anchor) { if ($anchor) {
$href = $href.'#'.$anchor; $href = $href.'#'.$anchor;
@ -85,7 +92,7 @@ abstract class PhabricatorObjectRemarkupRule extends PhutilRemarkupRule {
$id) { $id) {
$href = $this->getObjectHref($object, $handle, $id); $href = $this->getObjectHref($object, $handle, $id);
$text = $this->getObjectNamePrefix().$id; $text = $this->getObjectNameText($object, $handle, $id);
$status_closed = PhabricatorObjectHandle::STATUS_CLOSED; $status_closed = PhabricatorObjectHandle::STATUS_CLOSED;
if ($anchor) { if ($anchor) {

View file

@ -890,7 +890,8 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView
} else { } else {
$content = $this->render(); $content = $this->render();
$response = id(new AphrontWebpageResponse()) $response = id(new AphrontWebpageResponse())
->setContent($content); ->setContent($content)
->setFrameable($this->getFrameable());
} }
return $response; return $response;

View file

@ -38,6 +38,7 @@
.setup-issue table td { .setup-issue table td {
border: 1px solid #BFCFDA; border: 1px solid #BFCFDA;
padding: 8px; padding: 8px;
word-break: break-word;
} }
.setup-issue pre { .setup-issue pre {