diff --git a/resources/sql/autopatches/20150611.spaces.2.appmail.sql b/resources/sql/autopatches/20150611.spaces.2.appmail.sql new file mode 100644 index 0000000000..c846e4338f --- /dev/null +++ b/resources/sql/autopatches/20150611.spaces.2.appmail.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_metamta.metamta_applicationemail + ADD spacePHID VARBINARY(64); diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index ccd860a69a..80cf17dcbc 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -5498,6 +5498,7 @@ phutil_register_library_map(array( 'PhabricatorPolicyInterface', 'PhabricatorApplicationTransactionInterface', 'PhabricatorDestructibleInterface', + 'PhabricatorSpacesInterface', ), 'PhabricatorMetaMTAApplicationEmailDatasource' => 'PhabricatorTypeaheadDatasource', 'PhabricatorMetaMTAApplicationEmailEditor' => 'PhabricatorApplicationTransactionEditor', diff --git a/src/applications/maniphest/storage/ManiphestTask.php b/src/applications/maniphest/storage/ManiphestTask.php index f244a1c918..7fbc806bae 100644 --- a/src/applications/maniphest/storage/ManiphestTask.php +++ b/src/applications/maniphest/storage/ManiphestTask.php @@ -58,6 +58,7 @@ final class ManiphestTask extends ManiphestDAO ->setAuthorPHID($actor->getPHID()) ->setViewPolicy($view_policy) ->setEditPolicy($edit_policy) + ->setSpacePHID($actor->getDefaultSpacePHID()) ->attachProjectPHIDs(array()) ->attachSubscriberPHIDs(array()); } diff --git a/src/applications/metamta/applicationpanel/PhabricatorMetaMTAApplicationEmailPanel.php b/src/applications/metamta/applicationpanel/PhabricatorMetaMTAApplicationEmailPanel.php index e88e2210d8..6a3499300b 100644 --- a/src/applications/metamta/applicationpanel/PhabricatorMetaMTAApplicationEmailPanel.php +++ b/src/applications/metamta/applicationpanel/PhabricatorMetaMTAApplicationEmailPanel.php @@ -16,24 +16,7 @@ final class PhabricatorMetaMTAApplicationEmailPanel $viewer = $this->getViewer(); $application = $this->getApplication(); - $addresses = id(new PhabricatorMetaMTAApplicationEmailQuery()) - ->setViewer($viewer) - ->withApplicationPHIDs(array($application->getPHID())) - ->execute(); - - $rows = array(); - foreach ($addresses as $address) { - $rows[] = array( - $address->getAddress(), - ); - } - - $table = id(new AphrontTableView($rows)) - ->setNoDataString(pht('No email addresses configured.')) - ->setHeaders( - array( - pht('Address'), - )); + $table = $this->buildEmailTable($is_edit = false, null); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, @@ -91,68 +74,10 @@ final class PhabricatorMetaMTAApplicationEmailPanel return $this->returnDeleteAddressResponse($request, $uri, $delete); } - $emails = id(new PhabricatorMetaMTAApplicationEmailQuery()) - ->setViewer($viewer) - ->withApplicationPHIDs(array($application->getPHID())) - ->execute(); + $table = $this->buildEmailTable( + $is_edit = true, + $request->getInt('id')); - $highlight = $request->getInt('highlight'); - $rowc = array(); - $rows = array(); - foreach ($emails as $email) { - - $button_edit = javelin_tag( - 'a', - array( - 'class' => 'button small grey', - 'href' => $uri->alter('edit', $email->getID()), - 'sigil' => 'workflow', - ), - pht('Edit')); - - $button_remove = javelin_tag( - 'a', - array( - 'class' => 'button small grey', - 'href' => $uri->alter('delete', $email->getID()), - 'sigil' => 'workflow', - ), - pht('Delete')); - - if ($highlight == $email->getID()) { - $rowc[] = 'highlighted'; - } else { - $rowc[] = null; - } - - $rows[] = array( - $email->getAddress(), - $button_edit, - $button_remove, - ); - } - - $table = id(new AphrontTableView($rows)) - ->setNoDataString(pht('No application emails created yet.')); - $table->setHeaders( - array( - pht('Email'), - pht('Edit'), - pht('Delete'), - )); - $table->setColumnClasses( - array( - 'wide', - 'action', - 'action', - )); - $table->setRowClasses($rowc); - $table->setColumnVisibility( - array( - true, - true, - true, - )); $form = id(new AphrontFormView()) ->setUser($viewer); @@ -246,6 +171,8 @@ final class PhabricatorMetaMTAApplicationEmailPanel $e_email = true; $v_email = $email_object->getAddress(); + $e_space = null; + $v_space = $email_object->getSpacePHID(); $v_default = $email_object->getConfigValue($config_default); $validation_exception = null; @@ -253,11 +180,13 @@ final class PhabricatorMetaMTAApplicationEmailPanel $e_email = null; $v_email = trim($request->getStr('email')); + $v_space = $request->getStr('spacePHID'); $v_default = $request->getArr($config_default); $v_default = nonempty(head($v_default), null); $type_address = PhabricatorMetaMTAApplicationEmailTransaction::TYPE_ADDRESS; + $type_space = PhabricatorTransactions::TYPE_SPACE; $type_config = PhabricatorMetaMTAApplicationEmailTransaction::TYPE_CONFIG; @@ -269,6 +198,10 @@ final class PhabricatorMetaMTAApplicationEmailPanel ->setTransactionType($type_address) ->setNewValue($v_email); + $xactions[] = id(new PhabricatorMetaMTAApplicationEmailTransaction()) + ->setTransactionType($type_space) + ->setNewValue($v_space); + $xactions[] = id(new PhabricatorMetaMTAApplicationEmailTransaction()) ->setTransactionType($type_config) ->setMetadataValue($key_config, $config_default) @@ -287,6 +220,7 @@ final class PhabricatorMetaMTAApplicationEmailPanel } catch (PhabricatorApplicationTransactionValidationException $ex) { $validation_exception = $ex; $e_email = $ex->getShortMessage($type_address); + $e_space = $ex->getShortMessage($type_space); } } @@ -303,7 +237,22 @@ final class PhabricatorMetaMTAApplicationEmailPanel ->setLabel(pht('Email')) ->setName('email') ->setValue($v_email) - ->setError($e_email)) + ->setError($e_email)); + + if (PhabricatorSpacesNamespaceQuery::getViewerSpacesExist($viewer)) { + $form->appendControl( + id(new AphrontFormSelectControl()) + ->setLabel(pht('Space')) + ->setName('spacePHID') + ->setValue($v_space) + ->setError($e_space) + ->setOptions( + PhabricatorSpacesNamespaceQuery::getSpaceOptionsForViewer( + $viewer, + $v_space))); + } + + $form ->appendControl( id(new AphrontFormTokenizerControl()) ->setDatasource(new PhabricatorPeopleDatasource()) @@ -374,4 +323,85 @@ final class PhabricatorMetaMTAApplicationEmailPanel return id(new AphrontDialogResponse())->setDialog($dialog); } + private function buildEmailTable($is_edit, $highlight) { + $viewer = $this->getViewer(); + $application = $this->getApplication(); + $uri = new PhutilURI($this->getPanelURI()); + + $emails = id(new PhabricatorMetaMTAApplicationEmailQuery()) + ->setViewer($viewer) + ->withApplicationPHIDs(array($application->getPHID())) + ->execute(); + + $rowc = array(); + $rows = array(); + foreach ($emails as $email) { + + $button_edit = javelin_tag( + 'a', + array( + 'class' => 'button small grey', + 'href' => $uri->alter('edit', $email->getID()), + 'sigil' => 'workflow', + ), + pht('Edit')); + + $button_remove = javelin_tag( + 'a', + array( + 'class' => 'button small grey', + 'href' => $uri->alter('delete', $email->getID()), + 'sigil' => 'workflow', + ), + pht('Delete')); + + if ($highlight == $email->getID()) { + $rowc[] = 'highlighted'; + } else { + $rowc[] = null; + } + + $space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID($email); + if ($space_phid) { + $email_space = $viewer->renderHandle($space_phid); + } else { + $email_space = null; + } + + $rows[] = array( + $email_space, + $email->getAddress(), + $button_edit, + $button_remove, + ); + } + + $table = id(new AphrontTableView($rows)) + ->setNoDataString(pht('No application emails created yet.')); + $table->setHeaders( + array( + pht('Space'), + pht('Email'), + pht('Edit'), + pht('Delete'), + )); + $table->setColumnClasses( + array( + '', + 'wide', + 'action', + 'action', + )); + $table->setRowClasses($rowc); + $table->setColumnVisibility( + array( + PhabricatorSpacesNamespaceQuery::getViewerSpacesExist($viewer), + true, + $is_edit, + $is_edit, + )); + + return $table; + } + } diff --git a/src/applications/metamta/query/PhabricatorMetaMTAApplicationEmailQuery.php b/src/applications/metamta/query/PhabricatorMetaMTAApplicationEmailQuery.php index b173224914..9c0c5d941a 100644 --- a/src/applications/metamta/query/PhabricatorMetaMTAApplicationEmailQuery.php +++ b/src/applications/metamta/query/PhabricatorMetaMTAApplicationEmailQuery.php @@ -35,19 +35,7 @@ final class PhabricatorMetaMTAApplicationEmailQuery } protected function loadPage() { - $table = new PhabricatorMetaMTAApplicationEmail(); - $conn_r = $table->establishConnection('r'); - - $data = queryfx_all( - $conn_r, - 'SELECT * FROM %T appemail %Q %Q %Q %Q', - $table->getTableName(), - $this->buildWhereClause($conn_r), - $this->buildApplicationSearchGroupClause($conn_r), - $this->buildOrderClause($conn_r), - $this->buildLimitClause($conn_r)); - - return $table->loadAllFromArray($data); + return $this->loadStandardPage(new PhabricatorMetaMTAApplicationEmail()); } protected function willFilterPage(array $app_emails) { @@ -71,47 +59,45 @@ final class PhabricatorMetaMTAApplicationEmailQuery return $app_emails; } - protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { - $where = array(); + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { + $where = parent::buildWhereClauseParts($conn); if ($this->addresses !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'appemail.address IN (%Ls)', $this->addresses); } if ($this->addressPrefix !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'appemail.address LIKE %>', $this->addressPrefix); } if ($this->applicationPHIDs !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'appemail.applicationPHID IN (%Ls)', $this->applicationPHIDs); } if ($this->phids !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'appemail.phid IN (%Ls)', $this->phids); } if ($this->ids !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'appemail.id IN (%Ld)', $this->ids); } - $where[] = $this->buildPagingClause($conn_r); - - return $this->formatWhereClause($where); + return $where; } protected function getPrimaryTableAlias() { diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAApplicationEmail.php b/src/applications/metamta/storage/PhabricatorMetaMTAApplicationEmail.php index bb693c8d98..fb70b377a7 100644 --- a/src/applications/metamta/storage/PhabricatorMetaMTAApplicationEmail.php +++ b/src/applications/metamta/storage/PhabricatorMetaMTAApplicationEmail.php @@ -5,11 +5,13 @@ final class PhabricatorMetaMTAApplicationEmail implements PhabricatorPolicyInterface, PhabricatorApplicationTransactionInterface, - PhabricatorDestructibleInterface { + PhabricatorDestructibleInterface, + PhabricatorSpacesInterface { protected $applicationPHID; protected $address; protected $configData; + protected $spacePHID; private $application = self::ATTACHABLE; @@ -43,6 +45,7 @@ final class PhabricatorMetaMTAApplicationEmail public static function initializeNewAppEmail(PhabricatorUser $actor) { return id(new PhabricatorMetaMTAApplicationEmail()) + ->setSpacePHID($actor->getDefaultSpacePHID()) ->setConfigData(array()); } @@ -143,4 +146,12 @@ final class PhabricatorMetaMTAApplicationEmail $this->delete(); } + +/* -( PhabricatorSpacesInterface )----------------------------------------- */ + + + public function getSpacePHID() { + return $this->spacePHID; + } + } diff --git a/src/applications/paste/storage/PhabricatorPaste.php b/src/applications/paste/storage/PhabricatorPaste.php index da129b8cf4..661701ba09 100644 --- a/src/applications/paste/storage/PhabricatorPaste.php +++ b/src/applications/paste/storage/PhabricatorPaste.php @@ -38,7 +38,8 @@ final class PhabricatorPaste extends PhabricatorPasteDAO ->setTitle('') ->setAuthorPHID($actor->getPHID()) ->setViewPolicy($view_policy) - ->setEditPolicy($edit_policy); + ->setEditPolicy($edit_policy) + ->setSpacePHID($actor->getDefaultSpacePHID()); } public function getURI() { diff --git a/src/applications/pholio/storage/PholioMock.php b/src/applications/pholio/storage/PholioMock.php index aaebed878e..22c1015704 100644 --- a/src/applications/pholio/storage/PholioMock.php +++ b/src/applications/pholio/storage/PholioMock.php @@ -48,7 +48,8 @@ final class PholioMock extends PholioDAO ->attachImages(array()) ->setStatus(self::STATUS_OPEN) ->setViewPolicy($view_policy) - ->setEditPolicy($edit_policy); + ->setEditPolicy($edit_policy) + ->setSpacePHID($actor->getDefaultSpacePHID()); } public function getMonogram() { diff --git a/src/applications/spaces/query/PhabricatorSpacesNamespaceQuery.php b/src/applications/spaces/query/PhabricatorSpacesNamespaceQuery.php index 51ac66130a..65ac146bd0 100644 --- a/src/applications/spaces/query/PhabricatorSpacesNamespaceQuery.php +++ b/src/applications/spaces/query/PhabricatorSpacesNamespaceQuery.php @@ -170,6 +170,31 @@ final class PhabricatorSpacesNamespaceQuery return $spaces; } + public static function getSpaceOptionsForViewer( + PhabricatorUser $viewer, + $space_phid) { + + $viewer_spaces = self::getViewerSpaces($viewer); + + $map = array(); + foreach ($viewer_spaces as $space) { + + // Skip archived spaces, unless the object is already in that space. + if ($space->getIsArchived()) { + if ($space->getPHID() != $space_phid) { + continue; + } + } + + $map[$space->getPHID()] = pht( + 'Space %s: %s', + $space->getMonogram(), + $space->getNamespaceName()); + } + asort($map); + + return $map; + } /** diff --git a/src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php b/src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php index 14e27edc73..82f3eca2cc 100644 --- a/src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php +++ b/src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php @@ -56,6 +56,22 @@ abstract class PhabricatorApplicationTransactionReplyHandler final protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail) { $viewer = $this->getActor(); $object = $this->getMailReceiver(); + $app_email = $this->getApplicationEmail(); + + $is_new = !$object->getID(); + + // If this is a new object which implements the Spaces interface and was + // created by sending mail to an ApplicationEmail address, put the object + // in the same Space the address is in. + if ($is_new) { + if ($object instanceof PhabricatorSpacesInterface) { + if ($app_email) { + $space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID( + $app_email); + $object->setSpacePHID($space_phid); + } + } + } $body_data = $mail->parseBody(); $body = $body_data['body']; diff --git a/src/view/form/control/AphrontFormPolicyControl.php b/src/view/form/control/AphrontFormPolicyControl.php index 58d06cc5de..46dde71826 100644 --- a/src/view/form/control/AphrontFormPolicyControl.php +++ b/src/view/form/control/AphrontFormPolicyControl.php @@ -265,7 +265,9 @@ final class AphrontFormPolicyControl extends AphrontFormControl { $select = AphrontFormSelectControl::renderSelectTag( $space_phid, - $this->getSpaceOptions($space_phid), + PhabricatorSpacesNamespaceQuery::getSpaceOptionsForViewer( + $viewer, + $space_phid), array( 'name' => 'spacePHID', )); @@ -273,27 +275,4 @@ final class AphrontFormPolicyControl extends AphrontFormControl { return $select; } - protected function getSpaceOptions($space_phid) { - $viewer = $this->getUser(); - $viewer_spaces = PhabricatorSpacesNamespaceQuery::getViewerSpaces($viewer); - - $map = array(); - foreach ($viewer_spaces as $space) { - - // Skip archived spaces, unless the object is already in that space. - if ($space->getIsArchived()) { - if ($space->getPHID() != $space_phid) { - continue; - } - } - - $map[$space->getPHID()] = pht( - 'Space %s: %s', - $space->getMonogram(), - $space->getNamespaceName()); - } - asort($map); - - return $map; - } }