mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-30 17:30:59 +01:00
Add timezone support
Summary: Allows user-configurable timezones. Adds a preference panel, and migrates to the new date rendering in easily-modified areas of the code. ***In progress***. Test Plan: Check database to make sure the field is being changed when the settings are changed; check affected views to see how they render times. Reviewed By: epriestley Reviewers: epriestley CC: aran, epriestley, toulouse Differential Revision: 475
This commit is contained in:
parent
565cc43f27
commit
9b522982fa
20 changed files with 71 additions and 13 deletions
2
resources/sql/patches/045.timezone.sql
Normal file
2
resources/sql/patches/045.timezone.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE phabricator_user.user
|
||||||
|
ADD timezoneIdentifier varchar(255) NOT NULL DEFAULT "America/Los_Angeles";
|
|
@ -539,10 +539,13 @@ phutil_register_library_map(array(
|
||||||
'celerity_generate_unique_node_id' => 'infrastructure/celerity/api',
|
'celerity_generate_unique_node_id' => 'infrastructure/celerity/api',
|
||||||
'celerity_register_resource_map' => 'infrastructure/celerity/map',
|
'celerity_register_resource_map' => 'infrastructure/celerity/map',
|
||||||
'javelin_render_tag' => 'infrastructure/javelin/markup',
|
'javelin_render_tag' => 'infrastructure/javelin/markup',
|
||||||
|
'phabricator_date' => 'view/utils',
|
||||||
|
'phabricator_datetime' => 'view/utils',
|
||||||
'phabricator_format_relative_time' => 'view/utils',
|
'phabricator_format_relative_time' => 'view/utils',
|
||||||
'phabricator_format_timestamp' => 'view/utils',
|
'phabricator_format_timestamp' => 'view/utils',
|
||||||
'phabricator_format_units_generic' => 'view/utils',
|
'phabricator_format_units_generic' => 'view/utils',
|
||||||
'phabricator_render_form' => 'infrastructure/javelin/markup',
|
'phabricator_render_form' => 'infrastructure/javelin/markup',
|
||||||
|
'phabricator_time' => 'view/utils',
|
||||||
'qsprintf' => 'storage/qsprintf',
|
'qsprintf' => 'storage/qsprintf',
|
||||||
'queryfx' => 'storage/queryfx',
|
'queryfx' => 'storage/queryfx',
|
||||||
'queryfx_all' => 'storage/queryfx',
|
'queryfx_all' => 'storage/queryfx',
|
||||||
|
|
|
@ -23,6 +23,7 @@ class DiffusionCommitController extends DiffusionController {
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
$drequest = $this->getDiffusionRequest();
|
$drequest = $this->getDiffusionRequest();
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
$callsign = $drequest->getRepository()->getCallsign();
|
$callsign = $drequest->getRepository()->getCallsign();
|
||||||
|
|
||||||
|
@ -56,7 +57,7 @@ class DiffusionCommitController extends DiffusionController {
|
||||||
'<div class="diffusion-commit-dateline">'.
|
'<div class="diffusion-commit-dateline">'.
|
||||||
'r'.$callsign.$commit->getCommitIdentifier().
|
'r'.$callsign.$commit->getCommitIdentifier().
|
||||||
' · '.
|
' · '.
|
||||||
date('F jS, Y g:i A', $commit->getEpoch()).
|
phabricator_datetime($commit->getEpoch(), $user).
|
||||||
'</div>'.
|
'</div>'.
|
||||||
'<h1>Revision Detail</h1>'.
|
'<h1>Revision Detail</h1>'.
|
||||||
'<div class="diffusion-commit-details">'.
|
'<div class="diffusion-commit-details">'.
|
||||||
|
|
|
@ -20,6 +20,7 @@ phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
||||||
phutil_require_module('phabricator', 'storage/queryfx');
|
phutil_require_module('phabricator', 'storage/queryfx');
|
||||||
phutil_require_module('phabricator', 'view/form/error');
|
phutil_require_module('phabricator', 'view/form/error');
|
||||||
phutil_require_module('phabricator', 'view/layout/panel');
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
phutil_require_module('phabricator', 'view/utils');
|
||||||
|
|
||||||
phutil_require_module('phutil', 'markup');
|
phutil_require_module('phutil', 'markup');
|
||||||
phutil_require_module('phutil', 'utils');
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
class DiffusionHomeController extends DiffusionController {
|
class DiffusionHomeController extends DiffusionController {
|
||||||
|
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
$shortcuts = id(new PhabricatorRepositoryShortcut())->loadAll();
|
$shortcuts = id(new PhabricatorRepositoryShortcut())->loadAll();
|
||||||
if ($shortcuts) {
|
if ($shortcuts) {
|
||||||
|
@ -94,8 +96,8 @@ class DiffusionHomeController extends DiffusionController {
|
||||||
$date = '-';
|
$date = '-';
|
||||||
$time = '-';
|
$time = '-';
|
||||||
if ($commit) {
|
if ($commit) {
|
||||||
$date = date('M j, Y', $commit->getEpoch());
|
$date = phabricator_date($commit->getEpoch(), $user);
|
||||||
$time = date('g:i A', $commit->getEpoch());
|
$time = phabricator_time($commit->getEpoch(), $user);
|
||||||
}
|
}
|
||||||
|
|
||||||
$rows[] = array(
|
$rows[] = array(
|
||||||
|
|
|
@ -15,6 +15,7 @@ phutil_require_module('phabricator', 'applications/repository/storage/shortcut')
|
||||||
phutil_require_module('phabricator', 'storage/queryfx');
|
phutil_require_module('phabricator', 'storage/queryfx');
|
||||||
phutil_require_module('phabricator', 'view/control/table');
|
phutil_require_module('phabricator', 'view/control/table');
|
||||||
phutil_require_module('phabricator', 'view/layout/panel');
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
phutil_require_module('phabricator', 'view/utils');
|
||||||
|
|
||||||
phutil_require_module('phutil', 'markup');
|
phutil_require_module('phutil', 'markup');
|
||||||
phutil_require_module('phutil', 'utils');
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
|
@ -21,6 +21,7 @@ class HeraldTranscriptListController extends HeraldController {
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
|
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
// Get one page of data together with the pager.
|
// Get one page of data together with the pager.
|
||||||
// Pull these objects manually since the serialized fields are gigantic.
|
// Pull these objects manually since the serialized fields are gigantic.
|
||||||
|
@ -98,8 +99,8 @@ class HeraldTranscriptListController extends HeraldController {
|
||||||
$rows = array();
|
$rows = array();
|
||||||
foreach ($data as $xscript) {
|
foreach ($data as $xscript) {
|
||||||
$rows[] = array(
|
$rows[] = array(
|
||||||
date('F jS', $xscript['time']),
|
phabricator_date($xscript['time'],$user),
|
||||||
date('g:i:s A', $xscript['time']),
|
phabricator_time($xscript['time'],$user),
|
||||||
$handles[$xscript['objectPHID']]->renderLink(),
|
$handles[$xscript['objectPHID']]->renderLink(),
|
||||||
$xscript['dryRun'] ? 'Yes' : '',
|
$xscript['dryRun'] ? 'Yes' : '',
|
||||||
number_format((int)(1000 * $xscript['duration'])).' ms',
|
number_format((int)(1000 * $xscript['duration'])).' ms',
|
||||||
|
|
|
@ -14,6 +14,7 @@ phutil_require_module('phabricator', 'storage/queryfx');
|
||||||
phutil_require_module('phabricator', 'view/control/pager');
|
phutil_require_module('phabricator', 'view/control/pager');
|
||||||
phutil_require_module('phabricator', 'view/control/table');
|
phutil_require_module('phabricator', 'view/control/table');
|
||||||
phutil_require_module('phabricator', 'view/layout/panel');
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
phutil_require_module('phabricator', 'view/utils');
|
||||||
|
|
||||||
phutil_require_module('phutil', 'markup');
|
phutil_require_module('phutil', 'markup');
|
||||||
phutil_require_module('phutil', 'utils');
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
|
@ -22,6 +22,7 @@ class PhabricatorMetaMTAReceivedListController
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
|
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
$pager = new AphrontPagerView();
|
$pager = new AphrontPagerView();
|
||||||
$pager->setOffset($request->getInt('page'));
|
$pager->setOffset($request->getInt('page'));
|
||||||
|
@ -45,8 +46,8 @@ class PhabricatorMetaMTAReceivedListController
|
||||||
foreach ($mails as $mail) {
|
foreach ($mails as $mail) {
|
||||||
$rows[] = array(
|
$rows[] = array(
|
||||||
$mail->getID(),
|
$mail->getID(),
|
||||||
date('M jS Y', $mail->getDateCreated()),
|
phabricator_date($mail->getDateCreated(), $user),
|
||||||
date('g:i:s A', $mail->getDateCreated()),
|
phabricator_time($mail->getDateCreated(), $user),
|
||||||
$mail->getAuthorPHID()
|
$mail->getAuthorPHID()
|
||||||
? $handles[$mail->getAuthorPHID()]->renderLink()
|
? $handles[$mail->getAuthorPHID()]->renderLink()
|
||||||
: '-',
|
: '-',
|
||||||
|
|
|
@ -12,6 +12,7 @@ phutil_require_module('phabricator', 'applications/phid/handle/data');
|
||||||
phutil_require_module('phabricator', 'view/control/pager');
|
phutil_require_module('phabricator', 'view/control/pager');
|
||||||
phutil_require_module('phabricator', 'view/control/table');
|
phutil_require_module('phabricator', 'view/control/table');
|
||||||
phutil_require_module('phabricator', 'view/layout/panel');
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
phutil_require_module('phabricator', 'view/utils');
|
||||||
|
|
||||||
phutil_require_module('phutil', 'markup');
|
phutil_require_module('phutil', 'markup');
|
||||||
phutil_require_module('phutil', 'utils');
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
|
@ -27,6 +27,7 @@ class PhabricatorMetaMTAViewController extends PhabricatorMetaMTAController {
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
|
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
$mail = id(new PhabricatorMetaMTAMail())->load($this->id);
|
$mail = id(new PhabricatorMetaMTAMail())->load($this->id);
|
||||||
if (!$mail) {
|
if (!$mail) {
|
||||||
|
@ -46,7 +47,7 @@ class PhabricatorMetaMTAViewController extends PhabricatorMetaMTAController {
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormStaticControl())
|
id(new AphrontFormStaticControl())
|
||||||
->setLabel('Created')
|
->setLabel('Created')
|
||||||
->setValue(date('F jS, Y g:i:s A', $mail->getDateCreated())))
|
->setValue(phabricator_datetime($mail->getDateCreated(), $user)))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormStaticControl())
|
id(new AphrontFormStaticControl())
|
||||||
->setLabel('Status')
|
->setLabel('Status')
|
||||||
|
|
|
@ -14,6 +14,7 @@ phutil_require_module('phabricator', 'view/form/control/static');
|
||||||
phutil_require_module('phabricator', 'view/form/control/submit');
|
phutil_require_module('phabricator', 'view/form/control/submit');
|
||||||
phutil_require_module('phabricator', 'view/form/control/textarea');
|
phutil_require_module('phabricator', 'view/form/control/textarea');
|
||||||
phutil_require_module('phabricator', 'view/layout/panel');
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
phutil_require_module('phabricator', 'view/utils');
|
||||||
|
|
||||||
phutil_require_module('phutil', 'utils');
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
|
@ -53,8 +53,8 @@ class PhabricatorPeopleListController extends PhabricatorPeopleController {
|
||||||
}
|
}
|
||||||
|
|
||||||
$rows[] = array(
|
$rows[] = array(
|
||||||
date('M jS, Y', $user->getDateCreated()),
|
phabricator_date($user->getDateCreated(), $user),
|
||||||
date('g:i:s A', $user->getDateCreated()),
|
phabricator_time($user->getDateCreated(), $user),
|
||||||
phutil_render_tag(
|
phutil_render_tag(
|
||||||
'a',
|
'a',
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -12,6 +12,7 @@ phutil_require_module('phabricator', 'storage/queryfx');
|
||||||
phutil_require_module('phabricator', 'view/control/pager');
|
phutil_require_module('phabricator', 'view/control/pager');
|
||||||
phutil_require_module('phabricator', 'view/control/table');
|
phutil_require_module('phabricator', 'view/control/table');
|
||||||
phutil_require_module('phabricator', 'view/layout/panel');
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
phutil_require_module('phabricator', 'view/utils');
|
||||||
|
|
||||||
phutil_require_module('phutil', 'markup');
|
phutil_require_module('phutil', 'markup');
|
||||||
phutil_require_module('phutil', 'utils');
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
|
@ -169,8 +169,8 @@ class PhabricatorPeopleLogsController extends PhabricatorPeopleController {
|
||||||
$rows = array();
|
$rows = array();
|
||||||
foreach ($logs as $log) {
|
foreach ($logs as $log) {
|
||||||
$rows[] = array(
|
$rows[] = array(
|
||||||
date('M jS, Y', $log->getDateCreated()),
|
phabricator_date($log->getDateCreated(),$user),
|
||||||
date('g:i:s A', $log->getDateCreated()),
|
phabricator_time($log->getDateCreated(),$user),
|
||||||
$log->getAction(),
|
$log->getAction(),
|
||||||
$log->getActorPHID()
|
$log->getActorPHID()
|
||||||
? phutil_escape_html($handles[$log->getActorPHID()]->getName())
|
? phutil_escape_html($handles[$log->getActorPHID()]->getName())
|
||||||
|
|
|
@ -19,6 +19,7 @@ phutil_require_module('phabricator', 'view/form/control/text');
|
||||||
phutil_require_module('phabricator', 'view/form/control/tokenizer');
|
phutil_require_module('phabricator', 'view/form/control/tokenizer');
|
||||||
phutil_require_module('phabricator', 'view/layout/listfilter');
|
phutil_require_module('phabricator', 'view/layout/listfilter');
|
||||||
phutil_require_module('phabricator', 'view/layout/panel');
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
phutil_require_module('phabricator', 'view/utils');
|
||||||
|
|
||||||
phutil_require_module('phutil', 'markup');
|
phutil_require_module('phutil', 'markup');
|
||||||
phutil_require_module('phutil', 'utils');
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
|
@ -137,6 +137,14 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController {
|
||||||
$e_realname = 'Required';
|
$e_realname = 'Required';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$new_timezone = $request->getStr('timezone');
|
||||||
|
if (in_array($new_timezone, DateTimeZone::listIdentifiers(), true)) {
|
||||||
|
$user->setTimezoneIdentifier($new_timezone);
|
||||||
|
} else {
|
||||||
|
$errors[] =
|
||||||
|
'The selected timezone is not a valid timezone.';
|
||||||
|
}
|
||||||
|
|
||||||
if (!$errors) {
|
if (!$errors) {
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
||||||
|
@ -324,6 +332,9 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController {
|
||||||
))));
|
))));
|
||||||
|
|
||||||
if ($editable) {
|
if ($editable) {
|
||||||
|
$timezone_ids = DateTimeZone::listIdentifiers();
|
||||||
|
$timezone_id_map = array_combine($timezone_ids, $timezone_ids);
|
||||||
|
|
||||||
$form
|
$form
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormFileControl())
|
id(new AphrontFormFileControl())
|
||||||
|
@ -333,6 +344,15 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController {
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormMarkupControl())
|
id(new AphrontFormMarkupControl())
|
||||||
->setValue('<hr />'))
|
->setValue('<hr />'))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormSelectControl())
|
||||||
|
->setLabel('Timezone')
|
||||||
|
->setName('timezone')
|
||||||
|
->setOptions($timezone_id_map)
|
||||||
|
->setValue($user->getTimezoneIdentifier()))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormMarkupControl())
|
||||||
|
->setValue('<hr />'))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormSubmitControl())
|
id(new AphrontFormSubmitControl())
|
||||||
->setValue('Save'));
|
->setValue('Save'));
|
||||||
|
|
|
@ -22,6 +22,7 @@ phutil_require_module('phabricator', 'view/dialog');
|
||||||
phutil_require_module('phabricator', 'view/form/base');
|
phutil_require_module('phabricator', 'view/form/base');
|
||||||
phutil_require_module('phabricator', 'view/form/control/file');
|
phutil_require_module('phabricator', 'view/form/control/file');
|
||||||
phutil_require_module('phabricator', 'view/form/control/markup');
|
phutil_require_module('phabricator', 'view/form/control/markup');
|
||||||
|
phutil_require_module('phabricator', 'view/form/control/select');
|
||||||
phutil_require_module('phabricator', 'view/form/control/static');
|
phutil_require_module('phabricator', 'view/form/control/static');
|
||||||
phutil_require_module('phabricator', 'view/form/control/submit');
|
phutil_require_module('phabricator', 'view/form/control/submit');
|
||||||
phutil_require_module('phabricator', 'view/form/control/text');
|
phutil_require_module('phabricator', 'view/form/control/text');
|
||||||
|
|
|
@ -27,6 +27,7 @@ class PhabricatorUser extends PhabricatorUserDAO {
|
||||||
protected $passwordSalt;
|
protected $passwordSalt;
|
||||||
protected $passwordHash;
|
protected $passwordHash;
|
||||||
protected $profileImagePHID;
|
protected $profileImagePHID;
|
||||||
|
protected $timezoneIdentifier;
|
||||||
|
|
||||||
protected $consoleEnabled = 0;
|
protected $consoleEnabled = 0;
|
||||||
protected $consoleVisible = 0;
|
protected $consoleVisible = 0;
|
||||||
|
|
|
@ -16,6 +16,24 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
function phabricator_date($epoch, $user) {
|
||||||
|
$zone = new DateTimeZone($user->getTimezoneIdentifier());
|
||||||
|
$date = new DateTime('@'.$epoch, $zone);
|
||||||
|
return $date->format('M j Y');
|
||||||
|
}
|
||||||
|
|
||||||
|
function phabricator_time($epoch, $user) {
|
||||||
|
$zone = new DateTimeZone($user->getTimezoneIdentifier());
|
||||||
|
$date = new DateTime('@'.$epoch, $zone);
|
||||||
|
return $date->format('g:i A');
|
||||||
|
}
|
||||||
|
|
||||||
|
function phabricator_datetime($epoch, $user) {
|
||||||
|
$zone = new DateTimeZone($user->getTimezoneIdentifier());
|
||||||
|
$date = new DateTime('@'.$epoch, $zone);
|
||||||
|
return $date->format('M j Y, g:i A');
|
||||||
|
}
|
||||||
|
|
||||||
function phabricator_format_relative_time($duration) {
|
function phabricator_format_relative_time($duration) {
|
||||||
return phabricator_format_units_generic(
|
return phabricator_format_units_generic(
|
||||||
$duration,
|
$duration,
|
||||||
|
|
Loading…
Reference in a new issue