1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-19 03:01:11 +01:00

Modularize mail tags

Summary:
Ref T5861. Currently, mail tags are hard-coded; move them into applications. Each Editor defines its own tags.

This has zero impact on the UI or behavior.

Test Plan:
  - Checked/unchecked some options, saved form.
  - Swapped back to `master` and saw exactly the same values.

Reviewers: chad, btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T5861

Differential Revision: https://secure.phabricator.com/D10238
This commit is contained in:
epriestley 2014-08-12 12:28:41 -07:00
parent d011f8fdc6
commit f6f9d78f3a
39 changed files with 437 additions and 111 deletions

View file

@ -3,6 +3,14 @@
final class PhabricatorAuditEditor final class PhabricatorAuditEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorAuditApplication';
}
public function getEditorObjectsDescription() {
return pht('Audits');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -3,6 +3,14 @@
final class PhabricatorAuthProviderConfigEditor final class PhabricatorAuthProviderConfigEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorAuthApplication';
}
public function getEditorObjectsDescription() {
return pht('Auth Providers');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -3,6 +3,14 @@
final class PhabricatorConfigEditor final class PhabricatorConfigEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorConfigApplication';
}
public function getEditorObjectsDescription() {
return pht('Phabricator Configuration');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -5,6 +5,14 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
const ERROR_EMPTY_PARTICIPANTS = 'error-empty-participants'; const ERROR_EMPTY_PARTICIPANTS = 'error-empty-participants';
const ERROR_EMPTY_MESSAGE = 'error-empty-message'; const ERROR_EMPTY_MESSAGE = 'error-empty-message';
public function getEditorApplicationClass() {
return 'PhabricatorConpherenceApplication';
}
public function getEditorObjectsDescription() {
return pht('Conpherence Threads');
}
public static function createConpherence( public static function createConpherence(
PhabricatorUser $creator, PhabricatorUser $creator,
array $participant_phids, array $participant_phids,

View file

@ -3,6 +3,14 @@
final class PhabricatorDashboardPanelTransactionEditor final class PhabricatorDashboardPanelTransactionEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorDashboardApplication';
}
public function getEditorObjectsDescription() {
return pht('Dashboard Panels');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -3,6 +3,14 @@
final class PhabricatorDashboardTransactionEditor final class PhabricatorDashboardTransactionEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorDashboardApplication';
}
public function getEditorObjectsDescription() {
return pht('Dashboards');
}
public static function addPanelToDashboard( public static function addPanelToDashboard(
PhabricatorUser $actor, PhabricatorUser $actor,
PhabricatorContentSource $content_source, PhabricatorContentSource $content_source,

View file

@ -7,6 +7,14 @@ final class DifferentialTransactionEditor
private $changedPriorToCommitURI; private $changedPriorToCommitURI;
private $isCloseByCommit; private $isCloseByCommit;
public function getEditorApplicationClass() {
return 'PhabricatorDifferentialApplication';
}
public function getEditorObjectsDescription() {
return pht('Differential Revisions');
}
public function getDiffUpdateTransaction(array $xactions) { public function getDiffUpdateTransaction(array $xactions) {
$type_update = DifferentialTransaction::TYPE_UPDATE; $type_update = DifferentialTransaction::TYPE_UPDATE;
@ -1192,6 +1200,25 @@ final class DifferentialTransactionEditor
return $body; return $body;
} }
public function getMailTagsMap() {
return array(
MetaMTANotificationType::TYPE_DIFFERENTIAL_REVIEW_REQUEST =>
pht('A revision is created.'),
MetaMTANotificationType::TYPE_DIFFERENTIAL_UPDATED =>
pht('A revision is updated.'),
MetaMTANotificationType::TYPE_DIFFERENTIAL_COMMENT =>
pht('Someone comments on a revision.'),
MetaMTANotificationType::TYPE_DIFFERENTIAL_CLOSED =>
pht('A revision is closed.'),
MetaMTANotificationType::TYPE_DIFFERENTIAL_REVIEWERS =>
pht("A revision's reviewers change."),
MetaMTANotificationType::TYPE_DIFFERENTIAL_CC =>
pht("A revision's CCs change."),
MetaMTANotificationType::TYPE_DIFFERENTIAL_OTHER =>
pht('Other revision activity not listed above occurs.'),
);
}
protected function supportsSearch() { protected function supportsSearch() {
return true; return true;
} }

View file

@ -3,6 +3,14 @@
final class DrydockBlueprintEditor final class DrydockBlueprintEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorDrydockApplication';
}
public function getEditorObjectsDescription() {
return pht('Drydock Blueprints');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -3,6 +3,14 @@
final class PhabricatorFileEditor final class PhabricatorFileEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorFilesApplication';
}
public function getEditorObjectsDescription() {
return pht('Files');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -3,6 +3,14 @@
final class HarbormasterBuildPlanEditor final class HarbormasterBuildPlanEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorHarbormasterApplication';
}
public function getEditorObjectsDescription() {
return pht('Harbormaster Build Plans');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();
$types[] = HarbormasterBuildPlanTransaction::TYPE_NAME; $types[] = HarbormasterBuildPlanTransaction::TYPE_NAME;

View file

@ -3,6 +3,14 @@
final class HarbormasterBuildStepEditor final class HarbormasterBuildStepEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorHarbormasterApplication';
}
public function getEditorObjectsDescription() {
return pht('Harbormaster Build Steps');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -3,6 +3,14 @@
final class HarbormasterBuildTransactionEditor final class HarbormasterBuildTransactionEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorHarbormasterApplication';
}
public function getEditorObjectsDescription() {
return pht('Harbormaster Builds');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -3,6 +3,14 @@
final class HarbormasterBuildableTransactionEditor final class HarbormasterBuildableTransactionEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorHarbormasterApplication';
}
public function getEditorObjectsDescription() {
return pht('Harbormaster Buildables');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -3,6 +3,14 @@
final class HeraldRuleEditor final class HeraldRuleEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorHeraldApplication';
}
public function getEditorObjectsDescription() {
return pht('Herald Rules');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -5,6 +5,14 @@ final class LegalpadDocumentEditor
private $isContribution = false; private $isContribution = false;
public function getEditorApplicationClass() {
return 'PhabricatorLegalpadApplication';
}
public function getEditorObjectsDescription() {
return pht('Legalpad Documents');
}
private function setIsContribution($is_contribution) { private function setIsContribution($is_contribution) {
$this->isContribution = $is_contribution; $this->isContribution = $is_contribution;
} }

View file

@ -3,6 +3,14 @@
final class PhabricatorMacroEditor final class PhabricatorMacroEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorMacroApplication';
}
public function getEditorObjectsDescription() {
return pht('Macros');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -5,6 +5,14 @@ final class ManiphestTransactionEditor
private $heraldEmailPHIDs = array(); private $heraldEmailPHIDs = array();
public function getEditorApplicationClass() {
return 'PhabricatorManiphestApplication';
}
public function getEditorObjectsDescription() {
return pht('Maniphest Tasks');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();
@ -428,6 +436,25 @@ final class ManiphestTransactionEditor
return $phids; return $phids;
} }
public function getMailTagsMap() {
return array(
MetaMTANotificationType::TYPE_MANIPHEST_STATUS =>
pht("A task's status changes."),
MetaMTANotificationType::TYPE_MANIPHEST_OWNER =>
pht("A task's owner changes."),
MetaMTANotificationType::TYPE_MANIPHEST_PRIORITY =>
pht("A task's priority changes."),
MetaMTANotificationType::TYPE_MANIPHEST_CC =>
pht("A task's CCs change."),
MetaMTANotificationType::TYPE_MANIPHEST_PROJECTS =>
pht("A task's associated projects change."),
MetaMTANotificationType::TYPE_MANIPHEST_COMMENT =>
pht('Someone comments on a task.'),
MetaMTANotificationType::TYPE_MANIPHEST_OTHER =>
pht('Other task activity not listed above occurs.'),
);
}
protected function buildReplyHandler(PhabricatorLiskDAO $object) { protected function buildReplyHandler(PhabricatorLiskDAO $object) {
return id(new ManiphestReplyHandler()) return id(new ManiphestReplyHandler())
->setMailReceiver($object); ->setMailReceiver($object);

View file

@ -3,6 +3,14 @@
final class NuanceItemEditor final class NuanceItemEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorNuanceApplication';
}
public function getEditorObjectsDescription() {
return pht('Nuance Items');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -3,6 +3,14 @@
final class NuanceQueueEditor final class NuanceQueueEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorNuanceApplication';
}
public function getEditorObjectsDescription() {
return pht('Nuance Queues');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -3,6 +3,14 @@
final class NuanceRequestorEditor final class NuanceRequestorEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorNuanceApplication';
}
public function getEditorObjectsDescription() {
return pht('Nuance Requestors');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -3,6 +3,14 @@
final class NuanceSourceEditor final class NuanceSourceEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorNuanceApplication';
}
public function getEditorObjectsDescription() {
return pht('Nuance Sources');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -3,6 +3,14 @@
final class PassphraseCredentialTransactionEditor final class PassphraseCredentialTransactionEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorPassphraseApplication';
}
public function getEditorObjectsDescription() {
return pht('Passphrase Credentials');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -5,6 +5,14 @@ final class PhabricatorPasteEditor
private $pasteFile; private $pasteFile;
public function getEditorApplicationClass() {
return 'PhabricatorPasteApplication';
}
public function getEditorObjectsDescription() {
return pht('Pastes');
}
public static function initializeFileForPaste( public static function initializeFileForPaste(
PhabricatorUser $actor, PhabricatorUser $actor,
$name, $name,

View file

@ -3,5 +3,13 @@
final class PhabricatorUserProfileEditor final class PhabricatorUserProfileEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorPeopleApplication';
}
public function getEditorObjectsDescription() {
return pht('User Profiles');
}
} }

View file

@ -3,6 +3,14 @@
final class PhluxVariableEditor final class PhluxVariableEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorPhluxApplication';
}
public function getEditorObjectsDescription() {
return pht('Phlux Variables');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();
$types[] = PhluxTransaction::TYPE_EDIT_KEY; $types[] = PhluxTransaction::TYPE_EDIT_KEY;

View file

@ -3,6 +3,15 @@
final class PholioMockEditor extends PhabricatorApplicationTransactionEditor { final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
private $newImages = array(); private $newImages = array();
public function getEditorApplicationClass() {
return 'PhabricatorPholioApplication';
}
public function getEditorObjectsDescription() {
return pht('Pholio Mocks');
}
private function setNewImages(array $new_images) { private function setNewImages(array $new_images) {
assert_instances_of($new_images, 'PholioImage'); assert_instances_of($new_images, 'PholioImage');
$this->newImages = $new_images; $this->newImages = $new_images;
@ -411,6 +420,19 @@ final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
return PhabricatorEnv::getEnvConfig('metamta.pholio.subject-prefix'); return PhabricatorEnv::getEnvConfig('metamta.pholio.subject-prefix');
} }
public function getMailTagsMap() {
return array(
MetaMTANotificationType::TYPE_PHOLIO_STATUS =>
pht("A mock's status changes."),
MetaMTANotificationType::TYPE_PHOLIO_COMMENT =>
pht('Someone comments on a mock.'),
MetaMTANotificationType::TYPE_PHOLIO_UPDATED =>
pht('Mock images or descriptions change.'),
MetaMTANotificationType::TYPE_PHOLIO_OTHER =>
pht('Other mock activity not listed above occurs.'),
);
}
protected function shouldPublishFeedStory( protected function shouldPublishFeedStory(
PhabricatorLiskDAO $object, PhabricatorLiskDAO $object,
array $xactions) { array $xactions) {

View file

@ -4,6 +4,14 @@
final class PhortuneAccountEditor final class PhortuneAccountEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorPhortuneApplication';
}
public function getEditorObjectsDescription() {
return pht('Phortune Accounts');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -4,6 +4,14 @@
final class PhortuneProductEditor final class PhortuneProductEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorPhortuneApplication';
}
public function getEditorObjectsDescription() {
return pht('Phortune Products');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -2,6 +2,10 @@
final class PonderAnswerEditor extends PonderEditor { final class PonderAnswerEditor extends PonderEditor {
public function getEditorObjectsDescription() {
return pht('Ponder Answers');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -3,6 +3,10 @@
abstract class PonderEditor abstract class PonderEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorPonderApplication';
}
protected function shouldPublishFeedStory( protected function shouldPublishFeedStory(
PhabricatorLiskDAO $object, PhabricatorLiskDAO $object,
array $xactions) { array $xactions) {

View file

@ -5,6 +5,10 @@ final class PonderQuestionEditor
private $answer; private $answer;
public function getEditorObjectsDescription() {
return pht('Ponder Questions');
}
/** /**
* This is used internally on @{method:applyInitialEffects} if a transaction * This is used internally on @{method:applyInitialEffects} if a transaction
* of type PonderQuestionTransaction::TYPE_ANSWERS is in the mix. The value * of type PonderQuestionTransaction::TYPE_ANSWERS is in the mix. The value

View file

@ -3,6 +3,14 @@
final class PhabricatorProjectColumnTransactionEditor final class PhabricatorProjectColumnTransactionEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorProjectApplication';
}
public function getEditorObjectsDescription() {
return pht('Workboard Columns');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -3,6 +3,14 @@
final class PhabricatorProjectTransactionEditor final class PhabricatorProjectTransactionEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorProjectApplication';
}
public function getEditorObjectsDescription() {
return pht('Projects');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -3,6 +3,14 @@
final class ReleephProductEditor final class ReleephProductEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorReleephApplication';
}
public function getEditorObjectsDescription() {
return pht('Releeph Products');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -3,6 +3,14 @@
final class ReleephRequestTransactionalEditor final class ReleephRequestTransactionalEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorReleephApplication';
}
public function getEditorObjectsDescription() {
return pht('Releeph Requests');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -3,6 +3,14 @@
final class PhabricatorRepositoryEditor final class PhabricatorRepositoryEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
public function getEditorObjectsDescription() {
return pht('Repositories');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -35,17 +35,7 @@ final class PhabricatorSettingsPanelEmailPreferences
$new_tags = $request->getArr('mailtags'); $new_tags = $request->getArr('mailtags');
$mailtags = $preferences->getPreference('mailtags', array()); $mailtags = $preferences->getPreference('mailtags', array());
$all_tags = $this->getMailTags(); $all_tags = $this->getAllTags($user);
$maniphest = 'PhabricatorManiphestApplication';
if (!PhabricatorApplication::isClassInstalled($maniphest)) {
$all_tags = array_diff_key($all_tags, $this->getManiphestMailTags());
}
$pholio = 'PhabricatorPholioApplication';
if (!PhabricatorApplication::isClassInstalled($pholio)) {
$all_tags = array_diff_key($all_tags, $this->getPholioMailTags());
}
foreach ($all_tags as $key => $label) { foreach ($all_tags as $key => $label) {
$mailtags[$key] = (bool)idx($new_tags, $key, false); $mailtags[$key] = (bool)idx($new_tags, $key, false);
@ -125,34 +115,51 @@ final class PhabricatorSettingsPanelEmailPreferences
'CC\'d on). To receive email alerts when other objects are created, '. 'CC\'d on). To receive email alerts when other objects are created, '.
'configure [[ /herald/ | Herald Rules ]].'. 'configure [[ /herald/ | Herald Rules ]].'.
"\n\n". "\n\n".
'**Phabricator will send an email to your primary account when:**')); 'Phabricator will send an email to your primary account when:'));
if (PhabricatorApplication::isClassInstalledForViewer( $editors = $this->getAllEditorsWithTags($user);
'PhabricatorDifferentialApplication', $user)) {
$form // Find all the tags shared by more than one application, and put them
->appendChild( // in a "common" group.
$this->buildMailTagCheckboxes( $all_tags = array();
$this->getDifferentialMailTags(), foreach ($editors as $editor) {
$mailtags) foreach ($editor->getMailTagsMap() as $tag => $name) {
->setLabel(pht('Differential'))); if (empty($all_tags[$tag])) {
$all_tags[$tag] = array(
'count' => 0,
'name' => $name,
);
}
$all_tags[$tag]['count'];
}
} }
if (PhabricatorApplication::isClassInstalledForViewer( $common_tags = array();
'PhabricatorManiphestApplication', $user)) { foreach ($all_tags as $tag => $info) {
$form->appendChild( if ($info['count'] > 1) {
$this->buildMailTagCheckboxes( $common_tags[$tag] = $info['name'];
$this->getManiphestMailTags(), }
$mailtags)
->setLabel(pht('Maniphest')));
} }
if (PhabricatorApplication::isClassInstalledForViewer( // Build up the groups of application-specific options.
'PhabricatorPholioApplication', $user)) { $tag_groups = array();
$form->appendChild( foreach ($editors as $editor) {
$this->buildMailTagCheckboxes( $tag_groups[] = array(
$this->getPholioMailTags(), $editor->getEditorObjectsDescription(),
$mailtags) array_diff_key($editor->getMailTagsMap(), $common_tags));
->setLabel(pht('Pholio'))); }
// Sort them, then put "Common" at the top.
$tag_groups = isort($tag_groups, 0);
if ($common_tags) {
array_unshift($tag_groups, array(pht('Common'), $common_tags));
}
// Finally, build the controls.
foreach ($tag_groups as $spec) {
list($label, $map) = $spec;
$control = $this->buildMailTagControl($label, $map, $mailtags);
$form->appendChild($control);
} }
$form $form
@ -173,91 +180,44 @@ final class PhabricatorSettingsPanelEmailPreferences
)); ));
} }
private function getMailTags() { private function getAllEditorsWithTags(PhabricatorUser $user) {
return array( $editors = id(new PhutilSymbolLoader())
MetaMTANotificationType::TYPE_DIFFERENTIAL_REVIEW_REQUEST => ->setAncestorClass('PhabricatorApplicationTransactionEditor')
pht('A revision is created.'), ->loadObjects();
MetaMTANotificationType::TYPE_DIFFERENTIAL_UPDATED =>
pht('A revision is updated.'), foreach ($editors as $key => $editor) {
MetaMTANotificationType::TYPE_DIFFERENTIAL_COMMENT => // Remove editors which do not support mail tags.
pht('Someone comments on a revision.'), if (!$editor->getMailTagsMap()) {
MetaMTANotificationType::TYPE_DIFFERENTIAL_REVIEWERS => unset($editors[$key]);
pht("A revision's reviewers change."),
MetaMTANotificationType::TYPE_DIFFERENTIAL_CLOSED =>
pht('A revision is closed.'),
MetaMTANotificationType::TYPE_DIFFERENTIAL_CC =>
pht("A revision's CCs change."),
MetaMTANotificationType::TYPE_DIFFERENTIAL_OTHER =>
pht('Other revision activity not listed above occurs.'),
MetaMTANotificationType::TYPE_MANIPHEST_STATUS =>
pht("A task's status changes."),
MetaMTANotificationType::TYPE_MANIPHEST_OWNER =>
pht("A task's owner changes."),
MetaMTANotificationType::TYPE_MANIPHEST_COMMENT =>
pht('Someone comments on a task.'),
MetaMTANotificationType::TYPE_MANIPHEST_PRIORITY =>
pht("A task's priority changes."),
MetaMTANotificationType::TYPE_MANIPHEST_CC =>
pht("A task's CCs change."),
MetaMTANotificationType::TYPE_MANIPHEST_PROJECTS =>
pht("A task's associated projects change."),
MetaMTANotificationType::TYPE_MANIPHEST_OTHER =>
pht('Other task activity not listed above occurs.'),
MetaMTANotificationType::TYPE_PHOLIO_STATUS =>
pht("A mock's status changes."),
MetaMTANotificationType::TYPE_PHOLIO_COMMENT =>
pht('Someone comments on a mock.'),
MetaMTANotificationType::TYPE_PHOLIO_UPDATED =>
pht('Mock images or descriptions change.'),
MetaMTANotificationType::TYPE_PHOLIO_OTHER =>
pht('Other mock activity not listed above occurs.'),
);
} }
private function getManiphestMailTags() { // Remove editors for applications which are not installed.
return array_select_keys( $app = $editor->getEditorApplicationClass();
$this->getMailTags(), if ($app !== null) {
array( if (!PhabricatorApplication::isClassInstalledForViewer($app, $user)) {
MetaMTANotificationType::TYPE_MANIPHEST_STATUS, unset($editors[$key]);
MetaMTANotificationType::TYPE_MANIPHEST_OWNER, }
MetaMTANotificationType::TYPE_MANIPHEST_PRIORITY, }
MetaMTANotificationType::TYPE_MANIPHEST_CC,
MetaMTANotificationType::TYPE_MANIPHEST_PROJECTS,
MetaMTANotificationType::TYPE_MANIPHEST_COMMENT,
MetaMTANotificationType::TYPE_MANIPHEST_OTHER,
));
} }
private function getDifferentialMailTags() { return $editors;
return array_select_keys(
$this->getMailTags(),
array(
MetaMTANotificationType::TYPE_DIFFERENTIAL_REVIEW_REQUEST,
MetaMTANotificationType::TYPE_DIFFERENTIAL_UPDATED,
MetaMTANotificationType::TYPE_DIFFERENTIAL_COMMENT,
MetaMTANotificationType::TYPE_DIFFERENTIAL_CLOSED,
MetaMTANotificationType::TYPE_DIFFERENTIAL_REVIEWERS,
MetaMTANotificationType::TYPE_DIFFERENTIAL_CC,
MetaMTANotificationType::TYPE_DIFFERENTIAL_OTHER,
));
} }
private function getPholioMailTags() { private function getAllTags(PhabricatorUser $user) {
return array_select_keys( $tags = array();
$this->getMailTags(), foreach ($this->getAllEditorsWithTags($user) as $editor) {
array( $tags += $editor->getMailTagsMap();
MetaMTANotificationType::TYPE_PHOLIO_STATUS, }
MetaMTANotificationType::TYPE_PHOLIO_COMMENT, return $tags;
MetaMTANotificationType::TYPE_PHOLIO_UPDATED,
MetaMTANotificationType::TYPE_PHOLIO_OTHER,
));
} }
private function buildMailTagCheckboxes( private function buildMailTagControl(
$control_label,
array $tags, array $tags,
array $prefs) { array $prefs) {
$control = new AphrontFormCheckboxControl(); $control = new AphrontFormCheckboxControl();
$control->setLabel($control_label);
foreach ($tags as $key => $label) { foreach ($tags as $key => $label) {
$control->addCheckbox( $control->addCheckbox(
'mailtags['.$key.']', 'mailtags['.$key.']',

View file

@ -3,6 +3,14 @@
final class PhabricatorSlowvoteEditor final class PhabricatorSlowvoteEditor
extends PhabricatorApplicationTransactionEditor { extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorSlowvoteApplication';
}
public function getEditorObjectsDescription() {
return pht('Slowvotes');
}
public function getTransactionTypes() { public function getTransactionTypes() {
$types = parent::getTransactionTypes(); $types = parent::getTransactionTypes();

View file

@ -28,6 +28,26 @@ abstract class PhabricatorApplicationTransactionEditor
private $actingAsPHID; private $actingAsPHID;
private $disableEmail; private $disableEmail;
/**
* Get the class name for the application this editor is a part of.
*
* Uninstalling the application will disable the editor.
*
* @return string Editor's application class name.
*/
abstract public function getEditorApplicationClass();
/**
* Get a description of the objects this editor edits, like "Differential
* Revisions".
*
* @return string Human readable description of edited objects.
*/
abstract public function getEditorObjectsDescription();
public function setActingAsPHID($acting_as_phid) { public function setActingAsPHID($acting_as_phid) {
$this->actingAsPHID = $acting_as_phid; $this->actingAsPHID = $acting_as_phid;
return $this; return $this;
@ -40,6 +60,7 @@ abstract class PhabricatorApplicationTransactionEditor
return $this->getActor()->getPHID(); return $this->getActor()->getPHID();
} }
/** /**
* When the editor tries to apply transactions that have no effect, should * When the editor tries to apply transactions that have no effect, should
* it raise an exception (default) or drop them and continue? * it raise an exception (default) or drop them and continue?
@ -1930,6 +1951,15 @@ abstract class PhabricatorApplicationTransactionEditor
return array_mergev($tags); return array_mergev($tags);
} }
/**
* @task mail
*/
public function getMailTagsMap() {
// TODO: We should move shared mail tags, like "comment", here.
return array();
}
/** /**
* @task mail * @task mail
*/ */