mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-27 01:02:42 +01:00
Phlux v0
Summary: Yup, it's sitevars. No conduit or caching or fancy stuff yet. Ref T2793. Test Plan: {F36525} {F36526} {F36527} {F36528} {F36529} Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T2793 Differential Revision: https://secure.phabricator.com/D5397
This commit is contained in:
parent
eca49cb91f
commit
9a515171f4
16 changed files with 772 additions and 0 deletions
32
resources/sql/patches/20130320.phlux.sql
Normal file
32
resources/sql/patches/20130320.phlux.sql
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_phlux.phlux_variable (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
phid VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||||
|
variableKey VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||||
|
variableValue LONGTEXT NOT NULL COLLATE utf8_bin,
|
||||||
|
viewPolicy VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||||
|
editPolicy VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||||
|
dateCreated INT UNSIGNED NOT NULL,
|
||||||
|
dateModified INT UNSIGNED NOT NULL,
|
||||||
|
UNIQUE KEY `key_phid` (phid),
|
||||||
|
UNIQUE KEY `key_key` (variableKey)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
CREATE TABLE {$NAMESPACE}_phlux.phlux_transaction (
|
||||||
|
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
phid VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||||
|
authorPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||||
|
objectPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||||
|
viewPolicy VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||||
|
editPolicy VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||||
|
commentPHID VARCHAR(64) COLLATE utf8_bin,
|
||||||
|
commentVersion INT UNSIGNED NOT NULL,
|
||||||
|
transactionType VARCHAR(32) NOT NULL COLLATE utf8_bin,
|
||||||
|
oldValue LONGTEXT NOT NULL COLLATE utf8_bin,
|
||||||
|
newValue LONGTEXT NOT NULL COLLATE utf8_bin,
|
||||||
|
contentSource LONGTEXT NOT NULL COLLATE utf8_bin,
|
||||||
|
dateCreated INT UNSIGNED NOT NULL,
|
||||||
|
dateModified INT UNSIGNED NOT NULL,
|
||||||
|
UNIQUE KEY `key_phid` (phid),
|
||||||
|
KEY `key_object` (objectPHID)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
|
@ -700,6 +700,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorApplicationPaste' => 'applications/paste/application/PhabricatorApplicationPaste.php',
|
'PhabricatorApplicationPaste' => 'applications/paste/application/PhabricatorApplicationPaste.php',
|
||||||
'PhabricatorApplicationPeople' => 'applications/people/application/PhabricatorApplicationPeople.php',
|
'PhabricatorApplicationPeople' => 'applications/people/application/PhabricatorApplicationPeople.php',
|
||||||
'PhabricatorApplicationPhame' => 'applications/phame/application/PhabricatorApplicationPhame.php',
|
'PhabricatorApplicationPhame' => 'applications/phame/application/PhabricatorApplicationPhame.php',
|
||||||
|
'PhabricatorApplicationPhlux' => 'applications/phlux/application/PhabricatorApplicationPhlux.php',
|
||||||
'PhabricatorApplicationPholio' => 'applications/pholio/application/PhabricatorApplicationPholio.php',
|
'PhabricatorApplicationPholio' => 'applications/pholio/application/PhabricatorApplicationPholio.php',
|
||||||
'PhabricatorApplicationPhriction' => 'applications/phriction/application/PhabricatorApplicationPhriction.php',
|
'PhabricatorApplicationPhriction' => 'applications/phriction/application/PhabricatorApplicationPhriction.php',
|
||||||
'PhabricatorApplicationPonder' => 'applications/ponder/application/PhabricatorApplicationPonder.php',
|
'PhabricatorApplicationPonder' => 'applications/ponder/application/PhabricatorApplicationPonder.php',
|
||||||
|
@ -1482,6 +1483,16 @@ phutil_register_library_map(array(
|
||||||
'PhamePostViewController' => 'applications/phame/controller/post/PhamePostViewController.php',
|
'PhamePostViewController' => 'applications/phame/controller/post/PhamePostViewController.php',
|
||||||
'PhameResourceController' => 'applications/phame/controller/PhameResourceController.php',
|
'PhameResourceController' => 'applications/phame/controller/PhameResourceController.php',
|
||||||
'PhameSkinSpecification' => 'applications/phame/skins/PhameSkinSpecification.php',
|
'PhameSkinSpecification' => 'applications/phame/skins/PhameSkinSpecification.php',
|
||||||
|
'PhluxController' => 'applications/phlux/controller/PhluxController.php',
|
||||||
|
'PhluxDAO' => 'applications/phlux/storage/PhluxDAO.php',
|
||||||
|
'PhluxEditController' => 'applications/phlux/controller/PhluxEditController.php',
|
||||||
|
'PhluxListController' => 'applications/phlux/controller/PhluxListController.php',
|
||||||
|
'PhluxTransaction' => 'applications/phlux/storage/PhluxTransaction.php',
|
||||||
|
'PhluxTransactionQuery' => 'applications/phlux/query/PhluxTransactionQuery.php',
|
||||||
|
'PhluxVariable' => 'applications/phlux/storage/PhluxVariable.php',
|
||||||
|
'PhluxVariableEditor' => 'applications/phlux/editor/PhluxVariableEditor.php',
|
||||||
|
'PhluxVariableQuery' => 'applications/phlux/query/PhluxVariableQuery.php',
|
||||||
|
'PhluxViewController' => 'applications/phlux/controller/PhluxViewController.php',
|
||||||
'PholioConstants' => 'applications/pholio/constants/PholioConstants.php',
|
'PholioConstants' => 'applications/pholio/constants/PholioConstants.php',
|
||||||
'PholioController' => 'applications/pholio/controller/PholioController.php',
|
'PholioController' => 'applications/pholio/controller/PholioController.php',
|
||||||
'PholioDAO' => 'applications/pholio/storage/PholioDAO.php',
|
'PholioDAO' => 'applications/pholio/storage/PholioDAO.php',
|
||||||
|
@ -2310,6 +2321,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorApplicationPaste' => 'PhabricatorApplication',
|
'PhabricatorApplicationPaste' => 'PhabricatorApplication',
|
||||||
'PhabricatorApplicationPeople' => 'PhabricatorApplication',
|
'PhabricatorApplicationPeople' => 'PhabricatorApplication',
|
||||||
'PhabricatorApplicationPhame' => 'PhabricatorApplication',
|
'PhabricatorApplicationPhame' => 'PhabricatorApplication',
|
||||||
|
'PhabricatorApplicationPhlux' => 'PhabricatorApplication',
|
||||||
'PhabricatorApplicationPholio' => 'PhabricatorApplication',
|
'PhabricatorApplicationPholio' => 'PhabricatorApplication',
|
||||||
'PhabricatorApplicationPhriction' => 'PhabricatorApplication',
|
'PhabricatorApplicationPhriction' => 'PhabricatorApplication',
|
||||||
'PhabricatorApplicationPonder' => 'PhabricatorApplication',
|
'PhabricatorApplicationPonder' => 'PhabricatorApplication',
|
||||||
|
@ -3080,6 +3092,20 @@ phutil_register_library_map(array(
|
||||||
'PhamePostView' => 'AphrontView',
|
'PhamePostView' => 'AphrontView',
|
||||||
'PhamePostViewController' => 'PhameController',
|
'PhamePostViewController' => 'PhameController',
|
||||||
'PhameResourceController' => 'CelerityResourceController',
|
'PhameResourceController' => 'CelerityResourceController',
|
||||||
|
'PhluxController' => 'PhabricatorController',
|
||||||
|
'PhluxDAO' => 'PhabricatorLiskDAO',
|
||||||
|
'PhluxEditController' => 'PhluxController',
|
||||||
|
'PhluxListController' => 'PhluxController',
|
||||||
|
'PhluxTransaction' => 'PhabricatorApplicationTransaction',
|
||||||
|
'PhluxTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||||
|
'PhluxVariable' =>
|
||||||
|
array(
|
||||||
|
0 => 'PhluxDAO',
|
||||||
|
1 => 'PhabricatorPolicyInterface',
|
||||||
|
),
|
||||||
|
'PhluxVariableEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||||
|
'PhluxVariableQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhluxViewController' => 'PhluxController',
|
||||||
'PholioController' => 'PhabricatorController',
|
'PholioController' => 'PhabricatorController',
|
||||||
'PholioDAO' => 'PhabricatorLiskDAO',
|
'PholioDAO' => 'PhabricatorLiskDAO',
|
||||||
'PholioImage' =>
|
'PholioImage' =>
|
||||||
|
|
|
@ -32,6 +32,7 @@ final class PhabricatorPHIDConstants {
|
||||||
const PHID_TYPE_MCRO = 'MCRO';
|
const PHID_TYPE_MCRO = 'MCRO';
|
||||||
const PHID_TYPE_CONF = 'CONF';
|
const PHID_TYPE_CONF = 'CONF';
|
||||||
const PHID_TYPE_CONP = 'CONP';
|
const PHID_TYPE_CONP = 'CONP';
|
||||||
|
const PHID_TYPE_PVAR = 'PVAR';
|
||||||
|
|
||||||
const PHID_TYPE_XACT = 'XACT';
|
const PHID_TYPE_XACT = 'XACT';
|
||||||
const PHID_TYPE_XCMT = 'XCMT';
|
const PHID_TYPE_XCMT = 'XCMT';
|
||||||
|
|
|
@ -184,6 +184,13 @@ final class PhabricatorObjectHandleData {
|
||||||
->execute();
|
->execute();
|
||||||
return mpull($posts, null, 'getPHID');
|
return mpull($posts, null, 'getPHID');
|
||||||
|
|
||||||
|
case PhabricatorPHIDConstants::PHID_TYPE_PVAR:
|
||||||
|
$vars = id(new PhluxVariableQuery())
|
||||||
|
->withPHIDs($phids)
|
||||||
|
->setViewer($this->viewer)
|
||||||
|
->execute();
|
||||||
|
return mpull($vars, null, 'getPHID');
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -619,6 +626,25 @@ final class PhabricatorObjectHandleData {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PhabricatorPHIDConstants::PHID_TYPE_PVAR:
|
||||||
|
foreach ($phids as $phid) {
|
||||||
|
$handle = new PhabricatorObjectHandle();
|
||||||
|
$handle->setPHID($phid);
|
||||||
|
$handle->setType($type);
|
||||||
|
if (empty($objects[$phid])) {
|
||||||
|
$handle->setName('Unknown Variable');
|
||||||
|
} else {
|
||||||
|
$var = $objects[$phid];
|
||||||
|
$key = $var->getVariableKey();
|
||||||
|
$handle->setName($key);
|
||||||
|
$handle->setFullName('Phlux Variable "'.$key.'"');
|
||||||
|
$handle->setURI('/phlux/view/'.$key.'/');
|
||||||
|
$handle->setComplete(true);
|
||||||
|
}
|
||||||
|
$handles[$phid] = $handle;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$loader = null;
|
$loader = null;
|
||||||
if (isset($external_loaders[$type])) {
|
if (isset($external_loaders[$type])) {
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorApplicationPhlux extends PhabricatorApplication {
|
||||||
|
|
||||||
|
public function getBaseURI() {
|
||||||
|
return '/phlux/';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getShortDescription() {
|
||||||
|
return pht('Configuration Store');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIconName() {
|
||||||
|
return 'phlux';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitleGlyph() {
|
||||||
|
return "\xE2\x98\xBD";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApplicationGroup() {
|
||||||
|
return self::GROUP_UTILITIES;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isBeta() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRoutes() {
|
||||||
|
return array(
|
||||||
|
'/phlux/' => array(
|
||||||
|
'' => 'PhluxListController',
|
||||||
|
'view/(?P<key>[^/]+)/' => 'PhluxViewController',
|
||||||
|
'edit/(?:(?P<key>[^/]+)/)?' => 'PhluxEditController',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
16
src/applications/phlux/controller/PhluxController.php
Normal file
16
src/applications/phlux/controller/PhluxController.php
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class PhluxController extends PhabricatorController {
|
||||||
|
|
||||||
|
protected function buildApplicationCrumbs() {
|
||||||
|
$crumbs = parent::buildApplicationCrumbs();
|
||||||
|
$crumbs->addAction(
|
||||||
|
id(new PhabricatorMenuItemView())
|
||||||
|
->setName(pht('Create Variable'))
|
||||||
|
->setHref($this->getApplicationURI('/edit/'))
|
||||||
|
->setIcon('create'));
|
||||||
|
|
||||||
|
return $crumbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
201
src/applications/phlux/controller/PhluxEditController.php
Normal file
201
src/applications/phlux/controller/PhluxEditController.php
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhluxEditController extends PhluxController {
|
||||||
|
|
||||||
|
private $key;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->key = idx($data, 'key');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
|
$is_new = ($this->key === null);
|
||||||
|
if ($is_new) {
|
||||||
|
$var = new PhluxVariable();
|
||||||
|
$var->setViewPolicy(PhabricatorPolicies::POLICY_USER);
|
||||||
|
$var->setEditPolicy(PhabricatorPolicies::POLICY_USER);
|
||||||
|
} else {
|
||||||
|
$var = id(new PhluxVariableQuery())
|
||||||
|
->setViewer($user)
|
||||||
|
->requireCapabilities(
|
||||||
|
array(
|
||||||
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
))
|
||||||
|
->withKeys(array($this->key))
|
||||||
|
->executeOne();
|
||||||
|
if (!$var) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
$view_uri = $this->getApplicationURI('/view/'.$this->key.'/');
|
||||||
|
}
|
||||||
|
|
||||||
|
$e_key = ($is_new ? true : null);
|
||||||
|
$e_value = true;
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
$key = $var->getVariableKey();
|
||||||
|
|
||||||
|
$display_value = null;
|
||||||
|
$value = $var->getVariableValue();
|
||||||
|
|
||||||
|
if ($request->isFormPost()) {
|
||||||
|
if ($is_new) {
|
||||||
|
$key = $request->getStr('key');
|
||||||
|
if (!strlen($key)) {
|
||||||
|
$errors[] = pht('Variable key is required.');
|
||||||
|
$e_key = pht('Required');
|
||||||
|
} else if (!preg_match('/^[a-z0-9.-]+$/', $key)) {
|
||||||
|
$errors[] = pht(
|
||||||
|
'Variable key "%s" must contain only lowercase letters, digits, '.
|
||||||
|
'period, and hyphen.',
|
||||||
|
$key);
|
||||||
|
$e_key = pht('Invalid');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$raw_value = $request->getStr('value');
|
||||||
|
$value = json_decode($raw_value, true);
|
||||||
|
if ($value === null && strtolower($raw_value) !== 'null') {
|
||||||
|
$e_value = pht('Invalid');
|
||||||
|
$errors[] = pht('Variable value must be valid JSON.');
|
||||||
|
$display_value = $raw_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$errors) {
|
||||||
|
$editor = id(new PhluxVariableEditor())
|
||||||
|
->setActor($user)
|
||||||
|
->setContinueOnNoEffect(true)
|
||||||
|
->setContentSource(
|
||||||
|
PhabricatorContentSource::newForSource(
|
||||||
|
PhabricatorContentSource::SOURCE_WEB,
|
||||||
|
array(
|
||||||
|
'ip' => $request->getRemoteAddr(),
|
||||||
|
)));
|
||||||
|
|
||||||
|
$xactions = array();
|
||||||
|
$xactions[] = id(new PhluxTransaction())
|
||||||
|
->setTransactionType(PhluxTransaction::TYPE_EDIT_KEY)
|
||||||
|
->setNewValue($key);
|
||||||
|
|
||||||
|
$xactions[] = id(new PhluxTransaction())
|
||||||
|
->setTransactionType(PhluxTransaction::TYPE_EDIT_VALUE)
|
||||||
|
->setNewValue($value);
|
||||||
|
|
||||||
|
$xactions[] = id(new PhluxTransaction())
|
||||||
|
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
|
||||||
|
->setNewValue($request->getStr('viewPolicy'));
|
||||||
|
|
||||||
|
$xactions[] = id(new PhluxTransaction())
|
||||||
|
->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)
|
||||||
|
->setNewValue($request->getStr('editPolicy'));
|
||||||
|
|
||||||
|
try {
|
||||||
|
$editor->applyTransactions($var, $xactions);
|
||||||
|
$view_uri = $this->getApplicationURI('/view/'.$key.'/');
|
||||||
|
return id(new AphrontRedirectResponse())->setURI($view_uri);
|
||||||
|
} catch (AphrontQueryDuplicateKeyException $ex) {
|
||||||
|
$e_key = pht('Not Unique');
|
||||||
|
$errors[] = pht('Variable key must be unique.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($display_value === null) {
|
||||||
|
if (is_array($value) &&
|
||||||
|
(array_keys($value) !== array_keys(array_values($value)))) {
|
||||||
|
$json = new PhutilJSON();
|
||||||
|
$display_value = $json->encodeFormatted($value);
|
||||||
|
} else {
|
||||||
|
$display_value = json_encode($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($errors) {
|
||||||
|
$errors = id(new AphrontErrorView())
|
||||||
|
->setErrors($errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
$policies = id(new PhabricatorPolicyQuery())
|
||||||
|
->setViewer($user)
|
||||||
|
->setObject($var)
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$form = id(new AphrontFormView())
|
||||||
|
->setUser($user)
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTextControl())
|
||||||
|
->setValue($var->getVariableKey())
|
||||||
|
->setLabel(pht('Key'))
|
||||||
|
->setName('key')
|
||||||
|
->setError($e_key)
|
||||||
|
->setCaption(pht('Lowercase letters, digits, dot and hyphen only.'))
|
||||||
|
->setDisabled(!$is_new))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTextAreaControl())
|
||||||
|
->setValue($display_value)
|
||||||
|
->setLabel(pht('Value'))
|
||||||
|
->setName('value')
|
||||||
|
->setCaption(pht('Enter value as JSON.'))
|
||||||
|
->setError($e_value))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormPolicyControl())
|
||||||
|
->setName('viewPolicy')
|
||||||
|
->setPolicyObject($var)
|
||||||
|
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
|
||||||
|
->setPolicies($policies))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormPolicyControl())
|
||||||
|
->setName('editPolicy')
|
||||||
|
->setPolicyObject($var)
|
||||||
|
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
|
||||||
|
->setPolicies($policies));
|
||||||
|
|
||||||
|
if ($is_new) {
|
||||||
|
$form->appendChild(
|
||||||
|
id(new AphrontFormSubmitControl())
|
||||||
|
->setValue(pht('Create Variable')));
|
||||||
|
} else {
|
||||||
|
$form->appendChild(
|
||||||
|
id(new AphrontFormSubmitControl())
|
||||||
|
->setValue(pht('Update Variable'))
|
||||||
|
->addCancelButton($view_uri));
|
||||||
|
}
|
||||||
|
|
||||||
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
|
|
||||||
|
if ($is_new) {
|
||||||
|
$title = pht('Create Variable');
|
||||||
|
$crumbs->addCrumb(
|
||||||
|
id(new PhabricatorCrumbView())
|
||||||
|
->setName($title)
|
||||||
|
->setHref($request->getRequestURI()));
|
||||||
|
} else {
|
||||||
|
$title = pht('Edit %s', $this->key);
|
||||||
|
$crumbs->addCrumb(
|
||||||
|
id(new PhabricatorCrumbView())
|
||||||
|
->setName($title)
|
||||||
|
->setHref($request->getRequestURI()));
|
||||||
|
}
|
||||||
|
|
||||||
|
$header = id(new PhabricatorHeaderView())
|
||||||
|
->setHeader($title);
|
||||||
|
|
||||||
|
return $this->buildApplicationPage(
|
||||||
|
array(
|
||||||
|
$crumbs,
|
||||||
|
$header,
|
||||||
|
$errors,
|
||||||
|
$form,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'title' => $title,
|
||||||
|
'device' => true,
|
||||||
|
'dust' => true,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
56
src/applications/phlux/controller/PhluxListController.php
Normal file
56
src/applications/phlux/controller/PhluxListController.php
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhluxListController extends PhluxController {
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
|
$pager = new AphrontCursorPagerView();
|
||||||
|
$pager->readFromRequest($request);
|
||||||
|
$query = id(new PhluxVariableQuery())
|
||||||
|
->setViewer($user);
|
||||||
|
|
||||||
|
$vars = $query->executeWithCursorPager($pager);
|
||||||
|
|
||||||
|
$view = new PhabricatorObjectItemListView();
|
||||||
|
foreach ($vars as $var) {
|
||||||
|
$key = $var->getVariableKey();
|
||||||
|
|
||||||
|
$item = new PhabricatorObjectItemView();
|
||||||
|
$item->setHeader($key);
|
||||||
|
$item->setHref($this->getApplicationURI('/view/'.$key.'/'));
|
||||||
|
$item->addIcon(
|
||||||
|
'none',
|
||||||
|
phabricator_datetime($var->getDateModified(), $user));
|
||||||
|
|
||||||
|
$view->addItem($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
|
|
||||||
|
$title = pht('Variable List');
|
||||||
|
|
||||||
|
$crumbs->addCrumb(
|
||||||
|
id(new PhabricatorCrumbView())
|
||||||
|
->setName($title)
|
||||||
|
->setHref($this->getApplicationURI()));
|
||||||
|
|
||||||
|
$header = id(new PhabricatorHeaderView())
|
||||||
|
->setHeader($title);
|
||||||
|
|
||||||
|
return $this->buildApplicationPage(
|
||||||
|
array(
|
||||||
|
$crumbs,
|
||||||
|
$header,
|
||||||
|
$view,
|
||||||
|
$pager,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'title' => $title,
|
||||||
|
'device' => true,
|
||||||
|
'dust' => true,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
99
src/applications/phlux/controller/PhluxViewController.php
Normal file
99
src/applications/phlux/controller/PhluxViewController.php
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhluxViewController extends PhluxController {
|
||||||
|
|
||||||
|
private $key;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->key = $data['key'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
|
$var = id(new PhluxVariableQuery())
|
||||||
|
->setViewer($user)
|
||||||
|
->withKeys(array($this->key))
|
||||||
|
->executeOne();
|
||||||
|
|
||||||
|
if (!$var) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
|
|
||||||
|
$title = $var->getVariableKey();
|
||||||
|
|
||||||
|
$crumbs->addCrumb(
|
||||||
|
id(new PhabricatorCrumbView())
|
||||||
|
->setName($title)
|
||||||
|
->setHref($request->getRequestURI()));
|
||||||
|
|
||||||
|
$header = id(new PhabricatorHeaderView())
|
||||||
|
->setHeader($title);
|
||||||
|
|
||||||
|
$actions = id(new PhabricatorActionListView())
|
||||||
|
->setUser($user)
|
||||||
|
->setObject($var);
|
||||||
|
|
||||||
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||||
|
$user,
|
||||||
|
$var,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT);
|
||||||
|
|
||||||
|
$actions->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setIcon('edit')
|
||||||
|
->setName(pht('Edit Variable'))
|
||||||
|
->setHref($this->getApplicationURI('/edit/'.$var->getVariableKey().'/'))
|
||||||
|
->setDisabled(!$can_edit)
|
||||||
|
->setWorkflow(!$can_edit));
|
||||||
|
|
||||||
|
$display_value = json_encode($var->getVariableValue());
|
||||||
|
|
||||||
|
$descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
|
||||||
|
$user,
|
||||||
|
$var);
|
||||||
|
|
||||||
|
$properties = id(new PhabricatorPropertyListView())
|
||||||
|
->setUser($user)
|
||||||
|
->setObject($var)
|
||||||
|
->addProperty(pht('Value'), $display_value)
|
||||||
|
->addProperty(
|
||||||
|
pht('Visible To'),
|
||||||
|
$descriptions[PhabricatorPolicyCapability::CAN_VIEW])
|
||||||
|
->addProperty(
|
||||||
|
pht('Editable By'),
|
||||||
|
$descriptions[PhabricatorPolicyCapability::CAN_EDIT]);
|
||||||
|
|
||||||
|
|
||||||
|
$xactions = id(new PhluxTransactionQuery())
|
||||||
|
->setViewer($user)
|
||||||
|
->withObjectPHIDs(array($var->getPHID()))
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$engine = id(new PhabricatorMarkupEngine())
|
||||||
|
->setViewer($user);
|
||||||
|
|
||||||
|
$xaction_view = id(new PhabricatorApplicationTransactionView())
|
||||||
|
->setUser($user)
|
||||||
|
->setTransactions($xactions)
|
||||||
|
->setMarkupEngine($engine);
|
||||||
|
|
||||||
|
return $this->buildApplicationPage(
|
||||||
|
array(
|
||||||
|
$crumbs,
|
||||||
|
$header,
|
||||||
|
$actions,
|
||||||
|
$properties,
|
||||||
|
$xaction_view,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'title' => $title,
|
||||||
|
'device' => true,
|
||||||
|
'dust' => true,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
70
src/applications/phlux/editor/PhluxVariableEditor.php
Normal file
70
src/applications/phlux/editor/PhluxVariableEditor.php
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhluxVariableEditor
|
||||||
|
extends PhabricatorApplicationTransactionEditor {
|
||||||
|
|
||||||
|
public function getTransactionTypes() {
|
||||||
|
$types = parent::getTransactionTypes();
|
||||||
|
$types[] = PhluxTransaction::TYPE_EDIT_KEY;
|
||||||
|
$types[] = PhluxTransaction::TYPE_EDIT_VALUE;
|
||||||
|
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||||
|
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||||
|
return $types;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCustomTransactionOldValue(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
PhabricatorApplicationTransaction $xaction) {
|
||||||
|
switch ($xaction->getTransactionType()) {
|
||||||
|
case PhluxTransaction::TYPE_EDIT_KEY:
|
||||||
|
return $object->getVariableKey();
|
||||||
|
case PhluxTransaction::TYPE_EDIT_VALUE:
|
||||||
|
return $object->getVariableValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::getCustomTransactionOldValue($object, $xaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCustomTransactionNewValue(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
PhabricatorApplicationTransaction $xaction) {
|
||||||
|
switch ($xaction->getTransactionType()) {
|
||||||
|
case PhluxTransaction::TYPE_EDIT_KEY:
|
||||||
|
case PhluxTransaction::TYPE_EDIT_VALUE:
|
||||||
|
return $xaction->getNewValue();
|
||||||
|
}
|
||||||
|
return parent::getCustomTransactionNewValue($object, $xaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function applyCustomInternalTransaction(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
PhabricatorApplicationTransaction $xaction) {
|
||||||
|
switch ($xaction->getTransactionType()) {
|
||||||
|
case PhluxTransaction::TYPE_EDIT_KEY:
|
||||||
|
$object->setVariableKey($xaction->getNewValue());
|
||||||
|
return;
|
||||||
|
case PhluxTransaction::TYPE_EDIT_VALUE:
|
||||||
|
$object->setVariableValue($xaction->getNewValue());
|
||||||
|
return;
|
||||||
|
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
||||||
|
$object->setViewPolicy($xaction->getNewValue());
|
||||||
|
return;
|
||||||
|
case PhabricatorTransactions::TYPE_EDIT_POLICY:
|
||||||
|
$object->setEditPolicy($xaction->getNewValue());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return parent::applyCustomInternalTransaction($object, $xaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function applyCustomExternalTransaction(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
PhabricatorApplicationTransaction $xaction) {
|
||||||
|
switch ($xaction->getTransactionType()) {
|
||||||
|
case PhluxTransaction::TYPE_EDIT_KEY:
|
||||||
|
case PhluxTransaction::TYPE_EDIT_VALUE:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return parent::applyCustomExternalTransaction($object, $xaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
10
src/applications/phlux/query/PhluxTransactionQuery.php
Normal file
10
src/applications/phlux/query/PhluxTransactionQuery.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhluxTransactionQuery
|
||||||
|
extends PhabricatorApplicationTransactionQuery {
|
||||||
|
|
||||||
|
protected function getTemplateApplicationTransaction() {
|
||||||
|
return new PhluxTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
68
src/applications/phlux/query/PhluxVariableQuery.php
Normal file
68
src/applications/phlux/query/PhluxVariableQuery.php
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhluxVariableQuery
|
||||||
|
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
|
|
||||||
|
private $keys;
|
||||||
|
private $phids;
|
||||||
|
|
||||||
|
public function withPHIDs(array $phids) {
|
||||||
|
$this->phids = $phids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withKeys(array $keys) {
|
||||||
|
$this->keys = $keys;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function loadPage() {
|
||||||
|
$table = new PhluxVariable();
|
||||||
|
$conn_r = $table->establishConnection('r');
|
||||||
|
|
||||||
|
$rows = queryfx_all(
|
||||||
|
$conn_r,
|
||||||
|
'SELECT * FROM %T %Q %Q %Q',
|
||||||
|
$table->getTableName(),
|
||||||
|
$this->buildWhereClause($conn_r),
|
||||||
|
$this->buildOrderClause($conn_r),
|
||||||
|
$this->buildLimitClause($conn_r));
|
||||||
|
|
||||||
|
return $table->loadAllFromArray($rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
|
||||||
|
$where = array();
|
||||||
|
|
||||||
|
$where[] = $this->buildPagingClause($conn_r);
|
||||||
|
|
||||||
|
if ($this->keys) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'variableKey IN (%Ls)',
|
||||||
|
$this->keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->phids) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'phid IN (%Ls)',
|
||||||
|
$this->phids);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->formatWhereClause($where);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getPagingColumn() {
|
||||||
|
return 'variableKey';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getPagingValue($result) {
|
||||||
|
return $result->getVariableKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getReversePaging() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
9
src/applications/phlux/storage/PhluxDAO.php
Normal file
9
src/applications/phlux/storage/PhluxDAO.php
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class PhluxDAO extends PhabricatorLiskDAO {
|
||||||
|
|
||||||
|
public function getApplicationName() {
|
||||||
|
return 'phlux';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
62
src/applications/phlux/storage/PhluxTransaction.php
Normal file
62
src/applications/phlux/storage/PhluxTransaction.php
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhluxTransaction extends PhabricatorApplicationTransaction {
|
||||||
|
|
||||||
|
const TYPE_EDIT_KEY = 'phlux:key';
|
||||||
|
const TYPE_EDIT_VALUE = 'phlux:value';
|
||||||
|
|
||||||
|
public function getApplicationName() {
|
||||||
|
return 'phlux';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApplicationTransactionType() {
|
||||||
|
return PhabricatorPHIDConstants::PHID_TYPE_PVAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApplicationTransactionCommentObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApplicationObjectTypeName() {
|
||||||
|
return pht('variable');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle() {
|
||||||
|
$author_phid = $this->getAuthorPHID();
|
||||||
|
|
||||||
|
switch ($this->getTransactionType()) {
|
||||||
|
case self::TYPE_EDIT_KEY:
|
||||||
|
return pht(
|
||||||
|
'%s created this variable.',
|
||||||
|
$this->renderHandleLink($author_phid));
|
||||||
|
case self::TYPE_EDIT_VALUE:
|
||||||
|
return pht(
|
||||||
|
'%s updated this variable.',
|
||||||
|
$this->renderHandleLink($author_phid));
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::getTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasChangeDetails() {
|
||||||
|
switch ($this->getTransactionType()) {
|
||||||
|
case self::TYPE_EDIT_VALUE:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return parent::hasChangeDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderChangeDetails(PhabricatorUser $viewer) {
|
||||||
|
$old = $this->getOldValue();
|
||||||
|
$new = $this->getNewValue();
|
||||||
|
|
||||||
|
$view = id(new PhabricatorApplicationTransactionTextDiffDetailView())
|
||||||
|
->setUser($viewer)
|
||||||
|
->setOldText(json_encode($old))
|
||||||
|
->setNewText(json_encode($new));
|
||||||
|
|
||||||
|
return $view->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
49
src/applications/phlux/storage/PhluxVariable.php
Normal file
49
src/applications/phlux/storage/PhluxVariable.php
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhluxVariable extends PhluxDAO
|
||||||
|
implements PhabricatorPolicyInterface {
|
||||||
|
|
||||||
|
protected $variableKey;
|
||||||
|
protected $variableValue;
|
||||||
|
protected $viewPolicy;
|
||||||
|
protected $editPolicy;
|
||||||
|
|
||||||
|
public function getConfiguration() {
|
||||||
|
return array(
|
||||||
|
self::CONFIG_AUX_PHID => true,
|
||||||
|
self::CONFIG_SERIALIZATION => array(
|
||||||
|
'variableValue' => self::SERIALIZATION_JSON
|
||||||
|
),
|
||||||
|
) + parent::getConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generatePHID() {
|
||||||
|
return PhabricatorPHID::generateNewPHID(
|
||||||
|
PhabricatorPHIDConstants::PHID_TYPE_PVAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function getCapabilities() {
|
||||||
|
return array(
|
||||||
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPolicy($capability) {
|
||||||
|
switch ($capability) {
|
||||||
|
case PhabricatorPolicyCapability::CAN_VIEW:
|
||||||
|
return $this->viewPolicy;
|
||||||
|
case PhabricatorPolicyCapability::CAN_EDIT:
|
||||||
|
return $this->editPolicy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -175,6 +175,10 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList {
|
||||||
'type' => 'db',
|
'type' => 'db',
|
||||||
'name' => 'releeph',
|
'name' => 'releeph',
|
||||||
),
|
),
|
||||||
|
'db.phlux' => array(
|
||||||
|
'type' => 'db',
|
||||||
|
'name' => 'phlux',
|
||||||
|
),
|
||||||
'0000.legacy.sql' => array(
|
'0000.legacy.sql' => array(
|
||||||
'type' => 'sql',
|
'type' => 'sql',
|
||||||
'name' => $this->getPatchPath('0000.legacy.sql'),
|
'name' => $this->getPatchPath('0000.legacy.sql'),
|
||||||
|
@ -1178,6 +1182,10 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList {
|
||||||
'name' => $this->getPatchPath(
|
'name' => $this->getPatchPath(
|
||||||
'20130319.phabricatorfileexplicitupload.sql'),
|
'20130319.phabricatorfileexplicitupload.sql'),
|
||||||
),
|
),
|
||||||
|
'20130320.phlux.sql' => array(
|
||||||
|
'type' => 'sql',
|
||||||
|
'name' => $this->getPatchPath('20130320.phlux.sql'),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue