Compare commits

..

16 commits

Author SHA1 Message Date
maxpozdeev
c2ff9a8a7d + Add "Any tag" filter in tag cloud (GH-127) 2026-02-12 22:00:16 +03:00
maxpozdeev
c1467a72b1 Revert "+ can use mid: URL scheme in markdown links (GH-126)"
This reverts commit 1c86b1f606.
2026-02-12 19:35:21 +03:00
maxpozdeev
6b82fc2082 * rewrite titleMarkup() to be able to be redefined by extension 2026-02-12 19:34:47 +03:00
maxpozdeev
768cb550d6 - fix for e00ae3d 2026-01-29 16:03:50 +03:00
maxpozdeev
1c86b1f606 + can use mid: URL scheme in markdown links (GH-126) 2026-01-03 18:27:46 +03:00
maxpozdeev
6f5f329c12 - fix: unable to use 'j M Y ' short date format in duedate picker (closes GH-128) 2026-01-03 18:25:56 +03:00
maxpozdeev
0d1da0db87 - fix: incompatibility with postgesql while export to ical/csv/rss (closes GH-125) 2026-01-03 15:09:06 +03:00
maxpozdeev
e00ae3d1dd * avoid sqlite deprecation notices in PHP 8.5 2026-01-03 14:24:04 +03:00
Max Pozdeev
d0b19e59a6
* Update ZH-CN and ZH-TW Chinese translations (thanks to @wangyouworld)
Simplified and Traditional Chinese Translation based on v1.8.2
2025-07-23 14:38:15 +03:00
wangyouworld
f40b40f030 Simplified and Traditional Chinese Translation based on v1.8.2(file with 4-space indentation) 2025-07-23 09:13:34 +08:00
maxpozdeev
9403d1214a add script for emergency password reset 2025-06-25 15:31:24 +03:00
maxpozdeev
1c27df9b32 set version to 1.8.3 2025-05-29 18:07:03 +03:00
maxpozdeev
3ce7d21df9 update percentage of translations done 2025-05-29 17:51:22 +03:00
maxpozdeev
25f4818d2e - fix: incompatibility with SessionUpdateTimestampHandlerInterface in PHP 7.x 2025-05-29 17:44:58 +03:00
maxpozdeev
9c020ded6d - fix: escaped special html symbols in browser page title (closes GH-113) 2025-05-29 10:18:34 +03:00
maxpozdeev
71b325f389 update Dutch (nl) translation (thanks to J.C.Barnhoorn) 2025-05-17 15:21:37 +03:00
12 changed files with 435 additions and 272 deletions

View file

@ -45,6 +45,7 @@ unlink('./docker-config.php');
unlink('./includes/lang/en-rtl.json'); unlink('./includes/lang/en-rtl.json');
unlink('./includes/lang/_percent.php'); unlink('./includes/lang/_percent.php');
unlink('./mtt-edit-settings.php'); unlink('./mtt-edit-settings.php');
unlink('./mtt-emergency.php');
unlink('./content/theme/images/svg2base64.php'); unlink('./content/theme/images/svg2base64.php');
chdir('..'); # to the root of repo chdir('..'); # to the root of repo

View file

@ -107,7 +107,7 @@ var mytinytodo = window.mytinytodo = _mtt = {
this.__lang = lang; this.__lang = lang;
this.daysMin = this.__lang.daysMin; this.daysMin = this.__lang.daysMin;
this.daysLong = this.__lang.daysLong; this.daysLong = this.__lang.daysLong;
this.monthsShort =this.__lang.monthsLong; //this.__lang.monthsShort; this.monthsShort = this.__lang.monthsShort;
this.monthsLong = this.__lang.monthsLong; this.monthsLong = this.__lang.monthsLong;
}, },
@ -902,16 +902,19 @@ var mytinytodo = window.mytinytodo = _mtt = {
duedatepickerformat: function() duedatepickerformat: function()
{ {
if(!this.options.duedatepickerformat) return 'yy-mm-dd'; if (!this.options.duedatepickerformat)
return 'yy-mm-dd';
var s = this.options.duedatepickerformat.replace(/(.)/g, function(t,s) { const s = this.options.duedatepickerformat.replace(/(.)/g, function(t,s) {
switch(t) { switch(t) {
case 'Y': return 'yy'; case 'Y': return 'yy';
case 'y': return 'yy'; case 'y': return 'yy';
case 'd': return 'dd'; case 'd': return 'dd';
case 'j': return 'd'; case 'j': return 'd';
case 'm': return 'mm'; case 'm': return 'mm';
case 'M': return 'M';
case 'n': return 'm'; case 'n': return 'm';
case ' ':
case '/': case '/':
case '.': case '.':
case '-': return t; case '-': return t;
@ -919,7 +922,8 @@ var mytinytodo = window.mytinytodo = _mtt = {
} }
}); });
if(s == '') return 'yy-mm-dd'; if (s == '')
return 'yy-mm-dd';
return s; return s;
}, },
@ -985,6 +989,12 @@ var mytinytodo = window.mytinytodo = _mtt = {
addTag(tagId, tag, exclude) addTag(tagId, tag, exclude)
{ {
//Catch 'any tag' filter
if (tagId == -2) {
tagId = -1;
tag = '^';
exclude = true
}
for (const filter of this._filters) { for (const filter of this._filters) {
if (filter.tagId && filter.tagId == tagId) if (filter.tagId && filter.tagId == tagId)
return false; return false;
@ -1671,7 +1681,7 @@ function tabSelect(elementOrId)
'prevList':prevList 'prevList':prevList
}); });
} }
const newTitle = curList.name + ' - ' + _mtt.options.title; const newTitle = dehtml(curList.name) + ' - ' + _mtt.options.title;
const isFirstLoad = flag.firstLoad; const isFirstLoad = flag.firstLoad;
//replaceHistoryState( 'list', { list:id }, _mtt.urlForList(curList), newTitle ); //replaceHistoryState( 'list', { list:id }, _mtt.urlForList(curList), newTitle );
updateHistoryState( { list:id }, _mtt.urlForList(curList), newTitle ); updateHistoryState( { list:id }, _mtt.urlForList(curList), newTitle );
@ -1854,7 +1864,7 @@ function viewTask(id)
const item = fillTaskViewer(id); const item = fillTaskViewer(id);
if (!item) return; if (!item) return;
_mtt.pageSet('taskviewer'); _mtt.pageSet('taskviewer');
updateHistoryState({ task: item.id, list: item.listId }, '#task/'+item.id, dehtml(item.title) + ' - ' + curList.name + ' - ' + _mtt.options.title); updateHistoryState({ task: item.id, list: item.listId }, '#task/'+item.id, dehtml(item.title) + ' - ' + dehtml(curList.name) + ' - ' + _mtt.options.title);
} }
@ -2039,7 +2049,8 @@ function setTagcloudContent(tags, isFiltered = false)
cloud = _mtt.lang.get('noTags'); cloud = _mtt.lang.get('noTags');
} }
else if (!isFiltered) { else if (!isFiltered) {
cloud = `<span class="tag" data-tag="^" data-tag-id="-1">${_mtt.lang.get('withoutTags')}</span>` + cloud; cloud = `<span class="tag special-no-tags" data-tag="^" data-tag-id="-1">${_mtt.lang.get('withoutTags')}</span>` +
`<span class="tag special-any-tag" data-tag="^^" data-tag-id="-2">${_mtt.lang.get('withAnyTag')}</span>` + cloud;
} }
$('#tagcloudcontent').html(cloud) $('#tagcloudcontent').html(cloud)
} }

