Page MenuHomePhabricator

D20713.diff
No OneTemporary

D20713.diff

diff --git a/resources/sql/autopatches/20190802.email.01.storage.sql b/resources/sql/autopatches/20190802.email.01.storage.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20190802.email.01.storage.sql
@@ -0,0 +1,12 @@
+CREATE TABLE {$NAMESPACE}_phortune.phortune_accountemail (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ phid VARBINARY(64) NOT NULL,
+ accountPHID VARBINARY(64) NOT NULL,
+ authorPHID VARBINARY(64) NOT NULL,
+ address VARCHAR(128) NOT NULL COLLATE {$COLLATE_SORT},
+ status VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT},
+ addressKey VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT},
+ accessKey VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT},
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE {$COLLATE_TEXT};
diff --git a/resources/sql/autopatches/20190802.email.02.xaction.sql b/resources/sql/autopatches/20190802.email.02.xaction.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20190802.email.02.xaction.sql
@@ -0,0 +1,19 @@
+CREATE TABLE {$NAMESPACE}_phortune.phortune_accountemailtransaction (
+ 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) NOT NULL,
+ oldValue LONGTEXT NOT NULL,
+ newValue LONGTEXT NOT NULL,
+ contentSource LONGTEXT NOT NULL,
+ metadata LONGTEXT NOT NULL,
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL,
+ UNIQUE KEY `key_phid` (`phid`),
+ KEY `key_object` (`objectPHID`)
+) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} 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
@@ -5229,6 +5229,19 @@
'PhortuneAccountEditController' => 'applications/phortune/controller/account/PhortuneAccountEditController.php',
'PhortuneAccountEditEngine' => 'applications/phortune/editor/PhortuneAccountEditEngine.php',
'PhortuneAccountEditor' => 'applications/phortune/editor/PhortuneAccountEditor.php',
+ 'PhortuneAccountEmail' => 'applications/phortune/storage/PhortuneAccountEmail.php',
+ 'PhortuneAccountEmailAddressTransaction' => 'applications/phortune/xaction/PhortuneAccountEmailAddressTransaction.php',
+ 'PhortuneAccountEmailAddressesController' => 'applications/phortune/controller/account/PhortuneAccountEmailAddressesController.php',
+ 'PhortuneAccountEmailEditController' => 'applications/phortune/controller/account/PhortuneAccountEmailEditController.php',
+ 'PhortuneAccountEmailEditEngine' => 'applications/phortune/editor/PhortuneAccountEmailEditEngine.php',
+ 'PhortuneAccountEmailEditor' => 'applications/phortune/editor/PhortuneAccountEmailEditor.php',
+ 'PhortuneAccountEmailPHIDType' => 'applications/phortune/phid/PhortuneAccountEmailPHIDType.php',
+ 'PhortuneAccountEmailQuery' => 'applications/phortune/query/PhortuneAccountEmailQuery.php',
+ 'PhortuneAccountEmailStatus' => 'applications/phortune/constants/PhortuneAccountEmailStatus.php',
+ 'PhortuneAccountEmailTransaction' => 'applications/phortune/storage/PhortuneAccountEmailTransaction.php',
+ 'PhortuneAccountEmailTransactionQuery' => 'applications/phortune/query/PhortuneAccountEmailTransactionQuery.php',
+ 'PhortuneAccountEmailTransactionType' => 'applications/phortune/xaction/PhortuneAccountEmailTransactionType.php',
+ 'PhortuneAccountEmailViewController' => 'applications/phortune/controller/account/PhortuneAccountEmailViewController.php',
'PhortuneAccountHasMemberEdgeType' => 'applications/phortune/edge/PhortuneAccountHasMemberEdgeType.php',
'PhortuneAccountListController' => 'applications/phortune/controller/account/PhortuneAccountListController.php',
'PhortuneAccountManagersController' => 'applications/phortune/controller/account/PhortuneAccountManagersController.php',
@@ -11764,6 +11777,24 @@
'PhortuneAccountEditController' => 'PhortuneController',
'PhortuneAccountEditEngine' => 'PhabricatorEditEngine',
'PhortuneAccountEditor' => 'PhabricatorApplicationTransactionEditor',
+ 'PhortuneAccountEmail' => array(
+ 'PhortuneDAO',
+ 'PhabricatorApplicationTransactionInterface',
+ 'PhabricatorPolicyInterface',
+ 'PhabricatorExtendedPolicyInterface',
+ ),
+ 'PhortuneAccountEmailAddressTransaction' => 'PhortuneAccountEmailTransactionType',
+ 'PhortuneAccountEmailAddressesController' => 'PhortuneAccountProfileController',
+ 'PhortuneAccountEmailEditController' => 'PhortuneAccountController',
+ 'PhortuneAccountEmailEditEngine' => 'PhabricatorEditEngine',
+ 'PhortuneAccountEmailEditor' => 'PhabricatorApplicationTransactionEditor',
+ 'PhortuneAccountEmailPHIDType' => 'PhabricatorPHIDType',
+ 'PhortuneAccountEmailQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+ 'PhortuneAccountEmailStatus' => 'Phobject',
+ 'PhortuneAccountEmailTransaction' => 'PhabricatorModularTransaction',
+ 'PhortuneAccountEmailTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
+ 'PhortuneAccountEmailTransactionType' => 'PhabricatorModularTransactionType',
+ 'PhortuneAccountEmailViewController' => 'PhortuneAccountController',
'PhortuneAccountHasMemberEdgeType' => 'PhabricatorEdgeType',
'PhortuneAccountListController' => 'PhortuneController',
'PhortuneAccountManagersController' => 'PhortuneAccountProfileController',
diff --git a/src/applications/phortune/application/PhabricatorPhortuneApplication.php b/src/applications/phortune/application/PhabricatorPhortuneApplication.php
--- a/src/applications/phortune/application/PhabricatorPhortuneApplication.php
+++ b/src/applications/phortune/application/PhabricatorPhortuneApplication.php
@@ -80,8 +80,18 @@
'' => 'PhortuneAccountManagersController',
'add/' => 'PhortuneAccountAddManagerController',
),
+ 'addresses/' => array(
+ '' => 'PhortuneAccountEmailAddressesController',
+ $this->getEditRoutePattern('edit/')
+ => 'PhortuneAccountEmailEditController',
+ ),
),
),
+ 'address/' => array(
+ '(?P<id>\d+)/' => 'PhortuneAccountEmailViewController',
+ $this->getEditRoutePattern('edit/')
+ => 'PhortuneAccountEmailEditController',
+ ),
'product/' => array(
'' => 'PhortuneProductListController',
'view/(?P<id>\d+)/' => 'PhortuneProductViewController',
diff --git a/src/applications/phortune/constants/PhortuneAccountEmailStatus.php b/src/applications/phortune/constants/PhortuneAccountEmailStatus.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/constants/PhortuneAccountEmailStatus.php
@@ -0,0 +1,31 @@
+<?php
+
+final class PhortuneAccountEmailStatus
+ extends Phobject {
+
+ const STATUS_ACTIVE = 'active';
+ const STATUS_DISABLED = 'disabled';
+ const STATUS_UNSUBSCRIBED = 'unsubscribed';
+
+ public static function getDefaultStatusConstant() {
+ return self::STATUS_ACTIVE;
+ }
+
+ private static function getMap() {
+ return array(
+ self::STATUS_ACTIVE => array(
+ 'name' => pht('Active'),
+ 'closed' => false,
+ ),
+ self::STATUS_DISABLED => array(
+ 'name' => pht('Disabled'),
+ 'closed' => true,
+ ),
+ self::STATUS_UNSUBSCRIBED => array(
+ 'name' => pht('Unsubscribed'),
+ 'closed' => true,
+ ),
+ );
+ }
+
+}
diff --git a/src/applications/phortune/controller/account/PhortuneAccountController.php b/src/applications/phortune/controller/account/PhortuneAccountController.php
--- a/src/applications/phortune/controller/account/PhortuneAccountController.php
+++ b/src/applications/phortune/controller/account/PhortuneAccountController.php
@@ -9,6 +9,11 @@
return $this->account;
}
+ protected function setAccount(PhortuneAccount $account) {
+ $this->account = $account;
+ return $this;
+ }
+
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
@@ -29,7 +34,6 @@
return $this->loadAccountForEdit();
}
-
protected function loadAccountForEdit() {
$viewer = $this->getViewer();
$request = $this->getRequest();
diff --git a/src/applications/phortune/controller/account/PhortuneAccountEmailAddressesController.php b/src/applications/phortune/controller/account/PhortuneAccountEmailAddressesController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/controller/account/PhortuneAccountEmailAddressesController.php
@@ -0,0 +1,90 @@
+<?php
+
+final class PhortuneAccountEmailAddressesController
+ extends PhortuneAccountProfileController {
+
+ public function handleRequest(AphrontRequest $request) {
+ $response = $this->loadAccount();
+ if ($response) {
+ return $response;
+ }
+
+ $account = $this->getAccount();
+ $title = $account->getName();
+
+ $crumbs = $this->buildApplicationCrumbs();
+ $crumbs->addTextCrumb(pht('Email Addresses'));
+
+ $header = $this->buildHeaderView();
+ $addresses = $this->buildAddressesSection($account);
+
+ $view = id(new PHUITwoColumnView())
+ ->setHeader($header)
+ ->setFooter(
+ array(
+ $addresses,
+ ));
+
+ $navigation = $this->buildSideNavView('addresses');
+
+ return $this->newPage()
+ ->setTitle($title)
+ ->setCrumbs($crumbs)
+ ->setNavigation($navigation)
+ ->appendChild($view);
+ }
+
+ private function buildAddressesSection(PhortuneAccount $account) {
+ $viewer = $this->getViewer();
+
+ $can_edit = PhabricatorPolicyFilter::hasCapability(
+ $viewer,
+ $account,
+ PhabricatorPolicyCapability::CAN_EDIT);
+
+ $id = $account->getID();
+
+ $add = id(new PHUIButtonView())
+ ->setTag('a')
+ ->setText(pht('Add Address'))
+ ->setIcon('fa-plus')
+ ->setWorkflow(!$can_edit)
+ ->setDisabled(!$can_edit)
+ ->setHref("/phortune/account/{$id}/addresses/edit/");
+
+ $header = id(new PHUIHeaderView())
+ ->setHeader(pht('Billing Email Addresses'))
+ ->addActionLink($add);
+
+ $addresses = id(new PhortuneAccountEmailQuery())
+ ->setViewer($viewer)
+ ->withAccountPHIDs(array($account->getPHID()))
+ ->execute();
+
+ $list = id(new PHUIObjectItemListView())
+ ->setUser($viewer)
+ ->setNoDataString(
+ pht(
+ 'There are no billing email addresses associated '.
+ 'with this account.'));
+
+ $addresses = id(new PhortuneAccountEmailQuery())
+ ->setViewer($viewer)
+ ->withAccountPHIDs(array($account->getPHID()))
+ ->execute();
+ foreach ($addresses as $address) {
+ $item = id(new PHUIObjectItemView())
+ ->setObjectName($address->getObjectName())
+ ->setHeader($address->getAddress())
+ ->setHref($address->getURI());
+
+ $list->addItem($item);
+ }
+
+ return id(new PHUIObjectBoxView())
+ ->setHeader($header)
+ ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
+ ->setObjectList($list);
+ }
+
+}
diff --git a/src/applications/phortune/controller/account/PhortuneAccountEmailEditController.php b/src/applications/phortune/controller/account/PhortuneAccountEmailEditController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/controller/account/PhortuneAccountEmailEditController.php
@@ -0,0 +1,28 @@
+<?php
+
+final class PhortuneAccountEmailEditController
+ extends PhortuneAccountController {
+
+ public function handleRequest(AphrontRequest $request) {
+ $engine = id(new PhortuneAccountEmailEditEngine())
+ ->setController($this);
+
+ if (!$request->getURIData('id')) {
+
+ if (!$request->getURIData('accountID')) {
+ return new Aphront404Response();
+ }
+
+ $response = $this->loadAccount();
+ if ($response) {
+ return $response;
+ }
+
+ $account = $this->getAccount();
+
+ $engine->setAccount($account);
+ }
+
+ return $engine->buildResponse();
+ }
+}
diff --git a/src/applications/phortune/controller/account/PhortuneAccountEmailViewController.php b/src/applications/phortune/controller/account/PhortuneAccountEmailViewController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/controller/account/PhortuneAccountEmailViewController.php
@@ -0,0 +1,93 @@
+<?php
+
+final class PhortuneAccountEmailViewController
+ extends PhortuneAccountController {
+
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->getViewer();
+
+ $address = id(new PhortuneAccountEmailQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($request->getURIData('id')))
+ ->executeOne();
+ if (!$address) {
+ return new Aphront404Response();
+ }
+
+ $account = $address->getAccount();
+ $this->setAccount($account);
+
+ $crumbs = $this->buildApplicationCrumbs()
+ ->addTextCrumb(pht('Email Addresses'), $account->getEmailAddressesURI())
+ ->addTextCrumb($address->getObjectName())
+ ->setBorder(true);
+
+ $header = id(new PHUIHeaderView())
+ ->setHeader(pht('Account Email: %s', $address->getAddress()));
+
+ $details = $this->newDetailsView($address);
+
+ $timeline = $this->buildTransactionTimeline(
+ $address,
+ new PhortuneAccountEmailTransactionQuery());
+ $timeline->setShouldTerminate(true);
+
+ $curtain = $this->buildCurtainView($address);
+
+ $view = id(new PHUITwoColumnView())
+ ->setHeader($header)
+ ->setCurtain($curtain)
+ ->setMainColumn(
+ array(
+ $details,
+ $timeline,
+ ));
+
+ return $this->newPage()
+ ->setTitle($address->getObjectName())
+ ->setCrumbs($crumbs)
+ ->appendChild($view);
+
+ }
+
+ private function buildCurtainView(PhortuneAccountEmail $address) {
+ $viewer = $this->getViewer();
+ $account = $address->getAccount();
+
+ $can_edit = PhabricatorPolicyFilter::hasCapability(
+ $viewer,
+ $address,
+ PhabricatorPolicyCapability::CAN_EDIT);
+
+ $edit_uri = $this->getApplicationURI(
+ urisprintf(
+ 'address/edit/%d/',
+ $address->getID()));
+
+ $curtain = $this->newCurtainView($account);
+
+ $curtain->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Edit Address'))
+ ->setIcon('fa-pencil')
+ ->setHref($edit_uri)
+ ->setDisabled(!$can_edit)
+ ->setWorkflow(!$can_edit));
+
+ return $curtain;
+ }
+
+ private function newDetailsView(PhortuneAccountEmail $address) {
+ $viewer = $this->getViewer();
+
+ $view = id(new PHUIPropertyListView())
+ ->setUser($viewer);
+
+ $view->addProperty(pht('Email Address'), $address->getAddress());
+
+ return id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Email Address Details'))
+ ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
+ ->addPropertyList($view);
+ }
+}
diff --git a/src/applications/phortune/controller/account/PhortuneAccountProfileController.php b/src/applications/phortune/controller/account/PhortuneAccountProfileController.php
--- a/src/applications/phortune/controller/account/PhortuneAccountProfileController.php
+++ b/src/applications/phortune/controller/account/PhortuneAccountProfileController.php
@@ -82,6 +82,12 @@
$this->getApplicationURI("/account/{$id}/managers/"),
'fa-group');
+ $nav->addFilter(
+ 'addresses',
+ pht('Email Addresses'),
+ $this->getApplicationURI("/account/{$id}/addresses/"),
+ 'fa-envelope-o');
+
$nav->selectFilter($filter);
return $nav;
diff --git a/src/applications/phortune/editor/PhortuneAccountEmailEditEngine.php b/src/applications/phortune/editor/PhortuneAccountEmailEditEngine.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/editor/PhortuneAccountEmailEditEngine.php
@@ -0,0 +1,114 @@
+<?php
+
+final class PhortuneAccountEmailEditEngine
+ extends PhabricatorEditEngine {
+
+ const ENGINECONST = 'phortune.account.email';
+
+ private $account;
+
+ public function setAccount(PhortuneAccount $account) {
+ $this->account = $account;
+ return $this;
+ }
+
+ public function getAccount() {
+ return $this->account;
+ }
+
+ public function getEngineName() {
+ return pht('Phortune Account Emails');
+ }
+
+ public function getEngineApplicationClass() {
+ return 'PhabricatorPhortuneApplication';
+ }
+
+ public function getSummaryHeader() {
+ return pht('Configure Phortune Account Email Forms');
+ }
+
+ public function getSummaryText() {
+ return pht(
+ 'Configure creation and editing forms for Phortune Account '.
+ 'Email Addresses.');
+ }
+
+ public function isEngineConfigurable() {
+ return false;
+ }
+
+ protected function newEditableObject() {
+ $viewer = $this->getViewer();
+
+ $account = $this->getAccount();
+ if (!$account) {
+ $account = new PhortuneAccount();
+ }
+
+ return PhortuneAccountEmail::initializeNewAddress(
+ $account,
+ $viewer->getPHID());
+ }
+
+ protected function newObjectQuery() {
+ return new PhortuneAccountEmailQuery();
+ }
+
+ protected function getObjectCreateTitleText($object) {
+ return pht('Add Email Address');
+ }
+
+ protected function getObjectEditTitleText($object) {
+ return pht('Edit Account Email: %s', $object->getAddress());
+ }
+
+ protected function getObjectEditShortText($object) {
+ return pht('%s', $object->getAddress());
+ }
+
+ protected function getObjectCreateShortText() {
+ return pht('Add Email Address');
+ }
+
+ protected function getObjectName() {
+ return pht('Account Email');
+ }
+
+ protected function getObjectCreateCancelURI($object) {
+ return $this->getAccount()->getEmailAddressesURI();
+ }
+
+ protected function getEditorURI() {
+ return $this->getApplication()->getApplicationURI('address/edit/');
+ }
+
+ protected function getObjectViewURI($object) {
+ return $object->getURI();
+ }
+
+ protected function buildCustomEditFields($object) {
+ $viewer = $this->getViewer();
+
+ if ($this->getIsCreate()) {
+ $address_field = id(new PhabricatorTextEditField())
+ ->setTransactionType(
+ PhortuneAccountEmailAddressTransaction::TRANSACTIONTYPE)
+ ->setIsRequired(true);
+ } else {
+ $address_field = new PhabricatorStaticEditField();
+ }
+
+ $address_field
+ ->setKey('address')
+ ->setLabel(pht('Email Address'))
+ ->setDescription(pht('Email address.'))
+ ->setConduitTypeDescription(pht('New email address.'))
+ ->setValue($object->getAddress());
+
+ return array(
+ $address_field,
+ );
+ }
+
+}
diff --git a/src/applications/phortune/editor/PhortuneAccountEmailEditor.php b/src/applications/phortune/editor/PhortuneAccountEmailEditor.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/editor/PhortuneAccountEmailEditor.php
@@ -0,0 +1,36 @@
+<?php
+
+final class PhortuneAccountEmailEditor
+ extends PhabricatorApplicationTransactionEditor {
+
+ public function getEditorApplicationClass() {
+ return 'PhabricatorPhortuneApplication';
+ }
+
+ public function getEditorObjectsDescription() {
+ return pht('Phortune Account Emails');
+ }
+
+ public function getCreateObjectTitle($author, $object) {
+ return pht('%s created this account email.', $author);
+ }
+
+ protected function didCatchDuplicateKeyException(
+ PhabricatorLiskDAO $object,
+ array $xactions,
+ Exception $ex) {
+
+ $errors = array();
+
+ $errors[] = new PhabricatorApplicationTransactionValidationError(
+ PhortuneAccountEmailAddressTransaction::TRANSACTIONTYPE,
+ pht('Duplicate'),
+ pht(
+ 'The email address "%s" is already attached to this account.',
+ $object->getAddress()),
+ null);
+
+ throw new PhabricatorApplicationTransactionValidationException($errors);
+ }
+
+}
diff --git a/src/applications/phortune/phid/PhortuneAccountEmailPHIDType.php b/src/applications/phortune/phid/PhortuneAccountEmailPHIDType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/phid/PhortuneAccountEmailPHIDType.php
@@ -0,0 +1,41 @@
+<?php
+
+final class PhortuneAccountEmailPHIDType extends PhabricatorPHIDType {
+
+ const TYPECONST = 'AEML';
+
+ public function getTypeName() {
+ return pht('Phortune Account Email');
+ }
+
+ public function newObject() {
+ return new PhortuneAccountEmail();
+ }
+
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorPhortuneApplication';
+ }
+
+ protected function buildQueryForObjects(
+ PhabricatorObjectQuery $query,
+ array $phids) {
+
+ return id(new PhortuneAccountEmailQuery())
+ ->withPHIDs($phids);
+ }
+
+ public function loadHandles(
+ PhabricatorHandleQuery $query,
+ array $handles,
+ array $objects) {
+
+ foreach ($handles as $phid => $handle) {
+ $email = $objects[$phid];
+
+ $id = $email->getID();
+
+ $handle->setName($email->getObjectName());
+ }
+ }
+
+}
diff --git a/src/applications/phortune/query/PhortuneAccountEmailQuery.php b/src/applications/phortune/query/PhortuneAccountEmailQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/query/PhortuneAccountEmailQuery.php
@@ -0,0 +1,91 @@
+<?php
+
+final class PhortuneAccountEmailQuery
+ extends PhabricatorCursorPagedPolicyAwareQuery {
+
+ private $ids;
+ private $phids;
+ private $accountPHIDs;
+
+ public function withIDs(array $ids) {
+ $this->ids = $ids;
+ return $this;
+ }
+
+ public function withPHIDs(array $phids) {
+ $this->phids = $phids;
+ return $this;
+ }
+
+ public function withAccountPHIDs(array $phids) {
+ $this->accountPHIDs = $phids;
+ return $this;
+ }
+
+ public function newResultObject() {
+ return new PhortuneAccountEmail();
+ }
+
+ protected function loadPage() {
+ return $this->loadStandardPage($this->newResultObject());
+ }
+
+ protected function willFilterPage(array $addresses) {
+ $accounts = id(new PhortuneAccountQuery())
+ ->setViewer($this->getViewer())
+ ->setParentQuery($this)
+ ->withPHIDs(mpull($addresses, 'getAccountPHID'))
+ ->execute();
+ $accounts = mpull($accounts, null, 'getPHID');
+
+ foreach ($addresses as $key => $address) {
+ $account = idx($accounts, $address->getAccountPHID());
+
+ if (!$account) {
+ $this->didRejectResult($addresses[$key]);
+ unset($addresses[$key]);
+ continue;
+ }
+
+ $address->attachAccount($account);
+ }
+
+ return $addresses;
+ }
+
+ protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
+ $where = parent::buildWhereClauseParts($conn);
+
+ if ($this->ids !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'address.id IN (%Ld)',
+ $this->ids);
+ }
+
+ if ($this->phids !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'address.phid IN (%Ls)',
+ $this->phids);
+ }
+
+ if ($this->accountPHIDs !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'address.accountPHID IN (%Ls)',
+ $this->accountPHIDs);
+ }
+
+ return $where;
+ }
+
+ public function getQueryApplicationClass() {
+ return 'PhabricatorPhortuneApplication';
+ }
+
+ protected function getPrimaryTableAlias() {
+ return 'address';
+ }
+
+}
diff --git a/src/applications/phortune/query/PhortuneAccountEmailTransactionQuery.php b/src/applications/phortune/query/PhortuneAccountEmailTransactionQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/query/PhortuneAccountEmailTransactionQuery.php
@@ -0,0 +1,10 @@
+<?php
+
+final class PhortuneAccountEmailTransactionQuery
+ extends PhabricatorApplicationTransactionQuery {
+
+ public function getTemplateApplicationTransaction() {
+ return new PhortuneAccountEmailTransaction();
+ }
+
+}
diff --git a/src/applications/phortune/storage/PhortuneAccount.php b/src/applications/phortune/storage/PhortuneAccount.php
--- a/src/applications/phortune/storage/PhortuneAccount.php
+++ b/src/applications/phortune/storage/PhortuneAccount.php
@@ -109,6 +109,12 @@
$this->getID());
}
+ public function getEmailAddressesURI() {
+ return urisprintf(
+ '/phortune/account/%d/addresses/',
+ $this->getID());
+ }
+
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
diff --git a/src/applications/phortune/storage/PhortuneAccountEmail.php b/src/applications/phortune/storage/PhortuneAccountEmail.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/storage/PhortuneAccountEmail.php
@@ -0,0 +1,121 @@
+<?php
+
+final class PhortuneAccountEmail
+ extends PhortuneDAO
+ implements
+ PhabricatorApplicationTransactionInterface,
+ PhabricatorPolicyInterface,
+ PhabricatorExtendedPolicyInterface {
+
+ protected $accountPHID;
+ protected $authorPHID;
+ protected $address;
+ protected $status;
+ protected $addressKey;
+ protected $accessKey;
+
+ private $account = self::ATTACHABLE;
+
+ protected function getConfiguration() {
+ return array(
+ self::CONFIG_AUX_PHID => true,
+ self::CONFIG_COLUMN_SCHEMA => array(
+ 'address' => 'sort128',
+ 'status' => 'text32',
+ 'addressKey' => 'text32',
+ 'accessKey' => 'text32',
+ ),
+ self::CONFIG_KEY_SCHEMA => array(
+ 'key_account' => array(
+ 'columns' => array('accountPHID', 'address'),
+ 'unique' => true,
+ ),
+ 'key_address' => array(
+ 'columns' => array('addressKey'),
+ ),
+ ),
+ ) + parent::getConfiguration();
+ }
+
+ public function getPHIDType() {
+ return PhortuneAccountEmailPHIDType::TYPECONST;
+ }
+
+ public static function initializeNewAddress(
+ PhortuneAccount $account,
+ $author_phid) {
+
+ $address_key = Filesystem::readRandomCharacters(16);
+ $access_key = Filesystem::readRandomCharacters(16);
+ $default_status = PhortuneAccountEmailStatus::getDefaultStatusConstant();
+
+ return id(new self())
+ ->setAuthorPHID($author_phid)
+ ->setAccountPHID($account->getPHID())
+ ->setStatus($default_status)
+ ->attachAccount($account)
+ ->setAddressKey($address_key)
+ ->setAccessKey($access_key);
+ }
+
+ public function attachAccount(PhortuneAccount $account) {
+ $this->account = $account;
+ return $this;
+ }
+
+ public function getAccount() {
+ return $this->assertAttached($this->account);
+ }
+
+ public function getObjectName() {
+ return pht('Account Email %d', $this->getID());
+ }
+
+ public function getURI() {
+ return urisprintf(
+ '/phortune/address/%d/',
+ $this->getID());
+ }
+
+
+/* -( PhabricatorPolicyInterface )----------------------------------------- */
+
+
+ public function getCapabilities() {
+ return array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ );
+ }
+
+ public function getPolicy($capability) {
+ return PhabricatorPolicies::getMostOpenPolicy();
+ }
+
+ public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
+ return false;
+ }
+
+
+/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
+
+
+ public function getExtendedPolicy($capability, PhabricatorUser $viewer) {
+ return array(
+ array($this->getAccount(), $capability),
+ );
+ }
+
+
+/* -( PhabricatorApplicationTransactionInterface )------------------------- */
+
+
+ public function getApplicationTransactionEditor() {
+ return new PhortuneAccountEmailEditor();
+ }
+
+ public function getApplicationTransactionTemplate() {
+ return new PhortuneAccountEmailTransaction();
+ }
+
+}
diff --git a/src/applications/phortune/storage/PhortuneAccountEmailTransaction.php b/src/applications/phortune/storage/PhortuneAccountEmailTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/storage/PhortuneAccountEmailTransaction.php
@@ -0,0 +1,18 @@
+<?php
+
+final class PhortuneAccountEmailTransaction
+ extends PhabricatorModularTransaction {
+
+ public function getApplicationName() {
+ return 'phortune';
+ }
+
+ public function getApplicationTransactionType() {
+ return PhortuneAccountEmailPHIDType::TYPECONST;
+ }
+
+ public function getBaseTransactionClass() {
+ return 'PhortuneAccountEmailTransactionType';
+ }
+
+}
diff --git a/src/applications/phortune/xaction/PhortuneAccountEmailAddressTransaction.php b/src/applications/phortune/xaction/PhortuneAccountEmailAddressTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/xaction/PhortuneAccountEmailAddressTransaction.php
@@ -0,0 +1,63 @@
+<?php
+
+final class PhortuneAccountEmailAddressTransaction
+ extends PhortuneAccountEmailTransactionType {
+
+ const TRANSACTIONTYPE = 'address';
+
+ public function generateOldValue($object) {
+ return $object->getAddress();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setAddress($value);
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+
+ if ($this->isEmptyTextTransaction($object->getAddress(), $xactions)) {
+ $errors[] = $this->newRequiredError(
+ pht('You must provide an email address.'));
+ }
+
+ $max_length = $object->getColumnMaximumByteLength('address');
+ foreach ($xactions as $xaction) {
+ $old_value = $xaction->getOldValue();
+ $new_value = $xaction->getNewValue();
+
+ $new_length = strlen($new_value);
+ if ($new_length > $max_length) {
+ $errors[] = $this->newInvalidError(
+ pht(
+ 'The address can be no longer than %s characters.',
+ new PhutilNumber($max_length)),
+ $xaction);
+ continue;
+ }
+
+ if (!PhabricatorUserEmail::isValidAddress($new_value)) {
+ $errors[] = $this->newInvalidError(
+ PhabricatorUserEmail::describeValidAddresses(),
+ $xaction);
+ continue;
+ }
+
+ if ($new_value !== $old_value) {
+ if (!$this->isNewObject()) {
+ $errors[] = $this->newInvalidError(
+ pht(
+ 'Account email addresses can not be edited once they are '.
+ 'created. To change the billing address for an account, '.
+ 'disable the old address and then add a new address.'),
+ $xaction);
+ continue;
+ }
+ }
+
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/phortune/xaction/PhortuneAccountEmailTransactionType.php b/src/applications/phortune/xaction/PhortuneAccountEmailTransactionType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/xaction/PhortuneAccountEmailTransactionType.php
@@ -0,0 +1,4 @@
+<?php
+
+abstract class PhortuneAccountEmailTransactionType
+ extends PhabricatorModularTransactionType {}

File Metadata

Mime Type
text/plain
Expires
May 13 2024, 9:55 AM (4 w, 5 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6292636
Default Alt Text
D20713.diff (30 KB)

Event Timeline