mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-18 09:48:39 +01:00
Start of a config web interface.
Summary: This is somewhat clowny, particularly in how it handles JSON encode/decode, but I've commented why I did things the way I did. The goal is to store minified JSON but show pretty-printed JSON where possible, to the user editing it. Test Plan: * Went to /config/ and saw a list of keys from the `default` config. * Clicked on one of them, submitted the default value successfully. * Changed the value to invalid JSON and got a decent error. * Changed the value to valid JSON and checked the DB to confirm it saved. * Confirmed the DB values were minified. * Confirmed the user-facing values were pretty-printed where they could be. * Confirmed that PHIDs were getting assigned properly and that isDeleted properly defaulted to false/0. Reviewers: epriestley Reviewed By: epriestley CC: aran, Korvin Maniphest Tasks: T2246 Differential Revision: https://secure.phabricator.com/D4290
This commit is contained in:
parent
1e2dfb5b6b
commit
a774620042
11 changed files with 352 additions and 0 deletions
12
resources/sql/patches/20121226.config.sql
Normal file
12
resources/sql/patches/20121226.config.sql
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_config.config_entry (
|
||||||
|
`id` INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
`phid` VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||||
|
`namespace` VARCHAR(64) BINARY NOT NULL COLLATE utf8_bin,
|
||||||
|
`configKey` VARCHAR(64) BINARY NOT NULL COLLATE utf8_bin,
|
||||||
|
`value` LONGTEXT NOT NULL,
|
||||||
|
`isDeleted` BOOL NOT NULL,
|
||||||
|
`dateCreated` INT UNSIGNED NOT NULL,
|
||||||
|
`dateModified` INT UNSIGNED NOT NULL,
|
||||||
|
UNIQUE KEY `key_phid` (`phid`),
|
||||||
|
UNIQUE KEY `key_name` (`namespace`, `configKey`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
|
@ -580,6 +580,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorApplicationAuth' => 'applications/auth/application/PhabricatorApplicationAuth.php',
|
'PhabricatorApplicationAuth' => 'applications/auth/application/PhabricatorApplicationAuth.php',
|
||||||
'PhabricatorApplicationCalendar' => 'applications/calendar/application/PhabricatorApplicationCalendar.php',
|
'PhabricatorApplicationCalendar' => 'applications/calendar/application/PhabricatorApplicationCalendar.php',
|
||||||
'PhabricatorApplicationConduit' => 'applications/conduit/application/PhabricatorApplicationConduit.php',
|
'PhabricatorApplicationConduit' => 'applications/conduit/application/PhabricatorApplicationConduit.php',
|
||||||
|
'PhabricatorApplicationConfig' => 'applications/config/application/PhabricatorApplicationConfig.php',
|
||||||
'PhabricatorApplicationCountdown' => 'applications/countdown/application/PhabricatorApplicationCountdown.php',
|
'PhabricatorApplicationCountdown' => 'applications/countdown/application/PhabricatorApplicationCountdown.php',
|
||||||
'PhabricatorApplicationDaemons' => 'applications/daemon/application/PhabricatorApplicationDaemons.php',
|
'PhabricatorApplicationDaemons' => 'applications/daemon/application/PhabricatorApplicationDaemons.php',
|
||||||
'PhabricatorApplicationDifferential' => 'applications/differential/application/PhabricatorApplicationDifferential.php',
|
'PhabricatorApplicationDifferential' => 'applications/differential/application/PhabricatorApplicationDifferential.php',
|
||||||
|
@ -679,8 +680,13 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorConduitLogController' => 'applications/conduit/controller/PhabricatorConduitLogController.php',
|
'PhabricatorConduitLogController' => 'applications/conduit/controller/PhabricatorConduitLogController.php',
|
||||||
'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/PhabricatorConduitMethodCallLog.php',
|
'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/PhabricatorConduitMethodCallLog.php',
|
||||||
'PhabricatorConduitTokenController' => 'applications/conduit/controller/PhabricatorConduitTokenController.php',
|
'PhabricatorConduitTokenController' => 'applications/conduit/controller/PhabricatorConduitTokenController.php',
|
||||||
|
'PhabricatorConfigController' => 'applications/config/controller/PhabricatorConfigController.php',
|
||||||
'PhabricatorConfigDictionarySource' => 'infrastructure/env/PhabricatorConfigDictionarySource.php',
|
'PhabricatorConfigDictionarySource' => 'infrastructure/env/PhabricatorConfigDictionarySource.php',
|
||||||
|
'PhabricatorConfigEditController' => 'applications/config/controller/PhabricatorConfigEditController.php',
|
||||||
|
'PhabricatorConfigEntry' => 'applications/config/storage/PhabricatorConfigEntry.php',
|
||||||
|
'PhabricatorConfigEntryDAO' => 'applications/config/storage/PhabricatorConfigEntryDAO.php',
|
||||||
'PhabricatorConfigFileSource' => 'infrastructure/env/PhabricatorConfigFileSource.php',
|
'PhabricatorConfigFileSource' => 'infrastructure/env/PhabricatorConfigFileSource.php',
|
||||||
|
'PhabricatorConfigListController' => 'applications/config/controller/PhabricatorConfigListController.php',
|
||||||
'PhabricatorConfigProxySource' => 'infrastructure/env/PhabricatorConfigProxySource.php',
|
'PhabricatorConfigProxySource' => 'infrastructure/env/PhabricatorConfigProxySource.php',
|
||||||
'PhabricatorConfigSource' => 'infrastructure/env/PhabricatorConfigSource.php',
|
'PhabricatorConfigSource' => 'infrastructure/env/PhabricatorConfigSource.php',
|
||||||
'PhabricatorConfigStackSource' => 'infrastructure/env/PhabricatorConfigStackSource.php',
|
'PhabricatorConfigStackSource' => 'infrastructure/env/PhabricatorConfigStackSource.php',
|
||||||
|
@ -1873,6 +1879,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorApplicationAuth' => 'PhabricatorApplication',
|
'PhabricatorApplicationAuth' => 'PhabricatorApplication',
|
||||||
'PhabricatorApplicationCalendar' => 'PhabricatorApplication',
|
'PhabricatorApplicationCalendar' => 'PhabricatorApplication',
|
||||||
'PhabricatorApplicationConduit' => 'PhabricatorApplication',
|
'PhabricatorApplicationConduit' => 'PhabricatorApplication',
|
||||||
|
'PhabricatorApplicationConfig' => 'PhabricatorApplication',
|
||||||
'PhabricatorApplicationCountdown' => 'PhabricatorApplication',
|
'PhabricatorApplicationCountdown' => 'PhabricatorApplication',
|
||||||
'PhabricatorApplicationDaemons' => 'PhabricatorApplication',
|
'PhabricatorApplicationDaemons' => 'PhabricatorApplication',
|
||||||
'PhabricatorApplicationDifferential' => 'PhabricatorApplication',
|
'PhabricatorApplicationDifferential' => 'PhabricatorApplication',
|
||||||
|
@ -1986,8 +1993,13 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorConduitLogController' => 'PhabricatorConduitController',
|
'PhabricatorConduitLogController' => 'PhabricatorConduitController',
|
||||||
'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO',
|
'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO',
|
||||||
'PhabricatorConduitTokenController' => 'PhabricatorConduitController',
|
'PhabricatorConduitTokenController' => 'PhabricatorConduitController',
|
||||||
|
'PhabricatorConfigController' => 'PhabricatorController',
|
||||||
'PhabricatorConfigDictionarySource' => 'PhabricatorConfigSource',
|
'PhabricatorConfigDictionarySource' => 'PhabricatorConfigSource',
|
||||||
|
'PhabricatorConfigEditController' => 'PhabricatorConfigController',
|
||||||
|
'PhabricatorConfigEntry' => 'PhabricatorConfigEntryDAO',
|
||||||
|
'PhabricatorConfigEntryDAO' => 'PhabricatorLiskDAO',
|
||||||
'PhabricatorConfigFileSource' => 'PhabricatorConfigProxySource',
|
'PhabricatorConfigFileSource' => 'PhabricatorConfigProxySource',
|
||||||
|
'PhabricatorConfigListController' => 'PhabricatorConfigController',
|
||||||
'PhabricatorConfigProxySource' => 'PhabricatorConfigSource',
|
'PhabricatorConfigProxySource' => 'PhabricatorConfigSource',
|
||||||
'PhabricatorConfigStackSource' => 'PhabricatorConfigSource',
|
'PhabricatorConfigStackSource' => 'PhabricatorConfigSource',
|
||||||
'PhabricatorContentSourceView' => 'AphrontView',
|
'PhabricatorContentSourceView' => 'AphrontView',
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorApplicationConfig extends PhabricatorApplication {
|
||||||
|
|
||||||
|
public function getBaseURI() {
|
||||||
|
return '/config/';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIconName() {
|
||||||
|
return 'config';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitleGlyph() {
|
||||||
|
return "\xE2\x98\xBA";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApplicationGroup() {
|
||||||
|
return self::GROUP_ADMIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function shouldAppearInLaunchView() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRoutes() {
|
||||||
|
return array(
|
||||||
|
'/config/' => array(
|
||||||
|
'' => 'PhabricatorConfigListController',
|
||||||
|
'edit/(?P<key>[\w\.\-]+)/' => 'PhabricatorConfigEditController',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class PhabricatorConfigController extends PhabricatorController {
|
||||||
|
|
||||||
|
public function shouldRequireAdmin() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildSideNavView($filter = null, $for_app = false) {
|
||||||
|
$user = $this->getRequest()->getUser();
|
||||||
|
|
||||||
|
$nav = new AphrontSideNavFilterView();
|
||||||
|
$nav->setBaseURI(new PhutilURI($this->getApplicationURI('filter/')));
|
||||||
|
|
||||||
|
return $nav;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildApplicationMenu() {
|
||||||
|
return $this->buildSideNavView(null, true)->getMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildApplicationCrumbs() {
|
||||||
|
$crumbs = parent::buildApplicationCrumbs();
|
||||||
|
return $crumbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorConfigEditController
|
||||||
|
extends PhabricatorConfigController {
|
||||||
|
|
||||||
|
private $key;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->key = idx($data, 'key');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
|
$config = id(new PhabricatorConfigFileSource('default'))
|
||||||
|
->getAllKeys();
|
||||||
|
if (!$this->key || !array_key_exists($this->key, $config)) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the config key is already stored in the database.
|
||||||
|
// Grab the value if it is.
|
||||||
|
$value = null;
|
||||||
|
$config_entry = id(new PhabricatorConfigEntry())
|
||||||
|
->loadOneWhere(
|
||||||
|
'configKey = %s AND namespace=%s',
|
||||||
|
$this->key,
|
||||||
|
'default');
|
||||||
|
if ($config_entry) {
|
||||||
|
$value = $config_entry->getValue();
|
||||||
|
} else {
|
||||||
|
$config_entry = id(new PhabricatorConfigEntry())
|
||||||
|
->setConfigKey($this->key);
|
||||||
|
}
|
||||||
|
|
||||||
|
$e_value = null;
|
||||||
|
$errors = array();
|
||||||
|
if ($request->isFormPost()) {
|
||||||
|
$new_value = $request->getStr('value');
|
||||||
|
if (strlen($new_value)) {
|
||||||
|
$json = json_decode($new_value, true);
|
||||||
|
if ($json === null && strtolower($value) != 'null') {
|
||||||
|
$e_value = 'Invalid';
|
||||||
|
$errors[] = 'The given value must be valid JSON. This means, among '.
|
||||||
|
'other things, that you must wrap strings in double-quotes.';
|
||||||
|
$value = $new_value;
|
||||||
|
} else {
|
||||||
|
$value = $json;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: When we do Transactions, make this just set isDeleted = 1
|
||||||
|
$config_entry->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
$config_entry->setValue($value);
|
||||||
|
$config_entry->setNamespace('default');
|
||||||
|
|
||||||
|
if (!$errors) {
|
||||||
|
$config_entry->save();
|
||||||
|
return id(new AphrontRedirectResponse())
|
||||||
|
->setURI($config_entry->getURI());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$form = new AphrontFormView();
|
||||||
|
$form->setFlexible(true);
|
||||||
|
|
||||||
|
$error_view = null;
|
||||||
|
if ($errors) {
|
||||||
|
$error_view = id(new AphrontErrorView())
|
||||||
|
->setTitle('You broke everything!')
|
||||||
|
->setErrors($errors);
|
||||||
|
} else {
|
||||||
|
// Check not only that it's an array, but that it's an "unnatural" array
|
||||||
|
// meaning that the keys aren't 0 -> size_of_array.
|
||||||
|
if (is_array($value) &&
|
||||||
|
array_keys($value) != range(0, count($value) - 1)) {
|
||||||
|
$value = id(new PhutilJSON())->encodeFormatted($value);
|
||||||
|
} else {
|
||||||
|
$value = json_encode($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$form
|
||||||
|
->setUser($user)
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTextAreaControl())
|
||||||
|
->setLabel('JSON Value')
|
||||||
|
->setError($e_value)
|
||||||
|
->setValue($value)
|
||||||
|
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
|
||||||
|
->setCustomClass('PhabricatorMonospaced')
|
||||||
|
->setName('value'))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormSubmitControl())
|
||||||
|
->addCancelButton($config_entry->getURI())
|
||||||
|
->setValue(pht('Save Config Entry')));
|
||||||
|
|
||||||
|
$title = pht('Edit %s', $this->key);
|
||||||
|
$short = pht('Edit');
|
||||||
|
|
||||||
|
$crumbs = $this->buildApplicationCrumbs($this->buildSideNavView());
|
||||||
|
$crumbs->addCrumb(
|
||||||
|
id(new PhabricatorCrumbView())
|
||||||
|
->setName($this->key)
|
||||||
|
->setHref('/config/edit/'.$this->key));
|
||||||
|
$crumbs->addCrumb(
|
||||||
|
id(new PhabricatorCrumbView())->setName($short));
|
||||||
|
|
||||||
|
return $this->buildApplicationPage(
|
||||||
|
array(
|
||||||
|
$crumbs,
|
||||||
|
id(new PhabricatorHeaderView())->setHeader($title),
|
||||||
|
$error_view,
|
||||||
|
$form,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'title' => $title,
|
||||||
|
'device' => true,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorConfigListController
|
||||||
|
extends PhabricatorConfigController {
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
|
$nav = $this->buildSideNavView();
|
||||||
|
|
||||||
|
$pager = new AphrontCursorPagerView();
|
||||||
|
$pager->readFromRequest($request);
|
||||||
|
|
||||||
|
$config = new PhabricatorConfigFileSource('default');
|
||||||
|
$list = $this->buildConfigList(array_keys($config->getAllKeys()));
|
||||||
|
$list->setPager($pager);
|
||||||
|
$list->setNoDataString(
|
||||||
|
'No data. Something probably went wrong in reading the default config.');
|
||||||
|
|
||||||
|
$header = id(new PhabricatorHeaderView())
|
||||||
|
->setHeader(pht('Configuration'));
|
||||||
|
|
||||||
|
$nav->appendChild(
|
||||||
|
array(
|
||||||
|
$header,
|
||||||
|
$list,
|
||||||
|
));
|
||||||
|
|
||||||
|
$crumbs = $this
|
||||||
|
->buildApplicationCrumbs($nav)
|
||||||
|
->addCrumb(
|
||||||
|
id(new PhabricatorCrumbView())
|
||||||
|
->setName(pht('Configuration'))
|
||||||
|
->setHref($this->getApplicationURI('filter/')));
|
||||||
|
|
||||||
|
$nav->setCrumbs($crumbs);
|
||||||
|
|
||||||
|
return $this->buildApplicationPage(
|
||||||
|
$nav,
|
||||||
|
array(
|
||||||
|
'title' => pht('Configuration'),
|
||||||
|
'device' => true,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildConfigList(array $keys) {
|
||||||
|
$list = new PhabricatorObjectItemListView();
|
||||||
|
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$item = id(new PhabricatorObjectItemView())
|
||||||
|
->setHeader($key)
|
||||||
|
->setHref('/config/edit/'.$key)
|
||||||
|
->setObject($key);
|
||||||
|
$list->addItem($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
32
src/applications/config/storage/PhabricatorConfigEntry.php
Normal file
32
src/applications/config/storage/PhabricatorConfigEntry.php
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorConfigEntry extends PhabricatorConfigEntryDAO {
|
||||||
|
|
||||||
|
protected $id;
|
||||||
|
protected $phid;
|
||||||
|
protected $namespace;
|
||||||
|
protected $configKey;
|
||||||
|
protected $value;
|
||||||
|
|
||||||
|
// TODO: Remove this default when implementing Transactions.
|
||||||
|
protected $isDeleted = 0;
|
||||||
|
|
||||||
|
public function getURI() {
|
||||||
|
return '/config/edit/'.$this->configKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getConfiguration() {
|
||||||
|
return array(
|
||||||
|
self::CONFIG_AUX_PHID => true,
|
||||||
|
self::CONFIG_SERIALIZATION => array(
|
||||||
|
'value' => self::SERIALIZATION_JSON,
|
||||||
|
),
|
||||||
|
) + parent::getConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generatePHID() {
|
||||||
|
return PhabricatorPHID::generateNewPHID(
|
||||||
|
PhabricatorPHIDConstants::PHID_TYPE_CONF);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class PhabricatorConfigEntryDAO extends PhabricatorLiskDAO {
|
||||||
|
|
||||||
|
public function getApplicationName() {
|
||||||
|
return 'config';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -30,6 +30,7 @@ final class PhabricatorPHIDConstants {
|
||||||
const PHID_TYPE_ANSW = 'ANSW';
|
const PHID_TYPE_ANSW = 'ANSW';
|
||||||
const PHID_TYPE_MOCK = 'MOCK';
|
const PHID_TYPE_MOCK = 'MOCK';
|
||||||
const PHID_TYPE_MCRO = 'MCRO';
|
const PHID_TYPE_MCRO = 'MCRO';
|
||||||
|
const PHID_TYPE_CONF = 'CONF';
|
||||||
|
|
||||||
const PHID_TYPE_XACT = 'XACT';
|
const PHID_TYPE_XACT = 'XACT';
|
||||||
const PHID_TYPE_XCMT = 'XCMT';
|
const PHID_TYPE_XCMT = 'XCMT';
|
||||||
|
|
|
@ -77,6 +77,15 @@ final class PhabricatorObjectHandleData {
|
||||||
$objects[$task->getPHID()] = $task;
|
$objects[$task->getPHID()] = $task;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PhabricatorPHIDConstants::PHID_TYPE_CONF:
|
||||||
|
$config_dao = new PhabricatorConfigEntry();
|
||||||
|
$entries = $config_dao->loadAllWhere(
|
||||||
|
'phid IN (%Ls)',
|
||||||
|
$phids);
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$objects[$entry->getPHID()] = $entry;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case PhabricatorPHIDConstants::PHID_TYPE_DREV:
|
case PhabricatorPHIDConstants::PHID_TYPE_DREV:
|
||||||
$revision_dao = new DifferentialRevision();
|
$revision_dao = new DifferentialRevision();
|
||||||
$revisions = $revision_dao->loadAllWhere(
|
$revisions = $revision_dao->loadAllWhere(
|
||||||
|
@ -366,6 +375,28 @@ final class PhabricatorObjectHandleData {
|
||||||
$handles[$phid] = $handle;
|
$handles[$phid] = $handle;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PhabricatorPHIDConstants::PHID_TYPE_CONF:
|
||||||
|
$object = new PhabricatorConfigEntry();
|
||||||
|
|
||||||
|
$entries = $object->loadAllWhere('phid in (%Ls)', $phids);
|
||||||
|
$entries = mpull($entries, null, 'getPHID');
|
||||||
|
|
||||||
|
foreach ($phids as $phid) {
|
||||||
|
$handle = new PhabricatorObjectHandle();
|
||||||
|
$handle->setPHID($phid);
|
||||||
|
$handle->setType($type);
|
||||||
|
if (empty($entries[$phid])) {
|
||||||
|
$handle->setName('Unknown Config Entry');
|
||||||
|
} else {
|
||||||
|
$entry = $entry[$phid];
|
||||||
|
$handle->setName($entry->getKey());
|
||||||
|
$handle->setURI('/config/edit/'.$entry->getKey());
|
||||||
|
$handle->setFullName($entry->getKey());
|
||||||
|
$handle->setComplete(true);
|
||||||
|
}
|
||||||
|
$handles[$phid] = $handle;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case PhabricatorPHIDConstants::PHID_TYPE_FILE:
|
case PhabricatorPHIDConstants::PHID_TYPE_FILE:
|
||||||
$object = new PhabricatorFile();
|
$object = new PhabricatorFile();
|
||||||
|
|
||||||
|
|
|
@ -1064,6 +1064,14 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList {
|
||||||
'type' => 'sql',
|
'type' => 'sql',
|
||||||
'name' => $this->getPatchPath('20121220.generalcache.sql'),
|
'name' => $this->getPatchPath('20121220.generalcache.sql'),
|
||||||
),
|
),
|
||||||
|
'db.config' => array(
|
||||||
|
'type' => 'db',
|
||||||
|
'name' => 'config',
|
||||||
|
),
|
||||||
|
'20121226.config.sql' => array(
|
||||||
|
'type' => 'sql',
|
||||||
|
'name' => $this->getPatchPath('20121226.config.sql'),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue