diff --git a/langs/ru.php b/langs/ru.php index a24e06e..9f6f9d0 100644 --- a/langs/ru.php +++ b/langs/ru.php @@ -76,6 +76,7 @@ class Lang extends DefaultLang 'alltags_show' => "Показать все", 'alltags_hide' => "Скрыть все", 'a_settings' => "Настройки", + 'rss_feed' => "RSS-лента", ); } diff --git a/src/ajax.js b/src/ajax.js index 391928d..7948030 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -863,7 +863,6 @@ function editFormResize(startstop, event) function mttTabSelected(el, indx) { - $(el.parentNode.parentNode).children('.mtt-tabs-selected').removeClass('mtt-tabs-selected'); $(el.parentNode).addClass('mtt-tabs-selected'); if(!tabLists[indx]) return; @@ -874,6 +873,7 @@ function mttTabSelected(el, indx) $('#searchbarkeyword').text(''); $('#searchbar').hide(); } + if(flag.canAllRead) $('#rss_icon').find('a').attr('href', 'feed.php?list='+tabLists[indx].id); } curList = tabLists[indx]; flag.tagsChanged = true; @@ -977,12 +977,14 @@ function loadLists(onInit) } curList = tabLists[0]; loadTasks(); + if(flag.canAllRead) $('#rss_icon').show().find('a').attr('href', 'feed.php?list='+curList.id); } else { curList = 0; $('#lists .mtt-htabs').children().addClass('invisible'); $('#page_tasks h3').children().addClass('invisible'); $('#mylistscontainer .mtt-need-list').addClass('li-disabled'); + $('#rss_icon').hide(); } ti += ''; $('#lists>ul').html(ti); @@ -1152,4 +1154,4 @@ function submitFullTask(form) $("#edittags").flushCache(); flag.tagsChanged = true; return false; -} \ No newline at end of file +} diff --git a/src/ajax.php b/src/ajax.php index d8ae08c..747c6af 100644 --- a/src/ajax.php +++ b/src/ajax.php @@ -596,15 +596,15 @@ function prepare_duedate($duedate, $tz=null) } $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['dateformatshort'], (int)$ad[0], (int)$ad[1], (int)$ad[2]); } - elseif($diff < -604800) { $a['class'] = 'past'; $a['str'] = formatDate3($config['dateformat'], (int)$ad[0], (int)$ad[1], (int)$ad[2]); } + if($diff < -604800 && $ad[0] == $at[0]) { $a['class'] = 'past'; $a['str'] = formatDate3($config['dateformatshort'], (int)$ad[0], (int)$ad[1], (int)$ad[2], $lang); } + elseif($diff < -604800) { $a['class'] = 'past'; $a['str'] = formatDate3($config['dateformat'], (int)$ad[0], (int)$ad[1], (int)$ad[2], $lang); } elseif($diff < -86400) { $a['class'] = 'past'; $a['str'] = sprintf($lang->get('daysago'),ceil(abs($diff)/86400)); } elseif($diff < 0) { $a['class'] = 'past'; $a['str'] = $lang->get('yesterday'); } elseif($diff < 86400) { $a['class'] = 'today'; $a['str'] = $lang->get('today'); } elseif($diff < 172800) { $a['class'] = 'today'; $a['str'] = $lang->get('tomorrow'); } elseif($diff < 691200) { $a['class'] = 'soon'; $a['str'] = sprintf($lang->get('indays'),ceil($diff/86400)); } - elseif($ad[0] == $at[0]) { $a['class'] = 'future'; $a['str'] = formatDate3($config['dateformatshort'], (int)$ad[0], (int)$ad[1], (int)$ad[2]); } - else { $a['class'] = 'future'; $a['str'] = formatDate3($config['dateformat'], (int)$ad[0], (int)$ad[1], (int)$ad[2]); } + elseif($ad[0] == $at[0]) { $a['class'] = 'future'; $a['str'] = formatDate3($config['dateformatshort'], (int)$ad[0], (int)$ad[1], (int)$ad[2], $lang); } + else { $a['class'] = 'future'; $a['str'] = formatDate3($config['dateformat'], (int)$ad[0], (int)$ad[1], (int)$ad[2], $lang); } if($config['duedateformat'] == 2) $a['formatted'] = (int)$ad[1].'/'.(int)$ad[2].'/'.$ad[0]; elseif($config['duedateformat'] == 3) $a['formatted'] = $ad[2].'.'.$ad[1].'.'.$ad[0]; @@ -656,25 +656,4 @@ function myExceptionHandler($e) exit; } -function formatDate3($format, $ay, $am, $ad) -{ - # F - month long, M - month short - # m - month 2-digit, n - month 1-digit - # d - day 2-digit, j - day 1-digit - global $lang; - $ml = $lang->get('months_long'); - $ms = $lang->get('months_short'); - $Y = $ay; - $n = $am; - $m = $n < 10 ? '0'.$n : $n; - $F = $ml[$am-1]; - $M = $ms[$am-1]; - $j = $ad; - $d = $j < 10 ? '0'.$j : $j; - return str_replace( - array('Y','F','M','n','m','d','j'), - array($Y, $F, $M, $n, $m, $d, $j), - $format); -} - ?> \ No newline at end of file diff --git a/src/common.php b/src/common.php index 7063323..2a17453 100644 --- a/src/common.php +++ b/src/common.php @@ -109,4 +109,24 @@ class Config } } +function formatDate3($format, $ay, $am, $ad, $lang) +{ + # F - month long, M - month short + # m - month 2-digit, n - month 1-digit + # d - day 2-digit, j - day 1-digit + $ml = $lang->get('months_long'); + $ms = $lang->get('months_short'); + $Y = $ay; + $n = $am; + $m = $n < 10 ? '0'.$n : $n; + $F = $ml[$am-1]; + $M = $ms[$am-1]; + $j = $ad; + $d = $j < 10 ? '0'.$j : $j; + return str_replace( + array('Y','F','M','n','m','d','j'), + array($Y, $F, $M, $n, $m, $d, $j), + $format); +} + ?> \ No newline at end of file diff --git a/src/feed.php b/src/feed.php new file mode 100644 index 0000000..95356d0 --- /dev/null +++ b/src/feed.php @@ -0,0 +1,78 @@ + + Licensed under the GNU GPL v3 license. See file COPYRIGHT for details. +*/ + +$dontStartSession = 1; +require_once('./init.php'); +require_once('./lang/class.default.php'); +require_once('./lang/'.$config['lang'].'.php'); +$lang = new Lang(); + +if(!canAllRead()) { + die("Access denied!
Disable password protection or Grant read access"); +} + +$listId = (int)_get('list'); + +$listData = $db->sqa("SELECT * FROM lists WHERE id=$listId"); +if(!$listData) { + die("No such list"); +} +htmlarray_ref($listData); + +$data = array(); +$q = $db->dq("SELECT * FROM todolist WHERE list_id=$listId ORDER BY d DESC LIMIT 100"); +while($r = $q->fetch_assoc($q)) +{ + if($r['prio'] > 0) $r['prio'] = '+'.$r['prio']; + $a = array(); + if($r['prio']) $a[] = $lang->get('priority'). ": $r[prio]"; + if($r['duedate'] != '') { + $ad = explode('-', $r['duedate']); + $a[] = $lang->get('due'). ": ".formatDate3($config['dateformat'], (int)$ad[0], (int)$ad[1], (int)$ad[2], $lang); + } + if($r['tags'] != '') $a[] = $lang->get('tags'). ": ". str_replace(',', ', ', $r['tags']); + $r['_descr'] = nl2br($r['note']). ($a && $r['note']!='' ? "

" : ""). implode("
", $a); + $data[] = htmlarray($r); +} + +printRss($listData, $data); + + +function printRss($listData, $data) +{ + $link = htmlarray('http://'. $_SERVER['HTTP_HOST']. substr($_SERVER['REQUEST_URI'], 0, strrpos($_SERVER['REQUEST_URI'], '/') + 1)); + $buildDate = gmdate('r'); + + $s = "\n\n\n". + "$listData[name]\n$link\nNew tasks in $listData[name]\n". + "$buildDate\n\n"; + + foreach($data as $v) + { + $da = explode(' ', $v['d']); + $dDate = explode('-', $da[0]); + $dTime = explode(':', $da[1]); + $d = gmdate('r', mktime((int)$dTime[0],(int)$dTime[1],(int)$dTime[2], (int)$dDate[1],(int)$dDate[2],(int)$dDate[0])); + + $guid = $listData['id'].'-'.$v['id'].'-'.$da[0].'_'.$da[1]; + + $s .= "\n$v[title]\n". + "$link\n". + "$d\n". + "$v[_descr]\n". + "$guid\n". + "\n"; + } + + $s .= "\n"; + + header("Content-type: text/xml"); + print $s; +} + +?> \ No newline at end of file diff --git a/src/images/feed.png b/src/images/feed.png new file mode 100644 index 0000000..315c4f4 Binary files /dev/null and b/src/images/feed.png differ diff --git a/src/images/feed_bw.png b/src/images/feed_bw.png new file mode 100644 index 0000000..669fcbf Binary files /dev/null and b/src/images/feed_bw.png differ diff --git a/src/index.php b/src/index.php index ad428fe..e888f19 100644 --- a/src/index.php +++ b/src/index.php @@ -124,6 +124,8 @@ $().ajaxStop( function(r,s) {$("#loading").fadeOut();} );   | + + diff --git a/src/init.php b/src/init.php index 1e0231c..0816b6c 100644 --- a/src/init.php +++ b/src/init.php @@ -24,7 +24,7 @@ else $needAuth = (isset($config['password']) && $config['password'] != '') ? 1 : 0; -if($needAuth) +if($needAuth && !isset($dontStartSession)) { if(isset($config['session']) && $config['session'] == 'files') { diff --git a/src/lang/class.default.php b/src/lang/class.default.php index 590549b..8184e55 100644 --- a/src/lang/class.default.php +++ b/src/lang/class.default.php @@ -76,6 +76,7 @@ class DefaultLang 'alltags_show' => "Show all", 'alltags_hide' => "Hide all", 'a_settings' => "Settings", + 'rss_feed' => "RSS Feed", ); var $js = array(); diff --git a/src/lang/en.php b/src/lang/en.php index f56030c..332f48a 100644 --- a/src/lang/en.php +++ b/src/lang/en.php @@ -71,6 +71,7 @@ class Lang extends DefaultLang 'alltags_show' => "Show all", 'alltags_hide' => "Hide all", 'a_settings' => "Settings", + 'rss_feed' => "RSS Feed", ); } diff --git a/src/style.css b/src/style.css index d92c693..4af1f4f 100644 --- a/src/style.css +++ b/src/style.css @@ -56,6 +56,7 @@ a { color:#0000ff; } #sortform .li:hover { background-color:#316AC5; color:white; } .mtt-notes-showhide { font-size:8pt; font-weight:normal; margin-left:5px; } +#rss_icon { float:right;margin-top:4px; } .task-left { float:left; } .task-left .mtt-toggle { margin-top:2px; cursor:pointer; width:15px; height:15px; float:left; background:url(images/toggle_plus.gif) left top no-repeat; } @@ -184,6 +185,7 @@ div.task-note-area textarea { color:#999999; width:100%; display:block; height:6 .mtt-btnmenu-container .li { margin:1px 0px; padding:2px; cursor:pointer; } .mtt-btnmenu-container .li:hover { background-color:#316AC5; color:white; } .mtt-btnmenu-container .li.mtt-need-list.li-disabled {color:#ACA899; } +.mtt-btnmenu-delimiter { height:0px; border-top:1px solid #cccccc; margin:2px -1px 2px -1px } .mtt-settings-table { width:100%; border-collapse:collapse; } .mtt-settings-table th, .mtt-settings-table td { border-bottom:1px solid #dedede; padding:8px; vertical-align:top; }