Page MenuHomePhabricator

D16314.diff
No OneTemporary

D16314.diff

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

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)

Event Timeline