Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14295991
D16314.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
38 KB
Referenced Files
None
Subscribers
None
D16314.diff
View Options
diff --git a/resources/sql/autopatches/20160721.pack.01.pub.sql b/resources/sql/autopatches/20160721.pack.01.pub.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160721.pack.01.pub.sql
@@ -0,0 +1,11 @@
+CREATE TABLE {$NAMESPACE}_packages.packages_publisher (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ phid VARBINARY(64) NOT NULL,
+ name VARCHAR(64) NOT NULL COLLATE {$COLLATE_TEXT},
+ publisherKey VARCHAR(64) NOT NULL COLLATE {$COLLATE_SORT},
+ editPolicy VARBINARY(64) NOT NULL,
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL,
+ UNIQUE KEY `key_phid` (phid),
+ UNIQUE KEY `key_publisher` (publisherKey)
+) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
diff --git a/resources/sql/autopatches/20160721.pack.02.pubxaction.sql b/resources/sql/autopatches/20160721.pack.02.pubxaction.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160721.pack.02.pubxaction.sql
@@ -0,0 +1,19 @@
+CREATE TABLE {$NAMESPACE}_packages.packages_publishertransaction (
+ 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/resources/sql/autopatches/20160721.pack.03.edge.sql b/resources/sql/autopatches/20160721.pack.03.edge.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160721.pack.03.edge.sql
@@ -0,0 +1,16 @@
+CREATE TABLE {$NAMESPACE}_packages.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}_packages.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/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2972,6 +2972,30 @@
'PhabricatorPHPASTApplication' => 'applications/phpast/application/PhabricatorPHPASTApplication.php',
'PhabricatorPHPConfigSetupCheck' => 'applications/config/check/PhabricatorPHPConfigSetupCheck.php',
'PhabricatorPHPMailerConfigOptions' => 'applications/config/option/PhabricatorPHPMailerConfigOptions.php',
+ 'PhabricatorPackagesApplication' => 'applications/packages/application/PhabricatorPackagesApplication.php',
+ 'PhabricatorPackagesController' => 'applications/packages/controller/PhabricatorPackagesController.php',
+ 'PhabricatorPackagesDAO' => 'applications/packages/storage/PhabricatorPackagesDAO.php',
+ 'PhabricatorPackagesEditEngine' => 'applications/packages/editor/PhabricatorPackagesEditEngine.php',
+ 'PhabricatorPackagesEditor' => 'applications/packages/editor/PhabricatorPackagesEditor.php',
+ 'PhabricatorPackagesPublisher' => 'applications/packages/storage/PhabricatorPackagesPublisher.php',
+ 'PhabricatorPackagesPublisherController' => 'applications/packages/controller/PhabricatorPackagesPublisherController.php',
+ 'PhabricatorPackagesPublisherEditConduitAPIMethod' => 'applications/packages/conduit/PhabricatorPackagesPublisherEditConduitAPIMethod.php',
+ 'PhabricatorPackagesPublisherEditController' => 'applications/packages/controller/PhabricatorPackagesPublisherEditController.php',
+ 'PhabricatorPackagesPublisherEditEngine' => 'applications/packages/editor/PhabricatorPackagesPublisherEditEngine.php',
+ 'PhabricatorPackagesPublisherEditor' => 'applications/packages/editor/PhabricatorPackagesPublisherEditor.php',
+ 'PhabricatorPackagesPublisherKeyTransaction' => 'applications/packages/xaction/publisher/PhabricatorPackagesPublisherKeyTransaction.php',
+ 'PhabricatorPackagesPublisherListController' => 'applications/packages/controller/PhabricatorPackagesPublisherListController.php',
+ 'PhabricatorPackagesPublisherNameTransaction' => 'applications/packages/xaction/publisher/PhabricatorPackagesPublisherNameTransaction.php',
+ 'PhabricatorPackagesPublisherPHIDType' => 'applications/packages/phid/PhabricatorPackagesPublisherPHIDType.php',
+ 'PhabricatorPackagesPublisherQuery' => 'applications/packages/query/PhabricatorPackagesPublisherQuery.php',
+ 'PhabricatorPackagesPublisherSearchConduitAPIMethod' => 'applications/packages/conduit/PhabricatorPackagesPublisherSearchConduitAPIMethod.php',
+ 'PhabricatorPackagesPublisherSearchEngine' => 'applications/packages/query/PhabricatorPackagesPublisherSearchEngine.php',
+ 'PhabricatorPackagesPublisherTransaction' => 'applications/packages/storage/PhabricatorPackagesPublisherTransaction.php',
+ 'PhabricatorPackagesPublisherTransactionQuery' => 'applications/packages/query/PhabricatorPackagesPublisherTransactionQuery.php',
+ 'PhabricatorPackagesPublisherTransactionType' => 'applications/packages/xaction/publisher/PhabricatorPackagesPublisherTransactionType.php',
+ 'PhabricatorPackagesPublisherViewController' => 'applications/packages/controller/PhabricatorPackagesPublisherViewController.php',
+ 'PhabricatorPackagesSchemaSpec' => 'applications/packages/storage/PhabricatorPackagesSchemaSpec.php',
+ 'PhabricatorPackagesTransactionType' => 'applications/packages/xaction/PhabricatorPackagesTransactionType.php',
'PhabricatorPagerUIExample' => 'applications/uiexample/examples/PhabricatorPagerUIExample.php',
'PhabricatorPassphraseApplication' => 'applications/passphrase/application/PhabricatorPassphraseApplication.php',
'PhabricatorPasswordAuthProvider' => 'applications/auth/provider/PhabricatorPasswordAuthProvider.php',
@@ -7725,6 +7749,38 @@
'PhabricatorPHPASTApplication' => 'PhabricatorApplication',
'PhabricatorPHPConfigSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorPHPMailerConfigOptions' => 'PhabricatorApplicationConfigOptions',
+ 'PhabricatorPackagesApplication' => 'PhabricatorApplication',
+ 'PhabricatorPackagesController' => 'PhabricatorController',
+ 'PhabricatorPackagesDAO' => 'PhabricatorLiskDAO',
+ 'PhabricatorPackagesEditEngine' => 'PhabricatorEditEngine',
+ 'PhabricatorPackagesEditor' => 'PhabricatorApplicationTransactionEditor',
+ 'PhabricatorPackagesPublisher' => array(
+ 'PhabricatorPackagesDAO',
+ 'PhabricatorPolicyInterface',
+ 'PhabricatorApplicationTransactionInterface',
+ 'PhabricatorDestructibleInterface',
+ 'PhabricatorSubscribableInterface',
+ 'PhabricatorProjectInterface',
+ 'PhabricatorConduitResultInterface',
+ ),
+ 'PhabricatorPackagesPublisherController' => 'PhabricatorPackagesController',
+ 'PhabricatorPackagesPublisherEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
+ 'PhabricatorPackagesPublisherEditController' => 'PhabricatorPackagesPublisherController',
+ 'PhabricatorPackagesPublisherEditEngine' => 'PhabricatorPackagesEditEngine',
+ 'PhabricatorPackagesPublisherEditor' => 'PhabricatorPackagesEditor',
+ 'PhabricatorPackagesPublisherKeyTransaction' => 'PhabricatorPackagesPublisherTransactionType',
+ 'PhabricatorPackagesPublisherListController' => 'PhabricatorPackagesPublisherController',
+ 'PhabricatorPackagesPublisherNameTransaction' => 'PhabricatorPackagesPublisherTransactionType',
+ 'PhabricatorPackagesPublisherPHIDType' => 'PhabricatorPHIDType',
+ 'PhabricatorPackagesPublisherQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+ 'PhabricatorPackagesPublisherSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
+ 'PhabricatorPackagesPublisherSearchEngine' => 'PhabricatorApplicationSearchEngine',
+ 'PhabricatorPackagesPublisherTransaction' => 'PhabricatorModularTransaction',
+ 'PhabricatorPackagesPublisherTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
+ 'PhabricatorPackagesPublisherTransactionType' => 'PhabricatorPackagesTransactionType',
+ 'PhabricatorPackagesPublisherViewController' => 'PhabricatorPackagesPublisherController',
+ 'PhabricatorPackagesSchemaSpec' => 'PhabricatorConfigSchemaSpec',
+ 'PhabricatorPackagesTransactionType' => 'PhabricatorModularTransactionType',
'PhabricatorPagerUIExample' => 'PhabricatorUIExample',
'PhabricatorPassphraseApplication' => 'PhabricatorApplication',
'PhabricatorPasswordAuthProvider' => 'PhabricatorAuthProvider',
diff --git a/src/applications/packages/application/PhabricatorPackagesApplication.php b/src/applications/packages/application/PhabricatorPackagesApplication.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/application/PhabricatorPackagesApplication.php
@@ -0,0 +1,47 @@
+<?php
+
+final class PhabricatorPackagesApplication extends PhabricatorApplication {
+
+ public function getName() {
+ return pht('Packages');
+ }
+
+ public function getShortDescription() {
+ return pht('Publish Software');
+ }
+
+ public function getFlavorText() {
+ return pht('Applications and Extensions');
+ }
+
+ public function getBaseURI() {
+ return '/packages/';
+ }
+
+ public function getIcon() {
+ return 'fa-gift';
+ }
+
+ public function isPrototype() {
+ return true;
+ }
+
+ public function getRoutes() {
+ return array(
+ '/package/' => array(
+ '(?P<publisherKey>[^/]+)/' => array(
+ '' => 'PhabricatorPackagesPublisherViewController',
+ ),
+ ),
+ '/packages/' => array(
+ 'publisher/' => array(
+ $this->getQueryRoutePattern() =>
+ 'PhabricatorPackagesPublisherListController',
+ $this->getEditRoutePattern('edit/') =>
+ 'PhabricatorPackagesPublisherEditController',
+ ),
+ ),
+ );
+ }
+
+}
diff --git a/src/applications/packages/conduit/PhabricatorPackagesPublisherEditConduitAPIMethod.php b/src/applications/packages/conduit/PhabricatorPackagesPublisherEditConduitAPIMethod.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/conduit/PhabricatorPackagesPublisherEditConduitAPIMethod.php
@@ -0,0 +1,19 @@
+<?php
+
+final class PhabricatorPackagesPublisherEditConduitAPIMethod
+ extends PhabricatorEditEngineAPIMethod {
+
+ public function getAPIMethodName() {
+ return 'packages.publisher.edit';
+ }
+
+ public function newEditEngine() {
+ return new PhabricatorPackagesPublisherEditEngine();
+ }
+
+ public function getMethodSummary() {
+ return pht(
+ 'Apply transactions to create a new publisher or edit an existing one.');
+ }
+
+}
diff --git a/src/applications/packages/conduit/PhabricatorPackagesPublisherSearchConduitAPIMethod.php b/src/applications/packages/conduit/PhabricatorPackagesPublisherSearchConduitAPIMethod.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/conduit/PhabricatorPackagesPublisherSearchConduitAPIMethod.php
@@ -0,0 +1,18 @@
+<?php
+
+final class PhabricatorPackagesPublisherSearchConduitAPIMethod
+ extends PhabricatorSearchEngineAPIMethod {
+
+ public function getAPIMethodName() {
+ return 'packages.publisher.search';
+ }
+
+ public function newSearchEngine() {
+ return new PhabricatorPackagesPublisherSearchEngine();
+ }
+
+ public function getMethodSummary() {
+ return pht('Read information about publishers.');
+ }
+
+}
diff --git a/src/applications/packages/controller/PhabricatorPackagesController.php b/src/applications/packages/controller/PhabricatorPackagesController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/controller/PhabricatorPackagesController.php
@@ -0,0 +1,3 @@
+<?php
+
+abstract class PhabricatorPackagesController extends PhabricatorController {}
diff --git a/src/applications/packages/controller/PhabricatorPackagesPublisherController.php b/src/applications/packages/controller/PhabricatorPackagesPublisherController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/controller/PhabricatorPackagesPublisherController.php
@@ -0,0 +1,4 @@
+<?php
+
+abstract class PhabricatorPackagesPublisherController
+ extends PhabricatorPackagesController {}
diff --git a/src/applications/packages/controller/PhabricatorPackagesPublisherEditController.php b/src/applications/packages/controller/PhabricatorPackagesPublisherEditController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/controller/PhabricatorPackagesPublisherEditController.php
@@ -0,0 +1,12 @@
+<?php
+
+final class PhabricatorPackagesPublisherEditController
+ extends PhabricatorPackagesPublisherController {
+
+ public function handleRequest(AphrontRequest $request) {
+ return id(new PhabricatorPackagesPublisherEditEngine())
+ ->setController($this)
+ ->buildResponse();
+ }
+
+}
diff --git a/src/applications/packages/controller/PhabricatorPackagesPublisherListController.php b/src/applications/packages/controller/PhabricatorPackagesPublisherListController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/controller/PhabricatorPackagesPublisherListController.php
@@ -0,0 +1,26 @@
+<?php
+
+final class PhabricatorPackagesPublisherListController
+ extends PhabricatorPackagesPublisherController {
+
+ public function shouldAllowPublic() {
+ return true;
+ }
+
+ public function handleRequest(AphrontRequest $request) {
+ return id(new PhabricatorPackagesPublisherSearchEngine())
+ ->setController($this)
+ ->buildResponse();
+ }
+
+ protected function buildApplicationCrumbs() {
+ $crumbs = parent::buildApplicationCrumbs();
+
+ id(new PhabricatorPackagesPublisherEditEngine())
+ ->setViewer($this->getViewer())
+ ->addActionToCrumbs($crumbs);
+
+ return $crumbs;
+ }
+
+}
diff --git a/src/applications/packages/controller/PhabricatorPackagesPublisherViewController.php b/src/applications/packages/controller/PhabricatorPackagesPublisherViewController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/controller/PhabricatorPackagesPublisherViewController.php
@@ -0,0 +1,84 @@
+<?php
+
+final class PhabricatorPackagesPublisherViewController
+ extends PhabricatorPackagesPublisherController {
+
+ public function shouldAllowPublic() {
+ return true;
+ }
+
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $request->getViewer();
+ $publisher_key = $request->getURIData('publisherKey');
+
+ $publisher = id(new PhabricatorPackagesPublisherQuery())
+ ->setViewer($viewer)
+ ->withPublisherKeys(array($publisher_key))
+ ->executeOne();
+ if (!$publisher) {
+ return new Aphront404Response();
+ }
+
+ $crumbs = $this->buildApplicationCrumbs()
+ ->addTextCrumb(
+ pht('Publishers'),
+ $this->getApplicationURI('publisher/'))
+ ->addTextCrumb($publisher->getName())
+ ->setBorder(true);
+
+ $header = $this->buildHeaderView($publisher);
+ $curtain = $this->buildCurtain($publisher);
+
+ $timeline = $this->buildTransactionTimeline(
+ $publisher,
+ new PhabricatorPackagesPublisherTransactionQuery());
+
+ $publisher_view = id(new PHUITwoColumnView())
+ ->setHeader($header)
+ ->setCurtain($curtain)
+ ->setMainColumn($timeline);
+
+ return $this->newPage()
+ ->setCrumbs($crumbs)
+ ->setPageObjectPHIDs(
+ array(
+ $publisher->getPHID(),
+ ))
+ ->appendChild($publisher_view);
+ }
+
+
+ private function buildHeaderView(PhabricatorPackagesPublisher $publisher) {
+ $viewer = $this->getViewer();
+ $name = $publisher->getName();
+
+ return id(new PHUIHeaderView())
+ ->setViewer($viewer)
+ ->setHeader($name)
+ ->setPolicyObject($publisher)
+ ->setHeaderIcon('fa-paw');
+ }
+
+ private function buildCurtain(PhabricatorPackagesPublisher $publisher) {
+ $viewer = $this->getViewer();
+ $curtain = $this->newCurtainView($publisher);
+
+ $can_edit = PhabricatorPolicyFilter::hasCapability(
+ $viewer,
+ $publisher,
+ PhabricatorPolicyCapability::CAN_EDIT);
+
+ $id = $publisher->getID();
+ $edit_uri = $this->getApplicationURI("publisher/edit/{$id}/");
+
+ $curtain->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Edit Publisher'))
+ ->setIcon('fa-pencil')
+ ->setDisabled(!$can_edit)
+ ->setHref($edit_uri));
+
+ return $curtain;
+ }
+
+}
diff --git a/src/applications/packages/editor/PhabricatorPackagesEditEngine.php b/src/applications/packages/editor/PhabricatorPackagesEditEngine.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/editor/PhabricatorPackagesEditEngine.php
@@ -0,0 +1,14 @@
+<?php
+
+abstract class PhabricatorPackagesEditEngine
+ extends PhabricatorEditEngine {
+
+ public function isEngineConfigurable() {
+ return false;
+ }
+
+ public function getEngineApplicationClass() {
+ return 'PhabricatorPackagesApplication';
+ }
+
+}
diff --git a/src/applications/packages/editor/PhabricatorPackagesEditor.php b/src/applications/packages/editor/PhabricatorPackagesEditor.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/editor/PhabricatorPackagesEditor.php
@@ -0,0 +1,10 @@
+<?php
+
+abstract class PhabricatorPackagesEditor
+ extends PhabricatorApplicationTransactionEditor {
+
+ public function getEditorApplicationClass() {
+ return 'PhabricatorPasteApplication';
+ }
+
+}
diff --git a/src/applications/packages/editor/PhabricatorPackagesPublisherEditEngine.php b/src/applications/packages/editor/PhabricatorPackagesPublisherEditEngine.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/editor/PhabricatorPackagesPublisherEditEngine.php
@@ -0,0 +1,91 @@
+<?php
+
+final class PhabricatorPackagesPublisherEditEngine
+ extends PhabricatorPackagesEditEngine {
+
+ const ENGINECONST = 'packages.publisher';
+
+ public function getEngineName() {
+ return pht('Package Publishers');
+ }
+
+ public function getSummaryHeader() {
+ return pht('Edit Package Publisher Configurations');
+ }
+
+ public function getSummaryText() {
+ return pht('This engine is used to edit Packages publishers.');
+ }
+
+ protected function newEditableObject() {
+ $viewer = $this->getViewer();
+ return PhabricatorPackagesPublisher::initializeNewPublisher($viewer);
+ }
+
+ protected function newObjectQuery() {
+ return new PhabricatorPackagesPublisherQuery();
+ }
+
+ protected function getObjectCreateTitleText($object) {
+ return pht('Create Publisher');
+ }
+
+ protected function getObjectCreateButtonText($object) {
+ return pht('Create Publisher');
+ }
+
+ protected function getObjectEditTitleText($object) {
+ return pht('Edit Publisher: %s', $object->getName());
+ }
+
+ protected function getObjectEditShortText($object) {
+ return pht('Edit Publisher');
+ }
+
+ protected function getObjectCreateShortText() {
+ return pht('Create Publisher');
+ }
+
+ protected function getObjectName() {
+ return pht('Publisher');
+ }
+
+ protected function getEditorURI() {
+ return '/packages/publisher/edit/';
+ }
+
+ protected function getObjectCreateCancelURI($object) {
+ return '/packages/publisher/';
+ }
+
+ protected function getObjectViewURI($object) {
+ return $object->getURI();
+ }
+
+ protected function buildCustomEditFields($object) {
+ $fields = array();
+
+ $fields[] = id(new PhabricatorTextEditField())
+ ->setKey('name')
+ ->setLabel(pht('Name'))
+ ->setDescription(pht('Name of the publisher.'))
+ ->setTransactionType(
+ PhabricatorPackagesPublisherNameTransaction::TRANSACTIONTYPE)
+ ->setIsRequired(true)
+ ->setValue($object->getName());
+
+ if ($this->getIsCreate()) {
+ $fields[] = id(new PhabricatorTextEditField())
+ ->setKey('publisherKey')
+ ->setLabel(pht('Publisher Key'))
+ ->setDescription(pht('Unique key to identify the publisher.'))
+ ->setTransactionType(
+ PhabricatorPackagesPublisherKeyTransaction::TRANSACTIONTYPE)
+ ->setIsRequired(true)
+ ->setValue($object->getPublisherKey());
+ }
+
+ return $fields;
+ }
+
+}
diff --git a/src/applications/packages/editor/PhabricatorPackagesPublisherEditor.php b/src/applications/packages/editor/PhabricatorPackagesPublisherEditor.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/editor/PhabricatorPackagesPublisherEditor.php
@@ -0,0 +1,51 @@
+<?php
+
+final class PhabricatorPackagesPublisherEditor
+ extends PhabricatorPackagesEditor {
+
+ public function getEditorObjectsDescription() {
+ return pht('Package Publishers');
+ }
+
+ public function getCreateObjectTitle($author, $object) {
+ return pht('%s created this publisher.', $author);
+ }
+
+ public function getCreateObjectTitleForFeed($author, $object) {
+ return pht('%s created %s.', $author, $object);
+ }
+
+ public function getTransactionTypes() {
+ $types = parent::getTransactionTypes();
+ $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
+ return $types;
+ }
+
+ protected function shouldPublishFeedStory(
+ PhabricatorLiskDAO $object,
+ array $xactions) {
+ return true;
+ }
+
+ protected function getMailTo(PhabricatorLiskDAO $object) {
+ return array();
+ }
+
+ protected function didCatchDuplicateKeyException(
+ PhabricatorLiskDAO $object,
+ array $xactions,
+ Exception $ex) {
+
+ $errors = array();
+ $errors[] = new PhabricatorApplicationTransactionValidationError(
+ PhabricatorPackagesPublisherKeyTransaction::TRANSACTIONTYPE,
+ pht('Duplicate'),
+ pht(
+ 'The publisher key "%s" is already in use by another publisher.',
+ $object->getPublisherKey()),
+ null);
+
+ throw new PhabricatorApplicationTransactionValidationException($errors);
+ }
+
+}
diff --git a/src/applications/packages/phid/PhabricatorPackagesPublisherPHIDType.php b/src/applications/packages/phid/PhabricatorPackagesPublisherPHIDType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/phid/PhabricatorPackagesPublisherPHIDType.php
@@ -0,0 +1,45 @@
+<?php
+
+final class PhabricatorPackagesPublisherPHIDType
+ extends PhabricatorPHIDType {
+
+ const TYPECONST = 'PPUB';
+
+ public function getTypeName() {
+ return pht('Package Publisher');
+ }
+
+ public function newObject() {
+ return new PhabricatorPackagesPublisher();
+ }
+
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPackagesApplication';
+ }
+
+ protected function buildQueryForObjects(
+ PhabricatorObjectQuery $query,
+ array $phids) {
+
+ return id(new PhabricatorPackagesPublisherQuery())
+ ->withPHIDs($phids);
+ }
+
+ public function loadHandles(
+ PhabricatorHandleQuery $query,
+ array $handles,
+ array $objects) {
+
+ foreach ($handles as $phid => $handle) {
+ $publisher = $objects[$phid];
+
+ $name = $publisher->getName();
+ $uri = $publisher->getURI();
+
+ $handle
+ ->setName($name)
+ ->setURI($uri);
+ }
+ }
+
+}
diff --git a/src/applications/packages/query/PhabricatorPackagesPublisherQuery.php b/src/applications/packages/query/PhabricatorPackagesPublisherQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/query/PhabricatorPackagesPublisherQuery.php
@@ -0,0 +1,64 @@
+<?php
+
+final class PhabricatorPackagesPublisherQuery
+ extends PhabricatorCursorPagedPolicyAwareQuery {
+
+ private $ids;
+ private $phids;
+ private $publisherKeys;
+
+ public function withIDs(array $ids) {
+ $this->ids = $ids;
+ return $this;
+ }
+
+ public function withPHIDs(array $phids) {
+ $this->phids = $phids;
+ return $this;
+ }
+
+ public function withPublisherKeys(array $keys) {
+ $this->publisherKeys = $keys;
+ return $this;
+ }
+
+ public function newResultObject() {
+ return new PhabricatorPackagesPublisher();
+ }
+
+ protected function loadPage() {
+ return $this->loadStandardPage($this->newResultObject());
+ }
+
+ protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
+ $where = parent::buildWhereClauseParts($conn);
+
+ if ($this->ids !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'id IN (%Ld)',
+ $this->ids);
+ }
+
+ if ($this->phids !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'phid IN (%Ls)',
+ $this->phids);
+ }
+
+ if ($this->publisherKeys !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'publisherKey IN (%Ls)',
+ $this->publisherKeys);
+ }
+
+ return $where;
+ }
+
+ public function getQueryApplicationClass() {
+ return 'PhabricatorPackagesApplication';
+ }
+
+}
diff --git a/src/applications/packages/query/PhabricatorPackagesPublisherSearchEngine.php b/src/applications/packages/query/PhabricatorPackagesPublisherSearchEngine.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/query/PhabricatorPackagesPublisherSearchEngine.php
@@ -0,0 +1,77 @@
+<?php
+
+final class PhabricatorPackagesPublisherSearchEngine
+ extends PhabricatorApplicationSearchEngine {
+
+ public function getResultTypeDescription() {
+ return pht('Package Publishers');
+ }
+
+ public function getApplicationClassName() {
+ return 'PhabricatorPackagesApplication';
+ }
+
+ public function newQuery() {
+ return id(new PhabricatorPackagesPublisherQuery());
+ }
+
+ protected function buildQueryFromParameters(array $map) {
+ $query = $this->newQuery();
+
+ return $query;
+ }
+
+ protected function buildCustomSearchFields() {
+ return array();
+ }
+
+ protected function getURI($path) {
+ return '/packages/publisher/'.$path;
+ }
+
+ protected function getBuiltinQueryNames() {
+ $names = array(
+ 'all' => pht('All Publishers'),
+ );
+
+ return $names;
+ }
+
+ public function buildSavedQueryFromBuiltin($query_key) {
+ $query = $this->newSavedQuery();
+ $query->setQueryKey($query_key);
+
+ switch ($query_key) {
+ case 'all':
+ return $query;
+ }
+
+ return parent::buildSavedQueryFromBuiltin($query_key);
+ }
+
+ protected function renderResultList(
+ array $publishers,
+ PhabricatorSavedQuery $query,
+ array $handles) {
+
+ assert_instances_of($publishers, 'PhabricatorPackagesPublisher');
+
+ $viewer = $this->requireViewer();
+
+ $list = id(new PHUIObjectItemListView())
+ ->setViewer($viewer);
+ foreach ($publishers as $publisher) {
+ $item = id(new PHUIObjectItemView())
+ ->setObjectName($publisher->getPublisherKey())
+ ->setHeader($publisher->getName())
+ ->setHref($publisher->getURI());
+
+ $list->addItem($item);
+ }
+
+ return id(new PhabricatorApplicationSearchResultView())
+ ->setObjectList($list)
+ ->setNoDataString(pht('No publishers found.'));
+ }
+
+}
diff --git a/src/applications/packages/query/PhabricatorPackagesPublisherTransactionQuery.php b/src/applications/packages/query/PhabricatorPackagesPublisherTransactionQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/query/PhabricatorPackagesPublisherTransactionQuery.php
@@ -0,0 +1,10 @@
+<?php
+
+final class PhabricatorPackagesPublisherTransactionQuery
+ extends PhabricatorApplicationTransactionQuery {
+
+ public function getTemplateApplicationTransaction() {
+ return new PhabricatorPackagesPublisherTransaction();
+ }
+
+}
diff --git a/src/applications/packages/storage/PhabricatorPackagesDAO.php b/src/applications/packages/storage/PhabricatorPackagesDAO.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/storage/PhabricatorPackagesDAO.php
@@ -0,0 +1,9 @@
+<?php
+
+abstract class PhabricatorPackagesDAO extends PhabricatorLiskDAO {
+
+ public function getApplicationName() {
+ return 'packages';
+ }
+
+}
diff --git a/src/applications/packages/storage/PhabricatorPackagesPublisher.php b/src/applications/packages/storage/PhabricatorPackagesPublisher.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/storage/PhabricatorPackagesPublisher.php
@@ -0,0 +1,191 @@
+<?php
+
+final class PhabricatorPackagesPublisher
+ extends PhabricatorPackagesDAO
+ implements
+ PhabricatorPolicyInterface,
+ PhabricatorApplicationTransactionInterface,
+ PhabricatorDestructibleInterface,
+ PhabricatorSubscribableInterface,
+ PhabricatorProjectInterface,
+ PhabricatorConduitResultInterface {
+
+ protected $name;
+ protected $publisherKey;
+ protected $editPolicy;
+
+ public static function initializeNewPublisher(PhabricatorUser $actor) {
+ return id(new self());
+ }
+
+ protected function getConfiguration() {
+ return array(
+ self::CONFIG_AUX_PHID => true,
+ self::CONFIG_COLUMN_SCHEMA => array(
+ 'name' => 'text64',
+ 'publisherKey' => 'sort64',
+ ),
+ self::CONFIG_KEY_SCHEMA => array(
+ 'key_publisher' => array(
+ 'columns' => array('publisherKey'),
+ 'unique' => true,
+ ),
+ ),
+ ) + parent::getConfiguration();
+ }
+
+ public function generatePHID() {
+ return PhabricatorPHID::generateNewPHID(
+ PhabricatorPackagesPublisherPHIDType::TYPECONST);
+ }
+
+ public function getURI() {
+ $publisher_key = $this->getPublisherKey();
+ return "/package/{$publisher_key}/";
+ }
+
+ public static function assertValidPublisherName($value) {
+ $length = phutil_utf8_strlen($value);
+ if (!$length) {
+ throw new Exception(
+ pht(
+ 'Publisher name "%s" is not valid: publisher names are required.',
+ $value));
+ }
+
+ $max_length = 64;
+ if ($length > $max_length) {
+ throw new Exception(
+ pht(
+ 'Publisher name "%s" is not valid: publisher names must not be '.
+ 'more than %s characters long.',
+ $value,
+ new PhutilNumber($max_length)));
+ }
+ }
+
+ public static function assertValidPublisherKey($value) {
+ $length = phutil_utf8_strlen($value);
+ if (!$length) {
+ throw new Exception(
+ pht(
+ 'Publisher key "%s" is not valid: publisher keys are required.',
+ $value));
+ }
+
+ $max_length = 64;
+ if ($length > $max_length) {
+ throw new Exception(
+ pht(
+ 'Publisher key "%s" is not valid: publisher keys must not be '.
+ 'more than %s characters long.',
+ $value,
+ new PhutilNumber($max_length)));
+ }
+
+ if (!preg_match('/^[a-z]+\z/', $value)) {
+ throw new Exception(
+ pht(
+ 'Publisher key "%s" is not valid: publisher keys may only contain '.
+ 'lowercase latin letters.',
+ $value));
+ }
+ }
+
+
+/* -( PhabricatorSubscribableInterface )----------------------------------- */
+
+
+ public function isAutomaticallySubscribed($phid) {
+ return false;
+ }
+
+
+/* -( Policy Interface )--------------------------------------------------- */
+
+
+ public function getCapabilities() {
+ return array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ );
+ }
+
+ public function getPolicy($capability) {
+ switch ($capability) {
+ case PhabricatorPolicyCapability::CAN_VIEW:
+ return PhabricatorPolicies::getMostOpenPolicy();
+ case PhabricatorPolicyCapability::CAN_EDIT:
+ return $this->getEditPolicy();
+ }
+ }
+
+ public function hasAutomaticCapability($capability, PhabricatorUser $user) {
+ return false;
+ }
+
+ public function describeAutomaticCapability($capability) {
+ return null;
+ }
+
+
+/* -( PhabricatorDestructibleInterface )----------------------------------- */
+
+
+ public function destroyObjectPermanently(
+ PhabricatorDestructionEngine $engine) {
+ $this->delete();
+ }
+
+
+/* -( PhabricatorApplicationTransactionInterface )------------------------- */
+
+
+ public function getApplicationTransactionEditor() {
+ return new PhabricatorPackagesPublisherEditor();
+ }
+
+ public function getApplicationTransactionObject() {
+ return $this;
+ }
+
+ public function getApplicationTransactionTemplate() {
+ return new PhabricatorPackagesPublisherTransaction();
+ }
+
+ public function willRenderTimeline(
+ PhabricatorApplicationTransactionView $timeline,
+ AphrontRequest $request) {
+ return $timeline;
+ }
+
+
+/* -( PhabricatorConduitResultInterface )---------------------------------- */
+
+
+ public function getFieldSpecificationsForConduit() {
+ return array(
+ id(new PhabricatorConduitSearchFieldSpecification())
+ ->setKey('name')
+ ->setType('string')
+ ->setDescription(pht('The name of the publisher.')),
+ id(new PhabricatorConduitSearchFieldSpecification())
+ ->setKey('publisherKey')
+ ->setType('string')
+ ->setDescription(pht('The unique key of the publisher.')),
+ );
+ }
+
+ public function getFieldValuesForConduit() {
+ return array(
+ 'name' => $this->getName(),
+ 'publisherKey' => $this->getPublisherKey(),
+ );
+ }
+
+ public function getConduitSearchAttachments() {
+ return array();
+ }
+
+
+}
diff --git a/src/applications/packages/storage/PhabricatorPackagesPublisherTransaction.php b/src/applications/packages/storage/PhabricatorPackagesPublisherTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/storage/PhabricatorPackagesPublisherTransaction.php
@@ -0,0 +1,18 @@
+<?php
+
+final class PhabricatorPackagesPublisherTransaction
+ extends PhabricatorModularTransaction {
+
+ public function getApplicationName() {
+ return 'packages';
+ }
+
+ public function getApplicationTransactionType() {
+ return PhabricatorPackagesPublisherPHIDType::TYPECONST;
+ }
+
+ public function getBaseTransactionClass() {
+ return 'PhabricatorPackagesPublisherTransactionType';
+ }
+
+}
diff --git a/src/applications/packages/storage/PhabricatorPackagesSchemaSpec.php b/src/applications/packages/storage/PhabricatorPackagesSchemaSpec.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/storage/PhabricatorPackagesSchemaSpec.php
@@ -0,0 +1,10 @@
+<?php
+
+final class PhabricatorPackagesSchemaSpec
+ extends PhabricatorConfigSchemaSpec {
+
+ public function buildSchemata() {
+ $this->buildEdgeSchemata(new PhabricatorPackagesPublisher());
+ }
+
+}
diff --git a/src/applications/packages/xaction/PhabricatorPackagesTransactionType.php b/src/applications/packages/xaction/PhabricatorPackagesTransactionType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/xaction/PhabricatorPackagesTransactionType.php
@@ -0,0 +1,4 @@
+<?php
+
+abstract class PhabricatorPackagesTransactionType
+ extends PhabricatorModularTransactionType {}
diff --git a/src/applications/packages/xaction/publisher/PhabricatorPackagesPublisherKeyTransaction.php b/src/applications/packages/xaction/publisher/PhabricatorPackagesPublisherKeyTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/xaction/publisher/PhabricatorPackagesPublisherKeyTransaction.php
@@ -0,0 +1,44 @@
+<?php
+
+final class PhabricatorPackagesPublisherKeyTransaction
+ extends PhabricatorPackagesPublisherTransactionType {
+
+ const TRANSACTIONTYPE = 'packages.publisher.key';
+
+ public function generateOldValue($object) {
+ return $object->getPublisherKey();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setPublisherKey($value);
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+
+ if ($this->isEmptyTextTransaction($object->getName(), $xactions)) {
+ $errors[] = $this->newRequiredError(
+ pht('Publishers must have a unique publisher key.'));
+ }
+
+ if (!$this->isNewObject()) {
+ foreach ($xactions as $xaction) {
+ $errors[] = $this->newInvalidError(
+ pht('Once a publisher is created, its key can not be changed.'),
+ $xaction);
+ }
+ }
+
+ foreach ($xactions as $xaction) {
+ $value = $xaction->getNewValue();
+ try {
+ PhabricatorPackagesPublisher::assertValidPublisherKey($value);
+ } catch (Exception $ex) {
+ $errors[] = $this->newInvalidError($ex->getMessage(), $xaction);
+ }
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/packages/xaction/publisher/PhabricatorPackagesPublisherNameTransaction.php b/src/applications/packages/xaction/publisher/PhabricatorPackagesPublisherNameTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/xaction/publisher/PhabricatorPackagesPublisherNameTransaction.php
@@ -0,0 +1,53 @@
+<?php
+
+final class PhabricatorPackagesPublisherNameTransaction
+ extends PhabricatorPackagesPublisherTransactionType {
+
+ const TRANSACTIONTYPE = 'packages.publisher.name';
+
+ public function generateOldValue($object) {
+ return $object->getName();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setName($value);
+ }
+
+ public function getTitle() {
+ return pht(
+ '%s changed the name of this publisher from %s to %s.',
+ $this->renderAuthor(),
+ $this->renderOldValue(),
+ $this->renderNewValue());
+ }
+
+ public function getTitleForFeed() {
+ return pht(
+ '%s updated the name for %s from %s to %s.',
+ $this->renderAuthor(),
+ $this->renderObject(),
+ $this->renderOldValue(),
+ $this->renderNewValue());
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+
+ if ($this->isEmptyTextTransaction($object->getName(), $xactions)) {
+ $errors[] = $this->newRequiredError(
+ pht('Publishers must have a name.'));
+ }
+
+ foreach ($xactions as $xaction) {
+ $value = $xaction->getNewValue();
+ try {
+ PhabricatorPackagesPublisher::assertValidPublisherName($value);
+ } catch (Exception $ex) {
+ $errors[] = $this->newInvalidError($ex->getMessage(), $xaction);
+ }
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/packages/xaction/publisher/PhabricatorPackagesPublisherTransactionType.php b/src/applications/packages/xaction/publisher/PhabricatorPackagesPublisherTransactionType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/packages/xaction/publisher/PhabricatorPackagesPublisherTransactionType.php
@@ -0,0 +1,4 @@
+<?php
+
+abstract class PhabricatorPackagesPublisherTransactionType
+ extends PhabricatorPackagesTransactionType {}
diff --git a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
--- a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
+++ b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
@@ -111,6 +111,7 @@
'db.spaces' => array(),
'db.phurl' => array(),
'db.badges' => array(),
+ 'db.packages' => array(),
'0000.legacy.sql' => array(
'legacy' => 0,
),
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Dec 18, 1:07 PM (5 h, 19 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6902909
Default Alt Text
D16314.diff (38 KB)
Attached To
Mode
D16314: Add a Packages application and PackagePublisher
Attached
Detach File
Event Timeline
Log In to Comment