@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add date format preference and respect it in date selection controls

Summary: Ref T8362, Add date format preference and respect it in date selection controls

Test Plan: Set date format preference in the user settings panels, create new event, select new start date in the correct format.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: jasonrumney, eadler, epriestley, Korvin

Maniphest Tasks: T8362

Differential Revision: https://secure.phabricator.com/D13262

+199 -23
+23 -6
src/applications/settings/panel/PhabricatorDateTimeSettingsPanel.php
··· 19 19 $username = $user->getUsername(); 20 20 21 21 $pref_time = PhabricatorUserPreferences::PREFERENCE_TIME_FORMAT; 22 + $pref_date = PhabricatorUserPreferences::PREFERENCE_DATE_FORMAT; 22 23 $pref_week_start = PhabricatorUserPreferences::PREFERENCE_WEEK_START_DAY; 23 24 $preferences = $user->loadPreferences(); 24 25 ··· 31 32 $errors[] = pht('The selected timezone is not a valid timezone.'); 32 33 } 33 34 34 - $preferences->setPreference( 35 - $pref_time, 36 - $request->getStr($pref_time)); 37 - $preferences->setPreference( 38 - $pref_week_start, 39 - $request->getStr($pref_week_start)); 35 + $preferences 36 + ->setPreference( 37 + $pref_time, 38 + $request->getStr($pref_time)) 39 + ->setPreference( 40 + $pref_date, 41 + $request->getStr($pref_date)) 42 + ->setPreference( 43 + $pref_week_start, 44 + $request->getStr($pref_week_start)); 40 45 41 46 if (!$errors) { 42 47 $preferences->save(); ··· 69 74 ->setCaption( 70 75 pht('Format used when rendering a time of day.')) 71 76 ->setValue($preferences->getPreference($pref_time))) 77 + ->appendChild( 78 + id(new AphrontFormSelectControl()) 79 + ->setLabel(pht('Date Format')) 80 + ->setName($pref_date) 81 + ->setOptions(array( 82 + 'Y-m-d' => pht('ISO 8601 (2000-02-28)'), 83 + 'n/j/Y' => pht('US (2/28/2000)'), 84 + 'd-m-Y' => pht('European (28-02-2000)'), 85 + )) 86 + ->setCaption( 87 + pht('Format used when rendering a date.')) 88 + ->setValue($preferences->getPreference($pref_date))) 72 89 ->appendChild( 73 90 id(new AphrontFormSelectControl()) 74 91 ->setLabel(pht('Week Starts On'))
+1
src/applications/settings/storage/PhabricatorUserPreferences.php
··· 8 8 const PREFERENCE_MULTIEDIT = 'multiedit'; 9 9 const PREFERENCE_TITLES = 'titles'; 10 10 const PREFERENCE_MONOSPACED_TEXTAREAS = 'monospaced-textareas'; 11 + const PREFERENCE_DATE_FORMAT = 'date-format'; 11 12 const PREFERENCE_TIME_FORMAT = 'time-format'; 12 13 const PREFERENCE_WEEK_START_DAY = 'week-start-day'; 13 14
+18 -2
src/view/form/control/AphrontFormDateControl.php
··· 127 127 } 128 128 129 129 private function getDateInputValue() { 130 - return $this->valueDate; 130 + $date_format = $this->getDateFormat(); 131 + $timezone = $this->getTimezone(); 132 + 133 + $datetime = new DateTime($this->valueDate, $timezone); 134 + $date = $datetime->format($date_format); 135 + 136 + return $date; 137 + } 138 + 139 + private function getDateFormat() { 140 + $viewer = $this->getUser(); 141 + $preferences = $viewer->loadPreferences(); 142 + $pref_date_format = PhabricatorUserPreferences::PREFERENCE_DATE_FORMAT; 143 + 144 + return $preferences->getPreference($pref_date_format, 'Y-m-d'); 131 145 } 132 146 133 147 private function getTimeInputValue() { ··· 242 256 ), 243 257 $time_sel); 244 258 245 - Javelin::initBehavior('fancy-datepicker', array()); 259 + Javelin::initBehavior('fancy-datepicker', array( 260 + 'format' => $this->getDateFormat(), 261 + )); 246 262 247 263 $classes = array(); 248 264 $classes[] = 'aphront-form-date-container';
+59 -5
src/view/form/control/AphrontFormDateControlValue.php
··· 10 10 private $zone; 11 11 private $optional; 12 12 13 + 13 14 public function getValueDate() { 14 15 return $this->valueDate; 15 16 } ··· 65 66 66 67 $value = new AphrontFormDateControlValue(); 67 68 $value->viewer = $viewer; 68 - $value->valueDate = $month.'/'.$day.'/'.$year; 69 + $value->valueDate = $value->getFormattedDateFromParts( 70 + $year, 71 + $month, 72 + $day, 73 + $value); 69 74 $value->valueTime = coalesce($time, '12:00 AM'); 70 75 $value->valueEnabled = $enabled; 71 76 ··· 75 80 public static function newFromRequest(AphrontRequest $request, $key) { 76 81 $value = new AphrontFormDateControlValue(); 77 82 $value->viewer = $request->getViewer(); 78 - $value->valueDate = $request->getStr($key.'_d'); 83 + 84 + $value->valueDate = $value->getFormattedDateFromDate( 85 + $request->getStr($key.'_d'), 86 + $value); 87 + 79 88 $value->valueTime = $request->getStr($key.'_t'); 80 89 $value->valueEnabled = $request->getStr($key.'_e'); 81 - 82 90 return $value; 83 91 } 84 92 ··· 92 100 $month = $readable[1]; 93 101 $day = $readable[2]; 94 102 95 - $value->valueDate = $month.'/'.$day.'/'.$year; 103 + $value->valueDate = $value->getFormattedDateFromParts( 104 + $year, 105 + $month, 106 + $day, 107 + $value); 96 108 $value->valueTime = $readable[3]; 97 109 98 110 ··· 105 117 $value = new AphrontFormDateControlValue(); 106 118 $value->viewer = $viewer; 107 119 108 - $value->valueDate = idx($dictionary, 'd'); 120 + $value->valueDate = $value->getFormattedDateFromDate( 121 + idx($dictionary, 'd'), 122 + $value); 123 + 109 124 $value->valueTime = idx($dictionary, 't'); 110 125 $value->valueEnabled = idx($dictionary, 'e'); 111 126 ··· 183 198 $value = null; 184 199 } 185 200 return $value; 201 + } 202 + 203 + private function getDateFormat() { 204 + $preferences = $this->viewer->loadPreferences(); 205 + $pref_date_format = PhabricatorUserPreferences::PREFERENCE_DATE_FORMAT; 206 + 207 + return $preferences->getPreference($pref_date_format, 'Y-m-d'); 208 + } 209 + 210 + private function getFormattedDateFromDate($date, $value) { 211 + $original_input = $date; 212 + $zone = $value->getTimezone(); 213 + $separator = $value->getFormatSeparator(); 214 + $parts = preg_split('@[,./:-]@', $date); 215 + $date = implode($separator, $parts); 216 + $date = id(new DateTime($date, $zone)); 217 + 218 + if ($date) { 219 + return $date->format($value->getDateFormat()); 220 + } else { 221 + return $original_input; 222 + } 223 + } 224 + 225 + private function getFormattedDateFromParts($year, $month, $day, $value) { 226 + $zone = $value->getTimezone(); 227 + 228 + return id(new DateTime("{$year}-{$month}-{$day}", $zone)) 229 + ->format($value->getDateFormat()); 230 + } 231 + 232 + private function getFormatSeparator() { 233 + $format = $this->getDateFormat(); 234 + switch ($format) { 235 + case 'n/j/Y': 236 + return '/'; 237 + default: 238 + return '-'; 239 + } 186 240 } 187 241 188 242 public function getDateTime() {
+98 -10
webroot/rsrc/js/core/behavior-fancy-datepicker.js
··· 7 7 * javelin-vector 8 8 */ 9 9 10 - JX.behavior('fancy-datepicker', function() { 10 + JX.behavior('fancy-datepicker', function(config, statics) { 11 + if (statics.initialized) { 12 + return; 13 + } 14 + statics.initialized = true; 11 15 12 16 var picker; 13 17 var root; ··· 15 19 var value_y; 16 20 var value_m; 17 21 var value_d; 22 + 23 + var get_format_separator = function() { 24 + var format = get_format(); 25 + switch (format.toLowerCase()) { 26 + case 'n/j/y': 27 + return '/'; 28 + default: 29 + return '-'; 30 + } 31 + }; 32 + 33 + var get_key_maps = function() { 34 + var format = get_format(); 35 + var regex = new RegExp('[./ -]'); 36 + return format.split(regex); 37 + }; 38 + 39 + var get_format = function() { 40 + var format = config.format; 41 + 42 + if (format === null) { 43 + format = 'Y-m-d'; 44 + } 45 + 46 + return format; 47 + }; 18 48 19 49 var onopen = function(e) { 20 50 e.kill(); ··· 85 115 }; 86 116 }; 87 117 88 - var read_date = function() { 89 - var i = get_inputs(); 90 - var date = i.d.value; 91 - var parts = date.split('/'); 92 - value_y = +parts[2]; 93 - value_m = +parts[0]; 94 - value_d = +parts[1]; 118 + var read_date = function(){ 119 + var inputs = get_inputs(); 120 + var date = inputs.d.value; 121 + var regex = new RegExp('[./ -]'); 122 + var date_parts = date.split(regex); 123 + var map = get_key_maps(); 124 + 125 + for (var i=0; i < date_parts.length; i++) { 126 + var key = map[i].toLowerCase(); 127 + 128 + switch (key) { 129 + case 'y': 130 + value_y = date_parts[i]; 131 + break; 132 + case 'm': 133 + value_m = date_parts[i]; 134 + break; 135 + case 'd': 136 + value_d = date_parts[i]; 137 + break; 138 + } 139 + } 95 140 }; 96 141 97 142 var write_date = function() { 98 - var i = get_inputs(); 99 - i.d.value = value_m + '/' + value_d + '/' + value_y; 143 + var inputs = get_inputs(); 144 + var map = get_key_maps(); 145 + var arr_values = []; 146 + 147 + for(var i=0; i < map.length; i++) { 148 + switch (map[i].toLowerCase()) { 149 + case 'y': 150 + arr_values[i] = value_y; 151 + break; 152 + case 'm': 153 + arr_values[i] = value_m; 154 + break; 155 + case 'n': 156 + arr_values[i] = value_m; 157 + break; 158 + case 'd': 159 + arr_values[i] = value_d; 160 + break; 161 + case 'j': 162 + arr_values[i] = value_d; 163 + break; 164 + } 165 + } 166 + 167 + var text_value = ''; 168 + var separator = get_format_separator(); 169 + 170 + for(var j=0; j < arr_values.length; j++) { 171 + var element = arr_values[j]; 172 + var format = get_format(); 173 + 174 + if ((format.toLowerCase() === 'd-m-y' || 175 + format.toLowerCase() === 'y-m-d') && 176 + element < 10) { 177 + element = '0' + element; 178 + } 179 + 180 + if (text_value.length === 0) { 181 + text_value += element; 182 + } else { 183 + text_value = text_value + separator + element; 184 + } 185 + } 186 + 187 + inputs.d.value = text_value; 100 188 }; 101 189 102 190 var render = function() {