mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 14:52:41 +01:00
Add optional "Re:" prefix to all threaded mail and allow disabling mail about
your own actions Summary: - Mail.app on Lion has cumbersome threading rules, see T782. Add an option to stick "Re: " in front of all threaded mail so it behaves. This is horrible, but apparently the least-horrible option. - While I was in there, I added an option for T228. Test Plan: - Sent a bunch of threaded and unthreaded mail with varous "Re:" settings, seemed to get "Re:" in the right places. - Disabled email about my stuff, created a task with just me, got voided mail, added a CC, got mail to just the CC. Reviewers: btrahan, jungejason Reviewed By: btrahan CC: aran, mkjones Maniphest Tasks: T228, T782 Differential Revision: https://secure.phabricator.com/D1448
This commit is contained in:
parent
0402e4e06e
commit
ad36865e50
13 changed files with 346 additions and 108 deletions
|
@ -294,6 +294,11 @@ return array(
|
|||
// of any affected mail.
|
||||
'metamta.precedence-bulk' => false,
|
||||
|
||||
// Mail.app on OS X Lion won't respect threading headers unless the subject
|
||||
// is prefixed with "Re:". If you enable this option, Phabricator will add
|
||||
// "Re:" to the subject line of all mail which is expected to thread.
|
||||
'metamta.re-prefix' => false,
|
||||
|
||||
|
||||
// -- Auth ------------------------------------------------------------------ //
|
||||
|
||||
|
|
|
@ -711,6 +711,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorUserAccountSettingsPanelController' => 'applications/people/controller/settings/panels/account',
|
||||
'PhabricatorUserConduitSettingsPanelController' => 'applications/people/controller/settings/panels/conduit',
|
||||
'PhabricatorUserDAO' => 'applications/people/storage/base',
|
||||
'PhabricatorUserEmailPreferenceSettingsPanelController' => 'applications/people/controller/settings/panels/emailpref',
|
||||
'PhabricatorUserEmailSettingsPanelController' => 'applications/people/controller/settings/panels/email',
|
||||
'PhabricatorUserLog' => 'applications/people/storage/log',
|
||||
'PhabricatorUserOAuthInfo' => 'applications/people/storage/useroauthinfo',
|
||||
|
@ -1357,6 +1358,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorUserAccountSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
|
||||
'PhabricatorUserConduitSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
|
||||
'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
|
||||
'PhabricatorUserEmailPreferenceSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
|
||||
'PhabricatorUserEmailSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
|
||||
'PhabricatorUserLog' => 'PhabricatorUserDAO',
|
||||
'PhabricatorUserOAuthInfo' => 'PhabricatorUserDAO',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -90,9 +90,12 @@ Phabricator
|
|||
EOBODY;
|
||||
}
|
||||
|
||||
// NOTE: Don't set the user as 'from', or they may not receive the
|
||||
// mail if they have the "don't send me email about my own actions"
|
||||
// preference set.
|
||||
|
||||
$mail = new PhabricatorMetaMTAMail();
|
||||
$mail->setSubject('[Phabricator] Password Reset');
|
||||
$mail->setFrom($target_user->getPHID());
|
||||
$mail->addTos(
|
||||
array(
|
||||
$target_user->getPHID(),
|
||||
|
|
|
@ -24,6 +24,7 @@ class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
|
|||
const STATUS_QUEUE = 'queued';
|
||||
const STATUS_SENT = 'sent';
|
||||
const STATUS_FAIL = 'fail';
|
||||
const STATUS_VOID = 'void';
|
||||
|
||||
const MAX_RETRIES = 250;
|
||||
const RETRY_DELAY = 5;
|
||||
|
@ -264,29 +265,54 @@ class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
|
|||
$handles = id(new PhabricatorObjectHandleData($phids))
|
||||
->loadHandles();
|
||||
|
||||
$exclude = array();
|
||||
|
||||
$params = $this->parameters;
|
||||
$default = PhabricatorEnv::getEnvConfig('metamta.default-address');
|
||||
if (empty($params['from'])) {
|
||||
$mailer->setFrom($default);
|
||||
} else if (!PhabricatorEnv::getEnvConfig('metamta.can-send-as-user')) {
|
||||
} else {
|
||||
$from = $params['from'];
|
||||
$handle = $handles[$from];
|
||||
if (empty($params['reply-to'])) {
|
||||
$params['reply-to'] = $handle->getEmail();
|
||||
$params['reply-to-name'] = $handle->getFullName();
|
||||
|
||||
// If the user has set their preferences to not send them email about
|
||||
// things they do, exclude them from being on To or Cc.
|
||||
$from_user = id(new PhabricatorUser())->loadOneWhere(
|
||||
'phid = %s',
|
||||
$from);
|
||||
if ($from_user) {
|
||||
$pref_key = PhabricatorUserPreferences::PREFERENCE_NO_SELF_MAIL;
|
||||
$exclude_self = $from_user
|
||||
->loadPreferences()
|
||||
->getPreference($pref_key);
|
||||
if ($exclude_self) {
|
||||
$exclude[$from] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!PhabricatorEnv::getEnvConfig('metamta.can-send-as-user')) {
|
||||
$handle = $handles[$from];
|
||||
if (empty($params['reply-to'])) {
|
||||
$params['reply-to'] = $handle->getEmail();
|
||||
$params['reply-to-name'] = $handle->getFullName();
|
||||
}
|
||||
$mailer->setFrom(
|
||||
$default,
|
||||
$handle->getFullName());
|
||||
unset($params['from']);
|
||||
}
|
||||
$mailer->setFrom(
|
||||
$default,
|
||||
$handle->getFullName());
|
||||
unset($params['from']);
|
||||
}
|
||||
|
||||
$is_first = !empty($params['is-first-message']);
|
||||
$is_first = idx($params, 'is-first-message');
|
||||
unset($params['is-first-message']);
|
||||
|
||||
$is_threaded = (bool)idx($params, 'thread-id');
|
||||
|
||||
$reply_to_name = idx($params, 'reply-to-name', '');
|
||||
unset($params['reply-to-name']);
|
||||
|
||||
$add_cc = null;
|
||||
$add_to = null;
|
||||
|
||||
foreach ($params as $key => $value) {
|
||||
switch ($key) {
|
||||
case 'from':
|
||||
|
@ -296,22 +322,21 @@ class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
|
|||
$mailer->addReplyTo($value, $reply_to_name);
|
||||
break;
|
||||
case 'to':
|
||||
$emails = $this->getDeliverableEmailsFromHandles($value, $handles);
|
||||
$emails = $this->getDeliverableEmailsFromHandles(
|
||||
$value,
|
||||
$handles,
|
||||
$exclude);
|
||||
if ($emails) {
|
||||
$mailer->addTos($emails);
|
||||
} else {
|
||||
if ($value) {
|
||||
throw new Exception(
|
||||
"All 'To' objects are undeliverable (e.g., disabled users).");
|
||||
} else {
|
||||
throw new Exception("No 'To' specified!");
|
||||
}
|
||||
$add_to = $emails;
|
||||
}
|
||||
break;
|
||||
case 'cc':
|
||||
$emails = $this->getDeliverableEmailsFromHandles($value, $handles);
|
||||
$emails = $this->getDeliverableEmailsFromHandles(
|
||||
$value,
|
||||
$handles,
|
||||
$exclude);
|
||||
if ($emails) {
|
||||
$mailer->addCCs($emails);
|
||||
$add_cc = $emails;
|
||||
}
|
||||
break;
|
||||
case 'headers':
|
||||
|
@ -335,6 +360,30 @@ class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
|
|||
$mailer->setBody($value);
|
||||
break;
|
||||
case 'subject':
|
||||
if ($is_threaded) {
|
||||
$add_re = PhabricatorEnv::getEnvConfig('metamta.re-prefix');
|
||||
|
||||
// If this message has a single recipient, respect their "Re:"
|
||||
// preference. Otherwise, use the global setting.
|
||||
|
||||
$to = idx($params, 'to', array());
|
||||
$cc = idx($params, 'cc', array());
|
||||
if (count($to) == 1 && count($cc) == 0) {
|
||||
$user = id(new PhabricatorUser())->loadOneWhere(
|
||||
'phid = %s',
|
||||
head($to));
|
||||
if ($user) {
|
||||
$prefs = $user->loadPreferences();
|
||||
$pref_key = PhabricatorUserPreferences::PREFERENCE_RE_PREFIX;
|
||||
$add_re = $prefs->getPreference($pref_key, $add_re);
|
||||
}
|
||||
}
|
||||
|
||||
if ($add_re) {
|
||||
$value = 'Re: '.$value;
|
||||
}
|
||||
}
|
||||
|
||||
$mailer->setSubject($value);
|
||||
break;
|
||||
case 'is-html':
|
||||
|
@ -376,6 +425,23 @@ class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
|
|||
|
||||
$mailer->addHeader('X-Mail-Transport-Agent', 'MetaMTA');
|
||||
|
||||
if ($add_to) {
|
||||
$mailer->addTos($add_to);
|
||||
if ($add_cc) {
|
||||
$mailer->addCCs($add_cc);
|
||||
}
|
||||
} else if ($add_cc) {
|
||||
// If we have CC addresses but no "to" address, promote the CCs to
|
||||
// "to".
|
||||
$mailer->addTos($add_cc);
|
||||
} else {
|
||||
$this->setStatus(self::STATUS_VOID);
|
||||
$this->setMessage(
|
||||
"Message has no valid recipients: all To/CC are disabled or ".
|
||||
"configured not to receive this mail.");
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
} catch (Exception $ex) {
|
||||
$this->setStatus(self::STATUS_FAIL);
|
||||
$this->setMessage($ex->getMessage());
|
||||
|
@ -416,6 +482,7 @@ class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
|
|||
self::STATUS_QUEUE => "Queued for Delivery",
|
||||
self::STATUS_FAIL => "Delivery Failed",
|
||||
self::STATUS_SENT => "Sent",
|
||||
self::STATUS_VOID => "Void",
|
||||
);
|
||||
$status_code = coalesce($status_code, '?');
|
||||
return idx($readable, $status_code, $status_code);
|
||||
|
@ -454,7 +521,8 @@ class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
|
|||
|
||||
private function getDeliverableEmailsFromHandles(
|
||||
array $phids,
|
||||
array $handles) {
|
||||
array $handles,
|
||||
array $exclude) {
|
||||
|
||||
$emails = array();
|
||||
foreach ($phids as $phid) {
|
||||
|
@ -464,6 +532,9 @@ class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
|
|||
if (!$handles[$phid]->isComplete()) {
|
||||
continue;
|
||||
}
|
||||
if (isset($exclude[$phid])) {
|
||||
continue;
|
||||
}
|
||||
$emails[] = $handles[$phid]->getEmail();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/metamta/storage/base');
|
||||
phutil_require_module('phabricator', 'applications/people/storage/preferences');
|
||||
phutil_require_module('phabricator', 'applications/people/storage/user');
|
||||
phutil_require_module('phabricator', 'applications/phid/handle/data');
|
||||
phutil_require_module('phabricator', 'infrastructure/env');
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -29,37 +29,9 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController {
|
|||
|
||||
$request = $this->getRequest();
|
||||
|
||||
$this->pages = array(
|
||||
'account' => 'Account',
|
||||
'profile' => 'Profile',
|
||||
'email' => 'Email',
|
||||
'password' => 'Password',
|
||||
'preferences' => 'Preferences',
|
||||
'conduit' => 'Conduit Certificate',
|
||||
);
|
||||
|
||||
if (!PhabricatorEnv::getEnvConfig('account.editable') ||
|
||||
!PhabricatorEnv::getEnvConfig('auth.password-auth-enabled')) {
|
||||
unset($this->pages['password']);
|
||||
}
|
||||
|
||||
if (PhabricatorUserSSHKeysSettingsPanelController::isEnabled()) {
|
||||
$this->pages['sshkeys'] = 'SSH Public Keys';
|
||||
}
|
||||
|
||||
$oauth_providers = PhabricatorOAuthProvider::getAllProviders();
|
||||
foreach ($oauth_providers as $provider) {
|
||||
if (!$provider->isProviderEnabled()) {
|
||||
continue;
|
||||
}
|
||||
$key = $provider->getProviderKey();
|
||||
$name = $provider->getProviderName();
|
||||
$this->pages[$key] = $name.' Account';
|
||||
}
|
||||
|
||||
if (empty($this->pages[$this->page])) {
|
||||
$this->page = key($this->pages);
|
||||
}
|
||||
$sidenav = $this->renderSideNav($oauth_providers);
|
||||
$this->page = $sidenav->selectFilter($this->page, 'account');
|
||||
|
||||
switch ($this->page) {
|
||||
case 'account':
|
||||
|
@ -71,6 +43,10 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController {
|
|||
case 'email':
|
||||
$delegate = new PhabricatorUserEmailSettingsPanelController($request);
|
||||
break;
|
||||
case 'emailpref':
|
||||
$delegate = new PhabricatorUserEmailPreferenceSettingsPanelController(
|
||||
$request);
|
||||
break;
|
||||
case 'password':
|
||||
$delegate = new PhabricatorUserPasswordSettingsPanelController(
|
||||
$request);
|
||||
|
@ -86,17 +62,14 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController {
|
|||
$request);
|
||||
break;
|
||||
default:
|
||||
if (empty($this->pages[$this->page])) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$delegate = new PhabricatorUserOAuthSettingsPanelController($request);
|
||||
$delegate->setOAuthProvider($oauth_providers[$this->page]);
|
||||
break;
|
||||
}
|
||||
|
||||
$response = $this->delegateToController($delegate);
|
||||
|
||||
if ($response instanceof AphrontView) {
|
||||
$sidenav = $this->renderSideNav();
|
||||
$sidenav->appendChild($response);
|
||||
return $this->buildStandardPageResponse(
|
||||
$sidenav,
|
||||
|
@ -108,20 +81,53 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController {
|
|||
}
|
||||
}
|
||||
|
||||
private function renderSideNav() {
|
||||
$sidenav = new AphrontSideNavView();
|
||||
foreach ($this->pages as $page => $name) {
|
||||
$sidenav->addNavItem(
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/settings/page/'.$page.'/',
|
||||
'class' => ($page == $this->page)
|
||||
? 'aphront-side-nav-selected'
|
||||
: null,
|
||||
),
|
||||
phutil_escape_html($name)));
|
||||
private function renderSideNav($oauth_providers) {
|
||||
$sidenav = new AphrontSideNavFilterView();
|
||||
$sidenav
|
||||
->setBaseURI(new PhutilURI('/settings/page/'))
|
||||
->addLabel('Account Information')
|
||||
->addFilter('account', 'Account')
|
||||
->addFilter('profile', 'Profile')
|
||||
->addSpacer()
|
||||
->addLabel('Email')
|
||||
->addFilter('email', 'Email Address')
|
||||
->addFilter('emailpref', 'Email Preferences')
|
||||
->addSpacer()
|
||||
->addLabel('Authentication');
|
||||
|
||||
if (PhabricatorEnv::getEnvConfig('account.editable') &&
|
||||
PhabricatorEnv::getEnvConfig('auth.password-auth-enabled')) {
|
||||
$sidenav->addFilter('password', 'Password');
|
||||
}
|
||||
|
||||
$sidenav->addFilter('conduit', 'Conduit Certificate');
|
||||
|
||||
if (PhabricatorUserSSHKeysSettingsPanelController::isEnabled()) {
|
||||
$sidenav->addFilter('sshkeys', 'SSH Public Keys');
|
||||
}
|
||||
|
||||
$sidenav->addSpacer();
|
||||
$sidenav->addLabel('Application Settings');
|
||||
$sidenav->addFilter('preferences', 'Display Preferences');
|
||||
|
||||
$items = array();
|
||||
foreach ($oauth_providers as $provider) {
|
||||
if (!$provider->isProviderEnabled()) {
|
||||
continue;
|
||||
}
|
||||
$key = $provider->getProviderKey();
|
||||
$name = $provider->getProviderName();
|
||||
$items[$key] = $name.' Account';
|
||||
}
|
||||
|
||||
if ($items) {
|
||||
$sidenav->addSpacer();
|
||||
$sidenav->addLabel('Linked Accounts');
|
||||
foreach ($items as $key => $name) {
|
||||
$sidenav->addFilter($key, $name);
|
||||
}
|
||||
}
|
||||
|
||||
return $sidenav;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,21 +6,21 @@
|
|||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'aphront/response/404');
|
||||
phutil_require_module('phabricator', 'applications/auth/oauth/provider/base');
|
||||
phutil_require_module('phabricator', 'applications/people/controller/base');
|
||||
phutil_require_module('phabricator', 'applications/people/controller/settings/panels/account');
|
||||
phutil_require_module('phabricator', 'applications/people/controller/settings/panels/conduit');
|
||||
phutil_require_module('phabricator', 'applications/people/controller/settings/panels/email');
|
||||
phutil_require_module('phabricator', 'applications/people/controller/settings/panels/emailpref');
|
||||
phutil_require_module('phabricator', 'applications/people/controller/settings/panels/oauth');
|
||||
phutil_require_module('phabricator', 'applications/people/controller/settings/panels/password');
|
||||
phutil_require_module('phabricator', 'applications/people/controller/settings/panels/preferences');
|
||||
phutil_require_module('phabricator', 'applications/people/controller/settings/panels/profile');
|
||||
phutil_require_module('phabricator', 'applications/people/controller/settings/panels/sshkeys');
|
||||
phutil_require_module('phabricator', 'infrastructure/env');
|
||||
phutil_require_module('phabricator', 'view/layout/sidenav');
|
||||
phutil_require_module('phabricator', 'view/layout/sidenavfilter');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
phutil_require_module('phutil', 'parser/uri');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
class PhabricatorUserEmailPreferenceSettingsPanelController
|
||||
extends PhabricatorUserSettingsPanelController {
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
$preferences = $user->loadPreferences();
|
||||
|
||||
$pref_re_prefix = PhabricatorUserPreferences::PREFERENCE_RE_PREFIX;
|
||||
$pref_no_self_mail = PhabricatorUserPreferences::PREFERENCE_NO_SELF_MAIL;
|
||||
|
||||
$errors = array();
|
||||
if ($request->isFormPost()) {
|
||||
|
||||
if ($request->getStr($pref_re_prefix) == 'default') {
|
||||
$preferences->unsetPreference($pref_re_prefix);
|
||||
} else {
|
||||
$preferences->setPreference(
|
||||
$pref_re_prefix,
|
||||
$request->getBool($pref_re_prefix));
|
||||
}
|
||||
|
||||
$preferences->setPreference(
|
||||
$pref_no_self_mail,
|
||||
$request->getStr($pref_no_self_mail));
|
||||
|
||||
$preferences->save();
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/settings/page/emailpref/?saved=true');
|
||||
}
|
||||
|
||||
$notice = null;
|
||||
if (!$errors) {
|
||||
if ($request->getStr('saved')) {
|
||||
$notice = new AphrontErrorView();
|
||||
$notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
|
||||
$notice->setTitle('Changes Saved');
|
||||
$notice->appendChild('<p>Your changes have been saved.</p>');
|
||||
}
|
||||
} else {
|
||||
$notice = new AphrontErrorView();
|
||||
$notice->setTitle('Form Errors');
|
||||
$notice->setErrors($errors);
|
||||
}
|
||||
|
||||
$re_prefix_default = PhabricatorEnv::getEnvConfig('metamta.re-prefix')
|
||||
? 'Enabled'
|
||||
: 'Disabled';
|
||||
|
||||
$re_prefix_value = $preferences->getPreference($pref_re_prefix);
|
||||
if ($re_prefix_value === null) {
|
||||
$re_prefix_value = 'defualt';
|
||||
} else {
|
||||
$re_prefix_value = $re_prefix_value
|
||||
? 'true'
|
||||
: 'false';
|
||||
}
|
||||
|
||||
$form = new AphrontFormView();
|
||||
$form
|
||||
->setUser($user)
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel('Self Actions')
|
||||
->setName($pref_no_self_mail)
|
||||
->setOptions(
|
||||
array(
|
||||
'0' => 'Send me an email when I take an action',
|
||||
'1' => 'Do not send me an email when I take an action',
|
||||
))
|
||||
->setCaption('You can disable email about your own actions.')
|
||||
->setValue($preferences->getPreference($pref_no_self_mail, 0)))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel('Add "Re:" Prefix')
|
||||
->setName($pref_re_prefix)
|
||||
->setCaption(
|
||||
'Enable this option to fix threading in Mail.app on OS X Lion, '.
|
||||
'or if you like "Re:" in your email subjects.')
|
||||
->setOptions(
|
||||
array(
|
||||
'default' => 'Use Server Default ('.$re_prefix_default.')',
|
||||
'true' => 'Enable "Re:" prefix',
|
||||
'false' => 'Disable "Re:" prefix',
|
||||
))
|
||||
->setValue($re_prefix_value));
|
||||
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue('Save'));
|
||||
|
||||
$panel = new AphrontPanelView();
|
||||
$panel->setHeader('Email Preferences');
|
||||
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
||||
$panel->appendChild($form);
|
||||
|
||||
return id(new AphrontNullView())
|
||||
->appendChild(
|
||||
array(
|
||||
$notice,
|
||||
$panel,
|
||||
));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'aphront/response/redirect');
|
||||
phutil_require_module('phabricator', 'applications/people/controller/settings/panels/base');
|
||||
phutil_require_module('phabricator', 'applications/people/storage/preferences');
|
||||
phutil_require_module('phabricator', 'infrastructure/env');
|
||||
phutil_require_module('phabricator', 'view/form/base');
|
||||
phutil_require_module('phabricator', 'view/form/control/select');
|
||||
phutil_require_module('phabricator', 'view/form/control/submit');
|
||||
phutil_require_module('phabricator', 'view/form/error');
|
||||
phutil_require_module('phabricator', 'view/layout/panel');
|
||||
phutil_require_module('phabricator', 'view/null');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorUserEmailPreferenceSettingsPanelController.php');
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -56,15 +56,6 @@ class PhabricatorUserOAuthSettingsPanelController
|
|||
'can link an account, which will allow you to use it to log into '.
|
||||
'Phabricator.</p>');
|
||||
|
||||
switch ($provider_key) {
|
||||
case PhabricatorOAuthProvider::PROVIDER_GITHUB:
|
||||
$form->appendChild(
|
||||
'<p class="aphront-form-instructions">Additionally, you must '.
|
||||
'link your Github account before Phabricator can access any '.
|
||||
'information about hosted repositories.</p>');
|
||||
break;
|
||||
}
|
||||
|
||||
$auth_uri = $provider->getAuthURI();
|
||||
$client_id = $provider->getClientID();
|
||||
$redirect_uri = $provider->getRedirectURI();
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/auth/oauth/provider/base');
|
||||
phutil_require_module('phabricator', 'applications/people/controller/settings/panels/base');
|
||||
phutil_require_module('phabricator', 'applications/people/storage/useroauthinfo');
|
||||
phutil_require_module('phabricator', 'view/form/base');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -15,6 +15,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
class PhabricatorUserPreferenceSettingsPanelController
|
||||
extends PhabricatorUserSettingsPanelController {
|
||||
|
||||
|
@ -24,20 +25,18 @@ class PhabricatorUserPreferenceSettingsPanelController
|
|||
$user = $request->getUser();
|
||||
$preferences = $user->loadPreferences();
|
||||
|
||||
$pref_monospaced = PhabricatorUserPreferences::PREFERENCE_MONOSPACED;
|
||||
$pref_titles = PhabricatorUserPreferences::PREFERENCE_TITLES;
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$monospaced = $request->getStr(
|
||||
PhabricatorUserPreferences::PREFERENCE_MONOSPACED);
|
||||
$monospaced = $request->getStr($pref_monospaced);
|
||||
|
||||
// Prevent the user from doing stupid things.
|
||||
$monospaced = preg_replace('/[^a-z0-9 ,"]+/i', '', $monospaced);
|
||||
|
||||
$pref_dict = array(
|
||||
PhabricatorUserPreferences::PREFERENCE_TITLES =>
|
||||
$request->getStr(PhabricatorUserPreferences::PREFERENCE_TITLES),
|
||||
PhabricatorUserPreferences::PREFERENCE_MONOSPACED =>
|
||||
$monospaced);
|
||||
$preferences->setPreference($pref_titles, $request->getStr($pref_titles));
|
||||
$preferences->setPreference($pref_monospaced, $monospaced);
|
||||
|
||||
$preferences->setPreferences($pref_dict);
|
||||
$preferences->save();
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/settings/page/preferences/?saved=true');
|
||||
|
@ -56,9 +55,8 @@ EXAMPLE;
|
|||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel('Page Titles')
|
||||
->setName(PhabricatorUserPreferences::PREFERENCE_TITLES)
|
||||
->setValue($preferences->getPreference(
|
||||
PhabricatorUserPreferences::PREFERENCE_TITLES))
|
||||
->setName($pref_titles)
|
||||
->setValue($preferences->getPreference($pref_titles))
|
||||
->setOptions(
|
||||
array(
|
||||
'glyph' =>
|
||||
|
@ -69,13 +67,12 @@ EXAMPLE;
|
|||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel('Monospaced Font')
|
||||
->setName(PhabricatorUserPreferences::PREFERENCE_MONOSPACED)
|
||||
->setName($pref_monospaced)
|
||||
->setCaption(
|
||||
'Overrides default fonts in tools like Differential. '.
|
||||
'(Default: 10px "Menlo", "Consolas", "Monaco", '.
|
||||
'monospace)')
|
||||
->setValue($preferences->getPreference(
|
||||
PhabricatorUserPreferences::PREFERENCE_MONOSPACED)))
|
||||
->setValue($preferences->getPreference($pref_monospaced)))
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setValue(
|
||||
|
@ -88,7 +85,7 @@ EXAMPLE;
|
|||
|
||||
$panel = new AphrontPanelView();
|
||||
$panel->setWidth(AphrontPanelView::WIDTH_WIDE);
|
||||
$panel->setHeader('Phabricator Preferences');
|
||||
$panel->setHeader('Display Preferences');
|
||||
$panel->appendChild($form);
|
||||
|
||||
$error_view = null;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -18,11 +18,14 @@
|
|||
|
||||
class PhabricatorUserPreferences extends PhabricatorUserDAO {
|
||||
|
||||
const PREFERENCE_MONOSPACED = 'monospaced';
|
||||
const PREFERENCE_TITLES = 'titles';
|
||||
const PREFERENCE_MONOSPACED = 'monospaced';
|
||||
const PREFERENCE_TITLES = 'titles';
|
||||
|
||||
const PREFERENCE_RE_PREFIX = 're-prefix';
|
||||
const PREFERENCE_NO_SELF_MAIL = 'self-mail';
|
||||
|
||||
protected $userPHID;
|
||||
protected $preferences;
|
||||
protected $preferences = array();
|
||||
|
||||
public function getConfiguration() {
|
||||
return array(
|
||||
|
@ -33,7 +36,18 @@ class PhabricatorUserPreferences extends PhabricatorUserDAO {
|
|||
) + parent::getConfiguration();
|
||||
}
|
||||
|
||||
public function getPreference($key) {
|
||||
return idx($this->getPreferences(), $key);
|
||||
public function getPreference($key, $default = null) {
|
||||
return idx($this->preferences, $key, $default);
|
||||
}
|
||||
|
||||
public function setPreference($key, $value) {
|
||||
$this->preferences[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function unsetPreference($key) {
|
||||
unset($this->preferences[$key]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue