Page MenuHomePhabricator

D13028.diff
No OneTemporary

D13028.diff

diff --git a/resources/sql/autopatches/20150526.owners.mailkey.1.sql b/resources/sql/autopatches/20150526.owners.mailkey.1.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150526.owners.mailkey.1.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_owners.owners_package
+ ADD mailKey binary(20) NOT NULL;
diff --git a/resources/sql/autopatches/20150526.owners.mailkey.2.php b/resources/sql/autopatches/20150526.owners.mailkey.2.php
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150526.owners.mailkey.2.php
@@ -0,0 +1,18 @@
+<?php
+
+$table = new PhabricatorOwnersPackage();
+$conn_w = $table->establishConnection('w');
+$iterator = new LiskMigrationIterator($table);
+foreach ($iterator as $package) {
+ $id = $package->getID();
+
+ echo pht('Adding mail key for package %d...', $id);
+ echo "\n";
+
+ queryfx(
+ $conn_w,
+ 'UPDATE %T SET mailKey = %s WHERE id = %d',
+ $table->getTableName(),
+ Filesystem::readRandomCharacters(20),
+ $id);
+}
diff --git a/resources/sql/autopatches/20150526.owners.xaction.sql b/resources/sql/autopatches/20150526.owners.xaction.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150526.owners.xaction.sql
@@ -0,0 +1,19 @@
+CREATE TABLE {$NAMESPACE}_owners.owners_packagetransaction (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ phid VARBINARY(64) NOT NULL,
+ authorPHID VARBINARY(64) NOT NULL,
+ objectPHID VARBINARY(64) NOT NULL,
+ viewPolicy VARBINARY(64) NOT NULL,
+ editPolicy VARBINARY(64) NOT NULL,
+ commentPHID VARBINARY(64) DEFAULT NULL,
+ commentVersion INT UNSIGNED NOT NULL,
+ transactionType VARCHAR(32) COLLATE {$COLLATE_TEXT} NOT NULL,
+ oldValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ newValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ contentSource LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ metadata LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL,
+ UNIQUE KEY `key_phid` (`phid`),
+ KEY `key_object` (`objectPHID`)
+) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2180,6 +2180,9 @@
'PhabricatorOwnersPackageQuery' => 'applications/owners/query/PhabricatorOwnersPackageQuery.php',
'PhabricatorOwnersPackageSearchEngine' => 'applications/owners/query/PhabricatorOwnersPackageSearchEngine.php',
'PhabricatorOwnersPackageTestCase' => 'applications/owners/storage/__tests__/PhabricatorOwnersPackageTestCase.php',
+ 'PhabricatorOwnersPackageTransaction' => 'applications/owners/storage/PhabricatorOwnersPackageTransaction.php',
+ 'PhabricatorOwnersPackageTransactionEditor' => 'applications/owners/editor/PhabricatorOwnersPackageTransactionEditor.php',
+ 'PhabricatorOwnersPackageTransactionQuery' => 'applications/owners/query/PhabricatorOwnersPackageTransactionQuery.php',
'PhabricatorOwnersPath' => 'applications/owners/storage/PhabricatorOwnersPath.php',
'PhabricatorOwnersPathsController' => 'applications/owners/controller/PhabricatorOwnersPathsController.php',
'PhabricatorPHDConfigOptions' => 'applications/config/option/PhabricatorPHDConfigOptions.php',
@@ -5581,6 +5584,7 @@
'PhabricatorOwnersPackage' => array(
'PhabricatorOwnersDAO',
'PhabricatorPolicyInterface',
+ 'PhabricatorApplicationTransactionInterface',
),
'PhabricatorOwnersPackageDatasource' => 'PhabricatorTypeaheadDatasource',
'PhabricatorOwnersPackageEditor' => 'PhabricatorEditor',
@@ -5588,6 +5592,9 @@
'PhabricatorOwnersPackageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorOwnersPackageSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorOwnersPackageTestCase' => 'PhabricatorTestCase',
+ 'PhabricatorOwnersPackageTransaction' => 'PhabricatorApplicationTransaction',
+ 'PhabricatorOwnersPackageTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
+ 'PhabricatorOwnersPackageTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorOwnersPath' => 'PhabricatorOwnersDAO',
'PhabricatorOwnersPathsController' => 'PhabricatorOwnersController',
'PhabricatorPHDConfigOptions' => 'PhabricatorApplicationConfigOptions',
diff --git a/src/applications/owners/controller/PhabricatorOwnersDetailController.php b/src/applications/owners/controller/PhabricatorOwnersDetailController.php
--- a/src/applications/owners/controller/PhabricatorOwnersDetailController.php
+++ b/src/applications/owners/controller/PhabricatorOwnersDetailController.php
@@ -124,12 +124,18 @@
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($package->getName());
+ $timeline = $this->buildTransactionTimeline(
+ $package,
+ new PhabricatorOwnersPackageTransactionQuery());
+ $timeline->setShouldTerminate(true);
+
return $this->buildApplicationPage(
array(
$crumbs,
$panel,
$this->renderPathsTable($paths, $repositories),
$commit_panels,
+ $timeline,
),
array(
'title' => $package->getName(),
diff --git a/src/applications/owners/controller/PhabricatorOwnersEditController.php b/src/applications/owners/controller/PhabricatorOwnersEditController.php
--- a/src/applications/owners/controller/PhabricatorOwnersEditController.php
+++ b/src/applications/owners/controller/PhabricatorOwnersEditController.php
@@ -21,86 +21,93 @@
if (!$package) {
return new Aphront404Response();
}
-
$is_new = false;
} else {
- $package = new PhabricatorOwnersPackage();
- $package->setPrimaryOwnerPHID($viewer->getPHID());
-
+ $package = PhabricatorOwnersPackage::initializeNewPackage($viewer);
$is_new = true;
}
$e_name = true;
$e_primary = true;
- $errors = array();
+ $v_name = $package->getName();
+ $v_primary = $package->getPrimaryOwnerPHID();
+ // TODO: Pull these off needOwners() on the Query.
+ $v_owners = mpull($package->loadOwners(), 'getUserPHID');
+ $v_auditing = $package->getAuditingEnabled();
+ $v_description = $package->getDescription();
+
+ $errors = array();
if ($request->isFormPost()) {
- $package->setName($request->getStr('name'));
- $package->setDescription($request->getStr('description'));
- $old_auditing_enabled = $package->getAuditingEnabled();
- $package->setAuditingEnabled(
- ($request->getStr('auditing') === 'enabled')
- ? 1
- : 0);
-
- $primary = $request->getArr('primary');
- $primary = reset($primary);
- $old_primary = $package->getPrimaryOwnerPHID();
- $package->setPrimaryOwnerPHID($primary);
-
- $owners = $request->getArr('owners');
- if ($primary) {
- array_unshift($owners, $primary);
- }
- $owners = array_unique($owners);
+ $xactions = array();
- if (!strlen($package->getName())) {
- $e_name = pht('Required');
- $errors[] = pht('Package name is required.');
- } else {
- $e_name = null;
- }
+ $v_name = $request->getStr('name');
+ $v_primary = head($request->getArr('primary'));
+ $v_owners = $request->getArr('owners');
+ $v_auditing = ($request->getStr('auditing') == 'enabled');
+ $v_description = $request->getStr('description');
- if (!$package->getPrimaryOwnerPHID()) {
- $e_primary = pht('Required');
- $errors[] = pht('Package must have a primary owner.');
- } else {
- $e_primary = null;
+ if ($v_primary) {
+ $v_owners[] = $v_primary;
+ $v_owners = array_unique($v_owners);
}
- if (!$errors) {
- $package->attachUnsavedOwners($owners);
- $package->attachUnsavedPaths(array());
- $package->attachOldAuditingEnabled($old_auditing_enabled);
- $package->attachOldPrimaryOwnerPHID($old_primary);
- try {
- id(new PhabricatorOwnersPackageEditor())
- ->setActor($viewer)
- ->setPackage($package)
- ->save();
-
- $id = $package->getID();
- if ($is_new) {
- $next_uri = '/owners/paths/'.$id.'/';
- } else {
- $next_uri = '/owners/package/'.$id.'/';
- }
-
- return id(new AphrontRedirectResponse())->setURI($next_uri);
- } catch (AphrontDuplicateKeyQueryException $ex) {
- $e_name = pht('Duplicate');
- $errors[] = pht('Package name must be unique.');
+ $type_name = PhabricatorOwnersPackageTransaction::TYPE_NAME;
+ $type_primary = PhabricatorOwnersPackageTransaction::TYPE_PRIMARY;
+ $type_owners = PhabricatorOwnersPackageTransaction::TYPE_OWNERS;
+ $type_auditing = PhabricatorOwnersPackageTransaction::TYPE_AUDITING;
+ $type_description = PhabricatorOwnersPackageTransaction::TYPE_DESCRIPTION;
+
+ $xactions[] = id(new PhabricatorOwnersPackageTransaction())
+ ->setTransactionType($type_name)
+ ->setNewValue($v_name);
+
+ $xactions[] = id(new PhabricatorOwnersPackageTransaction())
+ ->setTransactionType($type_primary)
+ ->setNewValue($v_primary);
+
+ $xactions[] = id(new PhabricatorOwnersPackageTransaction())
+ ->setTransactionType($type_owners)
+ ->setNewValue($v_owners);
+
+ $xactions[] = id(new PhabricatorOwnersPackageTransaction())
+ ->setTransactionType($type_auditing)
+ ->setNewValue($v_auditing);
+
+ $xactions[] = id(new PhabricatorOwnersPackageTransaction())
+ ->setTransactionType($type_description)
+ ->setNewValue($v_description);
+
+ $editor = id(new PhabricatorOwnersPackageTransactionEditor())
+ ->setActor($viewer)
+ ->setContentSourceFromRequest($request)
+ ->setContinueOnNoEffect(true);
+
+ try {
+ $editor->applyTransactions($package, $xactions);
+
+ $id = $package->getID();
+ if ($is_new) {
+ $next_uri = '/owners/paths/'.$id.'/';
+ } else {
+ $next_uri = '/owners/package/'.$id.'/';
}
+
+ return id(new AphrontRedirectResponse())->setURI($next_uri);
+ } catch (AphrontDuplicateKeyQueryException $ex) {
+ $e_name = pht('Duplicate');
+ $errors[] = pht('Package name must be unique.');
+ } catch (PhabricatorApplicationTransactionValidationException $ex) {
+ $validation_exception = $ex;
+
+ $e_name = $ex->getShortMessage($type_name);
+ $e_primary = $ex->getShortMessage($type_primary);
}
- } else {
- $owners = $package->loadOwners();
- $owners = mpull($owners, 'getUserPHID');
}
- $primary = $package->getPrimaryOwnerPHID();
- if ($primary) {
- $value_primary_owner = array($primary);
+ if ($v_primary) {
+ $value_primary_owner = array($v_primary);
} else {
$value_primary_owner = array();
}
@@ -121,7 +128,7 @@
id(new AphrontFormTextControl())
->setLabel(pht('Name'))
->setName('name')
- ->setValue($package->getName())
+ ->setValue($v_name)
->setError($e_name))
->appendControl(
id(new AphrontFormTokenizerControl())
@@ -136,7 +143,7 @@
->setDatasource(new PhabricatorProjectOrUserDatasource())
->setLabel(pht('Owners'))
->setName('owners')
- ->setValue($owners))
+ ->setValue($v_owners))
->appendChild(
id(new AphrontFormSelectControl())
->setName('auditing')
@@ -147,19 +154,18 @@
'this package will be reviewed to make sure an owner '.
'of the package is involved and the commit message has '.
'a valid revision, reviewed by, and author.'))
- ->setOptions(array(
- 'disabled' => pht('Disabled'),
- 'enabled' => pht('Enabled'),
- ))
- ->setValue(
- $package->getAuditingEnabled()
- ? 'enabled'
- : 'disabled'))
+ ->setOptions(
+ array(
+ 'disabled' => pht('Disabled'),
+ 'enabled' => pht('Enabled'),
+ ))
+ ->setValue(($v_auditing ? 'enabled' : 'disabled')))
->appendChild(
- id(new AphrontFormTextAreaControl())
+ id(new PhabricatorRemarkupControl())
+ ->setUser($viewer)
->setLabel(pht('Description'))
->setName('description')
- ->setValue($package->getDescription()))
+ ->setValue($v_description))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton($cancel_uri)
diff --git a/src/applications/owners/editor/PhabricatorOwnersPackageTransactionEditor.php b/src/applications/owners/editor/PhabricatorOwnersPackageTransactionEditor.php
new file mode 100644
--- /dev/null
+++ b/src/applications/owners/editor/PhabricatorOwnersPackageTransactionEditor.php
@@ -0,0 +1,240 @@
+<?php
+
+final class PhabricatorOwnersPackageTransactionEditor
+ extends PhabricatorApplicationTransactionEditor {
+
+ public function getEditorApplicationClass() {
+ return 'PhabricatorOwnersApplication';
+ }
+
+ public function getEditorObjectsDescription() {
+ return pht('Owners Packages');
+ }
+
+ public function getTransactionTypes() {
+ $types = parent::getTransactionTypes();
+
+ $types[] = PhabricatorOwnersPackageTransaction::TYPE_NAME;
+ $types[] = PhabricatorOwnersPackageTransaction::TYPE_PRIMARY;
+ $types[] = PhabricatorOwnersPackageTransaction::TYPE_OWNERS;
+ $types[] = PhabricatorOwnersPackageTransaction::TYPE_AUDITING;
+ $types[] = PhabricatorOwnersPackageTransaction::TYPE_DESCRIPTION;
+
+ return $types;
+ }
+
+ protected function getCustomTransactionOldValue(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorOwnersPackageTransaction::TYPE_NAME:
+ return $object->getName();
+ case PhabricatorOwnersPackageTransaction::TYPE_PRIMARY:
+ return $object->getPrimaryOwnerPHID();
+ case PhabricatorOwnersPackageTransaction::TYPE_OWNERS:
+ // TODO: needOwners() this on the Query.
+ $phids = mpull($object->loadOwners(), 'getUserPHID');
+ $phids = array_values($phids);
+ return $phids;
+ case PhabricatorOwnersPackageTransaction::TYPE_AUDITING:
+ return (int)$object->getAuditingEnabled();
+ case PhabricatorOwnersPackageTransaction::TYPE_DESCRIPTION:
+ return $object->getDescription();
+ }
+ }
+
+ protected function getCustomTransactionNewValue(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorOwnersPackageTransaction::TYPE_NAME:
+ case PhabricatorOwnersPackageTransaction::TYPE_PRIMARY:
+ case PhabricatorOwnersPackageTransaction::TYPE_DESCRIPTION:
+ return $xaction->getNewValue();
+ case PhabricatorOwnersPackageTransaction::TYPE_AUDITING:
+ return (int)$xaction->getNewValue();
+ case PhabricatorOwnersPackageTransaction::TYPE_OWNERS:
+ $phids = $xaction->getNewValue();
+ $phids = array_unique($phids);
+ $phids = array_values($phids);
+ return $phids;
+ }
+ }
+
+ protected function applyCustomInternalTransaction(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorOwnersPackageTransaction::TYPE_NAME:
+ $object->setName($xaction->getNewValue());
+ return;
+ case PhabricatorOwnersPackageTransaction::TYPE_PRIMARY:
+ $object->setPrimaryOwnerPHID($xaction->getNewValue());
+ return;
+ case PhabricatorOwnersPackageTransaction::TYPE_DESCRIPTION:
+ $object->setDescription($xaction->getNewValue());
+ return;
+ case PhabricatorOwnersPackageTransaction::TYPE_AUDITING:
+ $object->setAuditingEnabled($xaction->getNewValue());
+ return;
+ case PhabricatorOwnersPackageTransaction::TYPE_OWNERS:
+ return;
+ }
+
+ return parent::applyCustomInternalTransaction($object, $xaction);
+ }
+
+ protected function applyCustomExternalTransaction(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorOwnersPackageTransaction::TYPE_NAME:
+ case PhabricatorOwnersPackageTransaction::TYPE_PRIMARY:
+ case PhabricatorOwnersPackageTransaction::TYPE_DESCRIPTION:
+ case PhabricatorOwnersPackageTransaction::TYPE_AUDITING:
+ return;
+ case PhabricatorOwnersPackageTransaction::TYPE_OWNERS:
+ $old = $xaction->getOldValue();
+ $new = $xaction->getNewValue();
+
+ // TODO: needOwners this
+ $owners = $object->loadOwners();
+ $owners = mpull($owners, null, 'getUserPHID');
+
+ $rem = array_diff($old, $new);
+ foreach ($rem as $phid) {
+ if (isset($owners[$phid])) {
+ $owners[$phid]->delete();
+ unset($owners[$phid]);
+ }
+ }
+
+ $add = array_diff($new, $old);
+ foreach ($add as $phid) {
+ $owners[$phid] = id(new PhabricatorOwnersOwner())
+ ->setPackageID($object->getID())
+ ->setUserPHID($phid)
+ ->save();
+ }
+
+ // TODO: Attach owners here
+ return;
+ }
+
+ return parent::applyCustomExternalTransaction($object, $xaction);
+ }
+
+ protected function validateTransaction(
+ PhabricatorLiskDAO $object,
+ $type,
+ array $xactions) {
+
+ $errors = parent::validateTransaction($object, $type, $xactions);
+
+ switch ($type) {
+ case PhabricatorOwnersPackageTransaction::TYPE_NAME:
+ $missing = $this->validateIsEmptyTextField(
+ $object->getName(),
+ $xactions);
+
+ if ($missing) {
+ $error = new PhabricatorApplicationTransactionValidationError(
+ $type,
+ pht('Required'),
+ pht('Package name is required.'),
+ nonempty(last($xactions), null));
+
+ $error->setIsMissingFieldError(true);
+ $errors[] = $error;
+ }
+ break;
+ case PhabricatorOwnersPackageTransaction::TYPE_PRIMARY:
+ $missing = $this->validateIsEmptyTextField(
+ $object->getPrimaryOwnerPHID(),
+ $xactions);
+
+ if ($missing) {
+ $error = new PhabricatorApplicationTransactionValidationError(
+ $type,
+ pht('Required'),
+ pht('Packages must have a primary owner.'),
+ nonempty(last($xactions), null));
+
+ $error->setIsMissingFieldError(true);
+ $errors[] = $error;
+ }
+ break;
+ }
+
+ return $errors;
+ }
+
+ protected function extractFilePHIDsFromCustomTransaction(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorOwnersPackageTransaction::TYPE_DESCRIPTION:
+ return array($xaction->getNewValue());
+ }
+
+ return parent::extractFilePHIDsFromCustomTransaction($object, $xaction);
+ }
+
+ protected function shouldSendMail(
+ PhabricatorLiskDAO $object,
+ array $xactions) {
+ return true;
+ }
+
+ protected function getMailSubjectPrefix() {
+ return PhabricatorEnv::getEnvConfig('metamta.package.subject-prefix');
+ }
+
+ protected function getMailTo(PhabricatorLiskDAO $object) {
+ return array(
+ $object->getPrimaryOwnerPHID(),
+ $this->requireActor()->getPHID(),
+ );
+ }
+
+ protected function getMailCC(PhabricatorLiskDAO $object) {
+ // TODO: needOwners() this
+ return mpull($object->loadOwners(), 'getUserPHID');
+ }
+
+ protected function buildReplyHandler(PhabricatorLiskDAO $object) {
+ return id(new OwnersPackageReplyHandler())
+ ->setMailReceiver($object);
+ }
+
+ protected function buildMailTemplate(PhabricatorLiskDAO $object) {
+ $id = $object->getID();
+ $name = $object->getName();
+
+ return id(new PhabricatorMetaMTAMail())
+ ->setSubject($name)
+ ->addHeader('Thread-Topic', $object->getPHID());
+ }
+
+ protected function buildMailBody(
+ PhabricatorLiskDAO $object,
+ array $xactions) {
+
+ $body = parent::buildMailBody($object, $xactions);
+
+ $detail_uri = PhabricatorEnv::getProductionURI(
+ '/owners/package/'.$object->getID().'/');
+
+ $body->addLinkSection(
+ pht('PACKAGE DETAIL'),
+ $detail_uri);
+
+ return $body;
+ }
+
+}
diff --git a/src/applications/owners/query/PhabricatorOwnersPackageTransactionQuery.php b/src/applications/owners/query/PhabricatorOwnersPackageTransactionQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/owners/query/PhabricatorOwnersPackageTransactionQuery.php
@@ -0,0 +1,10 @@
+<?php
+
+final class PhabricatorOwnersPackageTransactionQuery
+ extends PhabricatorApplicationTransactionQuery {
+
+ public function getTemplateApplicationTransaction() {
+ return new PhabricatorOwnersPackageTransaction();
+ }
+
+}
diff --git a/src/applications/owners/storage/PhabricatorOwnersPackage.php b/src/applications/owners/storage/PhabricatorOwnersPackage.php
--- a/src/applications/owners/storage/PhabricatorOwnersPackage.php
+++ b/src/applications/owners/storage/PhabricatorOwnersPackage.php
@@ -1,13 +1,17 @@
<?php
-final class PhabricatorOwnersPackage extends PhabricatorOwnersDAO
- implements PhabricatorPolicyInterface {
+final class PhabricatorOwnersPackage
+ extends PhabricatorOwnersDAO
+ implements
+ PhabricatorPolicyInterface,
+ PhabricatorApplicationTransactionInterface {
protected $name;
protected $originalName;
protected $auditingEnabled;
protected $description;
protected $primaryOwnerPHID;
+ protected $mailKey;
private $unsavedOwners = self::ATTACHABLE;
private $unsavedPaths = self::ATTACHABLE;
@@ -15,6 +19,12 @@
private $oldPrimaryOwnerPHID;
private $oldAuditingEnabled;
+ public static function initializeNewPackage(PhabricatorUser $actor) {
+ return id(new PhabricatorOwnersPackage())
+ ->setAuditingEnabled(0)
+ ->setPrimaryOwnerPHID($actor->getPHID());
+ }
+
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
@@ -44,6 +54,7 @@
'description' => 'text',
'primaryOwnerPHID' => 'phid?',
'auditingEnabled' => 'bool',
+ 'mailKey' => 'bytes20',
),
self::CONFIG_KEY_SCHEMA => array(
'key_phid' => null,
@@ -64,6 +75,14 @@
PhabricatorOwnersPackagePHIDType::TYPECONST);
}
+ public function save() {
+ if (!$this->getMailKey()) {
+ $this->setMailKey(Filesystem::readRandomCharacters(20));
+ }
+
+ return parent::save();
+ }
+
public function attachUnsavedOwners(array $owners) {
$this->unsavedOwners = $owners;
return $this;
@@ -269,4 +288,27 @@
}
return $result;
}
+
+
+/* -( PhabricatorApplicationTransactionInterface )------------------------- */
+
+
+ public function getApplicationTransactionEditor() {
+ return new PhabricatorOwnersPackageTransactionEditor();
+ }
+
+ public function getApplicationTransactionObject() {
+ return $this;
+ }
+
+ public function getApplicationTransactionTemplate() {
+ return new PhabricatorOwnersPackageTransaction();
+ }
+
+ public function willRenderTimeline(
+ PhabricatorApplicationTransactionView $timeline,
+ AphrontRequest $request) {
+ return $timeline;
+ }
+
}
diff --git a/src/applications/owners/storage/PhabricatorOwnersPackageTransaction.php b/src/applications/owners/storage/PhabricatorOwnersPackageTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/owners/storage/PhabricatorOwnersPackageTransaction.php
@@ -0,0 +1,152 @@
+<?php
+
+final class PhabricatorOwnersPackageTransaction
+ extends PhabricatorApplicationTransaction {
+
+ const TYPE_NAME = 'owners.name';
+ const TYPE_PRIMARY = 'owners.primary';
+ const TYPE_OWNERS = 'owners.owners';
+ const TYPE_AUDITING = 'owners.auditing';
+ const TYPE_DESCRIPTION = 'owners.description';
+
+ public function getApplicationName() {
+ return 'owners';
+ }
+
+ public function getApplicationTransactionType() {
+ return PhabricatorOwnersPackagePHIDType::TYPECONST;
+ }
+
+ public function getRequiredHandlePHIDs() {
+ $phids = parent::getRequiredHandlePHIDs();
+
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ switch ($this->getTransactionType()) {
+ case self::TYPE_PRIMARY:
+ if ($old) {
+ $phids[] = $old;
+ }
+ if ($new) {
+ $phids[] = $new;
+ }
+ break;
+ case self::TYPE_OWNERS:
+ $add = array_diff($new, $old);
+ foreach ($add as $phid) {
+ $phids[] = $phid;
+ }
+ $rem = array_diff($old, $new);
+ foreach ($rem as $phid) {
+ $phids[] = $phid;
+ }
+ break;
+ }
+
+ return $phids;
+ }
+
+ public function shouldHide() {
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ switch ($this->getTransactionType()) {
+ case self::TYPE_DESCRIPTION:
+ return ($old === null);
+ }
+ }
+
+ public function getTitle() {
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+ $author_phid = $this->getAuthorPHID();
+
+ switch ($this->getTransactionType()) {
+ case self::TYPE_NAME:
+ if ($old === null) {
+ return pht(
+ '%s created this package.',
+ $this->renderHandleLink($author_phid));
+ } else {
+ return pht(
+ '%s renamed this package from "%s" to "%s".',
+ $this->renderHandleLink($author_phid),
+ $old,
+ $new);
+ }
+ case self::TYPE_PRIMARY:
+ return pht(
+ '%s changed the primary owner for this package from %s to %s.',
+ $this->renderHandleLink($author_phid),
+ $this->renderHandleLink($old),
+ $this->renderHandleLink($new));
+ case self::TYPE_OWNERS:
+ $add = array_diff($new, $old);
+ $rem = array_diff($old, $new);
+ if ($add && !$rem) {
+ return pht(
+ '%s added %s owner(s): %s.',
+ $this->renderHandleLink($author_phid),
+ count($add),
+ $this->renderHandleList($add));
+ } else if ($rem && !$add) {
+ return pht(
+ '%s removed %s owner(s): %s.',
+ $this->renderHandleLink($author_phid),
+ count($rem),
+ $this->renderHandleList($rem));
+ } else {
+ return pht(
+ '%s changed %s package owner(s), added %s: %s; removed %s: %s.',
+ $this->renderHandleLink($author_phid),
+ count($add) + count($rem),
+ count($add),
+ $this->renderHandleList($add),
+ count($rem),
+ $this->renderHandleList($rem));
+ }
+ case self::TYPE_AUDITING:
+ if ($new) {
+ return pht(
+ '%s enabled auditing for this package.',
+ $this->renderHandleLink($author_phid));
+ } else {
+ return pht(
+ '%s disabled auditing for this package.',
+ $this->renderHandleLink($author_phid));
+ }
+ case self::TYPE_DESCRIPTION:
+ return pht(
+ '%s updated the description for this package.',
+ $this->renderHandleLink($author_phid));
+ }
+
+ return parent::getTitle();
+ }
+
+ public function hasChangeDetails() {
+ switch ($this->getTransactionType()) {
+ case self::TYPE_DESCRIPTION:
+ return ($this->getOldValue() !== null);
+ }
+
+ return parent::hasChangeDetails();
+ }
+
+ public function renderChangeDetails(PhabricatorUser $viewer) {
+ switch ($this->getTransactionType()) {
+ case self::TYPE_DESCRIPTION:
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ return $this->renderTextCorpusChangeDetails(
+ $viewer,
+ $old,
+ $new);
+ }
+
+ return parent::renderChangeDetails($viewer);
+ }
+
+}
diff --git a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
--- a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
+++ b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
@@ -1078,6 +1078,24 @@
'Are you absolutely certain you want to destroy these objects?',
),
+ '%s added %s owner(s): %s.' => array(
+ array(
+ '%s added an owner: %3$s.',
+ '%s added owners: %3$s.',
+ ),
+ ),
+
+ '%s removed %s owner(s): %s.' => array(
+ array(
+ '%s removed an owner: %3$s.',
+ '%s removed owners: %3$s.',
+ ),
+ ),
+
+ '%s changed %s package owner(s), added %s: %s; removed %s: %s.' => array(
+ '%s changed package owners, added: %4$s; removed: %6$s.',
+ ),
+
);
}

File Metadata

Mime Type
text/plain
Expires
Fri, Mar 7, 6:12 AM (17 h, 50 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7224222
Default Alt Text
D13028.diff (28 KB)

Event Timeline