Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15564597
D13091.id31821.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
19 KB
Referenced Files
None
Subscribers
None
D13091.id31821.diff
View Options
diff --git a/resources/sql/autopatches/20150605.diviner.edges.sql b/resources/sql/autopatches/20150605.diviner.edges.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150605.diviner.edges.sql
@@ -0,0 +1,17 @@
+CREATE TABLE {$NAMESPACE}_diviner.edge (
+ src VARBINARY(64) NOT NULL,
+ type INT UNSIGNED NOT NULL,
+ dst VARBINARY(64) NOT NULL,
+ dateCreated INT UNSIGNED NOT NULL,
+ seq INT UNSIGNED NOT NULL,
+ dataID INT UNSIGNED,
+
+ PRIMARY KEY (src, type, dst),
+ KEY src (src, type, dateCreated, seq),
+ UNIQUE KEY key_dst (dst, type, src)
+) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
+
+CREATE TABLE {$NAMESPACE}_diviner.edgedata (
+ id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ data LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT}
+) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
diff --git a/resources/sql/autopatches/20150605.diviner.editPolicy.sql b/resources/sql/autopatches/20150605.diviner.editPolicy.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150605.diviner.editPolicy.sql
@@ -0,0 +1,6 @@
+ALTER TABLE {$NAMESPACE}_diviner.diviner_livebook
+ ADD COLUMN editPolicy VARBINARY(64) NOT NULL AFTER viewPolicy;
+
+UPDATE {$NAMESPACE}_diviner.diviner_livebook
+ SET editPolicy = 'admin'
+ WHERE editPolicy IS NULL;
diff --git a/resources/sql/autopatches/20150605.diviner.xaction.sql b/resources/sql/autopatches/20150605.diviner.xaction.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150605.diviner.xaction.sql
@@ -0,0 +1,19 @@
+CREATE TABLE {$NAMESPACE}_diviner.diviner_livebooktransaction (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ phid VARBINARY(64) NOT NULL,
+ authorPHID VARBINARY(64) NOT NULL,
+ objectPHID VARBINARY(64) NOT NULL,
+ viewPolicy VARBINARY(64) NOT NULL,
+ editPolicy VARBINARY(64) NOT NULL,
+ commentPHID VARBINARY(64) DEFAULT NULL,
+ commentVersion INT UNSIGNED NOT NULL,
+ transactionType VARCHAR(32) COLLATE {$COLLATE_TEXT} NOT NULL,
+ oldValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ newValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ contentSource LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ metadata LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL,
+ UNIQUE KEY key_phid (phid),
+ KEY key_object (objectPHID)
+) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -646,19 +646,24 @@
'DivinerAtomizeWorkflow' => 'applications/diviner/workflow/DivinerAtomizeWorkflow.php',
'DivinerAtomizer' => 'applications/diviner/atomizer/DivinerAtomizer.php',
'DivinerBookController' => 'applications/diviner/controller/DivinerBookController.php',
+ 'DivinerBookEditController' => 'applications/diviner/controller/DivinerBookEditController.php',
'DivinerBookItemView' => 'applications/diviner/view/DivinerBookItemView.php',
'DivinerBookPHIDType' => 'applications/diviner/phid/DivinerBookPHIDType.php',
'DivinerBookQuery' => 'applications/diviner/query/DivinerBookQuery.php',
'DivinerBookSearchIndexer' => 'applications/diviner/search/DivinerBookSearchIndexer.php',
'DivinerController' => 'applications/diviner/controller/DivinerController.php',
'DivinerDAO' => 'applications/diviner/storage/DivinerDAO.php',
+ 'DivinerDefaultEditCapability' => 'applications/diviner/capability/DivinerDefaultEditCapability.php',
'DivinerDefaultRenderer' => 'applications/diviner/renderer/DivinerDefaultRenderer.php',
+ 'DivinerDefaultViewCapability' => 'applications/diviner/capability/DivinerDefaultViewCapability.php',
'DivinerDiskCache' => 'applications/diviner/cache/DivinerDiskCache.php',
'DivinerFileAtomizer' => 'applications/diviner/atomizer/DivinerFileAtomizer.php',
'DivinerFindController' => 'applications/diviner/controller/DivinerFindController.php',
'DivinerGenerateWorkflow' => 'applications/diviner/workflow/DivinerGenerateWorkflow.php',
'DivinerLiveAtom' => 'applications/diviner/storage/DivinerLiveAtom.php',
'DivinerLiveBook' => 'applications/diviner/storage/DivinerLiveBook.php',
+ 'DivinerLiveBookEditor' => 'applications/diviner/editor/DivinerLiveBookEditor.php',
+ 'DivinerLiveBookTransaction' => 'applications/diviner/storage/DivinerLiveBookTransaction.php',
'DivinerLivePublisher' => 'applications/diviner/publisher/DivinerLivePublisher.php',
'DivinerLiveSymbol' => 'applications/diviner/storage/DivinerLiveSymbol.php',
'DivinerMainController' => 'applications/diviner/controller/DivinerMainController.php',
@@ -668,6 +673,7 @@
'DivinerPublisher' => 'applications/diviner/publisher/DivinerPublisher.php',
'DivinerRenderer' => 'applications/diviner/renderer/DivinerRenderer.php',
'DivinerReturnTableView' => 'applications/diviner/view/DivinerReturnTableView.php',
+ 'DivinerSchemaSpec' => 'applications/diviner/storage/DivinerSchemaSpec.php',
'DivinerSectionView' => 'applications/diviner/view/DivinerSectionView.php',
'DivinerStaticPublisher' => 'applications/diviner/publisher/DivinerStaticPublisher.php',
'DivinerSymbolRemarkupRule' => 'applications/diviner/markup/DivinerSymbolRemarkupRule.php',
@@ -3890,13 +3896,16 @@
'DivinerAtomSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
'DivinerAtomizeWorkflow' => 'DivinerWorkflow',
'DivinerBookController' => 'DivinerController',
+ 'DivinerBookEditController' => 'DivinerController',
'DivinerBookItemView' => 'AphrontTagView',
'DivinerBookPHIDType' => 'PhabricatorPHIDType',
'DivinerBookQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'DivinerBookSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
'DivinerController' => 'PhabricatorController',
'DivinerDAO' => 'PhabricatorLiskDAO',
+ 'DivinerDefaultEditCapability' => 'PhabricatorPolicyCapability',
'DivinerDefaultRenderer' => 'DivinerRenderer',
+ 'DivinerDefaultViewCapability' => 'PhabricatorPolicyCapability',
'DivinerFileAtomizer' => 'DivinerAtomizer',
'DivinerFindController' => 'DivinerController',
'DivinerGenerateWorkflow' => 'DivinerWorkflow',
@@ -3904,8 +3913,11 @@
'DivinerLiveBook' => array(
'DivinerDAO',
'PhabricatorPolicyInterface',
+ 'PhabricatorProjectInterface',
'PhabricatorDestructibleInterface',
),
+ 'DivinerLiveBookEditor' => 'PhabricatorApplicationTransactionEditor',
+ 'DivinerLiveBookTransaction' => 'PhabricatorApplicationTransaction',
'DivinerLivePublisher' => 'DivinerPublisher',
'DivinerLiveSymbol' => array(
'DivinerDAO',
@@ -3918,6 +3930,7 @@
'DivinerParameterTableView' => 'AphrontTagView',
'DivinerPublishCache' => 'DivinerDiskCache',
'DivinerReturnTableView' => 'AphrontTagView',
+ 'DivinerSchemaSpec' => 'PhabricatorConfigSchemaSpec',
'DivinerSectionView' => 'AphrontTagView',
'DivinerStaticPublisher' => 'DivinerPublisher',
'DivinerSymbolRemarkupRule' => 'PhutilRemarkupRule',
diff --git a/src/applications/diviner/application/PhabricatorDivinerApplication.php b/src/applications/diviner/application/PhabricatorDivinerApplication.php
--- a/src/applications/diviner/application/PhabricatorDivinerApplication.php
+++ b/src/applications/diviner/application/PhabricatorDivinerApplication.php
@@ -39,6 +39,7 @@
'find/' => 'DivinerFindController',
),
'/book/(?P<book>[^/]+)/' => 'DivinerBookController',
+ '/book/(?P<book>[^/]+)/edit/' => 'DivinerBookEditController',
'/book/'.
'(?P<book>[^/]+)/'.
'(?P<type>[^/]+)/'.
@@ -52,6 +53,15 @@
return self::GROUP_UTILITIES;
}
+ protected function getCustomCapabilities() {
+ return array(
+ DivinerDefaultViewCapability::CAPABILITY => array(),
+ DivinerDefaultEditCapability::CAPABILITY => array(
+ 'default' => PhabricatorPolicies::POLICY_ADMIN,
+ ),
+ );
+ }
+
public function getRemarkupRules() {
return array(
new DivinerSymbolRemarkupRule(),
diff --git a/src/applications/diviner/capability/DivinerDefaultEditCapability.php b/src/applications/diviner/capability/DivinerDefaultEditCapability.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diviner/capability/DivinerDefaultEditCapability.php
@@ -0,0 +1,11 @@
+<?php
+
+final class DivinerDefaultEditCapability extends PhabricatorPolicyCapability {
+
+ const CAPABILITY = 'diviner.default.edit';
+
+ public function getCapabilityName() {
+ return pht('Default Edit Policy');
+ }
+
+}
diff --git a/src/applications/diviner/capability/DivinerDefaultViewCapability.php b/src/applications/diviner/capability/DivinerDefaultViewCapability.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diviner/capability/DivinerDefaultViewCapability.php
@@ -0,0 +1,15 @@
+<?php
+
+final class DivinerDefaultViewCapability extends PhabricatorPolicyCapability {
+
+ const CAPABILITY = 'diviner.default.view';
+
+ public function getCapabilityName() {
+ return pht('Default View Policy');
+ }
+
+ public function shouldAllowPublicPolicySetting() {
+ return true;
+ }
+
+}
diff --git a/src/applications/diviner/controller/DivinerBookEditController.php b/src/applications/diviner/controller/DivinerBookEditController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diviner/controller/DivinerBookEditController.php
@@ -0,0 +1,91 @@
+<?php
+
+final class DivinerBookEditController extends DivinerController {
+
+ private $bookName;
+
+ public function willProcessRequest(array $data) {
+ $this->bookName = $data['book'];
+ }
+
+ protected function processRequest() {
+ $request = $this->getRequest();
+ $user = $request->getUser();
+
+ $book = id(new DivinerBookQuery())
+ ->setViewer($user)
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ ))
+ ->needProjectPHIDs(true)
+ ->withNames(array($this->bookName))
+ ->executeOne();
+
+ $view_uri = '/book/'.$book->getName();
+ $edit_uri = '/book/'.$book->getName().'/edit/';
+
+ if (!$book) {
+ return new Aphront404Response();
+ }
+
+ if ($request->isFormPost()) {
+ $v_projects = $request->getArr('projectPHIDs');
+
+ $xactions = array();
+ $template = id(new DivinerLiveBookTransaction());
+
+ $xactions[] = id(clone $template)
+ ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
+ ->setMetadataValue(
+ 'edge:type',
+ PhabricatorProjectObjectHasProjectEdgeType::EDGECONST)
+ ->setNewValue(
+ array(
+ '=' => array_fuse($v_projects),
+ ));
+
+ id(new DivinerLiveBookEditor())
+ ->setContinueOnNoEffect(true)
+ ->setContentSourceFromRequest($request)
+ ->setActor($user)
+ ->applyTransactions($book, $xactions);
+
+ return id(new AphrontRedirectResponse())->setURI($view_uri);
+ }
+
+ $crumbs = $this->buildApplicationCrumbs();
+ $crumbs->addTextCrumb(pht('Edit Basics'));
+
+ $title = pht('Edit %s', $book->getTitle());
+
+ $form = id(new AphrontFormView())
+ ->setUser($user)
+ ->appendControl(
+ id(new AphrontFormTokenizerControl())
+ ->setDatasource(new PhabricatorProjectDatasource())
+ ->setName('projectPHIDs')
+ ->setLabel(pht('Projects'))
+ ->setValue($book->getProjectPHIDs()))
+ ->appendChild(
+ id(new AphrontFormSubmitControl())
+ ->setValue(pht('Save'))
+ ->addCancelButton($view_uri))
+ ->appendChild(id(new PHUIFormDividerControl()));
+
+ $object_box = id(new PHUIObjectBoxView())
+ ->setHeaderText($title)
+ ->setForm($form);
+
+ return $this->buildApplicationPage(
+ array(
+ $crumbs,
+ $object_box,
+ ),
+ array(
+ 'title' => $title,
+ ));
+ }
+
+}
diff --git a/src/applications/diviner/editor/DivinerLiveBookEditor.php b/src/applications/diviner/editor/DivinerLiveBookEditor.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diviner/editor/DivinerLiveBookEditor.php
@@ -0,0 +1,121 @@
+<?php
+
+final class DivinerLiveBookEditor
+ extends PhabricatorApplicationTransactionEditor {
+
+ public function getEditorApplicationClass() {
+ return 'PhabricatorDivinerApplication';
+ }
+
+ public function getEditorObjectsDescription() {
+ return pht('Books');
+ }
+
+ public function getTransactionTypes() {
+ $types = parent::getTransactionTypes();
+
+ $types[] = DivinerLiveBookTransaction::TYPE_REPOSITORY;
+
+ $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
+ $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
+
+ return $types;
+ }
+
+ protected function getCustomTransactionOldValue(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case DivinerLiveBookTransaction::TYPE_REPOSITORY:
+ return $object->getRepositoryPHID();
+ }
+ }
+
+ protected function getCustomTransactionNewValue(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case DivinerLiveBookTransaction::TYPE_REPOSITORY:
+ return $xaction->getNewValue();
+ }
+ }
+
+ protected function applyCustomInternalTransaction(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case DivinerLiveBookTransaction::TYPE_REPOSITORY:
+ $object->setRepositoryPHID($xaction->getNewValue());
+ break;
+ }
+ }
+
+ protected function applyCustomExternalTransaction(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case DivinerLiveBookTransaction::TYPE_REPOSITORY:
+ break;
+ }
+
+ }
+
+ protected function mergeTransactions(
+ PhabricatorApplicationTransaction $u,
+ PhabricatorApplicationTransaction $v) {
+
+ $type = $u->getTransactionType();
+ switch ($type) {}
+
+ return parent::mergeTransactions($u, $v);
+ }
+
+ protected function transactionHasEffect(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ $old = $xaction->getOldValue();
+ $new = $xaction->getNewValue();
+
+ $type = $xaction->getTransactionType();
+ switch ($type) {}
+
+ return parent::transactionHasEffect($object, $xaction);
+ }
+
+ protected function requireCapabilities(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case DivinerLiveBookTransaction::TYPE_REPOSITORY:
+ PhabricatorPolicyFilter::requireCapability(
+ $this->requireActor(),
+ $object,
+ PhabricatorPolicyCapability::CAN_EDIT);
+ break;
+ }
+ }
+
+ protected function validateTransaction(
+ PhabricatorLiskDAO $object,
+ $type,
+ array $xactions) {
+
+ $errors = parent::validateTransaction($object, $type, $xactions);
+
+ switch ($type) {
+ case DivinerLiveBookTransaction::TYPE_REPOSITORY:
+ // TODO: Implement this;
+ $ok = true;
+ break;
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/diviner/query/DivinerBookQuery.php b/src/applications/diviner/query/DivinerBookQuery.php
--- a/src/applications/diviner/query/DivinerBookQuery.php
+++ b/src/applications/diviner/query/DivinerBookQuery.php
@@ -6,6 +6,8 @@
private $phids;
private $names;
+ private $needProjectPHIDs;
+
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
@@ -21,6 +23,11 @@
return $this;
}
+ public function needProjectPHIDs($need_phids) {
+ $this->needProjectPHIDs = $need_phids;
+ return $this;
+ }
+
protected function loadPage() {
$table = new DivinerLiveBook();
$conn_r = $table->establishConnection('r');
@@ -36,6 +43,27 @@
return $table->loadAllFromArray($data);
}
+ protected function didFilterPage(array $books) {
+ if ($this->needProjectPHIDs) {
+ $type_project = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
+
+ $edge_query = id(new PhabricatorEdgeQuery())
+ ->withSourcePHIDs(mpull($books, 'getPHID'))
+ ->withEdgeTypes(array($type_project));
+ $edge_query->execute();
+
+ foreach ($books as $book) {
+ $project_phids = $edge_query->getDestinationPHIDs(
+ array(
+ $book->getPHID(),
+ ));
+ $book->attachProjectPHIDs($project_phids);
+ }
+ }
+
+ return $books;
+ }
+
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
diff --git a/src/applications/diviner/storage/DivinerLiveBook.php b/src/applications/diviner/storage/DivinerLiveBook.php
--- a/src/applications/diviner/storage/DivinerLiveBook.php
+++ b/src/applications/diviner/storage/DivinerLiveBook.php
@@ -3,12 +3,16 @@
final class DivinerLiveBook extends DivinerDAO
implements
PhabricatorPolicyInterface,
+ PhabricatorProjectInterface,
PhabricatorDestructibleInterface {
protected $name;
protected $viewPolicy;
+ protected $editPolicy;
protected $configurationData = array();
+ private $projectPHIDs = self::ATTACHABLE;
+
protected function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
@@ -63,20 +67,36 @@
return idx($spec, 'name', $group);
}
+ public function attachProjectPHIDs(array $project_phids) {
+ $this->projectPHIDs = $project_phids;
+ return $this;
+ }
+
+ public function getProjectPHIDs() {
+ return $this->assertAttached($this->projectPHIDs);
+ }
+
+
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
- return PhabricatorPolicies::getMostOpenPolicy();
+ switch ($capability) {
+ case PhabricatorPolicyCapability::CAN_VIEW:
+ return $this->getViewPolicy();
+ case PhabricatorPolicyCapability::CAN_EDIT:
+ return $this->getEditPolicy();
+ }
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
- return false;
+ return false;
}
public function describeAutomaticCapability($capability) {
diff --git a/src/applications/diviner/storage/DivinerLiveBookTransaction.php b/src/applications/diviner/storage/DivinerLiveBookTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diviner/storage/DivinerLiveBookTransaction.php
@@ -0,0 +1,20 @@
+<?php
+
+final class DivinerLiveBookTransaction
+ extends PhabricatorApplicationTransaction {
+
+ const TYPE_REPOSITORY = 'book:repo';
+
+ public function getApplicationName() {
+ return 'diviner';
+ }
+
+ public function getApplicationTransactionType() {
+ return DivinerBookPHIDType::TYPECONST;
+ }
+
+ public function getApplicationTransactionCommentObject() {
+ return null;
+ }
+
+}
diff --git a/src/applications/diviner/storage/DivinerSchemaSpec.php b/src/applications/diviner/storage/DivinerSchemaSpec.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diviner/storage/DivinerSchemaSpec.php
@@ -0,0 +1,9 @@
+<?php
+
+final class DivinerSchemaSpec extends PhabricatorConfigSchemaSpec {
+
+ public function buildSchemata() {
+ $this->buildEdgeSchemata(new DivinerLiveBook());
+ }
+
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, May 1, 1:01 PM (1 w, 6 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7700401
Default Alt Text
D13091.id31821.diff (19 KB)
Attached To
Mode
D13091: Modernize Diviner
Attached
Detach File
Event Timeline
Log In to Comment