diff --git a/src/applications/config/management/PhabricatorConfigManagementDeleteWorkflow.php b/src/applications/config/management/PhabricatorConfigManagementDeleteWorkflow.php index d89d4b7eb3..8f8cea0838 100644 --- a/src/applications/config/management/PhabricatorConfigManagementDeleteWorkflow.php +++ b/src/applications/config/management/PhabricatorConfigManagementDeleteWorkflow.php @@ -1,76 +1,70 @@ setName('delete') ->setExamples('**delete** __key__') ->setSynopsis(pht('Delete a local configuration value.')) ->setArguments( array( array( 'name' => 'database', 'help' => pht('Delete configuration in the database instead of '. 'in local configuration.'), ), array( 'name' => 'args', 'wildcard' => true, ), )); } public function execute(PhutilArgumentParser $args) { $console = PhutilConsole::getConsole(); $argv = $args->getArg('args'); if (count($argv) == 0) { throw new PhutilArgumentUsageException(pht( 'Specify a configuration key to delete.')); } $key = $argv[0]; if (count($argv) > 1) { throw new PhutilArgumentUsageException(pht( 'Too many arguments: expected one key.')); } $use_database = $args->getArg('database'); if ($use_database) { $config = new PhabricatorConfigDatabaseSource('default'); $config_type = 'database'; } else { $config = new PhabricatorConfigLocalSource(); $config_type = 'local'; } $values = $config->getKeys(array($key)); if (!$values) { throw new PhutilArgumentUsageException(pht( "Configuration key '%s' is not set in %s configuration!", $key, $config_type)); } if ($use_database) { - $config_entry = id(new PhabricatorConfigOption()) - ->loadOneWhere( - 'namespace = %s and key = %s', - 'default', - $key); - PhabricatorConfigEditor::deleteConfig( - $this->getViewer(), - $config_entry, - PhabricatorContentSource::newConsoleSource()); + $config_entry = PhabricatorConfigEntry::loadConfigEntry($key); + $config_entry->setIsDeleted(1); + $config_entry->save(); } else { $config->deleteKeys(array($key)); } $console->writeOut( pht("Deleted '%s' from %s configuration.", $key, $config_type)."\n"); } } diff --git a/src/applications/config/management/PhabricatorConfigManagementMigrateWorkflow.php b/src/applications/config/management/PhabricatorConfigManagementMigrateWorkflow.php index 4b3caa09ce..1f992d003a 100644 --- a/src/applications/config/management/PhabricatorConfigManagementMigrateWorkflow.php +++ b/src/applications/config/management/PhabricatorConfigManagementMigrateWorkflow.php @@ -1,76 +1,74 @@ setName('migrate') ->setExamples('**migrate**') ->setSynopsis(pht( 'Migrate file-based configuration to more modern storage.')); } public function execute(PhutilArgumentParser $args) { $console = PhutilConsole::getConsole(); $key_count = 0; $options = PhabricatorApplicationConfigOptions::loadAllOptions(); $local_config = new PhabricatorConfigLocalSource(); $database_config = new PhabricatorConfigDatabaseSource('default'); $config_sources = PhabricatorEnv::getConfigSourceStack()->getStack(); $console->writeOut( pht('Migrating file-based config to more modern config...')."\n"); foreach ($config_sources as $config_source) { if (!($config_source instanceof PhabricatorConfigFileSource)) { $console->writeOut( pht('Skipping config of source type %s...', get_class($config_source))."\n"); continue; } $console->writeOut(pht('Migrating file source...')."\n"); $all_keys = $config_source->getAllKeys(); foreach ($all_keys as $key => $value) { $option = idx($options, $key); if (!$option) { $console->writeOut(pht('Skipping obsolete option: %s', $key)."\n"); continue; } $in_local = $local_config->getKeys(array($option->getKey())); if ($in_local) { $console->writeOut(pht( 'Skipping option "%s"; already in local config.', $key)."\n"); continue; } $is_locked = $option->getLocked(); if ($is_locked) { $local_config->setKeys(array($option->getKey() => $value)); $key_count++; $console->writeOut(pht( 'Migrated option "%s" from file to local config.', $key)."\n"); } else { $in_database = $database_config->getKeys(array($option->getKey())); if ($in_database) { $console->writeOut(pht( 'Skipping option "%s"; already in database config.', $key)."\n"); continue; } else { - PhabricatorConfigEditor::storeNewValue( - $this->getViewer(), - id(new PhabricatorConfigEntry()) - ->loadOneWhere('namespace = %s AND key = %s', 'default', $key), - PhabricatorContentSource::newConsoleSource()); + $config_entry = PhabricatorConfigEntry::loadConfigEntry($key); + $config_entry->setValue($value); + $config_entry->save(); $key_count++; $console->writeOut(pht( 'Migrated option "%s" from file to database config.', $key)."\n"); } } } } $console->writeOut(pht( 'Done. Migrated %d keys.', $key_count)."\n"); return 0; } } diff --git a/src/applications/config/management/PhabricatorConfigManagementSetWorkflow.php b/src/applications/config/management/PhabricatorConfigManagementSetWorkflow.php index 5c4fc2765c..b20c91cbff 100644 --- a/src/applications/config/management/PhabricatorConfigManagementSetWorkflow.php +++ b/src/applications/config/management/PhabricatorConfigManagementSetWorkflow.php @@ -1,130 +1,127 @@ setName('set') ->setExamples('**set** __key__ __value__') ->setSynopsis(pht('Set a local configuration value.')) ->setArguments( array( array( 'name' => 'database', 'help' => pht('Update configuration in the database instead of '. 'in local configuration.'), ), array( 'name' => 'args', 'wildcard' => true, ), )); } public function execute(PhutilArgumentParser $args) { $console = PhutilConsole::getConsole(); $argv = $args->getArg('args'); if (count($argv) == 0) { throw new PhutilArgumentUsageException(pht( 'Specify a configuration key and a value to set it to.')); } $key = $argv[0]; if (count($argv) == 1) { throw new PhutilArgumentUsageException(pht( "Specify a value to set the key '%s' to.", $key)); } $value = $argv[1]; if (count($argv) > 2) { throw new PhutilArgumentUsageException(pht( 'Too many arguments: expected one key and one value.')); } $options = PhabricatorApplicationConfigOptions::loadAllOptions(); if (empty($options[$key])) { throw new PhutilArgumentUsageException(pht( "No such configuration key '%s'! Use `config list` to list all ". "keys.", $key)); } $option = $options[$key]; $type = $option->getType(); switch ($type) { case 'string': case 'class': case 'enum': $value = (string)$value; break; case 'int': if (!ctype_digit($value)) { throw new PhutilArgumentUsageException(pht( "Config key '%s' is of type '%s'. Specify an integer.", $key, $type)); } $value = (int)$value; break; case 'bool': if ($value == 'true') { $value = true; } else if ($value == 'false') { $value = false; } else { throw new PhutilArgumentUsageException(pht( "Config key '%s' is of type '%s'. ". "Specify 'true' or 'false'.", $key, $type)); } break; default: $value = json_decode($value, true); if (!is_array($value)) { throw new PhutilArgumentUsageException(pht( "Config key '%s' is of type '%s'. Specify it in JSON.", $key, $type)); } break; } $use_database = $args->getArg('database'); if ($option->getLocked() && $use_database) { throw new PhutilArgumentUsageException(pht( "Config key '%s' is locked and can only be set in local ". 'configuration.', $key)); } try { $option->getGroup()->validateOption($option, $value); } catch (PhabricatorConfigValidationException $validation) { // Convert this into a usage exception so we don't dump a stack trace. throw new PhutilArgumentUsageException($validation->getMessage()); } if ($use_database) { $config_type = 'database'; - PhabricatorConfigEditor::storeNewValue( - $this->getViewer(), - id(new PhabricatorConfigEntry()) - ->loadOneWhere('namespace = %s AND key = %s', 'default', $key), - $value, - PhabricatorContentSource::newConsoleSource()); + $config_entry = PhabricatorConfigEntry::loadConfigEntry($key); + $config_entry->setValue($value); + $config_entry->save(); } else { $config_type = 'local'; id(new PhabricatorConfigLocalSource()) ->setKeys(array($key => $value)); } $console->writeOut( pht("Set '%s' in %s configuration.", $key, $config_type)."\n"); } } diff --git a/src/applications/config/storage/PhabricatorConfigEntry.php b/src/applications/config/storage/PhabricatorConfigEntry.php index 54fac1e333..abe7f4e036 100644 --- a/src/applications/config/storage/PhabricatorConfigEntry.php +++ b/src/applications/config/storage/PhabricatorConfigEntry.php @@ -1,101 +1,102 @@ true, self::CONFIG_SERIALIZATION => array( 'value' => self::SERIALIZATION_JSON, ), self::CONFIG_COLUMN_SCHEMA => array( 'namespace' => 'text64', 'configKey' => 'text64', 'isDeleted' => 'bool', ), self::CONFIG_KEY_SCHEMA => array( 'key_name' => array( 'columns' => array('namespace', 'configKey'), 'unique' => true, ), ), ) + parent::getConfiguration(); } public function generatePHID() { return PhabricatorPHID::generateNewPHID( PhabricatorConfigConfigPHIDType::TYPECONST); } public static function loadConfigEntry($key) { $config_entry = id(new PhabricatorConfigEntry()) ->loadOneWhere( 'configKey = %s AND namespace = %s', $key, 'default'); if (!$config_entry) { $config_entry = id(new PhabricatorConfigEntry()) ->setConfigKey($key) - ->setNamespace('default'); + ->setNamespace('default') + ->setIsDeleted(0); } return $config_entry; } /* -( PhabricatorApplicationTransactionInterface )------------------------- */ public function getApplicationTransactionEditor() { return new PhabricatorConfigEditor(); } public function getApplicationTransactionObject() { return $this; } public function getApplicationTransactionTemplate() { return new PhabricatorConfigTransaction(); } public function willRenderTimeline( PhabricatorApplicationTransactionView $timeline, AphrontRequest $request) { return $timeline; } /* -( PhabricatorPolicyInterface )----------------------------------------- */ public function getCapabilities() { return array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, ); } public function getPolicy($capability) { return PhabricatorPolicies::POLICY_ADMIN; } public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { return false; } public function describeAutomaticCapability($capability) { return null; } }