Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php b/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php
index 6547f9ca96..e32d7a1476 100644
--- a/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php
+++ b/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php
@@ -1,405 +1,421 @@
<?php
final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck {
public function getDefaultGroup() {
return self::GROUP_OTHER;
}
protected function executeChecks() {
$ancient_config = self::getAncientConfig();
$all_keys = PhabricatorEnv::getAllConfigKeys();
$all_keys = array_keys($all_keys);
sort($all_keys);
$defined_keys = PhabricatorApplicationConfigOptions::loadAllOptions();
foreach ($all_keys as $key) {
if (isset($defined_keys[$key])) {
continue;
}
if (isset($ancient_config[$key])) {
$summary = pht(
'This option has been removed. You may delete it at your '.
'convenience.');
$message = pht(
"The configuration option '%s' has been removed. You may delete ".
"it at your convenience.".
"\n\n%s",
$key,
$ancient_config[$key]);
$short = pht('Obsolete Config');
$name = pht('Obsolete Configuration Option "%s"', $key);
} else {
$summary = pht('This option is not recognized. It may be misspelled.');
$message = pht(
"The configuration option '%s' is not recognized. It may be ".
"misspelled, or it might have existed in an older version of ".
"Phabricator. It has no effect, and should be corrected or deleted.",
$key);
$short = pht('Unknown Config');
$name = pht('Unknown Configuration Option "%s"', $key);
}
$issue = $this->newIssue('config.unknown.'.$key)
->setShortName($short)
->setName($name)
->setSummary($summary);
$stack = PhabricatorEnv::getConfigSourceStack();
$stack = $stack->getStack();
$found = array();
$found_local = false;
$found_database = false;
foreach ($stack as $source_key => $source) {
$value = $source->getKeys(array($key));
if ($value) {
$found[] = $source->getName();
if ($source instanceof PhabricatorConfigDatabaseSource) {
$found_database = true;
}
if ($source instanceof PhabricatorConfigLocalSource) {
$found_local = true;
}
}
}
$message = $message."\n\n".pht(
'This configuration value is defined in these %d '.
'configuration source(s): %s.',
count($found),
implode(', ', $found));
$issue->setMessage($message);
if ($found_local) {
$command = csprintf('phabricator/ $ ./bin/config delete %s', $key);
$issue->addCommand($command);
}
if ($found_database) {
$issue->addPhabricatorConfig($key);
}
}
$this->executeManiphestFieldChecks();
}
/**
* Return a map of deleted config options. Keys are option keys; values are
* explanations of what happened to the option.
*/
public static function getAncientConfig() {
$reason_auth = pht(
'This option has been migrated to the "Auth" application. Your old '.
'configuration is still in effect, but now stored in "Auth" instead of '.
'configuration. Going forward, you can manage authentication from '.
'the web UI.');
$auth_config = array(
'controller.oauth-registration',
'auth.password-auth-enabled',
'facebook.auth-enabled',
'facebook.registration-enabled',
'facebook.auth-permanent',
'facebook.application-id',
'facebook.application-secret',
'facebook.require-https-auth',
'github.auth-enabled',
'github.registration-enabled',
'github.auth-permanent',
'github.application-id',
'github.application-secret',
'google.auth-enabled',
'google.registration-enabled',
'google.auth-permanent',
'google.application-id',
'google.application-secret',
'ldap.auth-enabled',
'ldap.hostname',
'ldap.port',
'ldap.base_dn',
'ldap.search_attribute',
'ldap.search-first',
'ldap.username-attribute',
'ldap.real_name_attributes',
'ldap.activedirectory_domain',
'ldap.version',
'ldap.referrals',
'ldap.anonymous-user-name',
'ldap.anonymous-user-password',
'ldap.start-tls',
'disqus.auth-enabled',
'disqus.registration-enabled',
'disqus.auth-permanent',
'disqus.application-id',
'disqus.application-secret',
'phabricator.oauth-uri',
'phabricator.auth-enabled',
'phabricator.registration-enabled',
'phabricator.auth-permanent',
'phabricator.application-id',
'phabricator.application-secret',
+ 'maniphest.priorities.unbreak-now',
+ 'maniphest.priorities.needs-triage',
+ 'welcome.html',
);
$ancient_config = array_fill_keys($auth_config, $reason_auth);
$markup_reason = pht(
'Custom remarkup rules are now added by subclassing '.
'%s or %s.',
'PhabricatorRemarkupCustomInlineRule',
'PhabricatorRemarkupCustomBlockRule');
$session_reason = pht(
'Sessions now expire and are garbage collected rather than having an '.
'arbitrary concurrency limit.');
$differential_field_reason = pht(
'All Differential fields are now managed through the configuration '.
'option "%s". Use that option to configure which fields are shown.',
'differential.fields');
$reply_domain_reason = pht(
'Individual application reply handler domains have been removed. '.
'Configure a reply domain with "%s".',
'metamta.reply-handler-domain');
$reply_handler_reason = pht(
'Reply handlers can no longer be overridden with configuration.');
$monospace_reason = pht(
'Phabricator no longer supports global customization of monospaced '.
'fonts.');
$public_mail_reason = pht(
'Inbound mail addresses are now configured for each application '.
'in the Applications tool.');
$gc_reason = pht(
'Garbage collectors are now configured with "%s".',
'bin/garbage set-policy');
$aphlict_reason = pht(
'Configuration of the notification server has changed substantially. '.
'For discussion, see T10794.');
$stale_reason = pht(
'The Differential revision list view age UI elements have been removed '.
'to simplify the interface.');
$global_settings_reason = pht(
'The "Re: Prefix" and "Vary Subjects" settings are now configured '.
'in global settings.');
$ancient_config += array(
'phid.external-loaders' =>
pht(
'External loaders have been replaced. Extend `%s` '.
'to implement new PHID and handle types.',
'PhabricatorPHIDType'),
'maniphest.custom-task-extensions-class' =>
pht(
'Maniphest fields are now loaded automatically. '.
'You can configure them with `%s`.',
'maniphest.fields'),
'maniphest.custom-fields' =>
pht(
'Maniphest fields are now defined in `%s`. '.
'Existing definitions have been migrated.',
'maniphest.custom-field-definitions'),
'differential.custom-remarkup-rules' => $markup_reason,
'differential.custom-remarkup-block-rules' => $markup_reason,
'auth.sshkeys.enabled' => pht(
'SSH keys are now actually useful, so they are always enabled.'),
'differential.anonymous-access' => pht(
'Phabricator now has meaningful global access controls. See `%s`.',
'policy.allow-public'),
'celerity.resource-path' => pht(
'An alternate resource map is no longer supported. Instead, use '.
'multiple maps. See T4222.'),
'metamta.send-immediately' => pht(
'Mail is now always delivered by the daemons.'),
'auth.sessions.conduit' => $session_reason,
'auth.sessions.web' => $session_reason,
'tokenizer.ondemand' => pht(
'Phabricator now manages typeahead strategies automatically.'),
'differential.revision-custom-detail-renderer' => pht(
'Obsolete; use standard rendering events instead.'),
'differential.show-host-field' => $differential_field_reason,
'differential.show-test-plan-field' => $differential_field_reason,
'differential.field-selector' => $differential_field_reason,
'phabricator.show-beta-applications' => pht(
'This option has been renamed to `%s` to emphasize the '.
'unfinished nature of many prototype applications. '.
'Your existing setting has been migrated.',
'phabricator.show-prototypes'),
'notification.user' => pht(
'The notification server no longer requires root permissions. Start '.
'the server as the user you want it to run under.'),
'notification.debug' => pht(
'Notifications no longer have a dedicated debugging mode.'),
'translation.provider' => pht(
'The translation implementation has changed and providers are no '.
'longer used or supported.'),
'config.mask' => pht(
'Use `%s` instead of this option.',
'config.hide'),
'phd.start-taskmasters' => pht(
'Taskmasters now use an autoscaling pool. You can configure the '.
'pool size with `%s`.',
'phd.taskmasters'),
'storage.engine-selector' => pht(
'Phabricator now automatically discovers available storage engines '.
'at runtime.'),
'storage.upload-size-limit' => pht(
'Phabricator now supports arbitrarily large files. Consult the '.
'documentation for configuration details.'),
'security.allow-outbound-http' => pht(
'This option has been replaced with the more granular option `%s`.',
'security.outbound-blacklist'),
'metamta.reply.show-hints' => pht(
'Phabricator no longer shows reply hints in mail.'),
'metamta.differential.reply-handler-domain' => $reply_domain_reason,
'metamta.diffusion.reply-handler-domain' => $reply_domain_reason,
'metamta.macro.reply-handler-domain' => $reply_domain_reason,
'metamta.maniphest.reply-handler-domain' => $reply_domain_reason,
'metamta.pholio.reply-handler-domain' => $reply_domain_reason,
'metamta.diffusion.reply-handler' => $reply_handler_reason,
'metamta.differential.reply-handler' => $reply_handler_reason,
'metamta.maniphest.reply-handler' => $reply_handler_reason,
'metamta.package.reply-handler' => $reply_handler_reason,
'metamta.precedence-bulk' => pht(
'Phabricator now always sends transaction mail with '.
'"Precedence: bulk" to improve deliverability.'),
'style.monospace' => $monospace_reason,
'style.monospace.windows' => $monospace_reason,
'search.engine-selector' => pht(
'Phabricator now automatically discovers available search engines '.
'at runtime.'),
'metamta.files.public-create-email' => $public_mail_reason,
'metamta.maniphest.public-create-email' => $public_mail_reason,
'metamta.maniphest.default-public-author' => $public_mail_reason,
'metamta.paste.public-create-email' => $public_mail_reason,
'security.allow-conduit-act-as-user' => pht(
'Impersonating users over the API is no longer supported.'),
'feed.public' => pht('The framable public feed is no longer supported.'),
'auth.login-message' => pht(
'This configuration option has been replaced with a modular '.
'handler. See T9346.'),
'gcdaemon.ttl.herald-transcripts' => $gc_reason,
'gcdaemon.ttl.daemon-logs' => $gc_reason,
'gcdaemon.ttl.differential-parse-cache' => $gc_reason,
'gcdaemon.ttl.markup-cache' => $gc_reason,
'gcdaemon.ttl.task-archive' => $gc_reason,
'gcdaemon.ttl.general-cache' => $gc_reason,
'gcdaemon.ttl.conduit-logs' => $gc_reason,
'phd.variant-config' => pht(
'This configuration is no longer relevant because daemons '.
'restart automatically on configuration changes.'),
'notification.ssl-cert' => $aphlict_reason,
'notification.ssl-key' => $aphlict_reason,
'notification.pidfile' => $aphlict_reason,
'notification.log' => $aphlict_reason,
'notification.enabled' => $aphlict_reason,
'notification.client-uri' => $aphlict_reason,
'notification.server-uri' => $aphlict_reason,
'metamta.differential.unified-comment-context' => pht(
'Inline comments are now always rendered with a limited amount '.
'of context.'),
'differential.days-fresh' => $stale_reason,
'differential.days-stale' => $stale_reason,
'metamta.re-prefix' => $global_settings_reason,
'metamta.vary-subjects' => $global_settings_reason,
'ui.custom-header' => pht(
'This option has been replaced with `ui.logo`, which provides more '.
'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;
}
private function executeManiphestFieldChecks() {
$maniphest_appclass = 'PhabricatorManiphestApplication';
if (!PhabricatorApplication::isClassInstalled($maniphest_appclass)) {
return;
}
$capabilities = array(
ManiphestEditAssignCapability::CAPABILITY,
ManiphestEditPoliciesCapability::CAPABILITY,
ManiphestEditPriorityCapability::CAPABILITY,
ManiphestEditProjectsCapability::CAPABILITY,
ManiphestEditStatusCapability::CAPABILITY,
);
// Check for any of these capabilities set to anything other than
// "All Users".
$any_set = false;
$app = new PhabricatorManiphestApplication();
foreach ($capabilities as $capability) {
$setting = $app->getPolicy($capability);
if ($setting != PhabricatorPolicies::POLICY_USER) {
$any_set = true;
break;
}
}
if (!$any_set) {
return;
}
$issue_summary = pht(
'Maniphest is currently configured with deprecated policy settings '.
'which will be removed in a future version of Phabricator.');
$message = pht(
'Some policy settings in Maniphest are now deprecated and will be '.
'removed in a future version of Phabricator. You are currently using '.
'at least one of these settings.'.
"\n\n".
'The deprecated settings are "Can Assign Tasks", '.
'"Can Edit Task Policies", "Can Prioritize Tasks", '.
'"Can Edit Task Projects", and "Can Edit Task Status". You can '.
'find these settings in Applications, or follow the link below.'.
"\n\n".
'You can find discussion of this change (including rationale and '.
'recommendations on how to configure similar features) in the upstream, '.
'at the link below.'.
"\n\n".
'To resolve this issue, set all of these policies to "All Users" after '.
'making any necessary form customization changes.');
$more_href = 'https://secure.phabricator.com/T10003';
$edit_href = '/applications/view/PhabricatorManiphestApplication/';
$issue = $this->newIssue('maniphest.T10003-per-field-policies')
->setShortName(pht('Deprecated Policies'))
->setName(pht('Deprecated Maniphest Field Policies'))
->setSummary($issue_summary)
->setMessage($message)
->addLink($more_href, pht('Learn More: Upstream Discussion'))
->addLink($edit_href, pht('Edit These Settings'));
}
}
diff --git a/src/applications/config/option/PhabricatorCoreConfigOptions.php b/src/applications/config/option/PhabricatorCoreConfigOptions.php
index c486ce0db1..6efd27d9a3 100644
--- a/src/applications/config/option/PhabricatorCoreConfigOptions.php
+++ b/src/applications/config/option/PhabricatorCoreConfigOptions.php
@@ -1,324 +1,320 @@
<?php
final class PhabricatorCoreConfigOptions
extends PhabricatorApplicationConfigOptions {
public function getName() {
return pht('Core');
}
public function getDescription() {
return pht('Configure core options, including URIs.');
}
public function getIcon() {
return 'fa-bullseye';
}
public function getGroup() {
return 'core';
}
public function getOptions() {
if (phutil_is_windows()) {
$paths = array();
} else {
$paths = array(
'/bin',
'/usr/bin',
'/usr/local/bin',
);
}
$path = getenv('PATH');
$proto_doc_href = PhabricatorEnv::getDoclink(
'User Guide: Prototype Applications');
$proto_doc_name = pht('User Guide: Prototype Applications');
$applications_app_href = '/applications/';
return array(
$this->newOption('phabricator.base-uri', 'string', null)
->setLocked(true)
->setSummary(pht('URI where Phabricator is installed.'))
->setDescription(
pht(
'Set the URI where Phabricator is installed. Setting this '.
'improves security by preventing cookies from being set on other '.
'domains, and allows daemons to send emails with links that have '.
'the correct domain.'))
->addExample('http://phabricator.example.com/', pht('Valid Setting')),
$this->newOption('phabricator.production-uri', 'string', null)
->setSummary(
pht('Primary install URI, for multi-environment installs.'))
->setDescription(
pht(
'If you have multiple Phabricator environments (like a '.
'development/staging environment for working on testing '.
'Phabricator, and a production environment for deploying it), '.
'set the production environment URI here so that emails and other '.
'durable URIs will always generate with links pointing at the '.
'production environment. If unset, defaults to `%s`. Most '.
'installs do not need to set this option.',
'phabricator.base-uri'))
->addExample('http://phabricator.example.com/', pht('Valid Setting')),
$this->newOption('phabricator.allowed-uris', 'list<string>', array())
->setLocked(true)
->setSummary(pht('Alternative URIs that can access Phabricator.'))
->setDescription(
pht(
"These alternative URIs will be able to access 'normal' pages ".
"on your Phabricator install. Other features such as OAuth ".
"won't work. The major use case for this is moving installs ".
"across domains."))
->addExample(
"http://phabricator2.example.com/\n".
"http://phabricator3.example.com/",
pht('Valid Setting')),
$this->newOption('phabricator.timezone', 'string', null)
->setSummary(
pht('The timezone Phabricator should use.'))
->setDescription(
pht(
"PHP requires that you set a timezone in your php.ini before ".
"using date functions, or it will emit a warning. If this isn't ".
"possible (for instance, because you are using HPHP) you can set ".
"some valid constant for %s here and Phabricator will set it on ".
"your behalf, silencing the warning.",
'date_default_timezone_set()'))
->addExample('America/New_York', pht('US East (EDT)'))
->addExample('America/Chicago', pht('US Central (CDT)'))
->addExample('America/Boise', pht('US Mountain (MDT)'))
->addExample('America/Los_Angeles', pht('US West (PDT)')),
$this->newOption('phabricator.cookie-prefix', 'string', null)
->setLocked(true)
->setSummary(
pht(
'Set a string Phabricator should use to prefix cookie names.'))
->setDescription(
pht(
'Cookies set for x.com are also sent for y.x.com. Assuming '.
'Phabricator instances are running on both domains, this will '.
'create a collision preventing you from logging in.'))
->addExample('dev', pht('Prefix cookie with "%s"', 'dev')),
$this->newOption('phabricator.show-prototypes', 'bool', false)
->setLocked(true)
->setBoolOptions(
array(
pht('Enable Prototypes'),
pht('Disable Prototypes'),
))
->setSummary(
pht(
'Install applications which are still under development.'))
->setDescription(
pht(
"IMPORTANT: The upstream does not provide support for prototype ".
"applications.".
"\n\n".
"Phabricator includes prototype applications which are in an ".
"**early stage of development**. By default, prototype ".
"applications are not installed, because they are often not yet ".
"developed enough to be generally usable. You can enable ".
"this option to install them if you're developing Phabricator ".
"or are interested in previewing upcoming features.".
"\n\n".
"To learn more about prototypes, see [[ %s | %s ]].".
"\n\n".
"After enabling prototypes, you can selectively uninstall them ".
"(like normal applications).",
$proto_doc_href,
$proto_doc_name)),
$this->newOption('phabricator.serious-business', 'bool', false)
->setBoolOptions(
array(
pht('Serious business'),
pht('Shenanigans'), // That should be interesting to translate. :P
))
->setSummary(
pht('Allows you to remove levity and jokes from the UI.'))
->setDescription(
pht(
'By default, Phabricator includes some flavor text in the UI, '.
'like a prompt to "Weigh In" rather than "Add Comment" in '.
'Maniphest. If you\'d prefer more traditional UI strings like '.
'"Add Comment", you can set this flag to disable most of the '.
'extra flavor.')),
$this->newOption('remarkup.ignored-object-names', 'string', '/^(Q|V)\d$/')
->setSummary(
pht('Text values that match this regex and are also object names '.
'will not be linked.'))
->setDescription(
pht(
'By default, Phabricator links object names in Remarkup fields '.
'to the corresponding object. This regex can be used to modify '.
'this behavior; object names that match this regex will not be '.
'linked.')),
$this->newOption('environment.append-paths', 'list<string>', $paths)
->setSummary(
pht(
'These paths get appended to your %s environment variable.',
'$PATH'))
->setDescription(
pht(
"Phabricator occasionally shells out to other binaries on the ".
"server. An example of this is the `%s` command, used to ".
"syntax-highlight code written in languages other than PHP. By ".
"default, it is assumed that these binaries are in the %s of the ".
"user running Phabricator (normally 'apache', 'httpd', or ".
"'nobody'). Here you can add extra directories to the %s ".
"environment variable, for when these binaries are in ".
"non-standard locations.\n\n".
"Note that you can also put binaries in `%s` (for example, by ".
"symlinking them).\n\n".
"The current value of PATH after configuration is applied is:\n\n".
" lang=text\n".
" %s",
'pygmentize',
'$PATH',
'$PATH',
'phabricator/support/bin/',
$path))
->setLocked(true)
->addExample('/usr/local/bin', pht('Add One Path'))
->addExample("/usr/bin\n/usr/local/bin", pht('Add Multiple Paths')),
$this->newOption('config.lock', 'set', array())
->setLocked(true)
->setDescription(pht('Additional configuration options to lock.')),
$this->newOption('config.hide', 'set', array())
->setLocked(true)
->setDescription(pht('Additional configuration options to hide.')),
$this->newOption('config.ignore-issues', 'set', array())
->setLocked(true)
->setDescription(pht('Setup issues to ignore.')),
$this->newOption('phabricator.env', 'string', null)
->setLocked(true)
->setDescription(pht('Internal.')),
$this->newOption('test.value', 'wild', null)
->setLocked(true)
->setDescription(pht('Unit test value.')),
$this->newOption('phabricator.uninstalled-applications', 'set', array())
->setLocked(true)
->setLockedMessage(pht(
'Use the %s to manage installed applications.',
phutil_tag(
'a',
array(
'href' => $applications_app_href,
),
pht('Applications application'))))
->setDescription(
pht('Array containing list of uninstalled applications.')),
$this->newOption('phabricator.application-settings', 'wild', array())
->setLocked(true)
->setDescription(
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')
->setLocked(true)
->setDescription(pht('Cache namespace.')),
$this->newOption('phabricator.allow-email-users', 'bool', false)
->setBoolOptions(
array(
pht('Allow'),
pht('Disallow'),
))
->setDescription(
pht('Allow non-members to interact with tasks over email.')),
$this->newOption('phabricator.silent', 'bool', false)
->setLocked(true)
->setBoolOptions(
array(
pht('Run Silently'),
pht('Run Normally'),
))
->setSummary(pht('Stop Phabricator from sending any email, etc.'))
->setDescription(
pht(
'This option allows you to stop Phabricator from sending '.
'any data to external services. Among other things, it will '.
'disable email, SMS, repository mirroring, and HTTP hooks.'.
"\n\n".
'This option is intended to allow a Phabricator instance to '.
'be exported, copied, imported, and run in a test environment '.
'without impacting users. For example, if you are migrating '.
'to new hardware, you could perform a test migration first, '.
'make sure things work, and then do a production cutover '.
'later with higher confidence and less disruption. Without '.
'this flag, users would receive duplicate email during the '.
'time the test instance and old production instance were '.
'both in operation.')),
);
}
protected function didValidateOption(
PhabricatorConfigOption $option,
$value) {
$key = $option->getKey();
if ($key == 'phabricator.base-uri' ||
$key == 'phabricator.production-uri') {
$uri = new PhutilURI($value);
$protocol = $uri->getProtocol();
if ($protocol !== 'http' && $protocol !== 'https') {
throw new PhabricatorConfigValidationException(
pht(
"Config option '%s' is invalid. The URI must start with ".
"%s' or '%s'.",
'http://',
'https://',
$key));
}
$domain = $uri->getDomain();
if (strpos($domain, '.') === false) {
throw new PhabricatorConfigValidationException(
pht(
"Config option '%s' is invalid. The URI must contain a dot ".
"('%s'), like '%s', not just a bare name like '%s'. Some web ".
"browsers will not set cookies on domains with no TLD.",
'.',
'http://example.com/',
'http://example/',
$key));
}
$path = $uri->getPath();
if ($path !== '' && $path !== '/') {
throw new PhabricatorConfigValidationException(
pht(
"Config option '%s' is invalid. The URI must NOT have a path, ".
"e.g. '%s' is OK, but '%s' is not. Phabricator must be installed ".
"on an entire domain; it can not be installed on a path.",
$key,
'http://phabricator.example.com/',
'http://example.com/phabricator/'));
}
}
if ($key === 'phabricator.timezone') {
$old = date_default_timezone_get();
$ok = @date_default_timezone_set($value);
@date_default_timezone_set($old);
if (!$ok) {
throw new PhabricatorConfigValidationException(
pht(
"Config option '%s' is invalid. The timezone identifier must ".
"be a valid timezone identifier recognized by PHP, like '%s'. "."
You can find a list of valid identifiers here: %s",
$key,
'America/Los_Angeles',
'http://php.net/manual/timezones.php'));
}
}
}
}
diff --git a/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php b/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php
index dc140d380a..21b76d1f33 100644
--- a/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php
+++ b/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php
@@ -1,389 +1,367 @@
<?php
final class PhabricatorManiphestConfigOptions
extends PhabricatorApplicationConfigOptions {
public function getName() {
return pht('Maniphest');
}
public function getDescription() {
return pht('Configure Maniphest.');
}
public function getIcon() {
return 'fa-anchor';
}
public function getGroup() {
return 'apps';
}
public function getOptions() {
$priority_type = 'custom:ManiphestPriorityConfigOptionType';
$priority_defaults = array(
100 => array(
'name' => pht('Unbreak Now!'),
'short' => pht('Unbreak!'),
'color' => 'pink',
'keywords' => array('unbreak'),
),
90 => array(
'name' => pht('Needs Triage'),
'short' => pht('Triage'),
'color' => 'violet',
'keywords' => array('triage'),
),
80 => array(
'name' => pht('High'),
'short' => pht('High'),
'color' => 'red',
'keywords' => array('high'),
),
50 => array(
'name' => pht('Normal'),
'short' => pht('Normal'),
'color' => 'orange',
'keywords' => array('normal'),
),
25 => array(
'name' => pht('Low'),
'short' => pht('Low'),
'color' => 'yellow',
'keywords' => array('low'),
),
0 => array(
'name' => pht('Wishlist'),
'short' => pht('Wish'),
'color' => 'sky',
'keywords' => array('wish', 'wishlist'),
),
);
$status_type = 'custom:ManiphestStatusConfigOptionType';
$status_defaults = array(
'open' => array(
'name' => pht('Open'),
'special' => ManiphestTaskStatus::SPECIAL_DEFAULT,
'prefixes' => array(
'open',
'opens',
'reopen',
'reopens',
),
),
'resolved' => array(
'name' => pht('Resolved'),
'name.full' => pht('Closed, Resolved'),
'closed' => true,
'special' => ManiphestTaskStatus::SPECIAL_CLOSED,
'transaction.icon' => 'fa-check-circle',
'prefixes' => array(
'closed',
'closes',
'close',
'fix',
'fixes',
'fixed',
'resolve',
'resolves',
'resolved',
),
'suffixes' => array(
'as resolved',
'as fixed',
),
'keywords' => array('closed', 'fixed', 'resolved'),
),
'wontfix' => array(
'name' => pht('Wontfix'),
'name.full' => pht('Closed, Wontfix'),
'transaction.icon' => 'fa-ban',
'closed' => true,
'prefixes' => array(
'wontfix',
'wontfixes',
'wontfixed',
),
'suffixes' => array(
'as wontfix',
),
),
'invalid' => array(
'name' => pht('Invalid'),
'name.full' => pht('Closed, Invalid'),
'transaction.icon' => 'fa-minus-circle',
'closed' => true,
'claim' => false,
'prefixes' => array(
'invalidate',
'invalidates',
'invalidated',
),
'suffixes' => array(
'as invalid',
),
),
'duplicate' => array(
'name' => pht('Duplicate'),
'name.full' => pht('Closed, Duplicate'),
'transaction.icon' => 'fa-files-o',
'special' => ManiphestTaskStatus::SPECIAL_DUPLICATE,
'closed' => true,
'claim' => false,
),
'spite' => array(
'name' => pht('Spite'),
'name.full' => pht('Closed, Spite'),
'name.action' => pht('Spited'),
'transaction.icon' => 'fa-thumbs-o-down',
'silly' => true,
'closed' => true,
'prefixes' => array(
'spite',
'spites',
'spited',
),
'suffixes' => array(
'out of spite',
'as spite',
),
),
);
$status_description = $this->deformat(pht(<<<EOTEXT
Allows you to edit, add, or remove the task statuses available in Maniphest,
like "Open", "Resolved" and "Invalid". The configuration should contain a map
of status constants to status specifications (see defaults below for examples).
The constant for each status should be 1-12 characters long and contain only
lowercase letters and digits. Valid examples are "open", "closed", and
"invalid". Users will not normally see these values.
The keys you can provide in a specification are:
- `name` //Required string.// Name of the status, like "Invalid".
- `name.full` //Optional string.// Longer name, like "Closed, Invalid". This
appears on the task detail view in the header.
- `name.action` //Optional string.// Action name for email subjects, like
"Marked Invalid".
- `closed` //Optional bool.// Statuses are either "open" or "closed".
Specifying `true` here will mark the status as closed (like "Resolved" or
"Invalid"). By default, statuses are open.
- `special` //Optional string.// Mark this status as special. The special
statuses are:
- `default` This is the default status for newly created tasks. You must
designate one status as default, and it must be an open status.
- `closed` This is the default status for closed tasks (for example, tasks
closed via the "!close" action in email or via the quick close button in
Maniphest). You must designate one status as the default closed status,
and it must be a closed status.
- `duplicate` This is the status used when tasks are merged into one
another as duplicates. You must designate one status for duplicates,
and it must be a closed status.
- `transaction.icon` //Optional string.// Allows you to choose a different
icon to use for this status when showing status changes in the transaction
log. Please see UIExamples, Icons and Images for a list.
- `transaction.color` //Optional string.// Allows you to choose a different
color to use for this status when showing status changes in the transaction
log.
- `silly` //Optional bool.// Marks this status as silly, and thus wholly
inappropriate for use by serious businesses.
- `prefixes` //Optional list<string>.// Allows you to specify a list of
text prefixes which will trigger a task transition into this status
when mentioned in a commit message. For example, providing "closes" here
will allow users to move tasks to this status by writing `Closes T123` in
commit messages.
- `suffixes` //Optional list<string>.// Allows you to specify a list of
text suffixes which will trigger a task transition into this status
when mentioned in a commit message, after a valid prefix. For example,
providing "as invalid" here will allow users to move tasks
to this status by writing `Closes T123 as invalid`, even if another status
is selected by the "Closes" prefix.
- `keywords` //Optional list<string>.// Allows you to specify a list
of keywords which can be used with `!status` commands in email to select
this status.
- `disabled` //Optional bool.// Marks this status as no longer in use so
tasks can not be created or edited to have this status. Existing tasks with
this status will not be affected, but you can batch edit them or let them
die out on their own.
- `claim` //Optional bool.// By default, closing an unassigned task claims
it. You can set this to `false` to disable this behavior for a particular
status.
Statuses will appear in the UI in the order specified. Note the status marked
`special` as `duplicate` is not settable directly and will not appear in UI
elements, and that any status marked `silly` does not appear if Phabricator
is configured with `phabricator.serious-business` set to true.
Examining the default configuration and examples below will probably be helpful
in understanding these options.
EOTEXT
));
$status_example = array(
'open' => array(
'name' => pht('Open'),
'special' => 'default',
),
'closed' => array(
'name' => pht('Closed'),
'special' => 'closed',
'closed' => true,
),
'duplicate' => array(
'name' => pht('Duplicate'),
'special' => 'duplicate',
'closed' => true,
),
);
$json = new PhutilJSON();
$status_example = $json->encodeFormatted($status_example);
// This is intentionally blank for now, until we can move more Maniphest
// logic to custom fields.
$default_fields = array();
foreach ($default_fields as $key => $enabled) {
$default_fields[$key] = array(
'disabled' => !$enabled,
);
}
$custom_field_type = 'custom:PhabricatorCustomFieldConfigOptionType';
$fields_example = array(
'mycompany.estimated-hours' => array(
'name' => pht('Estimated Hours'),
'type' => 'int',
'caption' => pht('Estimated number of hours this will take.'),
),
);
$fields_json = id(new PhutilJSON())->encodeFormatted($fields_example);
$points_type = 'custom:ManiphestPointsConfigOptionType';
$points_example_1 = array(
'enabled' => true,
'label' => pht('Story Points'),
'action' => pht('Change Story Points'),
);
$points_json_1 = id(new PhutilJSON())->encodeFormatted($points_example_1);
$points_example_2 = array(
'enabled' => true,
'label' => pht('Estimated Hours'),
'action' => pht('Change Estimate'),
);
$points_json_2 = id(new PhutilJSON())->encodeFormatted($points_example_2);
$points_description = $this->deformat(pht(<<<EOTEXT
Activates a points field on tasks. You can use points for estimation or
planning. If configured, points will appear on workboards.
To activate points, set this value to a map with these keys:
- `enabled` //Optional bool.// Use `true` to enable points, or
`false` to disable them.
- `label` //Optional string.// Label for points, like "Story Points" or
"Estimated Hours". If omitted, points will be called "Points".
- `action` //Optional string.// Label for the action which changes points
in Maniphest, like "Change Estimate". If omitted, the action will
be called "Change Points".
See the example below for a starting point.
EOTEXT
));
return array(
$this->newOption('maniphest.custom-field-definitions', 'wild', array())
->setSummary(pht('Custom Maniphest fields.'))
->setDescription(
pht(
'Array of custom fields for Maniphest tasks. For details on '.
'adding custom fields to Maniphest, see "Configuring Custom '.
'Fields" in the documentation.'))
->addExample($fields_json, pht('Valid setting')),
$this->newOption('maniphest.fields', $custom_field_type, $default_fields)
->setCustomData(id(new ManiphestTask())->getCustomFieldBaseClass())
->setDescription(pht('Select and reorder task fields.')),
$this->newOption(
'maniphest.priorities',
$priority_type,
$priority_defaults)
->setSummary(pht('Configure Maniphest priority names.'))
->setDescription(
pht(
'Allows you to edit or override the default priorities available '.
'in Maniphest, like "High", "Normal" and "Low". The configuration '.
'should contain a map of priority constants to priority '.
'specifications (see defaults below for examples).'.
"\n\n".
'The keys you can define for a priority are:'.
"\n\n".
' - `name` Name of the priority.'."\n".
' - `short` Alternate shorter name, used in UIs where there is '.
' not much space available.'."\n".
' - `color` A color for this priority, like "red" or "blue".'.
' - `keywords` An optional list of keywords which can '.
' be used to select this priority when using `!priority` '.
' commands in email.'."\n".
' - `disabled` Optional boolean to prevent users from choosing '.
' this priority when creating or editing tasks. Existing '.
' tasks will be unaffected, and can be batch edited to a '.
' different priority or left to eventually die out.'.
"\n\n".
'You can choose which priority is the default for newly created '.
'tasks with `%s`.',
'maniphest.default-priority')),
$this->newOption('maniphest.statuses', $status_type, $status_defaults)
->setSummary(pht('Configure Maniphest task statuses.'))
->setDescription($status_description)
->addExample($status_example, pht('Minimal Valid Config')),
$this->newOption('maniphest.default-priority', 'int', 90)
->setSummary(pht('Default task priority for create flows.'))
->setDescription(
pht(
'Choose a default priority for newly created tasks. You can '.
'review and adjust available priorities by using the '.
'%s configuration option. The default value (`90`) '.
'corresponds to the default "Needs Triage" priority.',
'maniphest.priorities')),
$this->newOption(
'metamta.maniphest.subject-prefix',
'string',
'[Maniphest]')
->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())
->setSummary(pht('Configure point values for tasks.'))
->setDescription($points_description)
->addExample($points_json_1, pht('Points Config'))
->addExample($points_json_2, pht('Hours Config')),
);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, Jul 2, 10:06 AM (1 d, 17 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
164841
Default Alt Text
(44 KB)

Event Timeline