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/_percent.php');
unlink('./mtt-edit-settings.php');
unlink('./mtt-emergency.php');
unlink('./content/theme/images/svg2base64.php');
chdir('..'); # to the root of repo

View file

@ -107,7 +107,7 @@ var mytinytodo = window.mytinytodo = _mtt = {
this.__lang = lang;
this.daysMin = this.__lang.daysMin;
this.daysLong = this.__lang.daysLong;
this.monthsShort =this.__lang.monthsLong; //this.__lang.monthsShort;
this.monthsShort = this.__lang.monthsShort;
this.monthsLong = this.__lang.monthsLong;
},
@ -902,16 +902,19 @@ var mytinytodo = window.mytinytodo = _mtt = {
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) {
case 'Y': return 'yy';
case 'y': return 'yy';
case 'd': return 'dd';
case 'j': return 'd';
case 'm': return 'mm';
case 'M': return 'M';
case 'n': return 'm';
case ' ':
case '/':
case '.':
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;
},
@ -985,6 +989,12 @@ var mytinytodo = window.mytinytodo = _mtt = {
addTag(tagId, tag, exclude)
{
//Catch 'any tag' filter
if (tagId == -2) {
tagId = -1;
tag = '^';
exclude = true
}
for (const filter of this._filters) {
if (filter.tagId && filter.tagId == tagId)
return false;
@ -1671,7 +1681,7 @@ function tabSelect(elementOrId)
'prevList':prevList
});
}
const newTitle = curList.name + ' - ' + _mtt.options.title;
const newTitle = dehtml(curList.name) + ' - ' + _mtt.options.title;
const isFirstLoad = flag.firstLoad;
//replaceHistoryState( 'list', { list:id }, _mtt.urlForList(curList), newTitle );
updateHistoryState( { list:id }, _mtt.urlForList(curList), newTitle );
@ -1854,7 +1864,7 @@ function viewTask(id)
const item = fillTaskViewer(id);
if (!item) return;
_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');
}
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)
}

View file

@ -58,7 +58,7 @@ class Database_Sqlite3 extends Database_Abstract
{
const DBTYPE = 'sqlite';
/** @var PDO */
/** @var PDO|\Pdo\Sqlite */
protected $dbh;
/** @var int */
@ -82,11 +82,21 @@ class Database_Sqlite3 extends Database_Abstract
$options = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
$this->dbh = new PDO("sqlite:$filename", null, null, $options); //throws PDOException
$this->dbh->sqliteCreateFunction('utf8_lower', [$this, 'utf8_lower'], 1);
$this->dbh->sqliteCreateFunction('utf8_normalized_lower', [$this, 'utf8_normalized_lower'], 1);
$this->dbh->sqliteCreateCollation('UTF8CI', [$this, 'collate_utf8ci']);
$this->dbh->sqliteCreateCollation('UTF8CI_NORMALIZED', [$this, 'collate_utf8ci_normalized']);
if (PHP_VERSION_ID < 80500) {
$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_normalized_lower', [$this, 'utf8_normalized_lower'], 1);
$this->dbh->sqliteCreateCollation('UTF8CI', [$this, 'collate_utf8ci']);
$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']);
}
}
/*

View file

@ -154,8 +154,14 @@ class DBCore
$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("
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
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

View file

@ -1,4 +1,4 @@
<?php
<?php declare(strict_types=1);
/*
This file is a part of myTinyTodo.
@ -128,7 +128,7 @@ class MTTSessionHandler implements SessionHandlerInterface, SessionUpdateTimesta
* @param string $id
* @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]);
if ($r)
@ -142,7 +142,7 @@ class MTTSessionHandler implements SessionHandlerInterface, SessionUpdateTimesta
* @param string $data
* @return bool
*/
public function updateTimestamp(string $id, string $data): bool
public function updateTimestamp($id, $data): bool
{
// Warning if return false
return true;

View file

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

View file

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

View file

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

View file

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

View file

@ -4,6 +4,6 @@ namespace mytinytodo;
class Version
{
const VERSION = '1.8.2';
const VERSION = '1.8.3';
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;
}