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 @@ + array( + '(?P[^/]+)/' => 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 @@ +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 @@ +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 @@ +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 @@ +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 @@ +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 @@ +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 @@ +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 @@ +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 @@ + 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 @@ +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 @@ +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 @@ +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 @@ + array(), 'db.phurl' => array(), 'db.badges' => array(), + 'db.packages' => array(), '0000.legacy.sql' => array( 'legacy' => 0, ),