Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15471140
D13091.id31606.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
17 KB
Referenced Files
None
Subscribers
None
D13091.id31606.diff
View Options
diff --git a/resources/sql/autopatches/20150601.divineredge.sql b/resources/sql/autopatches/20150601.divineredge.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150601.divineredge.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/20150601.divineredit.sql b/resources/sql/autopatches/20150601.divineredit.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150601.divineredit.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/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -647,12 +647,17 @@
'DivinerAtomizeWorkflow' => 'applications/diviner/workflow/DivinerAtomizeWorkflow.php',
'DivinerAtomizer' => 'applications/diviner/atomizer/DivinerAtomizer.php',
'DivinerBookController' => 'applications/diviner/controller/DivinerBookController.php',
+ 'DivinerBookEditController' => 'applications/diviner/storage/DivinerBookEditController.php',
+ 'DivinerBookEditor' => 'applications/diviner/editor/DivinerBookEditor.php',
'DivinerBookItemView' => 'applications/diviner/view/DivinerBookItemView.php',
'DivinerBookPHIDType' => 'applications/diviner/phid/DivinerBookPHIDType.php',
'DivinerBookQuery' => 'applications/diviner/query/DivinerBookQuery.php',
+ 'DivinerBookTransaction' => 'applications/diviner/storage/DivinerBookTransaction.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',
@@ -3877,12 +3882,17 @@
'DivinerAtomSearchEngine' => 'PhabricatorApplicationSearchEngine',
'DivinerAtomizeWorkflow' => 'DivinerWorkflow',
'DivinerBookController' => 'DivinerController',
+ 'DivinerBookEditController' => 'DivinerController',
+ 'DivinerBookEditor' => 'PhabricatorApplicationTransactionEditor',
'DivinerBookItemView' => 'AphrontTagView',
'DivinerBookPHIDType' => 'PhabricatorPHIDType',
'DivinerBookQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+ 'DivinerBookTransaction' => 'PhabricatorApplicationTransaction',
'DivinerController' => 'PhabricatorController',
'DivinerDAO' => 'PhabricatorLiskDAO',
+ 'DivinerDefaultEditCapability' => 'PhabricatorPolicyCapability',
'DivinerDefaultRenderer' => 'DivinerRenderer',
+ 'DivinerDefaultViewCapability' => 'PhabricatorPolicyCapability',
'DivinerFileAtomizer' => 'DivinerAtomizer',
'DivinerFindController' => 'DivinerController',
'DivinerGenerateWorkflow' => 'DivinerWorkflow',
@@ -3890,6 +3900,7 @@
'DivinerLiveBook' => array(
'DivinerDAO',
'PhabricatorPolicyInterface',
+ 'PhabricatorProjectInterface',
'PhabricatorDestructibleInterface',
),
'DivinerLivePublisher' => 'DivinerPublisher',
diff --git a/src/applications/diffusion/controller/DiffusionRepositoryController.php b/src/applications/diffusion/controller/DiffusionRepositoryController.php
--- a/src/applications/diffusion/controller/DiffusionRepositoryController.php
+++ b/src/applications/diffusion/controller/DiffusionRepositoryController.php
@@ -17,7 +17,7 @@
$crumbs = $this->buildCrumbs();
$content[] = $crumbs;
- $content[] = $this->buildPropertiesTable($drequest->getRepository());
+ $content[] = $this->buildPropertiesTable($repository);
// Before we do any work, make sure we're looking at a some content: we're
// on a valid branch, and the repository is not empty.
@@ -76,7 +76,7 @@
return $this->buildApplicationPage(
$content,
array(
- 'title' => $drequest->getRepository()->getName(),
+ 'title' => $repository->getName(),
));
}
@@ -552,7 +552,7 @@
}
$history_table->setIsHead(true);
- $callsign = $drequest->getRepository()->getCallsign();
+ $callsign = $repository->getCallsign();
$icon = id(new PHUIIconView())
->setIconFont('fa-list-alt');
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/DivinerBookController.php b/src/applications/diviner/controller/DivinerBookController.php
--- a/src/applications/diviner/controller/DivinerBookController.php
+++ b/src/applications/diviner/controller/DivinerBookController.php
@@ -13,8 +13,9 @@
}
public function processRequest() {
+ $content = array();
$request = $this->getRequest();
- $viewer = $request->getUser();
+ $viewer = $request->getUser();
$book = id(new DivinerBookQuery())
->setViewer($viewer)
@@ -31,6 +32,9 @@
$crumbs->addTextCrumb(
$book->getShortTitle(),
'/book/'.$book->getName().'/');
+ $content[] = $crumbs;
+
+ $content[] = $this->buildPropertiesTable($book);
$header = id(new PHUIHeaderView())
->setHeader($book->getTitle())
@@ -50,6 +54,7 @@
$document->setHeader($header);
$document->addClass('diviner-view');
$document->setFontKit(PHUIDocumentView::FONT_SOURCE_SANS);
+ $content[] = $document;
$atoms = id(new DivinerAtomQuery())
->setViewer($viewer)
@@ -97,13 +102,70 @@
$document->appendChild($out);
return $this->buildApplicationPage(
- array(
- $crumbs,
- $document,
- ),
+ $content,
array(
'title' => $book->getTitle(),
));
}
+ private function buildPropertiesTable(DivinerLiveBook $book) {
+ $user = $this->getRequest()->getUser();
+
+ $header = id(new PHUIHeaderView())
+ ->setHeader($book->getName())
+ ->setUser($user)
+ ->setPolicyObject($book);
+
+ $header->setStatus('fa-check', 'bluegrey', pht('Active'));
+
+ $actions = $this->buildActionList($book);
+
+ $view = id(new PHUIPropertyListView())
+ ->setUser($user);
+
+ $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
+ $book->getPHID(),
+ PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
+ if ($project_phids) {
+ $view->addProperty(
+ pht('Projects'),
+ $user->renderHandleList($project_phids));
+ }
+
+ $view->setActionList($actions);
+
+ $box = id(new PHUIObjectBoxView())
+ ->setHeader($header)
+ ->addPropertyList($view);
+
+ return $box;
+ }
+
+ private function buildActionList(DivinerLiveBook $book) {
+ $viewer = $this->getRequest()->getUser();
+
+ $view_uri = '/book/'.$book->getName().'/';
+ $edit_uri = '/book/'.$book->getName().'/edit/';
+
+ $view = id(new PhabricatorActionListView())
+ ->setUser($viewer)
+ ->setObject($book)
+ ->setObjectURI($view_uri);
+
+ $can_edit = PhabricatorPolicyFilter::hasCapability(
+ $viewer,
+ $book,
+ PhabricatorPolicyCapability::CAN_EDIT);
+
+ $view->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Edit Book'))
+ ->setIcon('fa-pencil')
+ ->setHref($edit_uri)
+ ->setWorkflow(!$can_edit)
+ ->setDisabled(!$can_edit));
+
+ return $view;
+ }
+
}
diff --git a/src/applications/diviner/editor/DivinerBookEditor.php b/src/applications/diviner/editor/DivinerBookEditor.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diviner/editor/DivinerBookEditor.php
@@ -0,0 +1,22 @@
+<?php
+
+final class DivinerBookEditor extends PhabricatorApplicationTransactionEditor {
+
+ public function getEditorApplicationClass() {
+ return 'PhabricatorDivinerApplication';
+ }
+
+ public function getEditorObjectsDescription() {
+ return pht('Books');
+ }
+
+ public function getTransactionTypes() {
+ $types = parent::getTransactionTypes();
+
+ $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
+ $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
+
+ return $types;
+ }
+
+}
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
@@ -7,6 +7,8 @@
private $names;
private $repositoryPHIDs;
+ private $needProjectPHIDs;
+
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
@@ -27,6 +29,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');
@@ -70,6 +77,27 @@
return $books;
}
+ 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/DivinerBookEditController.php b/src/applications/diviner/storage/DivinerBookEditController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diviner/storage/DivinerBookEditController.php
@@ -0,0 +1,98 @@
+<?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();
+
+ $edit_uri = '/book/'.$book->getName().'/edit/';
+
+ if (!$book) {
+ return new Aphront404Response();
+ }
+
+ $v_title = $book->getTitle();
+ $v_preface = $book->getPreface();
+ $e_name = true;
+ $errors = array();
+
+ if ($request->isFormPost()) {
+ $v_projects = $request->getArr('projectPHIDs');
+
+ $xactions = array();
+ $template = id(new DivinerBookTransaction());
+
+ $type_edge = PhabricatorTransactions::TYPE_EDGE;
+
+ $xactions[] = id(clone $template)
+ ->setTransactionType($type_edge)
+ ->setMetadataValue(
+ 'edge:type',
+ PhabricatorProjectObjectHasProjectEdgeType::EDGECONST)
+ ->setNewValue(
+ array(
+ '=' => array_fuse($v_projects),
+ ));
+
+ id(new DivinerBookEditor())
+ ->setContinueOnNoEffect(true)
+ ->setContentSourceFromRequest($request)
+ ->setActor($user)
+ ->applyTransactions($book, $xactions);
+
+ return id(new AphrontRedirectResponse())->setURI($edit_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($edit_uri))
+ ->appendChild(id(new PHUIFormDividerControl()));
+
+ $object_box = id(new PHUIObjectBoxView())
+ ->setHeaderText($title)
+ ->setForm($form)
+ ->setFormErrors($errors);
+
+ return $this->buildApplicationPage(
+ array(
+ $crumbs,
+ $object_box,
+ ),
+ array(
+ 'title' => $title,
+ ));
+ }
+
+}
diff --git a/src/applications/diviner/storage/DivinerBookTransaction.php b/src/applications/diviner/storage/DivinerBookTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diviner/storage/DivinerBookTransaction.php
@@ -0,0 +1,17 @@
+<?php
+
+final class DivinerBookTransaction extends PhabricatorApplicationTransaction {
+
+ public function getApplicationName() {
+ return 'diviner';
+ }
+
+ public function getApplicationTransactionType() {
+ return DivinerBookPHIDType::TYPECONST;
+ }
+
+ public function getApplicationTransactionCommentObject() {
+ return null;
+ }
+
+}
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,13 +3,16 @@
final class DivinerLiveBook extends DivinerDAO
implements
PhabricatorPolicyInterface,
+ PhabricatorProjectInterface,
PhabricatorDestructibleInterface {
protected $name;
protected $repositoryPHID;
protected $viewPolicy;
+ protected $editPolicy;
protected $configurationData = array();
+ private $projectPHIDs = self::ATTACHABLE;
private $repository = self::ATTACHABLE;
protected function getConfiguration() {
@@ -68,8 +71,13 @@
return idx($spec, 'name', $group);
}
- public function getRepository() {
- return $this->assertAttached($this->repository);
+ public function attachProjectPHIDs(array $project_phids) {
+ $this->projectPHIDs = $project_phids;
+ return $this;
+ }
+
+ public function getProjectPHIDs() {
+ return $this->assertAttached($this->projectPHIDs);
}
public function attachRepository(PhabricatorRepository $repository) {
@@ -77,16 +85,27 @@
return $this;
}
+ public function getRepository() {
+ return $this->assertAttached($this->repository);
+ }
+
+
/* -( 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 $user) {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Apr 6 2025, 3:36 AM (4 w, 5 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7720789
Default Alt Text
D13091.id31606.diff (17 KB)
Attached To
Mode
D13091: Modernize Diviner
Attached
Detach File
Event Timeline
Log In to Comment