From c405f03ce757c91d242fecb409995a77385ab215 Mon Sep 17 00:00:00 2001 From: Max Pozdeev Date: Mon, 25 Oct 2010 10:45:04 +0400 Subject: [PATCH] * Time zone have to be specified in settings --- src/ajax.php | 60 ++++++++++++++-------------------- src/common.php | 22 ++++++++++++- src/db/config.php.default | 4 +-- src/init.php | 15 +++++---- src/lang/class.default.php | 3 +- src/lang/en.php | 3 +- src/mytinytodo.js | 14 +++----- src/mytinytodo_ajax_storage.js | 12 +++---- src/settings.php | 43 +++++++++++++++++------- 9 files changed, 100 insertions(+), 76 deletions(-) diff --git a/src/ajax.php b/src/ajax.php index 5fdb631..1e32968 100644 --- a/src/ajax.php +++ b/src/ajax.php @@ -11,7 +11,7 @@ set_exception_handler('myExceptionHandler'); require_once('./init.php'); -$lang = Lang::instance(); +$db = DBConnection::instance(); if(isset($_GET['loadLists'])) { @@ -76,8 +76,6 @@ elseif(isset($_GET['loadTasks'])) if($sort == 1) $sqlSort .= "prio DESC, ddn ASC, duedate ASC, ow ASC"; elseif($sort == 2) $sqlSort .= "ddn ASC, duedate ASC, prio DESC, ow ASC"; else $sqlSort .= "ow ASC"; - $tz = (int)_get('tz'); - if(Config::get('autotz')==0 || $tz<-720 || $tz>720 || $tz%30!=0) $tz = round(date('Z')/60); $t = array(); $t['total'] = 0; $t['list'] = array(); @@ -85,7 +83,7 @@ elseif(isset($_GET['loadTasks'])) while($r = $q->fetch_assoc($q)) { $t['total']++; - $t['list'][] = prepareTaskRow($r, $tz); + $t['list'][] = prepareTaskRow($r); } if(_get('setCompl') && have_write_access()) { $bitwise = (_get('compl') == 0) ? 'taskview & ~1' : 'taskview | 1'; @@ -120,8 +118,6 @@ elseif(isset($_GET['newTask'])) exit; } if(Config::get('autotag')) $tags .= ','._post('tag'); - $tz = (int)_post('tz'); - if(Config::get('autotz')==0 || $tz<-720 || $tz>720 || $tz%30!=0 ) $tz = round(date('Z')/60); $ow = 1 + (int)$db->sq("SELECT MAX(ow) FROM {$db->prefix}todolist WHERE list_id=$listId AND compl=0"); $db->ex("BEGIN"); $db->dq("INSERT INTO {$db->prefix}todolist (uuid,list_id,title,d_created,d_edited,ow,prio) VALUES (?,?,?,?,?,?,?)", @@ -137,7 +133,7 @@ elseif(isset($_GET['newTask'])) } $db->ex("COMMIT"); $r = $db->sqa("SELECT * FROM {$db->prefix}todolist WHERE id=$id"); - $t['list'][] = prepareTaskRow($r, $tz); + $t['list'][] = prepareTaskRow($r); $t['total'] = 1; echo json_encode($t); exit; @@ -161,8 +157,6 @@ elseif(isset($_GET['fullNewTask'])) } $tags = trim(_post('tags')); if(Config::get('autotag')) $tags .= ','._post('tag'); - $tz = (int)_post('tz'); - if( Config::get('autotz')==0 || $tz<-720 || $tz>720 || $tz%30!=0 ) $tz = round(date('Z')/60); $ow = 1 + (int)$db->sq("SELECT MAX(ow) FROM {$db->prefix}todolist WHERE list_id=$listId AND compl=0"); $db->ex("BEGIN"); $db->dq("INSERT INTO {$db->prefix}todolist (uuid,list_id,title,d_created,d_edited,ow,prio,note,duedate) VALUES(?,?,?,?,?,?,?,?,?)", @@ -178,7 +172,7 @@ elseif(isset($_GET['fullNewTask'])) } $db->ex("COMMIT"); $r = $db->sqa("SELECT * FROM {$db->prefix}todolist WHERE id=$id"); - $t['list'][] = prepareTaskRow($r, $tz); + $t['list'][] = prepareTaskRow($r); $t['total'] = 1; echo json_encode($t); exit; @@ -204,11 +198,9 @@ elseif(isset($_GET['completeTask'])) $dateCompleted = $compl ? time() : 0; $db->dq("UPDATE {$db->prefix}todolist SET compl=$compl,ow=$ow,d_completed=?,d_edited=? WHERE id=$id", array($dateCompleted, time()) ); - $tz = (int)_post('tz'); - if(Config::get('autotz')==0 || $tz<-720 || $tz>720 || $tz%30!=0) $tz = round(date('Z')/60); $t = array(); $t['total'] = 1; - $t['list'][] = array('id'=>$id, 'compl'=>$compl, 'ow'=>$ow, 'dateCompleted'=>$dateCompleted?htmlarray(timestampToDatetime($dateCompleted, $tz)):''); + $t['list'][] = array('id'=>$id, 'compl'=>$compl, 'ow'=>$ow, 'dateCompleted'=>$dateCompleted?htmlarray(timestampToDatetime($dateCompleted)):''); echo json_encode($t); exit; } @@ -243,8 +235,6 @@ elseif(isset($_GET['editTask'])) echo json_encode($t); exit; } - $tz = (int)_post('tz'); - if( Config::get('autotz')==0 || $tz<-720 || $tz>720 || $tz%30!=0 ) $tz = round(date('Z')/60); $tags = trim(_post('tags')); $db->ex("BEGIN"); $db->ex("DELETE FROM {$db->prefix}tag2task WHERE task_id=$id"); @@ -259,7 +249,7 @@ elseif(isset($_GET['editTask'])) $db->ex("COMMIT"); $r = $db->sqa("SELECT * FROM {$db->prefix}todolist WHERE id=$id"); if($r) { - $t['list'][] = prepareTaskRow($r, $tz); + $t['list'][] = prepareTaskRow($r); $t['total'] = 1; } echo json_encode($t); @@ -530,25 +520,25 @@ elseif(isset($_GET['setShowNotesInList'])) ################################################################################################### -function prepareTaskRow($r, $tz) +function prepareTaskRow($r) { - global $lang; - $dueA = prepare_duedate($r['duedate'], $tz); + $lang = Lang::instance(); + $dueA = prepare_duedate($r['duedate']); $formatCreatedInline = $formatCompletedInline = 'M d'; if(date('Y') != date('Y',$r['d_created'])) $formatCreatedInline = 'M Y'; if($r['d_completed'] && date('Y') != date('Y',$r['d_completed'])) $formatCompletedInline = 'M Y'; - $dCreated = timestampToDatetime($r['d_created'], $tz); - $dCompleted = $r['d_completed'] ? timestampToDatetime($r['d_completed'], $tz) : ''; + $dCreated = timestampToDatetime($r['d_created']); + $dCompleted = $r['d_completed'] ? timestampToDatetime($r['d_completed']) : ''; return array( 'id' => $r['id'], 'title' => escapeTags($r['title']), 'date' => htmlarray($dCreated), - 'dateInline' => htmlarray(formatTime($formatCreatedInline, $r['d_created'], $tz)), + 'dateInline' => htmlarray(formatTime($formatCreatedInline, $r['d_created'])), 'dateInlineTitle' => htmlarray(sprintf($lang->get('taskdate_inline_created'), $dCreated)), 'dateCompleted' => htmlarray($dCompleted), - 'dateCompletedInline' => $r['d_completed'] ? htmlarray(formatTime($formatCompletedInline, $r['d_completed'], $tz)) : '', + 'dateCompletedInline' => $r['d_completed'] ? htmlarray(formatTime($formatCompletedInline, $r['d_completed'])) : '', 'dateCompletedInlineTitle' => htmlarray(sprintf($lang->get('taskdate_inline_completed'), $dCompleted)), 'compl' => (int)$r['compl'], 'prio' => $r['prio'], @@ -559,7 +549,7 @@ function prepareTaskRow($r, $tz) 'tags_ids' => htmlarray($r['tags_ids']), 'duedate' => $dueA['formatted'], 'dueClass' => $dueA['class'], - 'dueStr' => htmlarray($r['compl'] && $dueA['timestamp'] ? formatTime($formatCompletedInline, $dueA['timestamp'], $tz) : $dueA['str']), + 'dueStr' => htmlarray($r['compl'] && $dueA['timestamp'] ? formatTime($formatCompletedInline, $dueA['timestamp']) : $dueA['str']), 'dueInt' => date2int($r['duedate']), 'dueTitle' => htmlarray(sprintf($lang->get('taskdate_inline_duedate'), $dueA['formatted'])), ); @@ -567,7 +557,7 @@ function prepareTaskRow($r, $tz) function check_read_access($listId = null) { - global $db; + $db = DBConnection::instance(); if(Config::get('password') == '') return true; if(is_logged()) return true; if($listId) @@ -631,7 +621,7 @@ function prepareTags($tagsStr) function getOrCreateTag($name) { - global $db; + $db = DBConnection::instance(); $tagId = $db->sq("SELECT id FROM {$db->prefix}tags WHERE name=?", array($name)); if($tagId) return array('id'=>$tagId, 'name'=>$name); @@ -641,14 +631,14 @@ function getOrCreateTag($name) function getTagId($tag) { - global $db; + $db = DBConnection::instance(); $id = $db->sq("SELECT id FROM {$db->prefix}tags WHERE name=?", array($tag)); return $id ? $id : 0; } function get_task_tags($id) { - global $db; + $db = DBConnection::instance(); $q = $db->dq("SELECT tag_id FROM {$db->prefix}tag2task WHERE task_id=?", $id); $a = array(); while($r = $q->fetch_row()) { @@ -660,7 +650,7 @@ function get_task_tags($id) function addTaskTags($taskId, $tagIds, $listId) { - global $db; + $db = DBConnection::instance(); if(!$tagIds) return; foreach($tagIds as $tagId) { @@ -734,17 +724,17 @@ function parse_duedate($s) return "$y-$m-$d"; } -function prepare_duedate($duedate, $tz) +function prepare_duedate($duedate) { - global $lang; + $lang = Lang::instance(); $a = array( 'class'=>'', 'str'=>'', 'formatted'=>'', 'timestamp'=>0 ); if($duedate == '') { return $a; } $ad = explode('-', $duedate); - $at = explode('-', gmdate('Y-m-d', time() + $tz*60)); - $a['timestamp'] = gmmktime(0,0,0,$ad[1],$ad[2],$ad[0]) + $tz*60; + $at = explode('-', date('Y-m-d')); + $a['timestamp'] = mktime(0,0,0,$ad[1],$ad[2],$ad[0]); $diff = mktime(0,0,0,$ad[1],$ad[2],$ad[0]) - mktime(0,0,0,$at[1],$at[2],$at[0]); if($diff < -604800 && $ad[0] == $at[0]) { $a['class'] = 'past'; $a['str'] = formatDate3(Config::get('dateformatshort'), (int)$ad[0], (int)$ad[1], (int)$ad[2], $lang); } @@ -811,7 +801,7 @@ function myExceptionHandler($e) function deleteTask($id) { check_write_access(); - global $db; + $db = DBConnection::instance(); $db->ex("BEGIN"); $db->ex("DELETE FROM {$db->prefix}tag2task WHERE task_id=$id"); //TODO: delete unused tags? @@ -824,7 +814,7 @@ function deleteTask($id) function moveTask($id, $listId) { check_write_access(); - global $db; + $db = DBConnection::instance(); // Check task exists and not in target list $r = $db->sqa("SELECT * FROM {$db->prefix}todolist WHERE id=?", array($id)); diff --git a/src/common.php b/src/common.php index b9b9d52..d36f7cb 100644 --- a/src/common.php +++ b/src/common.php @@ -73,7 +73,7 @@ class Config 'lang' => array('default'=>'en', 'type'=>'s'), 'password' => array('default'=>'', 'type'=>'s'), 'smartsyntax' => array('default'=>1, 'type'=>'i'), - 'autotz' => array('default'=>1, 'type'=>'i'), + 'timezone' => array('default'=>'UTC', 'type'=>'s'), 'autotag' => array('default'=>1, 'type'=>'i'), 'duedateformat' => array('default'=>1, 'type'=>'i'), 'firstdayofweek' => array('default'=>1, 'type'=>'i'), @@ -176,5 +176,25 @@ function generateUUID() ); } +class DBConnection +{ + protected static $instance; + + public static function init($instance) + { + self::$instance = $instance; + return $instance; + } + + public static function instance() + { + if (!isset(self::$instance)) { + //$c = __CLASS__; + $c = 'DBConnection'; + self::$instance = new $c; + } + return self::$instance; + } +} ?> \ No newline at end of file diff --git a/src/db/config.php.default b/src/db/config.php.default index fcded0b..564bf55 100644 --- a/src/db/config.php.default +++ b/src/db/config.php.default @@ -31,8 +31,8 @@ $config['password'] = ""; # To disable smart syntax uncomment the line below #$config['smartsyntax'] = 0; -# To disable auto detecting user time zone uncomment the line below -#$config['autotz'] = 0; +# Default Time zone +$config['timezone'] = 'UTC'; # To disable auto adding selected tag comment out the line below or set value to 0 $config['autotag'] = 1; diff --git a/src/init.php b/src/init.php index 66da6ec..14b9fa7 100644 --- a/src/init.php +++ b/src/init.php @@ -16,11 +16,13 @@ if(!isset($config)) global $config; Config::loadConfig($config); unset($config); +date_default_timezone_set(Config::get('timezone')); + # MySQL Database Connection if(Config::get('db') == 'mysql') { require_once(MTTPATH. 'class.db.mysql.php'); - $db = new Database_Mysql; + $db = DBConnection::init(new Database_Mysql); $db->connect(Config::get('mysql.host'), Config::get('mysql.user'), Config::get('mysql.password'), Config::get('mysql.db')); $db->dq("SET NAMES utf8"); } @@ -29,7 +31,7 @@ if(Config::get('db') == 'mysql') elseif(Config::get('db') == 'sqlite') { require_once(MTTPATH. 'class.db.sqlite3.php'); - $db = new Database_Sqlite3; + $db = DBConnection::init(new Database_Sqlite3); $db->connect(MTTPATH. 'db/todolist.db'); } else { @@ -67,19 +69,18 @@ function is_logged() return true; } -function timestampToDatetime($timestamp, $tz) +function timestampToDatetime($timestamp) { $format = Config::get('dateformat') .' '. (Config::get('clock') == 12 ? 'g:i A' : 'H:i'); - return formatTime($format, $timestamp, $tz); + return formatTime($format, $timestamp); } -function formatTime($format, $timestamp=0, $tz=null) +function formatTime($format, $timestamp=0) { $lang = Lang::instance(); if($timestamp == 0) $timestamp = time(); - if(is_null($tz)) $tz = round(date('Z')/60); $newformat = strtr($format, array('F'=>'%1', 'M'=>'%2')); - $adate = explode(',', gmdate('n,'.$newformat, $timestamp + $tz*60), 2); + $adate = explode(',', date('n,'.$newformat, $timestamp), 2); $s = $adate[1]; if($newformat != $format) { diff --git a/src/lang/class.default.php b/src/lang/class.default.php index b60a6f1..0f8514c 100644 --- a/src/lang/class.default.php +++ b/src/lang/class.default.php @@ -111,8 +111,7 @@ class DefaultLang 'set_newpass_descr' => "(leave blank if won't change current password)", 'set_smartsyntax' => "Smart syntax", 'set_smartsyntax_descr' => "(/priority/ task /tags/)", - 'set_autotz' => "Automatic timezone", - 'set_autotz_descr' => "(determines timezone offset of user environment with javascript)", + 'set_timezone' => "Time zone", 'set_autotag' => "Autotagging", 'set_autotag_descr' => "(automatically adds tag of current tag filter to newly created task)", 'set_sessions' => "Session handling mechanism", diff --git a/src/lang/en.php b/src/lang/en.php index 0374455..bf995ba 100644 --- a/src/lang/en.php +++ b/src/lang/en.php @@ -113,8 +113,7 @@ class Lang extends DefaultLang 'set_newpass_descr' => "(leave blank if won't change current password)", 'set_smartsyntax' => "Smart syntax", 'set_smartsyntax_descr' => "(/priority/ task /tags/)", - 'set_autotz' => "Automatic timezone", - 'set_autotz_descr' => "(determines timezone offset of user environment with javascript)", + 'set_timezone' => "Time zone", 'set_autotag' => "Autotagging", 'set_autotag_descr' => "(automatically adds tag of current tag filter to newly created task)", 'set_sessions' => "Session handling mechanism", diff --git a/src/mytinytodo.js b/src/mytinytodo.js index 5efc021..d48b065 100644 --- a/src/mytinytodo.js +++ b/src/mytinytodo.js @@ -704,7 +704,6 @@ function loadTasks(opts) sort: curList.sort, search: filter.search, tag: _mtt.filter.getTags(true), - tz: tz(), setCompl: opts.setCompl }, function(json){ taskList.length = 0; @@ -799,7 +798,7 @@ function prepareDuedate(item) function submitNewTask(form) { if(form.task.value == '') return false; - _mtt.db.request('newTask', { list:curList.id, title: form.task.value, tz:tz(), tag:_mtt.filter.getTags() }, function(json){ + _mtt.db.request('newTask', { list:curList.id, title: form.task.value, tag:_mtt.filter.getTags() }, function(json){ if(!json.total) return; $('#total').text( parseInt($('#total').text()) + 1 ); taskCnt.total++; @@ -917,11 +916,6 @@ function setSort(v, init) }; -function tz() -{ - return -1 * (new Date()).getTimezoneOffset(); -}; - function changeTaskCnt(task, dir, old) { if(dir > 0) dir = 1; @@ -1064,7 +1058,7 @@ function completeTask(id, ch) if(!taskList[id]) return; //click on already removed from the list while anim. effect var compl = 0; if(ch.checked) compl = 1; - _mtt.db.request('completeTask', {id:id, compl:compl, list:curList.id, tz:tz()}, function(json){ + _mtt.db.request('completeTask', {id:id, compl:compl, list:curList.id}, function(json){ if(!parseInt(json.total)) return; var item = json.list[0]; if(item.compl) $('#taskrow_'+id).addClass('task-completed'); @@ -1170,7 +1164,7 @@ function showEditForm(isAdd) if(_mtt.options.autotag) form.tags.value = _mtt.filter.getTags(); if($('#task').val() != '') { - _mtt.db.request('parseTaskStr', { list:curList.id, title:$('#task').val(), tz:tz(), tag:_mtt.filter.getTags() }, function(json){ + _mtt.db.request('parseTaskStr', { list:curList.id, title:$('#task').val(), tag:_mtt.filter.getTags() }, function(json){ if(!json) return; form.task.value = json.title form.tags.value = (form.tags.value != '') ? form.tags.value +', '+ json.tags : json.tags; @@ -1194,7 +1188,7 @@ function saveTask(form) if(form.isadd.value != 0) return submitFullTask(form); - _mtt.db.request('editTask', {id:form.id.value, list:curList.id, tz:tz(), title: form.task.value, note:form.note.value, + _mtt.db.request('editTask', {id:form.id.value, list:curList.id, title: form.task.value, note:form.note.value, prio:form.prio.value, tags:form.tags.value, duedate:form.duedate.value}, function(json){ if(!parseInt(json.total)) return; diff --git a/src/mytinytodo_ajax_storage.js b/src/mytinytodo_ajax_storage.js index a1c33c1..26395ac 100644 --- a/src/mytinytodo_ajax_storage.js +++ b/src/mytinytodo_ajax_storage.js @@ -50,21 +50,21 @@ mytinytodoStorageAjax.prototype = }) */ - $.getJSON(this.mtt.mttUrl+'ajax.php?loadTasks&list='+params.list+'&compl='+params.compl+'&sort='+params.sort+'&tz='+params.tz+q, callback); + $.getJSON(this.mtt.mttUrl+'ajax.php?loadTasks&list='+params.list+'&compl='+params.compl+'&sort='+params.sort+q, callback); }, newTask: function(params, callback) { $.post(this.mtt.mttUrl+'ajax.php?newTask', - { list:params.list, title: params.title, tz:params.tz, tag:params.tag }, callback, 'json'); + { list:params.list, title: params.title, tag:params.tag }, callback, 'json'); }, fullNewTask: function(params, callback) { $.post(this.mtt.mttUrl+'ajax.php?fullNewTask', - { list:params.list, tz:params.tz, title:params.title, note:params.note, prio:params.prio, tags:params.tags, duedate:params.duedate }, + { list:params.list, title:params.title, note:params.note, prio:params.prio, tags:params.tags, duedate:params.duedate }, callback, 'json'); }, @@ -72,7 +72,7 @@ mytinytodoStorageAjax.prototype = editTask: function(params, callback) { $.post(this.mtt.mttUrl+'ajax.php?editTask='+params.id, - { id:params.id, list:params.list, tz:params.tz, title:params.title, note:params.note, prio:params.prio, tags:params.tags, duedate:params.duedate }, + { id:params.id, list:params.list, title:params.title, note:params.note, prio:params.prio, tags:params.tags, duedate:params.duedate }, callback, 'json'); }, @@ -85,7 +85,7 @@ mytinytodoStorageAjax.prototype = completeTask: function(params, callback) { - $.post(this.mtt.mttUrl+'ajax.php?completeTask='+params.id, { id:params.id, compl:params.compl, tz:params.tz }, callback, 'json'); + $.post(this.mtt.mttUrl+'ajax.php?completeTask='+params.id, { id:params.id, compl:params.compl }, callback, 'json'); }, @@ -127,7 +127,7 @@ mytinytodoStorageAjax.prototype = parseTaskStr: function(params, callback) { - $.post(this.mtt.mttUrl+'ajax.php?parseTaskStr', { list:params.list, title:params.title, tz:params.tz, tag:params.tag }, callback, 'json'); + $.post(this.mtt.mttUrl+'ajax.php?parseTaskStr', { list:params.list, title:params.title, tag:params.tag }, callback, 'json'); }, diff --git a/src/settings.php b/src/settings.php index 39fcaf6..1b31751 100644 --- a/src/settings.php +++ b/src/settings.php @@ -25,7 +25,14 @@ if(isset($_POST['save'])) if(isset($_POST['password']) && $_POST['password'] != '') Config::set('password', $_POST['password']); elseif(!_post('allowpassword')) Config::set('password', ''); Config::set('smartsyntax', (int)_post('smartsyntax')); - Config::set('autotz', (int)_post('autotz')); + // Do not set invalid timezone + try { + $tz = trim(_post('timezone')); + $testTZ = new DateTimeZone($tz); //will throw Exception on invalid timezone + Config::set('timezone', $tz); + } + catch (Exception $e) { + } Config::set('autotag', (int)_post('autotag')); Config::set('session', _post('session')); Config::set('firstdayofweek', (int)_post('firstdayofweek')); @@ -94,19 +101,34 @@ function selectOptions($a, $value, $default=null) return $s; } -function selectOptionsA($a, $value, $default=null) +/* + @param array $a array of id=>array(name, optional title) + @param mixed $key Key of OPTION to be selected + @param mixed $default Default key if $key is not present in $a +*/ +function selectOptionsA($a, $key, $default=null) { if(!$a) return ''; $s = ''; - if($default !== null && !isset($a[$value])) $value = $default; + if($default !== null && !isset($a[$key])) $key = $default; foreach($a as $k=>$v) { - $s .= ''; } return $s; } +function timezoneIdentifiers() +{ + $zones = DateTimeZone::listIdentifiers(); + $a = array(); + foreach($zones as $v) { + $a[$v] = $v; + } + return $a; +} + ?>
@@ -148,13 +170,6 @@ function selectOptionsA($a, $value, $default=null) - -:
- -
- - - :
@@ -169,6 +184,12 @@ function selectOptionsA($a, $value, $default=null) (<mytinytodo_dir>/tmp/sessions) + +: + + + + :