View file

@ -58,7 +58,7 @@ class Database_Sqlite3 extends Database_Abstract
{ {
const DBTYPE = 'sqlite'; const DBTYPE = 'sqlite';
/** @var PDO */ /** @var PDO|\Pdo\Sqlite */
protected $dbh; protected $dbh;
/** @var int */ /** @var int */
@ -82,12 +82,22 @@ class Database_Sqlite3 extends Database_Abstract
$options = array( $options = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
); );
if (PHP_VERSION_ID < 80500) {
$this->dbh = new PDO("sqlite:$filename", null, null, $options); //throws PDOException $this->dbh = new PDO("sqlite:$filename", null, null, $options); //throws PDOException
# Deprecated since PHP 8.5
$this->dbh->sqliteCreateFunction('utf8_lower', [$this, 'utf8_lower'], 1); $this->dbh->sqliteCreateFunction('utf8_lower', [$this, 'utf8_lower'], 1);
$this->dbh->sqliteCreateFunction('utf8_normalized_lower', [$this, 'utf8_normalized_lower'], 1); $this->dbh->sqliteCreateFunction('utf8_normalized_lower', [$this, 'utf8_normalized_lower'], 1);
$this->dbh->sqliteCreateCollation('UTF8CI', [$this, 'collate_utf8ci']); $this->dbh->sqliteCreateCollation('UTF8CI', [$this, 'collate_utf8ci']);
$this->dbh->sqliteCreateCollation('UTF8CI_NORMALIZED', [$this, 'collate_utf8ci_normalized']); $this->dbh->sqliteCreateCollation('UTF8CI_NORMALIZED', [$this, 'collate_utf8ci_normalized']);
} }
else {
$this->dbh = new \Pdo\Sqlite("sqlite:$filename", null, null, $options); //throws PDOException
$this->dbh->createFunction('utf8_lower', [$this, 'utf8_lower'], 1);
$this->dbh->createFunction('utf8_normalized_lower', [$this, 'utf8_normalized_lower'], 1);
$this->dbh->createCollation('UTF8CI', [$this, 'collate_utf8ci']);
$this->dbh->createCollation('UTF8CI_NORMALIZED', [$this, 'collate_utf8ci_normalized']);
}
}
/* /*
SELECT queries for single row SELECT queries for single row

View file

@ -154,8 +154,14 @@ class DBCore
$sqlLimit = "LIMIT $limit"; $sqlLimit = "LIMIT $limit";
} }
if ($db::DBTYPE == DBConnection::DBTYPE_POSTGRES) {
$groupConcat = "array_to_string(array_agg(tags.id), ',') AS tags_ids, string_agg(tags.name, ',') AS tags";
}
else {
$groupConcat = "GROUP_CONCAT(tags.id) AS tags_ids, GROUP_CONCAT(tags.name) AS tags";
}
$q = $db->dq(" $q = $db->dq("
SELECT todo.*, todo.duedate IS NULL AS ddn, GROUP_CONCAT(tags.id) AS tags_ids, GROUP_CONCAT(tags.name) AS tags SELECT todo.*, todo.duedate IS NULL AS ddn, $groupConcat
FROM {$db->prefix}todolist AS todo FROM {$db->prefix}todolist AS todo
LEFT JOIN {$db->prefix}tag2task AS t2t ON todo.id = t2t.task_id LEFT JOIN {$db->prefix}tag2task AS t2t ON todo.id = t2t.task_id
LEFT JOIN {$db->prefix}tags AS tags ON t2t.tag_id = tags.id LEFT JOIN {$db->prefix}tags AS tags ON t2t.tag_id = tags.id

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/* /*
This file is a part of myTinyTodo. This file is a part of myTinyTodo.
@ -128,7 +128,7 @@ class MTTSessionHandler implements SessionHandlerInterface, SessionUpdateTimesta
* @param string $id * @param string $id
* @return bool * @return bool
*/ */
public function validateId(string $id): bool public function validateId($id): bool
{ {
$r = $this->db->sq("SELECT COUNT(*) FROM {$this->db->prefix}sessions WHERE id = ?", [$id]); $r = $this->db->sq("SELECT COUNT(*) FROM {$this->db->prefix}sessions WHERE id = ?", [$id]);
if ($r) if ($r)
@ -142,7 +142,7 @@ class MTTSessionHandler implements SessionHandlerInterface, SessionUpdateTimesta
* @param string $data * @param string $data
* @return bool * @return bool
*/ */
public function updateTimestamp(string $id, string $data): bool public function updateTimestamp($id, $data): bool
{ {
// Warning if return false // Warning if return false
return true; return true;

View file

@ -1,24 +1,26 @@
{ {
"_header": { "_header": {
"ver": "v1.8.2",
"date": "2025-05-15",
"language": "Dutch", "language": "Dutch",
"original_name": "Nederlands", "original_name": "Nederlands",
"author": "J.C.Barnhoorn", "authors": [
"date": "2022-12-21", "J.C.Barnhoorn"
"ver": "v1.7" ]
}, },
"My Tiny Todolist": "Mijn aantekeningen", "My Tiny Todolist": "Mijn aantekeningen",
"powered_by": "Eigendom van", "powered_by": "Bijgehouden door",
"htab_newtask": "Nieuwe aantekening", "htab_newtask": "Nieuwe aantekening",
"htab_search": "Zoeken", "htab_search": "Zoeken",
"btn_add": "Toevoegen", "btn_add": "Toevoegen",
"btn_search": "Zoeken", "btn_search": "Zoeken",
"advanced_add": "Advanced", "advanced_add": "Gevorderd",
"searching": "Zoeken naar", "searching": "Zoeken naar",
"tasks": "Aantekeningen", "tasks": "Aantekening",
"taskdate_inline_created": "gemaakt op %s", "taskdate_inline_created": "gemaakt op %s",
"taskdate_inline_edited": "bewerkt op %s", "taskdate_inline_edited": "bewerkt op %s",
"taskdate_inline_completed": "klaar op %s", "taskdate_inline_completed": "klaar op %s",
"taskdate_inline_duedate": "Opgeleverd %s", "taskdate_inline_duedate": "afgerond op %s",
"taskdate_created": "Gemaakt", "taskdate_created": "Gemaakt",
"taskdate_edited": "Laatst gewijzigd", "taskdate_edited": "Laatst gewijzigd",
"taskdate_completed": "Klaar", "taskdate_completed": "Klaar",
@ -34,7 +36,7 @@
"btn_login": "Aanmelden", "btn_login": "Aanmelden",
"a_login": "Aanmelden", "a_login": "Aanmelden",
"a_logout": "Afmelden", "a_logout": "Afmelden",
"public_tasks": "Openbare aantekeningen", "public_tasks": "Openbaar",
"tagcloud": "Labels", "tagcloud": "Labels",
"tagfilter_cancel": "annuleer filter", "tagfilter_cancel": "annuleer filter",
"showTagsFromAllLists": "Toon labels van alle lijsten", "showTagsFromAllLists": "Toon labels van alle lijsten",
@ -47,64 +49,64 @@
"daysago": "%d dagen geleden", "daysago": "%d dagen geleden",
"indays": "binnen %d dagen", "indays": "binnen %d dagen",
"months_short": [ "months_short": [
"Jan", "jan",
"Feb", "feb",
"Mrt", "mrt",
"Apr", "apr",
"Mei", "mei",
"Jun", "jun",
"Jul", "jul",
"Aug", "aug",
"Sep", "sep",
"Okt", "okt",
"Nov", "nov",
"Dec" "dec"
], ],
"months_long": [ "months_long": [
"Januari", "januari",
"Februari", "februari",
"Maart", "maart",
"April", "april",
"Mei", "mei",
"Juni", "juni",
"Juli", "juli",
"Augustus", "augustus",
"September", "september",
"Oktober", "oktober",
"November", "november",
"December" "december"
], ],
"months_calendar": [ "months_calendar": [
"Januari", "januari",
"Februari", "februari",
"Maart", "maart",
"April", "april",
"Mei", "mei",
"Juni", "juni",
"Juli", "juli",
"Augustus", "augustus",
"September", "september",
"Oktober", "oktober",
"November", "november",
"December" "december"
], ],
"days_min": [ "days_min": [
"Zo", "zo",
"Ma", "ma",
"Di", "di",
"Wo", "wo",
"Do", "do",
"Vr", "vr",
"Za" "za"
], ],
"days_long": [ "days_long": [
"Zondag", "zondag",
"Maandag", "maandag",
"Dinsdag", "dinsdag",
"Woensdag", "woensdag",
"Donderdag", "donderdag",
"Vrijdag", "vrijdag",
"Zaterdag" "zaterdag"
], ],
"today": "vandaag", "today": "vandaag",
"yesterday": "gisteren", "yesterday": "gisteren",
@ -142,7 +144,7 @@
"a_settings": "Instellingen", "a_settings": "Instellingen",
"rss_feed": "RSS Feed", "rss_feed": "RSS Feed",
"feed_title": "%s", "feed_title": "%s",
"feed_completed_tasks": "Gecompleteerde aantekeningen", "feed_completed_tasks": "Afgeronde aantekeningen",
"feed_modified_tasks": "Gewijzigde aantekeningen", "feed_modified_tasks": "Gewijzigde aantekeningen",
"feed_new_tasks": "Nieuwe aantekeningen", "feed_new_tasks": "Nieuwe aantekeningen",
"feed_tasks": "Aantekeningen", "feed_tasks": "Aantekeningen",
@ -158,9 +160,9 @@
"set_enabled": "Ingeschakeld", "set_enabled": "Ingeschakeld",
"set_disabled": "Uitgeschakeld", "set_disabled": "Uitgeschakeld",
"set_newpass": "Nieuw wachtwoord", "set_newpass": "Nieuw wachtwoord",
"set_newpass_descr": "Leeglaten als het oude wachtwood moet blijven.", "set_newpass_descr": "Leeglaten als het oude wachtwoord moet blijven.",
"set_smartsyntax": "Slimme syntax", "set_smartsyntax": "Slimme syntax",
"set_smartsyntax2_descr": "Voorbeeld: +1 aantekening titel #label1 #label2", "set_smartsyntax3_descr": "Voorbeeld: +1 Aantekening titel #label1 #label2 @einddatum ",
"set_timezone": "Tijdzone", "set_timezone": "Tijdzone",
"set_autotag": "Autolabels", "set_autotag": "Autolabels",
"set_autotag_descr": "Automatisch labels toevoegen bij nieuwe aantekening.", "set_autotag_descr": "Automatisch labels toevoegen bij nieuwe aantekening.",
@ -172,16 +174,22 @@
"set_date2": "Korte datum indeling", "set_date2": "Korte datum indeling",
"set_shortdate": "Korte datum (huidig jaar)", "set_shortdate": "Korte datum (huidig jaar)",
"set_clock": "Klok opmaak", "set_clock": "Klok opmaak",
"set_12hour": "12-hour", "set_12hour": "12-uur",
"set_24hour": "24-hour", "set_24hour": "24-uur",
"set_submit": "Wijzigingen toepassen", "set_submit": "Wijzigingen toepassen",
"set_cancel": "Annuleren", "set_cancel": "Annuleren",
"set_showdate": "Laat datum aantekning zien in de lijst", "set_showdate": "Laat datum aantekening zien in de lijst",
"set_showtime": "Laat tijd zien", "set_showtime": "Laat tijd zien",
"set_showdate_inline": "Toon datum inline",
"set_exactduedate": "Altijd einddatum tonen als datum",
"set_appearance": "Opmaak", "set_appearance": "Opmaak",
"set_appearance_system": "Gelijk aan systeem", "set_appearance_system": "Gelijk aan systeem",
"set_appearance_light": "Licht thema", "set_appearance_light": "Licht thema",
"set_extensions": "Extensies", "set_appearance_dark": "Donker",
"set_newtaskcounter_h": "Nieuwe aantekeningen teller",
"set_newtaskcounter": "Controleer op nieuwe aantekeningen",
"set_newtaskcountericon": "Toon aantal in favicon",
"set_extensions": "Uitbreidingen",
"set_activate": "Activeren", "set_activate": "Activeren",
"set_deactivate": "Deactiveren", "set_deactivate": "Deactiveren",
"confirmDelete": "Wil je deze aantekening verwijderen?", "confirmDelete": "Wil je deze aantekening verwijderen?",
@ -191,12 +199,15 @@
"error": "Er heeft zich een fout voorgedaan (klik voor details)", "error": "Er heeft zich een fout voorgedaan (klik voor details)",
"denied": "Toegang geweigerd", "denied": "Toegang geweigerd",
"listNotFound": "Lijst niet gevonden", "listNotFound": "Lijst niet gevonden",
"noPublicLists": "Geen openbare aantekeningen", "noPublicLists": "Niets openbaar",
"noTags": "Geen labels",
"withoutTags": "Geen labels",
"withAnyTag": "Met labels",
"invalidpass": "Verkeerd wachtwoord", "invalidpass": "Verkeerd wachtwoord",
"addList": "Maak een nieuwe lijst", "addList": "Maak een nieuwe lijst",
"addListDefault": "Aantekening", "addListDefault": "Aantekening",
"renameList": "Hernoem lijst", "renameList": "Hernoem lijst",
"deleteList": "Dit zorgt ervoor dat huidige lijst wordt verwijderd.\nWeet je het zeker?", "deleteList": "Dit zorgt ervoor dat huidige lijst wordt verwijderd.\nWeet je het zeker?",
"clearCompleted": "Dit verwijderd alle aantekeningen in de huidige lijst.\nWeet je het zeker?", "clearCompleted": "Dit verwijderd alle afgeronde aantekeningen in de huidige lijst.\nWeet je het zeker?",
"settingsSaved": "Instellingen opgeslagen. Herladen..." "settingsSaved": "Instellingen opgeslagen. Herladen..."
} }

View file

@ -21,7 +21,7 @@
| ja | 147/202 | 73% | | ja | 147/202 | 73% |
| lt | 147/202 | 73% | | lt | 147/202 | 73% |
| mk | 147/202 | 73% | | mk | 147/202 | 73% |
| nl | 187/202 | 93% | | nl | 197/202 | 98% |
| no | 147/202 | 73% | | no | 147/202 | 73% |
| pl | 175/202 | 87% | | pl | 175/202 | 87% |
| pt-br | 187/202 | 93% | | pt-br | 187/202 | 93% |

View file

@ -1,18 +1,18 @@
{ {
"_header": { "_header": {
"ver": "v1.8.0", "ver": "v1.8.2",
"date": "2024-01-02", "date": "2025-07-23",
"language": "Chinese Simplified", "language": "Chinese Simplified",
"original_name": "中文 (简体)", "original_name": "中文 (简体)",
"authors": [ "authors": [
"v1.3 - heraldboy <heraldboy@gmail.com>", "v1.3 - heraldboy <heraldboy@gmail.com>",
"v1.6 - wangyouworld : http://ramble.3vshej.cn", "v1.6 - wangyouworld : http://ramble.3vshej.cn",
"v1.7 - xhemj <xhemj2680@163.com> : @xhemj", "v1.7 - xhemj <xhemj2680@163.com> : @xhemj",
"wangyouworld : https://blog.3vshej.cn : @wangyouworld" "v1.8.2 wangyouworld : https://blog.3vshej.cn"
] ]
}, },
"My Tiny Todolist": "我的待办事项列表", "My Tiny Todolist": "我的待办事项列表",
"powered_by": "", "powered_by": "来自",
"htab_newtask": "新建任务", "htab_newtask": "新建任务",
"htab_search": "搜索", "htab_search": "搜索",
"btn_add": "添加", "btn_add": "添加",
@ -33,7 +33,7 @@
"task": "任务", "task": "任务",
"note": "备注", "note": "备注",
"tags": "标签", "tags": "标签",
"list": "列表", "list": "清单",
"no_note": "无备注", "no_note": "无备注",
"save": "保存", "save": "保存",
"cancel": "取消", "cancel": "取消",
@ -41,11 +41,12 @@
"password": "密码", "password": "密码",
"btn_login": "登录", "btn_login": "登录",
"a_login": "登录", "a_login": "登录",
"a_logout": "出", "a_logout": "退出",
"public_tasks": "公任务", "public_tasks": "公任务",
"tagcloud": "标签", "tagcloud": "标签",
"tagfilter_cancel": "取消筛选", "tagfilter_cancel": "取消筛选",
"showTagsFromAllLists": "显示所有列表的标签", "filterTags": "筛选标签",
"showTagsFromAllLists": "显示所有清单的标签",
"sortByHand": "手动排序", "sortByHand": "手动排序",
"sortByTitle": "按标题排序", "sortByTitle": "按标题排序",
"sortByPriority": "按优先级排序", "sortByPriority": "按优先级排序",
@ -54,7 +55,7 @@
"sortByDateModified": "按修改日期排序", "sortByDateModified": "按修改日期排序",
"due": "截止日期", "due": "截止日期",
"daysago": "%d 天前", "daysago": "%d 天前",
"indays": "%d 天", "indays": "%d 天",
"months_short": [ "months_short": [
"1 月", "1 月",
"2 月", "2 月",
@ -120,7 +121,7 @@
"tomorrow": "明天", "tomorrow": "明天",
"f_past": "已过期", "f_past": "已过期",
"f_today": "今天和明天", "f_today": "今天和明天",
"f_soon": "很快", "f_soon": "即将到期",
"action_edit": "编辑", "action_edit": "编辑",
"action_note": "编辑备注", "action_note": "编辑备注",
"action_delete": "删除", "action_delete": "删除",
@ -131,33 +132,33 @@
"notes": "备注:", "notes": "备注:",
"notes_show": "显示", "notes_show": "显示",
"notes_hide": "隐藏", "notes_hide": "隐藏",
"list_new": "新建列表", "list_new": "新建清单",
"list_rename": "重命名列表", "list_rename": "重命名清单",
"list_delete": "删除列表", "list_delete": "删除清单",
"list_showcompleted": "显示已完成任务", "list_showcompleted": "显示已完成任务",
"list_clearcompleted": "清除已完成的任务", "list_clearcompleted": "清空已完成任务",
"list_select": "选择列表", "list_select": "选择清单",
"list_share": "分享", "list_share": "分享",
"list_publish": "发布列表", "list_publish": "发布清单",
"list_enable_feedkey": "启用 feed key", "list_enable_feedkey": "启用订阅密钥",
"list_show_feedkey": "显示 feed key", "list_show_feedkey": "显示订阅密钥",
"list_rssfeed": "RSS Feed", "list_rssfeed": "RSS 订阅",
"list_export_to_csv": "导出 CSV", "list_export_to_csv": "导出 CSV",
"list_export_to_ical": "导出 iCalendar", "list_export_to_ical": "导出 iCalendar",
"list_hide": "隐藏列表", "list_hide": "隐藏清单",
"alltags": "所有标签", "alltags": "所有标签:",
"alltags_show": "显示所有", "alltags_show": "显示全部",
"alltags_hide": "隐藏所有", "alltags_hide": "隐藏全部",
"a_settings": "设置", "a_settings": "设置",
"rss_feed": "RSS Feed", "rss_feed": "RSS 订阅",
"feed_title": "%s", "feed_title": "%s",
"feed_completed_tasks": "已完成任务", "feed_completed_tasks": "已完成任务",
"feed_modified_tasks": "修改过的任务", "feed_modified_tasks": "修改任务",
"feed_new_tasks": "新任务", "feed_new_tasks": "新任务",
"feed_tasks": "任务", "feed_tasks": "任务",
"feed_status_new": "新任务", "feed_status_new": "新",
"feed_status_updated": "更新过的任务", "feed_status_updated": "更新",
"feed_status_completed": "已完成的任务", "feed_status_completed": "已完成",
"alltasks": "所有任务", "alltasks": "所有任务",
"set_header": "设置", "set_header": "设置",
"set_title": "标题", "set_title": "标题",
@ -167,7 +168,7 @@
"set_enabled": "启用", "set_enabled": "启用",
"set_disabled": "禁用", "set_disabled": "禁用",
"set_newpass": "新密码", "set_newpass": "新密码",
"set_newpass_descr": "不想更改当前密码请留空。", "set_newpass_descr": "不修改密码请留空",
"set_smartsyntax": "智能语法", "set_smartsyntax": "智能语法",
"set_smartsyntax3_descr": "示例: +1 任务名 #1 标签 #2 @duedate", "set_smartsyntax3_descr": "示例: +1 任务名 #1 标签 #2 @duedate",
"set_timezone": "时区", "set_timezone": "时区",
@ -179,37 +180,42 @@
"set_custom": "自定义", "set_custom": "自定义",
"set_date": "日期格式", "set_date": "日期格式",
"set_date2": "短日期格式", "set_date2": "短日期格式",
"set_shortdate": "短日期 (当前年份)", "set_shortdate": "短日期(当年)",
"set_clock": "时格式", "set_clock": "时格式",
"set_12hour": "12 小时制", "set_12hour": "12 小时制",
"set_24hour": "24 小时制", "set_24hour": "24 小时制",
"set_submit": "提交更改", "set_submit": "提交更改",
"set_cancel": "取消", "set_cancel": "取消",
"set_showdate": "在任务列表中显示日期", "set_showdate": "在列表中显示任务日期",
"set_showtime": "显示时间", "set_showtime": "显示时间",
"set_showdate_inline": "显示日期内联", "set_showdate_inline": "内联显示日期",
"set_exactduedate": "总是显示到期日期作为日期", "set_exactduedate": "始终将截止日期显示为具体日期",
"set_appearance": "外观", "set_appearance": "外观",
"set_appearance_system": "与系统相同", "set_appearance_system": "跟随系统",
"set_appearance_light": "明亮主题", "set_appearance_light": "浅色",
"set_appearance_dark": "深色主题", "set_appearance_dark": "深色",
"set_extensions": "扩展", "set_newtaskcounter_h": "新任务计数器",
"set_newtaskcounter": "检查新任务",
"set_newtaskcountericon": "在网站图标显示计数器",
"set_extensions": "扩展功能",
"set_activate": "激活", "set_activate": "激活",
"set_deactivate": "停用", "set_deactivate": "停用",
"confirmDelete": "你确定要删除这个任务吗?", "confirmDelete": "确认删除此任务",
"confirmLeave": "可能存在未保存的数据。你真的想离开吗?", "confirmLeave": "可能存在未保存的数据,确定要离开吗?",
"actionNoteSave": "保存", "actionNoteSave": "保存",
"actionNoteCancel": "取消", "actionNoteCancel": "取消",
"error": "某些错误发生 (点击查看详情)", "error": "发生错误(点击查看详情)",
"denied": "访问被拒绝", "denied": "访问被拒绝",
"listNotFound": "列表未找到", "listNotFound": "清单未找到",
"noPublicLists": "没有公共任务", "noPublicLists": "无公开任务",
"noTags": "没有标签", "noTags": "无标签",
"withoutTags": "无标签",
"withAnyTag": "任意标签",
"invalidpass": "密码错误", "invalidpass": "密码错误",
"addList": "创建新列表", "addList": "创建新清单",
"addListDefault": "待办事项", "addListDefault": "待办事项",
"renameList": "重命名列表", "renameList": "重命名清单",
"deleteList": "这将删除当前列表及其所有任务。\n你确定吗", "deleteList": "将删除当前清单及其所有任务\n确定继续",
"clearCompleted": "这将删除当前列表中的所有已完成任务。\n你确定吗", "clearCompleted": "将清空本清单所有已完成任务\n确定继续",
"settingsSaved": "设置已保存重新加载..." "settingsSaved": "设置已保存,正在重新加载..."
} }

View file

@ -1,168 +1,219 @@
{ {
"_header": { "_header": {
"ver": "v1.3.6", "ver": "v1.8.2",
"date": "2010-10-06", "date": "2025-07-23",
"language": "Chinese Traditional", "language": "Chinese Traditional",
"original_name": "中文(繁體)", "original_name": "中文(繁體)",
"author": "DonaldIsFreak", "authors": [
"author_url": "http://donaldknuth.blogspot.com/" "v1.3.6 DonaldIsFreak : http://donaldknuth.blogspot.com/",
"v1.8.2 wangyouworld : https://blog.3vshej.cn"
]
}, },
"My Tiny Todolist": "我的小型待辦事項清單", "My Tiny Todolist": "我的待辦事項清單",
"powered_by": "來自",
"htab_newtask": "新增任務", "htab_newtask": "新增任務",
"htab_search": "查詢", "htab_search": "搜尋",
"btn_add": "確定", "btn_add": "新增",
"btn_search": "確定", "btn_search": "搜尋",
"advanced_add": "進階新增", "advanced_add": "進階",
"searching": "搜尋", "searching": "正在搜尋",
"tasks": "所有任務", "tasks": "任務",
"taskdate_inline_created": "created at %s", "taskdate_inline_created": "建立於 %s",
"taskdate_inline_completed": "Completed at %s", "taskdate_inline_edited": "編輯於 %s",
"taskdate_inline_duedate": "Due %s", "taskdate_inline_completed": "完成於 %s",
"taskdate_created": "建立日期", "taskdate_inline_duedate": "截止日期 %s",
"taskdate_completed": "完成日期", "taskdate_created": "建立時間",
"taskdate_edited": "最後編輯",
"taskdate_completed": "完成時間",
"edit_task": "編輯任務", "edit_task": "編輯任務",
"add_task": "新增任務", "add_task": "新增任務",
"priority": "優先", "priority": "優先",
"task": "任務名稱", "task": "任務",
"note": "內容", "note": "備註",
"tags": "標籤", "tags": "標籤",
"list": "清單",
"no_note": "無備註",
"save": "儲存", "save": "儲存",
"cancel": "取消", "cancel": "取消",
"close": "關閉",
"password": "密碼", "password": "密碼",
"btn_login": "登入", "btn_login": "登入",
"a_login": "登入", "a_login": "登入",
"a_logout": "登出", "a_logout": "登出",
"public_tasks": "任務", "public_tasks": "開任務",
"tagcloud": "Tags", "tagcloud": "標籤雲",
"tagfilter_cancel": "取消篩選", "tagfilter_cancel": "取消篩選",
"sortByHand": "自行排序", "filterTags": "篩選標籤",
"sortByPriority": "按優先權排序", "showTagsFromAllLists": "顯示所有清單的標籤",
"sortByDueDate": "按到期日排序", "sortByHand": "手動排序",
"sortByDateCreated": "Sort by date created", "sortByTitle": "按標題排序",
"sortByDateModified": "Sort by date modified", "sortByPriority": "按優先級排序",
"due": "到期日", "sortByDueDate": "按截止日期排序",
"sortByDateCreated": "按建立日期排序",
"sortByDateModified": "按修改日期排序",
"due": "截止",
"daysago": "%d 天前", "daysago": "%d 天前",
"indays": "在 %d 天", "indays": "%d 天",
"months_short": [ "months_short": [
"Jan", "1月",
"Feb", "2月",
"Mar", "3月",
"Apr", "4月",
"May", "5月",
"Jun", "6月",
"Jul", "7月",
"Aug", "8月",
"Sep", "9月",
"Oct", "10月",
"Nov", "11月",
"Dec" "12月"
], ],
"months_long": [ "months_long": [
"January", "一月",
"February", "二月",
"March", "三月",
"April", "四月",
"May", "五月",
"June", "六月",
"July", "七月",
"August", "八月",
"September", "九月",
"October", "十月",
"November", "十一月",
"December" "十二月"
],
"months_calendar": [
"一月",
"二月",
"三月",
"四月",
"五月",
"六月",
"七月",
"八月",
"九月",
"十月",
"十一月",
"十二月"
], ],
"days_min": [ "days_min": [
"Su", "",
"Mo", "",
"Tu", "",
"We", "",
"Th", "",
"Fr", "",
"Sa" ""
], ],
"days_long": [ "days_long": [
"Sunday", "星期日",
"Monday", "星期一",
"Tuesday", "星期二",
"Wednesday", "星期三",
"Thursday", "星期四",
"Friday", "星期五",
"Saturday" "星期六"
], ],
"today": "今天", "today": "今天",
"yesterday": "昨天", "yesterday": "昨天",
"tomorrow": "明天", "tomorrow": "明天",
"f_past": "超過到期日", "f_past": "已逾期",
"f_today": "今天和明天", "f_today": "今天和明天",
"f_soon": "即將到期", "f_soon": "即將到期",
"action_edit": "編輯", "action_edit": "編輯",
"action_note": "編輯內容", "action_note": "編輯備註",
"action_delete": "刪除", "action_delete": "刪除",
"action_priority": "優先權", "action_priority": "優先級",
"action_move": "移至", "action_move": "移動到",
"notes": "內容:", "action_ok": "確定",
"action_cancel": "取消",
"notes": "備註:",
"notes_show": "顯示", "notes_show": "顯示",
"notes_hide": "隱藏", "notes_hide": "隱藏",
"list_new": "新增清單", "list_new": "新增清單",
"list_rename": "重新命名清單", "list_rename": "重新命名清單",
"list_delete": "刪除清單", "list_delete": "刪除清單",
"list_publish": "開放清單",
"list_showcompleted": "顯示已完成任務", "list_showcompleted": "顯示已完成任務",
"list_clearcompleted": "清除已完成任務", "list_clearcompleted": "清除已完成任務",
"list_select": "Select list", "list_select": "選擇清單",
"list_export": "Export", "list_share": "分享",
"list_export_csv": "CSV", "list_publish": "發佈清單",
"list_export_ical": "iCalendar", "list_enable_feedkey": "啟用訂閱金鑰",
"list_rssfeed": "RSS Feed", "list_show_feedkey": "顯示訂閱金鑰",
"alltags": "所有標籤:", "list_rssfeed": "RSS訂閱",
"alltags_show": "顯示所有標籤", "list_export_to_csv": "匯出為CSV",
"alltags_hide": "穩藏所有標籤", "list_export_to_ical": "匯出為iCalendar",
"list_hide": "隱藏清單",
"alltags": "所有標籤:",
"alltags_show": "顯示全部",
"alltags_hide": "隱藏全部",
"a_settings": "設定", "a_settings": "設定",
"rss_feed": "RSS Feed", "rss_feed": "RSS訂閱",
"feed_title": "%s", "feed_title": "%s",
"feed_completed_tasks": "Completed tasks", "feed_completed_tasks": "已完成任務",
"feed_modified_tasks": "Modified tasks", "feed_modified_tasks": "已修改任務",
"feed_new_tasks": "New tasks", "feed_new_tasks": "新任務",
"alltasks": "All tasks", "feed_tasks": "任務",
"feed_status_new": "新建",
"feed_status_updated": "已更新",
"feed_status_completed": "已完成",
"alltasks": "所有任務",
"set_header": "設定", "set_header": "設定",
"set_title": "標題", "set_title": "標題",
"set_title_descr": "(如果想變更預設標題名稱。)", "set_title_descr": "如需修改預設標題請填寫此項",
"set_language": "語言", "set_language": "語言",
"set_protection": "密碼保護", "set_protection": "密碼保護",
"set_enabled": "開啟", "set_enabled": "啟用",
"set_disabled": "關閉", "set_disabled": "禁用",
"set_newpass": "設定新密碼", "set_newpass": "新密碼",
"set_newpass_descr": "(若不想改密碼,請留白。)", "set_newpass_descr": "若不修改密碼請留空",
"set_smartsyntax": "智慧語法", "set_smartsyntax": "智能語法",
"set_smartsyntax_descr": "新增任務時,使用進階參數(/priority/ task /tags/)", "set_smartsyntax3_descr": "範例:+1 任務標題 #標籤1 #標籤2 @截止日期",
"set_timezone": "Time zone", "set_timezone": "時區",
"set_autotag": "自動標籤化", "set_autotag": "自動標記",
"set_autotag_descr": "(新增任務時,自動增加目前標籤篩選器內的標籤)", "set_autotag_descr": "自動為新建任務添加當前標籤篩選器的標籤",
"set_sessions": "Session處理機制", "set_markdown": "Markdown",
"set_sessions_php": "PHP", "set_markdown_descr": "在備註中支援Markdown語法如需使用舊版標記請禁用",
"set_sessions_files": "Files", "set_firstdayofweek": "週起始日",
"set_firstdayofweek": "每週的第一天", "set_custom": "自訂",
"set_custom": "Custom",
"set_date": "日期格式", "set_date": "日期格式",
"set_date2": "Short Date format", "set_date2": "短日期格式",
"set_shortdate": "簡短的日期格式", "set_shortdate": "短日期(當年)",
"set_clock": "時格式", "set_clock": "時格式",
"set_12hour": "12小時制", "set_12hour": "12小時制",
"set_24hour": "24小時制", "set_24hour": "24小時制",
"set_submit": "確定送出", "set_submit": "提交變更",
"set_cancel": "取消", "set_cancel": "取消",
"set_showdate": "在清單顯示任務新增日期", "set_showdate": "在清單中顯示任務日期",
"confirmDelete": "確定要刪除此任務?", "set_showtime": "顯示時間",
"confirmLeave": "There can be unsaved data. Do you really want to leave?", "set_showdate_inline": "內聯顯示日期",
"set_exactduedate": "始終顯示具體截止日期",
"set_appearance": "外觀",
"set_appearance_system": "跟隨系統",
"set_appearance_light": "淺色",
"set_appearance_dark": "深色",
"set_newtaskcounter_h": "新任務計數器",
"set_newtaskcounter": "檢查新任務",
"set_newtaskcountericon": "在網站圖示顯示計數器",
"set_extensions": "擴充功能",
"set_activate": "啟用",
"set_deactivate": "停用",
"confirmDelete": "確認刪除該任務?",
"confirmLeave": "存在未儲存資料,確定要離開嗎?",
"actionNoteSave": "儲存", "actionNoteSave": "儲存",
"actionNoteCancel": "取消", "actionNoteCancel": "取消",
"error": "發生錯誤(點擊查看詳情)", "error": "發生錯誤(點擊查看詳情)",
"denied": "存取拒絕", "denied": "存取被拒絕",
"listNotFound": "清單未找到",
"noPublicLists": "無公開任務",
"noTags": "無標籤",
"withoutTags": "無標籤",
"withAnyTag": "任意標籤",
"invalidpass": "密碼錯誤", "invalidpass": "密碼錯誤",
"addList": "輸入新增清單名稱", "addList": "建立新清單",
"addListDefault": "Todo", "addListDefault": "待辦事項",
"renameList": "重新命名清單名稱", "renameList": "重新命名清單",
"deleteList": "將會刪除清單內所有的任務。\n確定刪除嗎?", "deleteList": "將刪除當前清單及其所有任務\n確定繼續",
"clearCompleted": "將會刪除清單內所有完成的任務。\n確定刪除嗎?", "clearCompleted": "將清空清單中所有已完成任務\n確定繼續",
"settingsSaved": "設定已儲存。重新讀取中..." "settingsSaved": "設定已儲存,正在重新載入..."
} }

View file

@ -50,6 +50,62 @@ final class MTTMarkdown
} }
} }
interface MTTTitleMarkupInterface
{
public function convert(string $title): string;
}
class MTTTitleMarkupConverter implements MTTTitleMarkupInterface
{
public function convert(string $title): string
{
//escape all unsafe
$title = htmlspecialchars($title, ENT_QUOTES);
// make links from text starting with 'www.'
$title = preg_replace(
"/(^|\s|>)(www\.([\w\#$%&~\/.\-\+;:=,\?\[\]@]+?))(,|\.|:|)?(?=\s|&quot;|&lt;|&gt;|\"|<|>|$)/iu" ,
'$1<a href="http://$2" target="_blank">$2</a>$4' ,
$title
);
// make link from text starting with protocol like 'http://'
$title = preg_replace(
"/(^|\s|>)([a-z]+:\/\/([\w\#$%&~\/.\-\+;:=,\?\[\]@]+?))(,|\.|:|)?(?=\s|&quot;|&lt;|&gt;|\"|<|>|$)/iu" ,
'$1<a href="$2" target="_blank">$2</a>$4' ,
$title
);
return $title;
}
}
final class MTTTitleMarkup
{
/** @var MTTTitleMarkupInterface */
private static $instance;
/** @var string */
private static $instanceClass = MTTTitleMarkupConverter::class;
public static function instance() : MTTTitleMarkupInterface
{
if (isset(self::$instance))
return self::$instance;
self::$instance = new self::$instanceClass();
return self::$instance;
}
public static function setInstanceClass(string $class)
{
if (!is_a($class, MTTTitleMarkupInterface::class, true)) {
throw new Exception("Class '$class' is not a MTTTitleMarkupInterface");
}
self::$instanceClass = $class;
self::$instance = null;
}
}
function noteMarkup($note, $toExternal = false) function noteMarkup($note, $toExternal = false)
{ {
if ($note === null) { if ($note === null) {
@ -101,22 +157,6 @@ function mttMarkup_v1($s)
// Convert raw title to html with allowed urls // Convert raw title to html with allowed urls
function titleMarkup($title) function titleMarkup($title)
{ {
//escape all unsafe return MTTTitleMarkup::instance()->convert($title);
$title = htmlspecialchars($title, ENT_QUOTES);
// make links from text starting with 'www.'
$title = preg_replace(
"/(^|\s|>)(www\.([\w\#$%&~\/.\-\+;:=,\?\[\]@]+?))(,|\.|:|)?(?=\s|&quot;|&lt;|&gt;|\"|<|>|$)/iu" ,
'$1<a href="http://$2" target="_blank">$2</a>$4' ,
$title
);
// make link from text starting with protocol like 'http://'
$title = preg_replace(
"/(^|\s|>)([a-z]+:\/\/([\w\#$%&~\/.\-\+;:=,\?\[\]@]+?))(,|\.|:|)?(?=\s|&quot;|&lt;|&gt;|\"|<|>|$)/iu" ,
'$1<a href="$2" target="_blank">$2</a>$4' ,
$title
);
return $title;
} }

View file

@ -4,6 +4,6 @@ namespace mytinytodo;
class Version class Version
{ {
const VERSION = '1.8.2'; const VERSION = '1.8.3';
const DB_VERSION = '1.8'; const DB_VERSION = '1.8';
} }

27
src/mtt-emergency.php Normal file
View file

@ -0,0 +1,27 @@
<?php
$dontStartSession = true;
require_once(__DIR__ . '/init.php');
if (!need_auth()) {
exitmsg("No password protection is set");
}
if (isset($_POST['reset'])) {
$pass = _post('pass');
$hash = passwordHash($pass);
Config::set('password', $hash);
Config::save();
exitmsg("Done");
}
else {
exitmsg("<form method=post><label>Enter new password:<br><input name=pass type=password> <input name=reset type=submit></label></form>");
}
function exitmsg(?string $text = '') {
echo "<h1>Password Reset</h1>\n";
echo $text;
echo "<br><br><hr> <i>For security reasons delete this file after usage!</i>";
exit;
}