From c327e298d8a258f51262c5274de2882b385be7b3 Mon Sep 17 00:00:00 2001 From: Tim Gerundt Date: Thu, 11 Sep 2025 21:18:05 +0200 Subject: [PATCH 01/12] Add `phpstan` --- composer.json | 4 +- composer.lock | 170 ++++++++++++++++++++++++++++++++++++++++++-------- phpstan.neon | 12 ++++ 3 files changed, 158 insertions(+), 28 deletions(-) create mode 100644 phpstan.neon diff --git a/composer.json b/composer.json index c22c07f..ebf46c1 100644 --- a/composer.json +++ b/composer.json @@ -19,6 +19,8 @@ "symfony/polyfill-intl-normalizer": "^1.31" }, "require-dev": { - "league/commonmark": "^2.6" + "league/commonmark": "^2.6", + "phpstan/phpstan": "*", + "phpstan/phpstan-deprecation-rules": "*" } } diff --git a/composer.lock b/composer.lock index b5d42db..c46409d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c27d4b183be86ec7d95203f1a84b86e2", + "content-hash": "215843776f9785615ca5e1630cc00228", "packages": [ { "name": "erusev/parsedown", @@ -58,7 +58,7 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.32.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", @@ -119,7 +119,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" }, "funding": [ { @@ -130,6 +130,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -216,16 +220,16 @@ }, { "name": "league/commonmark", - "version": "2.7.0", + "version": "2.7.1", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "6fbb36d44824ed4091adbcf4c7d4a3923cdb3405" + "reference": "10732241927d3971d28e7ea7b5712721fa2296ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/6fbb36d44824ed4091adbcf4c7d4a3923cdb3405", - "reference": "6fbb36d44824ed4091adbcf4c7d4a3923cdb3405", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/10732241927d3971d28e7ea7b5712721fa2296ca", + "reference": "10732241927d3971d28e7ea7b5712721fa2296ca", "shasum": "" }, "require": { @@ -254,7 +258,7 @@ "symfony/process": "^5.4 | ^6.0 | ^7.0", "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0", "unleashedtech/php-coding-standard": "^3.1.1", - "vimeo/psalm": "^4.24.0 || ^5.0.0" + "vimeo/psalm": "^4.24.0 || ^5.0.0 || ^6.0.0" }, "suggest": { "symfony/yaml": "v2.3+ required if using the Front Matter extension" @@ -319,7 +323,7 @@ "type": "tidelift" } ], - "time": "2025-05-05T12:20:28+00:00" + "time": "2025-07-20T12:47:49+00:00" }, { "name": "league/config", @@ -467,29 +471,29 @@ }, { "name": "nette/utils", - "version": "v4.0.6", + "version": "v4.0.8", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "ce708655043c7050eb050df361c5e313cf708309" + "reference": "c930ca4e3cf4f17dcfb03037703679d2396d2ede" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/ce708655043c7050eb050df361c5e313cf708309", - "reference": "ce708655043c7050eb050df361c5e313cf708309", + "url": "https://api.github.com/repos/nette/utils/zipball/c930ca4e3cf4f17dcfb03037703679d2396d2ede", + "reference": "c930ca4e3cf4f17dcfb03037703679d2396d2ede", "shasum": "" }, "require": { - "php": "8.0 - 8.4" + "php": "8.0 - 8.5" }, "conflict": { "nette/finder": "<3", "nette/schema": "<1.2.2" }, "require-dev": { - "jetbrains/phpstorm-attributes": "dev-master", + "jetbrains/phpstorm-attributes": "^1.2", "nette/tester": "^2.5", - "phpstan/phpstan": "^1.0", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.9" }, "suggest": { @@ -507,6 +511,9 @@ } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -547,9 +554,114 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.0.6" + "source": "https://github.com/nette/utils/tree/v4.0.8" }, - "time": "2025-03-30T21:06:30+00:00" + "time": "2025-08-06T21:43:34+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "2.1.23", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "a34502adbbd5c2366b5a97679848a5ace4f6f2f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a34502adbbd5c2366b5a97679848a5ace4f6f2f5", + "reference": "a34502adbbd5c2366b5a97679848a5ace4f6f2f5", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2025-09-10T11:42:22+00:00" + }, + { + "name": "phpstan/phpstan-deprecation-rules", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-deprecation-rules.git", + "reference": "468e02c9176891cc901143da118f09dc9505fc2f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/468e02c9176891cc901143da118f09dc9505fc2f", + "reference": "468e02c9176891cc901143da118f09dc9505fc2f", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.1.15" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan rules for detecting usage of deprecated classes, methods, properties, constants and traits.", + "support": { + "issues": "https://github.com/phpstan/phpstan-deprecation-rules/issues", + "source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/2.0.3" + }, + "time": "2025-05-14T10:56:57+00:00" }, { "name": "psr/event-dispatcher", @@ -603,16 +715,16 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.5.1", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", "shasum": "" }, "require": { @@ -625,7 +737,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.5-dev" + "dev-main": "3.6-dev" } }, "autoload": { @@ -650,7 +762,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" }, "funding": [ { @@ -666,11 +778,11 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.32.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", @@ -730,7 +842,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.32.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" }, "funding": [ { @@ -741,6 +853,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..ebb75dd --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,12 @@ +includes: + - src/includes/vendor/phpstan/phpstan-deprecation-rules/rules.neon + +parameters: + level: 1 + paths: + - src + excludePaths: + analyse: + - src/includes/vendor + fileExtensions: + - php \ No newline at end of file From 3d0d2bf51d13c5b81f7e524f41dc393c72452a05 Mon Sep 17 00:00:00 2001 From: Tim Gerundt Date: Thu, 11 Sep 2025 21:35:10 +0200 Subject: [PATCH 02/12] Constructor of class `DatabaseResult_Mysqli` has an unused parameter `$resultless` --- src/includes/class.db.mysqli.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/includes/class.db.mysqli.php b/src/includes/class.db.mysqli.php index 4f6e0f2..1cd5471 100644 --- a/src/includes/class.db.mysqli.php +++ b/src/includes/class.db.mysqli.php @@ -12,7 +12,7 @@ class DatabaseResult_Mysqli extends DatabaseResult_Abstract /** @var mysqli_result */ protected $q; - function __construct(mysqli $dbh, string $query, bool $resultless = false) + function __construct(mysqli $dbh, string $query) { $this->q = $dbh->query($query); //throws mysqli_sql_exception } @@ -105,7 +105,7 @@ class Database_Mysqli extends Database_Abstract $this->_dq($query, $values, true); } - private function _dq(string $query, ?array $values = null, bool $resultless = false) : DatabaseResult_Abstract + private function _dq(string $query, ?array $values = null) : DatabaseResult_Abstract { if (null !== $values && sizeof($values) > 0) { @@ -123,7 +123,7 @@ class Database_Mysqli extends Database_Abstract $query .= $m[$i]; } $this->setLastQuery($query); - return new DatabaseResult_Mysqli($this->dbh, $query, $resultless); + return new DatabaseResult_Mysqli($this->dbh, $query); } function affected(): int From 1ea7a7bc20a022924621588d51e373307ee550d9 Mon Sep 17 00:00:00 2001 From: Tim Gerundt Date: Thu, 11 Sep 2025 21:36:53 +0200 Subject: [PATCH 03/12] Add bootstrap file to `phpstan` --- phpstan.neon | 2 ++ 1 file changed, 2 insertions(+) diff --git a/phpstan.neon b/phpstan.neon index ebb75dd..9137f46 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -8,5 +8,7 @@ parameters: excludePaths: analyse: - src/includes/vendor + bootstrapFiles: + - src/config-sample.php fileExtensions: - php \ No newline at end of file From 153bd79ca51a50d6d837d06642e05d3b7c102b37 Mon Sep 17 00:00:00 2001 From: Tim Gerundt Date: Thu, 11 Sep 2025 21:40:26 +0200 Subject: [PATCH 04/12] Function `cmd_read` invoked with 2 parameters, 1 required --- src/mtt-edit-settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mtt-edit-settings.php b/src/mtt-edit-settings.php index 556c61c..0b84b67 100644 --- a/src/mtt-edit-settings.php +++ b/src/mtt-edit-settings.php @@ -20,7 +20,7 @@ $value = $argc > 3 ? $argv[3] : null; switch ($cmd) { - case 'read': cmd_read($param, $value); break; + case 'read': cmd_read($param); break; case 'write': cmd_write($param, $value); break; case 'password': cmd_password($param); break; default: die("Unknown command: $cmd\n"); From 0f02b9eb52bd49a1c00db1ae67094329b685bcaa Mon Sep 17 00:00:00 2001 From: Tim Gerundt Date: Sat, 13 Sep 2025 13:04:05 +0200 Subject: [PATCH 05/12] Constructor of class `DatabaseResult_Mysqli` has an unused parameter `$resultless` - Part 2 --- src/includes/class.db.mysqli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/includes/class.db.mysqli.php b/src/includes/class.db.mysqli.php index 1cd5471..52c26f0 100644 --- a/src/includes/class.db.mysqli.php +++ b/src/includes/class.db.mysqli.php @@ -102,7 +102,7 @@ class Database_Mysqli extends Database_Abstract */ function ex(string $query, ?array $values = null): void { - $this->_dq($query, $values, true); + $this->_dq($query, $values); } private function _dq(string $query, ?array $values = null) : DatabaseResult_Abstract From 7a501985731b82419cffd7717749b443e66cb2c0 Mon Sep 17 00:00:00 2001 From: Tim Gerundt Date: Mon, 15 Sep 2025 20:43:53 +0200 Subject: [PATCH 06/12] Fix access to protected property Database_Abstract::$prefix --- src/api.php | 4 +- src/export.php | 2 +- src/ext/backup/class.backup.php | 10 +- src/ext/backup/class.check.php | 28 ++-- src/ext/backup/class.restore.php | 14 +- src/ext/notifications/class.observer.php | 2 +- src/feed.php | 2 +- src/includes/api/ListsController.php | 36 ++--- src/includes/api/TagsController.php | 6 +- src/includes/api/TasksController.php | 68 ++++----- src/includes/class.config.php | 8 +- src/includes/class.dbconnection.php | 8 ++ src/includes/class.dbcore.php | 24 ++-- src/includes/class.sessionhandler.php | 16 +-- src/init.php | 2 +- src/setup.php | 168 +++++++++++------------ 16 files changed, 203 insertions(+), 195 deletions(-) diff --git a/src/api.php b/src/api.php index 39d750d..3752803 100644 --- a/src/api.php +++ b/src/api.php @@ -197,7 +197,7 @@ function checkReadAccess(?int $listId = null) if (is_logged()) return true; if ($listId !== null) { - $id = $db->sq("SELECT id FROM {$db->prefix}lists WHERE id=? AND published=1", array($listId)); + $id = $db->sq("SELECT id FROM {$db->getPrefix()}lists WHERE id=? AND published=1", array($listId)); if ($id) return; } http_response_code(403); @@ -221,7 +221,7 @@ function haveWriteAccess(?int $listId = null) : bool if ($listId !== null && $listId != -1) { $db = DBConnection::instance(); - $count = $db->sq("SELECT COUNT(*) FROM {$db->prefix}lists WHERE id=?", array($listId)); + $count = $db->sq("SELECT COUNT(*) FROM {$db->getPrefix()}lists WHERE id=?", array($listId)); if (!$count) return false; } return true; diff --git a/src/export.php b/src/export.php index d3cdca9..d01bdf8 100644 --- a/src/export.php +++ b/src/export.php @@ -11,7 +11,7 @@ require_once('./init.php'); $listId = (int)_get('list'); $db = DBConnection::instance(); -$listData = $db->sqa("SELECT * FROM {$db->prefix}lists WHERE id=$listId"); +$listData = $db->sqa("SELECT * FROM {$db->getPrefix()}lists WHERE id=$listId"); if ( $listData && !is_logged() && !$listData['published'] ) { $extra = json_decode($listData['extra'] ?? '', true, 10, JSON_INVALID_UTF8_SUBSTITUTE); $feedKey = (string) ($extra['feedKey'] ?? ''); diff --git a/src/ext/backup/class.backup.php b/src/ext/backup/class.backup.php index a8bd7e7..d5214f3 100644 --- a/src/ext/backup/class.backup.php +++ b/src/ext/backup/class.backup.php @@ -61,11 +61,11 @@ class Backup $this->level = 0; - $this->writeTable($db->prefix.'lists', 'lists', 'list'); - $this->writeTable($db->prefix.'todolist', 'tasks', 'task'); - $this->writeTable($db->prefix.'tags', 'tags', 'tag'); - $this->writeTable($db->prefix.'tag2task', 'tag2task', 'item'); - $this->writeTable($db->prefix.'settings', 'settings', 'item'); + $this->writeTable($db->getTableWithPrefix('lists'), 'lists', 'list'); + $this->writeTable($db->getTableWithPrefix('todolist'), 'tasks', 'task'); + $this->writeTable($db->getTableWithPrefix('tags'), 'tags', 'tag'); + $this->writeTable($db->getTableWithPrefix('tag2task'), 'tag2task', 'item'); + $this->writeTable($db->getTableWithPrefix('settings'), 'settings', 'item'); $this->writeClosingTag('mttdb'); diff --git a/src/ext/backup/class.check.php b/src/ext/backup/class.check.php index 9ec520d..d37d4af 100644 --- a/src/ext/backup/class.check.php +++ b/src/ext/backup/class.check.php @@ -21,31 +21,31 @@ class Check $msg = []; // Task without list - $count = $db->sq("SELECT COUNT(*) FROM {$db->prefix}todolist WHERE list_id NOT IN (SELECT id FROM {$db->prefix}lists)"); + $count = $db->sq("SELECT COUNT(*) FROM {$db->getPrefix()}todolist WHERE list_id NOT IN (SELECT id FROM {$db->getPrefix()}lists)"); if ($count) { $msg[] = "Tasks without list: $count"; } // Tag without task (not a broblem) - $count = $db->sq("SELECT COUNT(*) FROM {$db->prefix}tags WHERE id NOT IN (SELECT tag_id FROM {$db->prefix}tag2task)"); + $count = $db->sq("SELECT COUNT(*) FROM {$db->getPrefix()}tags WHERE id NOT IN (SELECT tag_id FROM {$db->getPrefix()}tag2task)"); if ($count) { $msg[] = "Tags without task: $count"; } // tag2task no list - $count = $db->sq("SELECT COUNT(*) FROM {$db->prefix}tag2task WHERE list_id NOT IN (SELECT id FROM {$db->prefix}lists)"); + $count = $db->sq("SELECT COUNT(*) FROM {$db->getPrefix()}tag2task WHERE list_id NOT IN (SELECT id FROM {$db->getPrefix()}lists)"); if ($count) { $msg[] = "tag2task no list: $count"; } // tag2task no tag - $count = $db->sq("SELECT COUNT(*) FROM {$db->prefix}tag2task WHERE tag_id NOT IN (SELECT id FROM {$db->prefix}tags)"); + $count = $db->sq("SELECT COUNT(*) FROM {$db->getPrefix()}tag2task WHERE tag_id NOT IN (SELECT id FROM {$db->getPrefix()}tags)"); if ($count) { $msg[] = "tag2task no tag: $count"; } // tag2task no task - $count = $db->sq("SELECT COUNT(*) FROM {$db->prefix}tag2task WHERE task_id NOT IN (SELECT id FROM {$db->prefix}todolist)"); + $count = $db->sq("SELECT COUNT(*) FROM {$db->getPrefix()}tag2task WHERE task_id NOT IN (SELECT id FROM {$db->getPrefix()}todolist)"); if ($count) { $msg[] = "tag2task no task: $count"; } @@ -53,7 +53,7 @@ class Check $count = 0; $uniqTag = []; // lowerTag => [id, tag] $nonuniqTag = []; // id => [tag, lowerTag, uniqId, uniqTag, taskCount] - $q = $db->dq("SELECT id,name,COUNT(task_id) c FROM {$db->prefix}tags t LEFT JOIN {$db->prefix}tag2task tt ON t.id=tt.tag_id GROUP BY id ORDER BY id"); + $q = $db->dq("SELECT id,name,COUNT(task_id) c FROM {$db->getPrefix()}tags t LEFT JOIN {$db->getPrefix()}tag2task tt ON t.id=tt.tag_id GROUP BY id ORDER BY id"); while ($r = $q->fetchAssoc()) { $v = mb_strtolower((string)$r['name'], 'UTF-8'); if (!isset($uniqTag[$v])) { @@ -86,22 +86,22 @@ class Check $db->ex("BEGIN"); // Task without list - $count = (int)$db->sq("SELECT COUNT(*) FROM {$db->prefix}todolist WHERE list_id NOT IN (SELECT id FROM {$db->prefix}lists)"); + $count = (int)$db->sq("SELECT COUNT(*) FROM {$db->getPrefix()}todolist WHERE list_id NOT IN (SELECT id FROM {$db->getPrefix()}lists)"); if ($count > 0) { // Move to new list $listID = \DBCore::default()->createListWithName("Restored tasks"); - $db->ex("UPDATE {$db->prefix}todolist SET list_id=? WHERE list_id NOT IN (SELECT id FROM {$db->prefix}lists)", [$listID]); + $db->ex("UPDATE {$db->getPrefix()}todolist SET list_id=? WHERE list_id NOT IN (SELECT id FROM {$db->getPrefix()}lists)", [$listID]); } //Tags - $db->ex("DELETE FROM {$db->prefix}tags WHERE id NOT IN (SELECT tag_id FROM {$db->prefix}tag2task)"); - $db->ex("DELETE FROM {$db->prefix}tag2task WHERE task_id NOT IN (SELECT id FROM {$db->prefix}todolist)"); - $db->ex("DELETE FROM {$db->prefix}tag2task WHERE tag_id NOT IN (SELECT id FROM {$db->prefix}tags)"); + $db->ex("DELETE FROM {$db->getPrefix()}tags WHERE id NOT IN (SELECT tag_id FROM {$db->getPrefix()}tag2task)"); + $db->ex("DELETE FROM {$db->getPrefix()}tag2task WHERE task_id NOT IN (SELECT id FROM {$db->getPrefix()}todolist)"); + $db->ex("DELETE FROM {$db->getPrefix()}tag2task WHERE tag_id NOT IN (SELECT id FROM {$db->getPrefix()}tags)"); //Non-unique tags replace with first unique $uniqTag = []; $replace = []; - $q = $db->dq("SELECT id,name FROM {$db->prefix}tags t LEFT JOIN {$db->prefix}tag2task tt ON t.id=tt.tag_id GROUP BY id ORDER BY id"); + $q = $db->dq("SELECT id,name FROM {$db->getPrefix()}tags t LEFT JOIN {$db->getPrefix()}tag2task tt ON t.id=tt.tag_id GROUP BY id ORDER BY id"); while ($r = $q->fetchAssoc()) { $v = mb_strtolower((string)$r['name'], 'UTF-8'); if (!isset($uniqTag[$v])) { @@ -112,9 +112,9 @@ class Check } } foreach ($replace as $id => $newId) { - $db->ex("UPDATE {$db->prefix}tag2task SET tag_id=? WHERE tag_id=?", [$newId, $id]); + $db->ex("UPDATE {$db->getPrefix()}tag2task SET tag_id=? WHERE tag_id=?", [$newId, $id]); } - $db->ex("DELETE FROM {$db->prefix}tags WHERE id NOT IN (SELECT tag_id FROM {$db->prefix}tag2task)"); + $db->ex("DELETE FROM {$db->getPrefix()}tags WHERE id NOT IN (SELECT tag_id FROM {$db->getPrefix()}tag2task)"); // TODO: tag2task no list ? diff --git a/src/ext/backup/class.restore.php b/src/ext/backup/class.restore.php index 94051a0..d05bcd8 100644 --- a/src/ext/backup/class.restore.php +++ b/src/ext/backup/class.restore.php @@ -197,11 +197,11 @@ class Restore $subsStr = implode(',', array_fill(0, count($fields), '?')); // ?,?,? ... $db = DBConnection::instance(); try { - $db->ex("INSERT INTO {$db->prefix}{$table} ($fieldsStr) VALUES ($subsStr)", $values); + $db->ex("INSERT INTO {$db->getPrefix()}{$table} ($fieldsStr) VALUES ($subsStr)", $values); } catch (Exception $e) { error_log("Failed query: {$db->lastQuery}"); - $this->lastErrorString = "Failed to add data to table '{$db->prefix}$table'. Database error (see query in error log): ". $e->getMessage(); + $this->lastErrorString = "Failed to add data to table '{$db->getPrefix()}$table'. Database error (see query in error log): ". $e->getMessage(); return false; } return true; @@ -212,13 +212,13 @@ class Restore $db = DBConnection::instance(); switch ($db::DBTYPE) { case DBConnection::DBTYPE_MYSQL: - $db->ex("ALTER TABLE {$db->prefix}$table AUTO_INCREMENT = ". (int)$autoinc); + $db->ex("ALTER TABLE {$db->getPrefix()}$table AUTO_INCREMENT = ". (int)$autoinc); break; case DBConnection::DBTYPE_POSTGRES: - $db->ex("ALTER TABLE {$db->prefix}$table ALTER COLUMN id RESTART WITH ". (int)$autoinc); + $db->ex("ALTER TABLE {$db->getPrefix()}$table ALTER COLUMN id RESTART WITH ". (int)$autoinc); break; case DBConnection::DBTYPE_SQLITE: - $db->ex("UPDATE sqlite_sequence SET seq=? WHERE name=?", [$autoinc, $db->prefix. $table]); + $db->ex("UPDATE sqlite_sequence SET seq=? WHERE name=?", [$autoinc, $db->getTableWithPrefix($table)]); break; default: break; @@ -230,7 +230,7 @@ class Restore $db = DBConnection::instance(); $db->ex("BEGIN"); foreach ($this->tableItem as $a) { - $table = $db->prefix. $a[0]; + $table = $db->getTableWithPrefix($a[0]); if ($db::DBTYPE == DBConnection::DBTYPE_POSTGRES) { $db->ex("TRUNCATE TABLE $table RESTART IDENTITY"); } @@ -241,7 +241,7 @@ class Restore $db->ex("DELETE FROM $table"); } } - $db->ex("DELETE FROM {$db->prefix}sessions"); + $db->ex("DELETE FROM {$db->getPrefix()}sessions"); } private function endRestore() diff --git a/src/ext/notifications/class.observer.php b/src/ext/notifications/class.observer.php index 1b0db2a..6e9cc1e 100644 --- a/src/ext/notifications/class.observer.php +++ b/src/ext/notifications/class.observer.php @@ -36,7 +36,7 @@ class NotificationObserver implements \MTTNotificationObserverInterface case MTTNotification::didCreateTask: case MTTNotification::didCreateList: // Get list name - $list = $db->sqa( "SELECT name FROM {$db->prefix}lists WHERE id=?", array($object['listId'] ?? 0) ); + $list = $db->sqa( "SELECT name FROM {$db->getPrefix()}lists WHERE id=?", array($object['listId'] ?? 0) ); $object['listName'] = htmlspecialchars($list['name'] ?? ''); $this->delayedNotifications[] = [ 'notification' => $notification, diff --git a/src/feed.php b/src/feed.php index 369a461..98b9076 100644 --- a/src/feed.php +++ b/src/feed.php @@ -14,7 +14,7 @@ $lang = Lang::instance(); $listId = (int)_get('list'); $db = DBConnection::instance(); -$listData = $db->sqa("SELECT * FROM {$db->prefix}lists WHERE id=$listId"); +$listData = $db->sqa("SELECT * FROM {$db->getPrefix()}lists WHERE id=$listId"); if ( $listData && need_auth() && !$listData['published'] ) { $extra = json_decode($listData['extra'] ?? '', true, 10, JSON_INVALID_UTF8_SUBSTITUTE); $feedKey = (string) ($extra['feedKey'] ?? ''); diff --git a/src/includes/api/ListsController.php b/src/includes/api/ListsController.php index 98ae2f2..e7c5395 100644 --- a/src/includes/api/ListsController.php +++ b/src/includes/api/ListsController.php @@ -29,7 +29,7 @@ class ListsController extends ApiController { $t['total'] = 1; } $t['time'] = time(); - $q = $db->dq("SELECT * FROM {$db->prefix}lists $sqlWhere ORDER BY ow ASC, id ASC"); + $q = $db->dq("SELECT * FROM {$db->getPrefix()}lists $sqlWhere ORDER BY ow ASC, id ASC"); while ($r = $q->fetchAssoc()) { $t['total']++; @@ -84,7 +84,7 @@ class ListsController extends ApiController { { checkReadAccess($id); $db = DBConnection::instance(); - $r = $db->sqa( "SELECT * FROM {$db->prefix}lists WHERE id=?", array($id) ); + $r = $db->sqa( "SELECT * FROM {$db->getPrefix()}lists WHERE id=?", array($id) ); if (!$r) { $this->response->data = null; return; @@ -203,7 +203,7 @@ class ListsController extends ApiController { } $db = DBConnection::instance(); $t['total'] = 1; - $r = $db->sqa("SELECT * FROM {$db->prefix}lists WHERE id=$id"); + $r = $db->sqa("SELECT * FROM {$db->getPrefix()}lists WHERE id=$id"); $oo = $this->prepareList($r, true); MTTNotificationCenter::postNotification(MTTNotification::didCreateList, $oo); $t['list'][] = $oo; @@ -218,9 +218,9 @@ class ListsController extends ApiController { $name = trim($this->req->jsonBody['name'] ?? ''); if ($name == '') return $t; - $db->dq("UPDATE {$db->prefix}lists SET name=?,d_edited=? WHERE id=$id", array($name, time()) ); + $db->dq("UPDATE {$db->getPrefix()}lists SET name=?,d_edited=? WHERE id=$id", array($name, time()) ); $t['total'] = $db->affected(); - $r = $db->sqa("SELECT * FROM {$db->prefix}lists WHERE id=$id"); + $r = $db->sqa("SELECT * FROM {$db->getPrefix()}lists WHERE id=$id"); $t['list'][] = $this->prepareList($r, true); return $t; } @@ -244,7 +244,7 @@ class ListsController extends ApiController { Config::saveDomain('alltasks.json', $opts); } else { - $db->ex("UPDATE {$db->prefix}lists SET sorting=$sort,d_edited=? WHERE id=$listId", array(time())); + $db->ex("UPDATE {$db->getPrefix()}lists SET sorting=$sort,d_edited=? WHERE id=$listId", array(time())); } } @@ -258,7 +258,7 @@ class ListsController extends ApiController { } else { $bitwise = $showCompleted ? 'taskview | 1' : 'taskview & ~1'; - $db->dq("UPDATE {$db->prefix}lists SET taskview=$bitwise WHERE id=?", [$listId]); + $db->dq("UPDATE {$db->getPrefix()}lists SET taskview=$bitwise WHERE id=?", [$listId]); } } @@ -266,7 +266,7 @@ class ListsController extends ApiController { { $db = DBConnection::instance(); $publish = (int)($this->req->jsonBody['publish'] ?? 0); - $db->ex("UPDATE {$db->prefix}lists SET published=?,d_edited=? WHERE id=$listId", array($publish ? 1 : 0, time())); + $db->ex("UPDATE {$db->getPrefix()}lists SET published=?,d_edited=? WHERE id=$listId", array($publish ? 1 : 0, time())); return ['total'=>1]; } @@ -274,7 +274,7 @@ class ListsController extends ApiController { { $db = DBConnection::instance(); $flag = (int)($this->req->jsonBody['enable'] ?? 0); - $json = $db->sq("SELECT extra FROM {$db->prefix}lists WHERE id=$listId") ?? ''; + $json = $db->sq("SELECT extra FROM {$db->getPrefix()}lists WHERE id=$listId") ?? ''; $extra = strlen($json) > 0 ? json_decode($json, true, 10, JSON_INVALID_UTF8_SUBSTITUTE) : []; if ($extra === false) { error_log("Failed to decodes JSON data of list extra listId=$listId: " . json_last_error_msg()); @@ -287,7 +287,7 @@ class ListsController extends ApiController { $extra['feedKey'] = randomString(); } $json = json_encode($extra, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); - $db->ex("UPDATE {$db->prefix}lists SET extra=?,d_edited=? WHERE id=$listId", array($json, time())); + $db->ex("UPDATE {$db->getPrefix()}lists SET extra=?,d_edited=? WHERE id=$listId", array($json, time())); return [ 'total' => 1, 'list' => [[ @@ -302,7 +302,7 @@ class ListsController extends ApiController { $db = DBConnection::instance(); $flag = (int)($this->req->jsonBody['shownotes'] ?? 0); $bitwise = ($flag == 0) ? 'taskview & ~2' : 'taskview | 2'; - $db->dq("UPDATE {$db->prefix}lists SET taskview=$bitwise WHERE id=$listId"); + $db->dq("UPDATE {$db->getPrefix()}lists SET taskview=$bitwise WHERE id=$listId"); return ['total'=>1]; } @@ -317,7 +317,7 @@ class ListsController extends ApiController { } else { $bitwise = ($flag == 0) ? 'taskview & ~4' : 'taskview | 4'; - $db->dq("UPDATE {$db->prefix}lists SET taskview=$bitwise WHERE id=$listId"); + $db->dq("UPDATE {$db->getPrefix()}lists SET taskview=$bitwise WHERE id=$listId"); } return ['total'=>1]; } @@ -328,8 +328,8 @@ class ListsController extends ApiController { $t = array(); $t['total'] = 0; $db->ex("BEGIN"); - $db->ex("DELETE FROM {$db->prefix}tag2task WHERE task_id IN (SELECT id FROM {$db->prefix}todolist WHERE list_id=? and compl=1)", array($listId)); - $db->ex("DELETE FROM {$db->prefix}todolist WHERE list_id=$listId and compl=1"); + $db->ex("DELETE FROM {$db->getPrefix()}tag2task WHERE task_id IN (SELECT id FROM {$db->getPrefix()}todolist WHERE list_id=? and compl=1)", array($listId)); + $db->ex("DELETE FROM {$db->getPrefix()}todolist WHERE list_id=$listId and compl=1"); $t['total'] = $db->affected(); $db->ex("COMMIT"); if (MTTNotificationCenter::hasObserversForNotification(MTTNotification::didDeleteCompletedInList)) { @@ -360,7 +360,7 @@ class ListsController extends ApiController { $setCase .= "WHEN id=$id THEN $i\n"; } $ids = implode(',', $a); - $db->dq("UPDATE {$db->prefix}lists SET d_edited=?, ow = CASE\n $setCase END WHERE id IN ($ids)", + $db->dq("UPDATE {$db->getPrefix()}lists SET d_edited=?, ow = CASE\n $setCase END WHERE id IN ($ids)", array(time()) ); $t['total'] = 1; return $t; @@ -377,11 +377,11 @@ class ListsController extends ApiController { $list = $this->getListRowById($id); } $db->ex("BEGIN"); - $db->ex("DELETE FROM {$db->prefix}lists WHERE id=$id"); + $db->ex("DELETE FROM {$db->getPrefix()}lists WHERE id=$id"); $t['total'] = $db->affected(); if ($t['total']) { - $db->ex("DELETE FROM {$db->prefix}tag2task WHERE list_id=$id"); - $db->ex("DELETE FROM {$db->prefix}todolist WHERE list_id=$id"); + $db->ex("DELETE FROM {$db->getPrefix()}tag2task WHERE list_id=$id"); + $db->ex("DELETE FROM {$db->getPrefix()}todolist WHERE list_id=$id"); } $db->ex("COMMIT"); if ($t['total'] && MTTNotificationCenter::hasObserversForNotification(MTTNotification::didDeleteList)) { diff --git a/src/includes/api/TagsController.php b/src/includes/api/TagsController.php index cbf9f6f..5f66765 100644 --- a/src/includes/api/TagsController.php +++ b/src/includes/api/TagsController.php @@ -21,7 +21,7 @@ class TagsController extends ApiController { $sqlWhere = ($listId == -1) ? "" : "WHERE list_id = $listId"; $q = $db->dq("SELECT name, tag_id, COUNT(tag_id) AS tags_count - FROM {$db->prefix}tag2task INNER JOIN {$db->prefix}tags ON tag_id = id + FROM {$db->getPrefix()}tag2task INNER JOIN {$db->getPrefix()}tags ON tag_id = id $sqlWhere GROUP BY tag_id, name ORDER BY tags_count DESC"); @@ -73,8 +73,8 @@ class TagsController extends ApiController { $db = DBConnection::instance(); $begin = trim(_get('q')); $limit = 8; - $q = $db->dq("SELECT name, tag_id AS id FROM {$db->prefix}tags - INNER JOIN {$db->prefix}tag2task ON id=tag_id + $q = $db->dq("SELECT name, tag_id AS id FROM {$db->getPrefix()}tags + INNER JOIN {$db->getPrefix()}tag2task ON id=tag_id WHERE list_id=$listId AND ". $db->like('name', '%s%%', $begin). " GROUP BY tag_id, name ORDER BY name diff --git a/src/includes/api/TasksController.php b/src/includes/api/TasksController.php index c54d7f9..f83ef20 100644 --- a/src/includes/api/TasksController.php +++ b/src/includes/api/TasksController.php @@ -75,15 +75,15 @@ class TasksController extends ApiController { if (count($tagIds) > 0) { $tagAnd = []; foreach ($tagIds as $ids) { - $tagAnd[] = "task_id IN (SELECT task_id FROM {$db->prefix}tag2task WHERE tag_id IN (". implode(',', $ids). "))"; + $tagAnd[] = "task_id IN (SELECT task_id FROM {$db->getPrefix()}tag2task WHERE tag_id IN (". implode(',', $ids). "))"; } $sqlWhere .= "\n AND todo.id IN (". - "SELECT DISTINCT task_id FROM {$db->prefix}tag2task WHERE ". implode(' AND ', $tagAnd). ")"; + "SELECT DISTINCT task_id FROM {$db->getPrefix()}tag2task WHERE ". implode(' AND ', $tagAnd). ")"; } // Exclude tags if (count($tagExIds) > 0) { - $sqlWhere .= "\n AND todo.id NOT IN (SELECT DISTINCT task_id FROM {$db->prefix}tag2task ". + $sqlWhere .= "\n AND todo.id NOT IN (SELECT DISTINCT task_id FROM {$db->getPrefix()}tag2task ". "WHERE tag_id IN (". implode(',', $tagExIds). "))"; } } @@ -132,9 +132,9 @@ class TasksController extends ApiController { $q = $db->dq(" 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 + FROM {$db->getPrefix()}todolist AS todo + LEFT JOIN {$db->getPrefix()}tag2task AS t2t ON todo.id = t2t.task_id + LEFT JOIN {$db->getPrefix()}tags AS tags ON t2t.tag_id = tags.id WHERE $sqlWhereListId $sqlWhere GROUP BY todo.id $sqlHaving $sqlSort @@ -295,7 +295,7 @@ class TasksController extends ApiController { if ($sqlWhereList) { $sqlWhere = implode(' OR ', $sqlWhereList); - $q = $db->dq("SELECT list_id, COUNT(id) c FROM {$db->prefix}todolist + $q = $db->dq("SELECT list_id, COUNT(id) c FROM {$db->getPrefix()}todolist WHERE $sqlWhere GROUP BY list_id"); while ($r = $q->fetchAssoc()) { $a[] = [ @@ -309,7 +309,7 @@ class TasksController extends ApiController { $list = (int) ($this->req->jsonBody['list'] ?? 0); $later = (int) ($this->req->jsonBody['later'] ?? 0); if ($list > 0 && $later > 0 && (!$userLists || in_array((string)$list, $userLists))) { - $q = $db->dq("SELECT id FROM {$db->prefix}todolist + $q = $db->dq("SELECT id FROM {$db->getPrefix()}todolist WHERE list_id = $list AND compl=0 AND d_created > $later"); while ($r = $q->fetchAssoc()) { $b[] = (int)$r['id']; @@ -355,10 +355,10 @@ class TasksController extends ApiController { if (Config::get('autotag')) { $tags .= ',' . ($this->req->jsonBody['tag'] ?? ''); } - $ow = 1 + (int)$db->sq("SELECT MAX(ow) FROM {$db->prefix}todolist WHERE list_id=$listId AND compl=0"); + $ow = 1 + (int)$db->sq("SELECT MAX(ow) FROM {$db->getPrefix()}todolist WHERE list_id=$listId AND compl=0"); $date = time(); $db->ex("BEGIN"); - $db->dq("INSERT INTO {$db->prefix}todolist (uuid,list_id,title,d_created,d_edited,ow,prio,duedate) VALUES (?,?,?,?,?,?,?,?)", + $db->dq("INSERT INTO {$db->getPrefix()}todolist (uuid,list_id,title,d_created,d_edited,ow,prio,duedate) VALUES (?,?,?,?,?,?,?,?)", array(generateUUID(), $listId, $title, $date, $date, $ow, $prio, $duedate) ); $id = (int) $db->lastInsertId(); if ($tags != '') @@ -393,10 +393,10 @@ class TasksController extends ApiController { $tags = $this->req->jsonBody['tags'] ?? ''; if (Config::get('autotag')) $tags .= ',' . ($this->req->jsonBody['tag'] ?? ''); - $ow = 1 + (int)$db->sq("SELECT MAX(ow) FROM {$db->prefix}todolist WHERE list_id=$listId AND compl=0"); + $ow = 1 + (int)$db->sq("SELECT MAX(ow) FROM {$db->getPrefix()}todolist WHERE list_id=$listId AND compl=0"); $date = time(); $db->ex("BEGIN"); - $db->dq("INSERT INTO {$db->prefix}todolist (uuid,list_id,title,d_created,d_edited,ow,prio,note,duedate) VALUES (?,?,?,?,?,?,?,?,?)", + $db->dq("INSERT INTO {$db->getPrefix()}todolist (uuid,list_id,title,d_created,d_edited,ow,prio,note,duedate) VALUES (?,?,?,?,?,?,?,?,?)", array(generateUUID(), $listId, $title, $date, $date, $ow, $prio, $note, $duedate) ); $id = (int) $db->lastInsertId(); if ($tags != '') @@ -428,15 +428,15 @@ class TasksController extends ApiController { if ($title == '') { return $t; } - $listId = (int) $db->sq("SELECT list_id FROM {$db->prefix}todolist WHERE id=$id"); + $listId = (int) $db->sq("SELECT list_id FROM {$db->getPrefix()}todolist WHERE id=$id"); $tags = trim( $this->req->jsonBody['tags'] ?? '' ); $db->ex("BEGIN"); - $db->ex("DELETE FROM {$db->prefix}tag2task WHERE task_id=$id"); + $db->ex("DELETE FROM {$db->getPrefix()}tag2task WHERE task_id=$id"); $aTags = $this->prepareTags($tags); if ($aTags) { $this->addTaskTags($id, $aTags['ids'], $listId); } - $db->dq("UPDATE {$db->prefix}todolist SET title=?,note=?,prio=?,duedate=?,d_edited=? WHERE id=$id", + $db->dq("UPDATE {$db->getPrefix()}todolist SET title=?,note=?,prio=?,duedate=?,d_edited=? WHERE id=$id", array($title, $note, $prio, $duedate, time()) ); $db->ex("COMMIT"); $task = $this->getTaskRowById($id, true); @@ -477,21 +477,21 @@ class TasksController extends ApiController { $db = DBConnection::instance(); // Check task exists and not in target list - $r = $db->sqa("SELECT * FROM {$db->prefix}todolist WHERE id=?", array($id)); + $r = $db->sqa("SELECT * FROM {$db->getPrefix()}todolist WHERE id=?", array($id)); if (!$r || $listId == $r['list_id']) return false; // Check target list exists - $l = $db->sqa("SELECT id,name FROM {$db->prefix}lists WHERE id=?", [$listId]); + $l = $db->sqa("SELECT id,name FROM {$db->getPrefix()}lists WHERE id=?", [$listId]); if (!$l) return false; $listName = $l['name']; - $ow = 1 + (int)$db->sq("SELECT MAX(ow) FROM {$db->prefix}todolist WHERE list_id=? AND compl=?", array($listId, $r['compl']?1:0)); + $ow = 1 + (int)$db->sq("SELECT MAX(ow) FROM {$db->getPrefix()}todolist WHERE list_id=? AND compl=?", array($listId, $r['compl']?1:0)); $db->ex("BEGIN"); - $db->ex("UPDATE {$db->prefix}tag2task SET list_id=? WHERE task_id=?", array($listId, $id)); - $db->dq("UPDATE {$db->prefix}todolist SET list_id=?, ow=?, d_edited=? WHERE id=?", array($listId, $ow, time(), $id)); + $db->ex("UPDATE {$db->getPrefix()}tag2task SET list_id=? WHERE task_id=?", array($listId, $id)); + $db->dq("UPDATE {$db->getPrefix()}todolist SET list_id=?, ow=?, d_edited=? WHERE id=?", array($listId, $ow, time(), $id)); $db->ex("COMMIT"); return true; } @@ -500,12 +500,12 @@ class TasksController extends ApiController { { $db = DBConnection::instance(); $compl = (int)($this->req->jsonBody['compl'] ?? 0); - $listId = (int)$db->sq("SELECT list_id FROM {$db->prefix}todolist WHERE id=$id"); - if ($compl) $ow = 1 + (int)$db->sq("SELECT MAX(ow) FROM {$db->prefix}todolist WHERE list_id=$listId AND compl=1"); - else $ow = 1 + (int)$db->sq("SELECT MAX(ow) FROM {$db->prefix}todolist WHERE list_id=$listId AND compl=0"); + $listId = (int)$db->sq("SELECT list_id FROM {$db->getPrefix()}todolist WHERE id=$id"); + if ($compl) $ow = 1 + (int)$db->sq("SELECT MAX(ow) FROM {$db->getPrefix()}todolist WHERE list_id=$listId AND compl=1"); + else $ow = 1 + (int)$db->sq("SELECT MAX(ow) FROM {$db->getPrefix()}todolist WHERE list_id=$listId AND compl=0"); $date = time(); $dateCompleted = $compl ? $date : 0; - $db->dq("UPDATE {$db->prefix}todolist SET compl=$compl,ow=$ow,d_completed=?,d_edited=? WHERE id=$id", + $db->dq("UPDATE {$db->getPrefix()}todolist SET compl=$compl,ow=$ow,d_completed=?,d_edited=? WHERE id=$id", array($dateCompleted, $date) ); $task = $this->getTaskRowById($id); MTTNotificationCenter::postNotification(MTTNotification::didCompleteTask, $task); @@ -520,7 +520,7 @@ class TasksController extends ApiController { $db = DBConnection::instance(); $note = $this->req->jsonBody['note'] ?? ''; $note = str_replace("\r\n", "\n", $note); - $db->dq("UPDATE {$db->prefix}todolist SET note=?,d_edited=? WHERE id=$id", array($note, time()) ); + $db->dq("UPDATE {$db->getPrefix()}todolist SET note=?,d_edited=? WHERE id=$id", array($note, time()) ); if (MTTNotificationCenter::hasObserversForNotification(MTTNotification::didEditTask)) { $task = $this->getTaskRowById($id); MTTNotificationCenter::postNotification(MTTNotification::didEditTask, [ @@ -540,7 +540,7 @@ class TasksController extends ApiController { $prio = (int)($this->req->jsonBody['prio'] ?? 0); if ($prio < -1) $prio = -1; elseif ($prio > 2) $prio = 2; - $db->ex("UPDATE {$db->prefix}todolist SET prio=$prio,d_edited=? WHERE id=$id", array(time()) ); + $db->ex("UPDATE {$db->getPrefix()}todolist SET prio=$prio,d_edited=? WHERE id=$id", array(time()) ); if (MTTNotificationCenter::hasObserversForNotification(MTTNotification::didEditTask)) { $task = $this->getTaskRowById($id); MTTNotificationCenter::postNotification(MTTNotification::didEditTask, [ @@ -573,7 +573,7 @@ class TasksController extends ApiController { foreach ($ad as $diff=>$ids) { if ($diff >=0) $set = "ow=ow+".$diff; else $set = "ow=ow-".abs($diff); - $db->dq("UPDATE {$db->prefix}todolist SET $set,d_edited=? WHERE id IN (".implode(',',$ids).")", array(time()) ); + $db->dq("UPDATE {$db->getPrefix()}todolist SET $set,d_edited=? WHERE id IN (".implode(',',$ids).")", array(time()) ); } $db->ex("COMMIT"); $t['total'] = 1; @@ -590,9 +590,9 @@ class TasksController extends ApiController { } $db = DBConnection::instance(); $db->ex("BEGIN"); - $db->ex("DELETE FROM {$db->prefix}tag2task WHERE task_id=$id"); + $db->ex("DELETE FROM {$db->getPrefix()}tag2task WHERE task_id=$id"); //TODO: delete unused tags? - $db->dq("DELETE FROM {$db->prefix}todolist WHERE id=$id"); + $db->dq("DELETE FROM {$db->getPrefix()}todolist WHERE id=$id"); $deleted = $db->affected(); $db->ex("COMMIT"); if ($deleted && MTTNotificationCenter::hasObserversForNotification(MTTNotification::didDeleteTask)) { @@ -612,7 +612,7 @@ class TasksController extends ApiController { $sqlWhere = "WHERE published=1"; } $a = array(); - $q = $db->dq("SELECT id,name FROM {$db->prefix}lists $sqlWhere ORDER BY id ASC"); + $q = $db->dq("SELECT id,name FROM {$db->getPrefix()}lists $sqlWhere ORDER BY id ASC"); while($r = $q->fetchRow()) { $a[ (string)$r[0] ] = (string)$r[1]; } @@ -770,18 +770,18 @@ class TasksController extends ApiController { private function getTagId($tag) { $db = DBConnection::instance(); - $id = $db->sq("SELECT id FROM {$db->prefix}tags WHERE name=?", array($tag)); + $id = $db->sq("SELECT id FROM {$db->getPrefix()}tags WHERE name=?", array($tag)); return $id ? $id : 0; } private function getOrCreateTag($name): array { $db = DBConnection::instance(); - $tagId = $db->sq("SELECT id FROM {$db->prefix}tags WHERE name=?", array($name)); + $tagId = $db->sq("SELECT id FROM {$db->getPrefix()}tags WHERE name=?", array($name)); if ($tagId) return array('id'=>$tagId, 'name'=>$name); - $db->ex("INSERT INTO {$db->prefix}tags (name) VALUES (?)", array($name)); + $db->ex("INSERT INTO {$db->getPrefix()}tags (name) VALUES (?)", array($name)); return array( 'id' => $db->lastInsertId(), 'name' => $name @@ -814,7 +814,7 @@ class TasksController extends ApiController { if (!$tagIds) return; foreach ($tagIds as $tagId) { $db->ex( - "INSERT INTO {$db->prefix}tag2task (task_id,tag_id,list_id) VALUES (?,?,?)", + "INSERT INTO {$db->getPrefix()}tag2task (task_id,tag_id,list_id) VALUES (?,?,?)", array($taskId, $tagId, $listId) ); } diff --git a/src/includes/class.config.php b/src/includes/class.config.php index 2446656..a5b440f 100644 --- a/src/includes/class.config.php +++ b/src/includes/class.config.php @@ -227,7 +227,7 @@ class Config public static function requestDomain(string $key): array { $db = DBConnection::instance(); - $json = $db->sq("SELECT param_value FROM {$db->prefix}settings WHERE param_key = ?", array($key)); + $json = $db->sq("SELECT param_value FROM {$db->getPrefix()}settings WHERE param_key = ?", array($key)); if (!$json) return array(); $j = json_decode($json, true, 100, JSON_INVALID_UTF8_SUBSTITUTE); if ($j === null) { @@ -263,12 +263,12 @@ class Config throw new Exception("Failed to create JSON object with settings. Code: ". (int)json_last_error()); } $db = DBConnection::instance(); - $keyExists = $db->sq("SELECT COUNT(param_key) FROM {$db->prefix}settings WHERE param_key = ?", array($key) ); + $keyExists = $db->sq("SELECT COUNT(param_key) FROM {$db->getPrefix()}settings WHERE param_key = ?", array($key) ); if ($keyExists) { - $db->ex("UPDATE {$db->prefix}settings SET param_value = ? WHERE param_key = ?", array($json,$key) ); + $db->ex("UPDATE {$db->getPrefix()}settings SET param_value = ? WHERE param_key = ?", array($json,$key) ); } else { - $db->ex("INSERT INTO {$db->prefix}settings (param_key,param_value) VALUES (?,?)", array($key,$json) ); + $db->ex("INSERT INTO {$db->getPrefix()}settings (param_key,param_value) VALUES (?,?)", array($key,$json) ); } } diff --git a/src/includes/class.dbconnection.php b/src/includes/class.dbconnection.php index 8f33262..9d300c5 100644 --- a/src/includes/class.dbconnection.php +++ b/src/includes/class.dbconnection.php @@ -77,6 +77,14 @@ abstract class Database_Abstract $this->prefix = $prefix; } + function getPrefix(): string { + return $this->prefix; + } + + function getTableWithPrefix(string $table): string { + return $this->prefix . $table; + } + function setLogQueryToFile(?string $path) { //any checks? $this->logQueryToFile = $path; diff --git a/src/includes/class.dbcore.php b/src/includes/class.dbcore.php index 942a58c..2fc4a72 100644 --- a/src/includes/class.dbcore.php +++ b/src/includes/class.dbcore.php @@ -70,7 +70,7 @@ class DBCore public function getListIdByTaskId(int $id): int { $db = $this->db; - $listId = (int)$db->sq("SELECT list_id FROM {$db->prefix}todolist WHERE id=". (int)$id); + $listId = (int)$db->sq("SELECT list_id FROM {$db->getPrefix()}todolist WHERE id=". (int)$id); return $listId; } @@ -78,7 +78,7 @@ class DBCore public function getListById(int $id): ?array { $db = $this->db; - $r = $db->sqa("SELECT * FROM {$db->prefix}lists WHERE id=?", [$id]); + $r = $db->sqa("SELECT * FROM {$db->getPrefix()}lists WHERE id=?", [$id]); return $r; } @@ -86,7 +86,7 @@ class DBCore public function taskExists(int $id): bool { $db = $this->db; - $count = (int) $db->sq("SELECT COUNT(*) FROM {$db->prefix}todolist WHERE id = $id"); + $count = (int) $db->sq("SELECT COUNT(*) FROM {$db->getPrefix()}todolist WHERE id = $id"); return ($count > 0) ? true : false; } @@ -103,9 +103,9 @@ class DBCore } $r = $db->sqa(" SELECT todo.*, $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 + FROM {$db->getPrefix()}todolist AS todo + LEFT JOIN {$db->getPrefix()}tag2task AS t2t ON todo.id = t2t.task_id + LEFT JOIN {$db->getPrefix()}tags AS tags ON t2t.tag_id = tags.id WHERE todo.id = $id GROUP BY todo.id "); @@ -156,9 +156,9 @@ class DBCore $q = $db->dq(" SELECT todo.*, todo.duedate IS NULL AS ddn, GROUP_CONCAT(tags.id) AS tags_ids, GROUP_CONCAT(tags.name) AS tags - 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 + FROM {$db->getPrefix()}todolist AS todo + LEFT JOIN {$db->getPrefix()}tag2task AS t2t ON todo.id = t2t.task_id + LEFT JOIN {$db->getPrefix()}tags AS tags ON t2t.tag_id = tags.id WHERE todo.list_id = $listId $sqlWhere GROUP BY todo.id $sqlSort @@ -179,9 +179,9 @@ class DBCore if ($name == '') { return null; } - $ow = 1 + (int)$db->sq("SELECT MAX(ow) FROM {$db->prefix}lists"); + $ow = 1 + (int)$db->sq("SELECT MAX(ow) FROM {$db->getPrefix()}lists"); $time = time(); - $db->dq("INSERT INTO {$db->prefix}lists (uuid,name,ow,d_created,d_edited,taskview) VALUES (?,?,?,?,?,?)", + $db->dq("INSERT INTO {$db->getPrefix()}lists (uuid,name,ow,d_created,d_edited,taskview) VALUES (?,?,?,?,?,?)", array(generateUUID(), $name, $ow, $time, $time, 1) ); $id = $db->lastInsertId(); return (int)$id; @@ -196,7 +196,7 @@ class DBCore function getTagIdsByName(string $name): array { $db = DBConnection::instance(); - $q = $db->dq("SELECT id FROM {$db->prefix}tags WHERE ". $db->ciEquals('name', $name)); + $q = $db->dq("SELECT id FROM {$db->getPrefix()}tags WHERE ". $db->ciEquals('name', $name)); $a = []; while ($r = $q->fetchAssoc()) { $a[] = (int) $r['id']; diff --git a/src/includes/class.sessionhandler.php b/src/includes/class.sessionhandler.php index 85c6c04..b92ebf0 100644 --- a/src/includes/class.sessionhandler.php +++ b/src/includes/class.sessionhandler.php @@ -45,7 +45,7 @@ class MTTSessionHandler implements SessionHandlerInterface, SessionUpdateTimesta { // read session data if not expired $time = time(); - $r = $this->db->sq("SELECT data,last_access,expires FROM {$this->db->prefix}sessions WHERE id = ?", [$id]); + $r = $this->db->sq("SELECT data,last_access,expires FROM {$this->db->getPrefix()}sessions WHERE id = ?", [$id]); if ( is_null($r) ) { // We return '' instead of false to avoid warning return ''; @@ -59,7 +59,7 @@ class MTTSessionHandler implements SessionHandlerInterface, SessionUpdateTimesta // refresh every 8 hours if ( $r[1] + 28800 < $time ) { $expire = $time + 14 * 86400; - $this->db->ex("UPDATE {$this->db->prefix}sessions SET last_access=?,expires=? WHERE id = ?", + $this->db->ex("UPDATE {$this->db->getPrefix()}sessions SET last_access=?,expires=? WHERE id = ?", array($time, $expire, $id) ); } @@ -84,15 +84,15 @@ class MTTSessionHandler implements SessionHandlerInterface, SessionUpdateTimesta $time = time(); $expire = $time + 14 * 86400; - $exists = $this->db->sq("SELECT COUNT(*) FROM {$this->db->prefix}sessions WHERE id = ?", [$id]); + $exists = $this->db->sq("SELECT COUNT(*) FROM {$this->db->getPrefix()}sessions WHERE id = ?", [$id]); if (!$exists) { // Create new session with 14 days lifetime - $this->db->ex("INSERT INTO {$this->db->prefix}sessions (id,data,last_access,expires) VALUES (?,?,?,?)", + $this->db->ex("INSERT INTO {$this->db->getPrefix()}sessions (id,data,last_access,expires) VALUES (?,?,?,?)", array($id, $data, $time, $expire) ); } else { // Update existing session - $this->db->ex("UPDATE {$this->db->prefix}sessions SET data = ?, last_access=?, expires=? WHERE id = ?", + $this->db->ex("UPDATE {$this->db->getPrefix()}sessions SET data = ?, last_access=?, expires=? WHERE id = ?", array($data, $time, $expire, $id) ); } return true; @@ -105,7 +105,7 @@ class MTTSessionHandler implements SessionHandlerInterface, SessionUpdateTimesta */ public function destroy($id): bool { - $this->db->ex("DELETE FROM {$this->db->prefix}sessions WHERE id = ?", [$id]); + $this->db->ex("DELETE FROM {$this->db->getPrefix()}sessions WHERE id = ?", [$id]); return true; } @@ -118,7 +118,7 @@ class MTTSessionHandler implements SessionHandlerInterface, SessionUpdateTimesta { // We ignore php runtime 'session.gc_maxlifetime' $expire = time(); - $this->db->ex("DELETE FROM {$this->db->prefix}sessions WHERE expires < $expire"); + $this->db->ex("DELETE FROM {$this->db->getPrefix()}sessions WHERE expires < $expire"); return $this->db->affected(); } @@ -130,7 +130,7 @@ class MTTSessionHandler implements SessionHandlerInterface, SessionUpdateTimesta */ 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->getPrefix()}sessions WHERE id = ?", [$id]); if ($r) return true; return false; diff --git a/src/init.php b/src/init.php index fbfbd39..1ef30c3 100644 --- a/src/init.php +++ b/src/init.php @@ -163,7 +163,7 @@ function configureDbConnection() # Check tables created global $checkDbExists; if (!Config::$noDatabase && isset($checkDbExists) && $checkDbExists) { - $exists = $db->tableExists($db->prefix.'settings'); + $exists = $db->tableExists($db->getTableWithPrefix('settings')); if (!$exists) { die("Need to create or update the database. Run setup.php first."); } diff --git a/src/setup.php b/src/setup.php index 63ac411..539155b 100644 --- a/src/setup.php +++ b/src/setup.php @@ -175,7 +175,7 @@ if ($ver == '') createAllTables($db, $dbtype); # throws # create default list - $db->ex( "INSERT INTO {$db->prefix}lists (uuid,name,d_created,taskview) VALUES (?,?,?,?)", array(generateUUID(), 'Todo', time(), 1) ); + $db->ex( "INSERT INTO {$db->getPrefix()}lists (uuid,name,d_created,taskview) VALUES (?,?,?,?)", array(generateUUID(), 'Todo', time(), 1) ); Config::save(); } @@ -347,7 +347,7 @@ function createMysqlTables(Database_Abstract $db) // Mysql does not support transactions while executing DDL $db->ex( -"CREATE TABLE {$db->prefix}lists ( +"CREATE TABLE {$db->getPrefix()}lists ( `id` INT UNSIGNED NOT NULL auto_increment, `uuid` CHAR(36) CHARACTER SET latin1 NOT NULL default '', `ow` INT NOT NULL default 0, @@ -364,7 +364,7 @@ function createMysqlTables(Database_Abstract $db) $db->ex( -"CREATE TABLE {$db->prefix}todolist ( +"CREATE TABLE {$db->getPrefix()}todolist ( `id` INT UNSIGNED NOT NULL auto_increment, `uuid` CHAR(36) CHARACTER SET latin1 NOT NULL default '', `list_id` INT UNSIGNED NOT NULL default 0, @@ -384,7 +384,7 @@ function createMysqlTables(Database_Abstract $db) // Max length of varchar of utf8mb4 with UNIQUE index is 191 until Mysql 5.7 and MariaDB 10.2 $db->ex( -"CREATE TABLE {$db->prefix}tags ( +"CREATE TABLE {$db->getPrefix()}tags ( `id` INT UNSIGNED NOT NULL auto_increment, `name` VARCHAR(250) NOT NULL default '', PRIMARY KEY(`id`), @@ -393,7 +393,7 @@ function createMysqlTables(Database_Abstract $db) $db->ex( -"CREATE TABLE {$db->prefix}tag2task ( +"CREATE TABLE {$db->getPrefix()}tag2task ( `tag_id` INT UNSIGNED NOT NULL, `task_id` INT UNSIGNED NOT NULL, `list_id` INT UNSIGNED NOT NULL, @@ -404,7 +404,7 @@ function createMysqlTables(Database_Abstract $db) $db->ex( -"CREATE TABLE {$db->prefix}settings ( +"CREATE TABLE {$db->getPrefix()}settings ( `param_key` VARCHAR(250) CHARACTER SET latin1 NOT NULL default '', `param_value` TEXT, UNIQUE KEY `param_key` (`param_key`) @@ -412,7 +412,7 @@ function createMysqlTables(Database_Abstract $db) $db->ex( -"CREATE TABLE {$db->prefix}sessions ( +"CREATE TABLE {$db->getPrefix()}sessions ( `id` VARCHAR(64) CHARACTER SET latin1 NOT NULL default '', /* upto 64 bytes for sha256 */ `data` TEXT, `last_access` INT UNSIGNED NOT NULL default 0, /* time() timestamp */ @@ -428,7 +428,7 @@ function createPostgresTables(Database_Abstract $db) //TODO: use BIGINT for time() timestamp to avoid the Year-2038 problem $db->ex( -"CREATE TABLE {$db->prefix}lists ( +"CREATE TABLE {$db->getPrefix()}lists ( id INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, uuid CHAR(36) NOT NULL default '', ow INTEGER NOT NULL default 0, @@ -440,10 +440,10 @@ function createPostgresTables(Database_Abstract $db) taskview INTEGER NOT NULL default 0, extra TEXT ) "); - $db->ex("CREATE UNIQUE INDEX {$db->prefix}lists_uuid ON {$db->prefix}lists (uuid)"); + $db->ex("CREATE UNIQUE INDEX {$db->getPrefix()}lists_uuid ON {$db->getPrefix()}lists (uuid)"); $db->ex( -"CREATE TABLE {$db->prefix}todolist ( +"CREATE TABLE {$db->getPrefix()}todolist ( id INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, uuid CHAR(36) NOT NULL default '', list_id INTEGER NOT NULL default 0, @@ -457,41 +457,41 @@ function createPostgresTables(Database_Abstract $db) ow INTEGER NOT NULL default 0, duedate DATE default NULL ) "); - $db->ex("CREATE INDEX {$db->prefix}todo_list_id ON {$db->prefix}todolist (list_id)"); - $db->ex("CREATE UNIQUE INDEX {$db->prefix}todo_uuid ON {$db->prefix}todolist (uuid)"); + $db->ex("CREATE INDEX {$db->getPrefix()}todo_list_id ON {$db->getPrefix()}todolist (list_id)"); + $db->ex("CREATE UNIQUE INDEX {$db->getPrefix()}todo_uuid ON {$db->getPrefix()}todolist (uuid)"); $db->ex( -"CREATE TABLE {$db->prefix}tags ( +"CREATE TABLE {$db->getPrefix()}tags ( id INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, name VARCHAR(250) NOT NULL DEFAULT '' ) "); - $db->ex("CREATE UNIQUE INDEX {$db->prefix}tags_lower_name ON {$db->prefix}tags ((LOWER(name)))"); + $db->ex("CREATE UNIQUE INDEX {$db->getPrefix()}tags_lower_name ON {$db->getPrefix()}tags ((LOWER(name)))"); $db->ex( -"CREATE TABLE {$db->prefix}tag2task ( +"CREATE TABLE {$db->getPrefix()}tag2task ( tag_id INTEGER NOT NULL, task_id INTEGER NOT NULL, list_id INTEGER NOT NULL ) "); - $db->ex("CREATE INDEX {$db->prefix}tag2task_tag_id ON {$db->prefix}tag2task (tag_id)"); - $db->ex("CREATE INDEX {$db->prefix}tag2task_task_id ON {$db->prefix}tag2task (task_id)"); - $db->ex("CREATE INDEX {$db->prefix}tag2task_list_id ON {$db->prefix}tag2task (list_id)"); + $db->ex("CREATE INDEX {$db->getPrefix()}tag2task_tag_id ON {$db->getPrefix()}tag2task (tag_id)"); + $db->ex("CREATE INDEX {$db->getPrefix()}tag2task_task_id ON {$db->getPrefix()}tag2task (task_id)"); + $db->ex("CREATE INDEX {$db->getPrefix()}tag2task_list_id ON {$db->getPrefix()}tag2task (list_id)"); $db->ex( -"CREATE TABLE {$db->prefix}settings ( +"CREATE TABLE {$db->getPrefix()}settings ( param_key VARCHAR(250) NOT NULL default '', param_value TEXT ) "); - $db->ex("CREATE UNIQUE INDEX {$db->prefix}settings_key ON {$db->prefix}settings (param_key)"); + $db->ex("CREATE UNIQUE INDEX {$db->getPrefix()}settings_key ON {$db->getPrefix()}settings (param_key)"); $db->ex( -"CREATE TABLE {$db->prefix}sessions ( +"CREATE TABLE {$db->getPrefix()}sessions ( id VARCHAR(64) NOT NULL default '', data TEXT, last_access INTEGER NOT NULL default 0, expires INTEGER NOT NULL default 0 ) "); - $db->ex("CREATE UNIQUE INDEX {$db->prefix}sessions_id ON {$db->prefix}sessions (id)"); + $db->ex("CREATE UNIQUE INDEX {$db->getPrefix()}sessions_id ON {$db->getPrefix()}sessions (id)"); } @@ -499,7 +499,7 @@ function createPostgresTables(Database_Abstract $db) function createSqliteTables(Database_Abstract $db) { $db->ex( -"CREATE TABLE {$db->prefix}lists ( +"CREATE TABLE {$db->getPrefix()}lists ( id INTEGER PRIMARY KEY, uuid CHAR(36) NOT NULL, ow INTEGER NOT NULL default 0, @@ -512,10 +512,10 @@ function createSqliteTables(Database_Abstract $db) extra TEXT ) "); - $db->ex("CREATE UNIQUE INDEX lists_uuid ON {$db->prefix}lists (uuid)"); + $db->ex("CREATE UNIQUE INDEX lists_uuid ON {$db->getPrefix()}lists (uuid)"); $db->ex( -"CREATE TABLE {$db->prefix}todolist ( +"CREATE TABLE {$db->getPrefix()}todolist ( id INTEGER PRIMARY KEY, uuid CHAR(36) NOT NULL default '', list_id INTEGER UNSIGNED NOT NULL default 0, @@ -529,68 +529,68 @@ function createSqliteTables(Database_Abstract $db) ow INTEGER NOT NULL default 0, duedate DATE default NULL ) "); - $db->ex("CREATE INDEX todo_list_id ON {$db->prefix}todolist (list_id)"); - $db->ex("CREATE UNIQUE INDEX todo_uuid ON {$db->prefix}todolist (uuid)"); + $db->ex("CREATE INDEX todo_list_id ON {$db->getPrefix()}todolist (list_id)"); + $db->ex("CREATE UNIQUE INDEX todo_uuid ON {$db->getPrefix()}todolist (uuid)"); $db->ex( -"CREATE TABLE {$db->prefix}tags ( +"CREATE TABLE {$db->getPrefix()}tags ( id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(250) NOT NULL DEFAULT '' COLLATE UTF8CI ) "); - $db->ex("CREATE INDEX tags_name ON {$db->prefix}tags (name)"); //NB: unique in mysql + $db->ex("CREATE INDEX tags_name ON {$db->getPrefix()}tags (name)"); //NB: unique in mysql $db->ex( -"CREATE TABLE {$db->prefix}tag2task ( +"CREATE TABLE {$db->getPrefix()}tag2task ( tag_id INTEGER NOT NULL, task_id INTEGER NOT NULL, list_id INTEGER NOT NULL ) "); - $db->ex("CREATE INDEX tag2task_tag_id ON {$db->prefix}tag2task (tag_id)"); - $db->ex("CREATE INDEX tag2task_task_id ON {$db->prefix}tag2task (task_id)"); - $db->ex("CREATE INDEX tag2task_list_id ON {$db->prefix}tag2task (list_id)"); /* for tagcloud */ + $db->ex("CREATE INDEX tag2task_tag_id ON {$db->getPrefix()}tag2task (tag_id)"); + $db->ex("CREATE INDEX tag2task_task_id ON {$db->getPrefix()}tag2task (task_id)"); + $db->ex("CREATE INDEX tag2task_list_id ON {$db->getPrefix()}tag2task (list_id)"); /* for tagcloud */ $db->ex( -"CREATE TABLE {$db->prefix}settings ( +"CREATE TABLE {$db->getPrefix()}settings ( param_key VARCHAR(250) NOT NULL default '', param_value TEXT ) "); - $db->ex("CREATE UNIQUE INDEX settings_key ON {$db->prefix}settings (param_key COLLATE NOCASE)"); + $db->ex("CREATE UNIQUE INDEX settings_key ON {$db->getPrefix()}settings (param_key COLLATE NOCASE)"); $db->ex( -"CREATE TABLE {$db->prefix}sessions ( +"CREATE TABLE {$db->getPrefix()}sessions ( id VARCHAR(64) NOT NULL default '', data TEXT, last_access INTEGER UNSIGNED NOT NULL default 0, expires INTEGER UNSIGNED NOT NULL default 0 ) "); - $db->ex("CREATE UNIQUE INDEX sessions_id ON {$db->prefix}sessions (id COLLATE NOCASE)"); + $db->ex("CREATE UNIQUE INDEX sessions_id ON {$db->getPrefix()}sessions (id COLLATE NOCASE)"); } function databaseVersion(Database_Abstract $db): string { if ( !$db ) return ''; - if ( !$db->tableExists($db->prefix.'todolist') ) return ''; + if ( !$db->tableExists($db->getTableWithPrefix('todolist')) ) return ''; $v = '1.0'; - if ( !$db->tableExists($db->prefix.'tags') ) return $v; + if ( !$db->tableExists($db->getTableWithPrefix('tags')) ) return $v; $v = '1.1'; - if ( !$db->tableFieldExists($db->prefix.'todolist', 'duedate') ) return $v; + if ( !$db->tableFieldExists($db->getTableWithPrefix('todolist'), 'duedate') ) return $v; $v = '1.2'; - if ( !$db->tableExists($db->prefix.'lists') ) return $v; + if ( !$db->tableExists($db->getTableWithPrefix('lists')) ) return $v; $v = '1.3.0'; - if ( !$db->tableFieldExists($db->prefix.'todolist', 'd_completed') ) return $v; + if ( !$db->tableFieldExists($db->getTableWithPrefix('todolist'), 'd_completed') ) return $v; $v = '1.3.1'; - if ( !$db->tableFieldExists($db->prefix.'todolist', 'd_edited') ) return $v; + if ( !$db->tableFieldExists($db->getTableWithPrefix('todolist'), 'd_edited') ) return $v; $v = '1.4'; - if ( !$db->tableExists($db->prefix.'settings') ) return $v; + if ( !$db->tableExists($db->getTableWithPrefix('settings')) ) return $v; $v = '1.7'; - if ( $db->tableFieldExists($db->prefix.'todolist', 'tags') ) return $v; + if ( $db->tableFieldExists($db->getTableWithPrefix('todolist'), 'tags') ) return $v; $v = '1.8'; return $v; } @@ -790,25 +790,25 @@ function update_14_17(Database_Abstract $db, $dbtype) if($dbtype=='mysql') { - $db->ex("ALTER TABLE {$db->prefix}lists ADD `extra` TEXT"); + $db->ex("ALTER TABLE {$db->getPrefix()}lists ADD `extra` TEXT"); # increase the length of list and tag name # (not applicable to sqlite because it uses VARCHAR fields of any length as TEXT) - $db->ex("ALTER TABLE {$db->prefix}todolist CHANGE `tags` `tags` VARCHAR(2000) NOT NULL default '' "); - $db->ex("ALTER TABLE {$db->prefix}tags CHANGE `name` `name` VARCHAR(250) NOT NULL default '' "); - $db->ex("ALTER TABLE {$db->prefix}lists CHANGE `name` `name` VARCHAR(250) NOT NULL default '' "); + $db->ex("ALTER TABLE {$db->getPrefix()}todolist CHANGE `tags` `tags` VARCHAR(2000) NOT NULL default '' "); + $db->ex("ALTER TABLE {$db->getPrefix()}tags CHANGE `name` `name` VARCHAR(250) NOT NULL default '' "); + $db->ex("ALTER TABLE {$db->getPrefix()}lists CHANGE `name` `name` VARCHAR(250) NOT NULL default '' "); # convert charset to utf8mb4 - $db->ex("ALTER TABLE {$db->prefix}lists CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); - $db->ex("ALTER TABLE {$db->prefix}todolist CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); - $db->ex("ALTER TABLE {$db->prefix}tags CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); - $db->ex("ALTER TABLE {$db->prefix}tag2task CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); + $db->ex("ALTER TABLE {$db->getPrefix()}lists CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); + $db->ex("ALTER TABLE {$db->getPrefix()}todolist CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); + $db->ex("ALTER TABLE {$db->getPrefix()}tags CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); + $db->ex("ALTER TABLE {$db->getPrefix()}tag2task CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); # create settings table $db->ex( -"CREATE TABLE {$db->prefix}settings ( +"CREATE TABLE {$db->getPrefix()}settings ( `param_key` VARCHAR(250) NOT NULL default '', `param_value` TEXT, UNIQUE KEY `param_key` (`param_key`) @@ -817,7 +817,7 @@ UNIQUE KEY `param_key` (`param_key`) # create sessions table $db->ex( -"CREATE TABLE {$db->prefix}sessions ( +"CREATE TABLE {$db->getPrefix()}sessions ( `id` VARCHAR(64) NOT NULL default '', `data` TEXT, `last_access` INT UNSIGNED NOT NULL default 0, @@ -829,28 +829,28 @@ UNIQUE KEY `id` (`id`) else #sqlite { - $db->ex("ALTER TABLE {$db->prefix}lists ADD extra TEXT"); + $db->ex("ALTER TABLE {$db->getPrefix()}lists ADD extra TEXT"); # settings $db->ex( -"CREATE TABLE {$db->prefix}settings ( +"CREATE TABLE {$db->getPrefix()}settings ( param_key VARCHAR(100) NOT NULL default '', param_value TEXT ) "); - $db->ex("CREATE UNIQUE INDEX settings_key ON {$db->prefix}settings (param_key COLLATE NOCASE)"); + $db->ex("CREATE UNIQUE INDEX settings_key ON {$db->getPrefix()}settings (param_key COLLATE NOCASE)"); # sessions $db->ex( -"CREATE TABLE {$db->prefix}sessions ( +"CREATE TABLE {$db->getPrefix()}sessions ( id VARCHAR(250) NOT NULL default '', data TEXT, last_access INTEGER UNSIGNED NOT NULL default 0, expires INTEGER UNSIGNED NOT NULL default 0 ) "); - $db->ex("CREATE UNIQUE INDEX sessions_id ON {$db->prefix}sessions (id COLLATE NOCASE)"); + $db->ex("CREATE UNIQUE INDEX sessions_id ON {$db->getPrefix()}sessions (id COLLATE NOCASE)"); } $db->ex("COMMIT"); @@ -870,9 +870,9 @@ function update_17_18(Database_Abstract $db, $dbtype) // Use UTF8CI collate. Old sqlite does not support DROP COLUMN (before v3.35.0 2021-03-12) $db->ex("DROP INDEX todo_list_id"); $db->ex("DROP INDEX todo_uuid"); - $db->ex("ALTER TABLE {$db->prefix}todolist RENAME TO {$db->prefix}todolist_old"); + $db->ex("ALTER TABLE {$db->getPrefix()}todolist RENAME TO {$db->getPrefix()}todolist_old"); $db->ex( - "CREATE TABLE {$db->prefix}todolist ( + "CREATE TABLE {$db->getPrefix()}todolist ( id INTEGER PRIMARY KEY, uuid CHAR(36) NOT NULL default '', list_id INTEGER UNSIGNED NOT NULL default 0, @@ -886,45 +886,45 @@ function update_17_18(Database_Abstract $db, $dbtype) ow INTEGER NOT NULL default 0, duedate DATE default NULL )" ); - $db->ex("INSERT INTO {$db->prefix}todolist SELECT id,uuid,list_id,d_created,d_completed,d_edited,compl,title,note,prio,ow,duedate FROM {$db->prefix}todolist_old"); - $db->ex("CREATE INDEX todo_list_id ON {$db->prefix}todolist (list_id)"); - $db->ex("CREATE UNIQUE INDEX todo_uuid ON {$db->prefix}todolist (uuid)"); - $db->ex("DROP TABLE {$db->prefix}todolist_old"); + $db->ex("INSERT INTO {$db->getPrefix()}todolist SELECT id,uuid,list_id,d_created,d_completed,d_edited,compl,title,note,prio,ow,duedate FROM {$db->getPrefix()}todolist_old"); + $db->ex("CREATE INDEX todo_list_id ON {$db->getPrefix()}todolist (list_id)"); + $db->ex("CREATE UNIQUE INDEX todo_uuid ON {$db->getPrefix()}todolist (uuid)"); + $db->ex("DROP TABLE {$db->getPrefix()}todolist_old"); $db->ex("DROP INDEX tags_name"); - $db->ex("ALTER TABLE {$db->prefix}tags RENAME TO {$db->prefix}tags_old"); + $db->ex("ALTER TABLE {$db->getPrefix()}tags RENAME TO {$db->getPrefix()}tags_old"); $db->ex( - "CREATE TABLE {$db->prefix}tags ( + "CREATE TABLE {$db->getPrefix()}tags ( id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(250) NOT NULL DEFAULT '' COLLATE UTF8CI )" ); - $db->ex("INSERT INTO {$db->prefix}tags SELECT * FROM {$db->prefix}tags_old"); - $db->ex("CREATE INDEX tags_name ON {$db->prefix}tags (name)"); - $db->ex("DROP TABLE {$db->prefix}tags_old"); + $db->ex("INSERT INTO {$db->getPrefix()}tags SELECT * FROM {$db->getPrefix()}tags_old"); + $db->ex("CREATE INDEX tags_name ON {$db->getPrefix()}tags (name)"); + $db->ex("DROP TABLE {$db->getPrefix()}tags_old"); } else // mysql { - $db->ex("ALTER TABLE {$db->prefix}todolist DROP COLUMN tags"); - $db->ex("ALTER TABLE {$db->prefix}todolist DROP COLUMN tags_ids"); + $db->ex("ALTER TABLE {$db->getPrefix()}todolist DROP COLUMN tags"); + $db->ex("ALTER TABLE {$db->getPrefix()}todolist DROP COLUMN tags_ids"); // if mysql db was created in v1.7.x then // tags.name field has length of 50 instead of 250, // settings.param_key field has length of 100 instead of 250 - $db->ex("ALTER TABLE {$db->prefix}lists MODIFY `uuid` CHAR(36) CHARACTER SET latin1 NOT NULL default '' "); - $db->ex("ALTER TABLE {$db->prefix}lists MODIFY `name` VARCHAR(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL default '' "); - $db->ex("ALTER TABLE {$db->prefix}lists MODIFY `extra` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci "); + $db->ex("ALTER TABLE {$db->getPrefix()}lists MODIFY `uuid` CHAR(36) CHARACTER SET latin1 NOT NULL default '' "); + $db->ex("ALTER TABLE {$db->getPrefix()}lists MODIFY `name` VARCHAR(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL default '' "); + $db->ex("ALTER TABLE {$db->getPrefix()}lists MODIFY `extra` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci "); - $db->ex("ALTER TABLE {$db->prefix}todolist MODIFY `uuid` CHAR(36) CHARACTER SET latin1 NOT NULL default '' "); - $db->ex("ALTER TABLE {$db->prefix}todolist MODIFY `title` VARCHAR(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL default '' "); - $db->ex("ALTER TABLE {$db->prefix}todolist MODIFY `note` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci "); + $db->ex("ALTER TABLE {$db->getPrefix()}todolist MODIFY `uuid` CHAR(36) CHARACTER SET latin1 NOT NULL default '' "); + $db->ex("ALTER TABLE {$db->getPrefix()}todolist MODIFY `title` VARCHAR(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL default '' "); + $db->ex("ALTER TABLE {$db->getPrefix()}todolist MODIFY `note` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci "); - $db->ex("ALTER TABLE {$db->prefix}tags MODIFY `name` VARCHAR(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL default '' "); + $db->ex("ALTER TABLE {$db->getPrefix()}tags MODIFY `name` VARCHAR(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL default '' "); - $db->ex("ALTER TABLE {$db->prefix}settings MODIFY `param_key` VARCHAR(250) CHARACTER SET latin1 NOT NULL default '' "); - $db->ex("ALTER TABLE {$db->prefix}settings MODIFY `param_value` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci "); + $db->ex("ALTER TABLE {$db->getPrefix()}settings MODIFY `param_key` VARCHAR(250) CHARACTER SET latin1 NOT NULL default '' "); + $db->ex("ALTER TABLE {$db->getPrefix()}settings MODIFY `param_value` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci "); - $db->ex("ALTER TABLE {$db->prefix}sessions MODIFY `id` VARCHAR(64) CHARACTER SET latin1 NOT NULL default '' "); - $db->ex("ALTER TABLE {$db->prefix}sessions MODIFY `data` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci "); + $db->ex("ALTER TABLE {$db->getPrefix()}sessions MODIFY `id` VARCHAR(64) CHARACTER SET latin1 NOT NULL default '' "); + $db->ex("ALTER TABLE {$db->getPrefix()}sessions MODIFY `data` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci "); } $db->ex("COMMIT"); From 5f94030c47358b6f2d76b539c9e0767ea181e068 Mon Sep 17 00:00:00 2001 From: Tim Gerundt Date: Mon, 15 Sep 2025 20:48:22 +0200 Subject: [PATCH 07/12] Fix access to protected property Database_Abstract::$lastQuery --- src/ext/backup/class.restore.php | 2 +- src/includes/class.dbconnection.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ext/backup/class.restore.php b/src/ext/backup/class.restore.php index d05bcd8..048e6d7 100644 --- a/src/ext/backup/class.restore.php +++ b/src/ext/backup/class.restore.php @@ -200,7 +200,7 @@ class Restore $db->ex("INSERT INTO {$db->getPrefix()}{$table} ($fieldsStr) VALUES ($subsStr)", $values); } catch (Exception $e) { - error_log("Failed query: {$db->lastQuery}"); + error_log("Failed query: {$db->getLastQuery()}"); $this->lastErrorString = "Failed to add data to table '{$db->getPrefix()}$table'. Database error (see query in error log): ". $e->getMessage(); return false; } diff --git a/src/includes/class.dbconnection.php b/src/includes/class.dbconnection.php index 9d300c5..e21d60c 100644 --- a/src/includes/class.dbconnection.php +++ b/src/includes/class.dbconnection.php @@ -100,6 +100,10 @@ abstract class Database_Abstract } } } + + function getLastQuery(): string { + return $this->lastQuery; + } } abstract class DatabaseResult_Abstract From 626c4eaf99c239b67b53a0f88dbdcff4871ed61c Mon Sep 17 00:00:00 2001 From: Tim Gerundt Date: Mon, 15 Sep 2025 20:56:40 +0200 Subject: [PATCH 08/12] Fix PHPDoc tag `@var` for `MTTExtensionSettingsInterface` --- src/includes/api/ExtSettingsController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/includes/api/ExtSettingsController.php b/src/includes/api/ExtSettingsController.php index f218f23..29c1bf0 100644 --- a/src/includes/api/ExtSettingsController.php +++ b/src/includes/api/ExtSettingsController.php @@ -11,7 +11,7 @@ class ExtSettingsController extends ApiController { { checkWriteAccess(); - /** @var MTTExtension|MTTExtensionSettingsInterface $instance */ + /** @var MTTExtensionSettingsInterface $instance */ $instance = $this->extInstance($ext); if (!$instance) { return; @@ -72,7 +72,7 @@ EOD; { checkWriteAccess(); - /** @var MTTExtension|MTTExtensionSettingsInterface $instance */ + /** @var MTTExtensionSettingsInterface $instance */ $instance = $this->extInstance($ext); if (!$instance) { return; From f5167c76f879314776865a6d1cdf7e76572dc7bd Mon Sep 17 00:00:00 2001 From: Tim Gerundt Date: Mon, 15 Sep 2025 21:06:52 +0200 Subject: [PATCH 09/12] Fix PHPDoc tags in `config` class --- src/includes/class.config.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/includes/class.config.php b/src/includes/class.config.php index a5b440f..a1ef31d 100644 --- a/src/includes/class.config.php +++ b/src/includes/class.config.php @@ -11,7 +11,7 @@ class Config /** @var bool */ public static $noDatabase = false; - /** @var array[] */ + /** @var array */ private static $dbparams = array( # Database type: sqlite or mysql 'db.type' => array('default'=>'sqlite', 'type'=>'s'), @@ -29,7 +29,7 @@ class Config 'db.prefix' => array('default'=>'', 'type'=>'s') ); - /** @var array[] */ + /** @var array */ private static $convert = array( 'mysql.host' => 'db.host', 'mysql.user' => 'db.user', @@ -39,7 +39,7 @@ class Config 'prefix' => 'db.prefix' ); - /** @var array[] */ + /** @var array */ public static $params = array( # These two parameters are used when mytinytodo index.php called not from installation directory # 'url' - URL where index.php is called from (ex.: http://site.com/todo.php) @@ -98,13 +98,13 @@ class Config 'extensions' => array('default'=>[], 'type'=>'a') ); - /** @var mixed[] */ + /** @var array */ private static $config = array(); /** * - * @param mixed[] $config + * @param array $config * @return void */ public static function loadConfigV14(array $config) From fdb41e546e5662d28ad467fd023984b61d1f6ee5 Mon Sep 17 00:00:00 2001 From: Tim Gerundt Date: Wed, 17 Sep 2025 21:23:18 +0200 Subject: [PATCH 10/12] Fix null `array` return types --- src/ext/notifications/class.telegramapi.php | 10 +++++----- src/includes/api/AuthController.php | 6 +++--- src/includes/api/ListsController.php | 18 +++++++++--------- src/includes/api/TasksController.php | 18 +++++++++--------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/ext/notifications/class.telegramapi.php b/src/ext/notifications/class.telegramapi.php index 51df96e..a12d588 100644 --- a/src/ext/notifications/class.telegramapi.php +++ b/src/ext/notifications/class.telegramapi.php @@ -21,22 +21,22 @@ class TelegramApi $this->token = $token; } - function getMe(): ?array + function getMe(): array { return $this->makeGetRequest('getMe'); } - function getUpdates(?array $params = null): ?array + function getUpdates(?array $params = null): array { return $this->makePostRequest('getUpdates', $params ?? []); } - function sendMessage(array $params): ?array + function sendMessage(array $params): array { return $this->makePostRequest('sendMessage', $params); } - private function makeGetRequest(string $method): ?array + private function makeGetRequest(string $method): array { $options = array( 'http' => array( @@ -67,7 +67,7 @@ class TelegramApi return $decodedBody['result'] ?? []; } - private function makePostRequest(string $method, array $params): ?array + private function makePostRequest(string $method, array $params): array { $json = json_encode($params, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_SUBSTITUTE); $options = array( diff --git a/src/includes/api/AuthController.php b/src/includes/api/AuthController.php index 74a3bee..a5cbb95 100644 --- a/src/includes/api/AuthController.php +++ b/src/includes/api/AuthController.php @@ -18,7 +18,7 @@ class AuthController extends ApiController { } } - private function login(): ?array + private function login(): array { check_token(); $t = array('logged' => 0); @@ -35,7 +35,7 @@ class AuthController extends ApiController { return $t; } - private function logout(): ?array + private function logout(): array { check_token(); updateSessionLogged(false); @@ -45,7 +45,7 @@ class AuthController extends ApiController { return $t; } - private function createSession(): ?array + private function createSession(): array { $t = array(); if (!need_auth()) { diff --git a/src/includes/api/ListsController.php b/src/includes/api/ListsController.php index e7c5395..7538e42 100644 --- a/src/includes/api/ListsController.php +++ b/src/includes/api/ListsController.php @@ -193,7 +193,7 @@ class ListsController extends ApiController { ); } - private function createList(): ?array + private function createList(): array { $t = array(); $t['total'] = 0; @@ -210,7 +210,7 @@ class ListsController extends ApiController { return $t; } - private function renameList(int $id): ?array + private function renameList(int $id): array { $db = DBConnection::instance(); $t = array(); @@ -225,7 +225,7 @@ class ListsController extends ApiController { return $t; } - private function sortList(int $listId): ?array + private function sortList(int $listId): array { $sort = (int)($this->req->jsonBody['sort'] ?? 0); self::setListSortingById($listId, $sort); @@ -262,7 +262,7 @@ class ListsController extends ApiController { } } - private function publishList(int $listId): ?array + private function publishList(int $listId): array { $db = DBConnection::instance(); $publish = (int)($this->req->jsonBody['publish'] ?? 0); @@ -270,7 +270,7 @@ class ListsController extends ApiController { return ['total'=>1]; } - private function enableFeedKey(int $listId): ?array + private function enableFeedKey(int $listId): array { $db = DBConnection::instance(); $flag = (int)($this->req->jsonBody['enable'] ?? 0); @@ -297,7 +297,7 @@ class ListsController extends ApiController { ]; } - private function showNotes(int $listId): ?array + private function showNotes(int $listId): array { $db = DBConnection::instance(); $flag = (int)($this->req->jsonBody['shownotes'] ?? 0); @@ -306,7 +306,7 @@ class ListsController extends ApiController { return ['total'=>1]; } - private function hideList(int $listId): ?array + private function hideList(int $listId): array { $db = DBConnection::instance(); $flag = (int)($this->req->jsonBody['hide'] ?? 0); @@ -322,7 +322,7 @@ class ListsController extends ApiController { return ['total'=>1]; } - private function clearCompleted(int $listId): ?array + private function clearCompleted(int $listId): array { $db = DBConnection::instance(); $t = array(); @@ -342,7 +342,7 @@ class ListsController extends ApiController { return $t; } - private function changeListOrder(): ?array + private function changeListOrder(): array { $t = array(); $t['total'] = 0; diff --git a/src/includes/api/TasksController.php b/src/includes/api/TasksController.php index f83ef20..c7c03fc 100644 --- a/src/includes/api/TasksController.php +++ b/src/includes/api/TasksController.php @@ -327,7 +327,7 @@ class TasksController extends ApiController { /* Private Functions */ - private function newTaskInList(int $listId): ?array + private function newTaskInList(int $listId): array { $db = DBConnection::instance(); $t = array(); @@ -376,7 +376,7 @@ class TasksController extends ApiController { return $t; } - private function fullNewTaskInList(int $listId): ?array + private function fullNewTaskInList(int $listId): array { $db = DBConnection::instance(); $title = trim($this->req->jsonBody['title'] ?? ''); @@ -414,7 +414,7 @@ class TasksController extends ApiController { return $t; } - private function editTask(int $id): ?array + private function editTask(int $id): array { $db = DBConnection::instance(); $title = trim($this->req->jsonBody['title'] ?? ''); @@ -446,7 +446,7 @@ class TasksController extends ApiController { return $t; } - private function moveTask(int $id): ?array + private function moveTask(int $id): array { $fromId = (int)($this->req->jsonBody['from'] ?? 0); $toId = (int)($this->req->jsonBody['to'] ?? 0); @@ -496,7 +496,7 @@ class TasksController extends ApiController { return true; } - private function completeTask(int $id): ?array + private function completeTask(int $id): array { $db = DBConnection::instance(); $compl = (int)($this->req->jsonBody['compl'] ?? 0); @@ -515,7 +515,7 @@ class TasksController extends ApiController { return $t; } - private function editNote(int $id): ?array + private function editNote(int $id): array { $db = DBConnection::instance(); $note = $this->req->jsonBody['note'] ?? ''; @@ -534,7 +534,7 @@ class TasksController extends ApiController { return $t; } - private function priorityTask(int $id): ?array + private function priorityTask(int $id): array { $db = DBConnection::instance(); $prio = (int)($this->req->jsonBody['prio'] ?? 0); @@ -555,7 +555,7 @@ class TasksController extends ApiController { } - private function changeTaskOrder(): ?array + private function changeTaskOrder(): array { $db = DBConnection::instance(); $order = $this->req->jsonBody['order'] ?? null; @@ -619,7 +619,7 @@ class TasksController extends ApiController { return $a; } - private function getTaskRowById(int $id, bool $getListName = false): ?array + private function getTaskRowById(int $id, bool $getListName = false): array { $r = DBCore::default()->getTaskById($id); if (!$r) { From 672eb83395fb14c39bbafda5f6481e3e04b43236 Mon Sep 17 00:00:00 2001 From: Tim Gerundt Date: Fri, 19 Sep 2025 21:52:50 +0200 Subject: [PATCH 11/12] Fix some PHPDoc infos --- src/includes/class.dbcore.php | 6 +++--- src/includes/markup.php | 2 +- src/includes/smartsyntax.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/includes/class.dbcore.php b/src/includes/class.dbcore.php index 2fc4a72..23d9b44 100644 --- a/src/includes/class.dbcore.php +++ b/src/includes/class.dbcore.php @@ -11,10 +11,10 @@ class DBCore { - /** @var Database_Abstract $db */ + /** @var Database_Abstract|null $db */ protected $db; - /** @var DBCore $defaultdb */ + /** @var DBCore|null $defaultdb */ protected static $defaultInstance; /** @@ -31,7 +31,7 @@ class DBCore * @return Database_Abstract * @throws Exception */ - public function connection() + public function connection() : Database_Abstract { if (!isset($this->db)) { throw new Exception("DBConnection is not set"); diff --git a/src/includes/markup.php b/src/includes/markup.php index 29b8bd7..00a5aeb 100644 --- a/src/includes/markup.php +++ b/src/includes/markup.php @@ -16,7 +16,7 @@ interface MTTMarkdownInterface final class MTTMarkdown { - /** @var MTTMarkdownInterface */ + /** @var MTTMarkdownInterface|null */ private static $instance; /** @var string */ diff --git a/src/includes/smartsyntax.php b/src/includes/smartsyntax.php index 5d718bd..05c4a15 100644 --- a/src/includes/smartsyntax.php +++ b/src/includes/smartsyntax.php @@ -12,7 +12,7 @@ class MTTSmartSyntax implements MTTSmartSyntaxInterface protected $duedatePrefix = '@!'; protected $weekdays = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']; //3-letter not present in lang - /** @var MTTSmartSyntaxInterface */ + /** @var MTTSmartSyntaxInterface|null */ protected static $instance; public static function instance(): MTTSmartSyntaxInterface From 0de28c6a02aea183e513ad95b4ca2315002c5ff2 Mon Sep 17 00:00:00 2001 From: Tim Gerundt Date: Fri, 19 Sep 2025 21:53:05 +0200 Subject: [PATCH 12/12] Use higher level in phpstan --- phpstan.neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan.neon b/phpstan.neon index 9137f46..28a65c2 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,7 +2,7 @@ includes: - src/includes/vendor/phpstan/phpstan-deprecation-rules/rules.neon parameters: - level: 1 + level: 4 paths: - src excludePaths: