aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/Controllers/feedController.php5
-rw-r--r--app/Controllers/tagController.php3
-rw-r--r--app/Controllers/userController.php6
-rw-r--r--app/Exceptions/AlreadySubscribedException.php6
-rw-r--r--app/Exceptions/BadUrlException.php2
-rw-r--r--app/Exceptions/FeedNotAddedException.php6
-rw-r--r--app/Exceptions/ZipException.php6
-rw-r--r--app/Mailers/UserMailer.php2
-rw-r--r--app/Models/BooleanSearch.php11
-rw-r--r--app/Models/CategoryDAO.php3
-rw-r--r--app/Models/CategoryDAOSQLite.php3
-rw-r--r--app/Models/DatabaseDAO.php18
-rw-r--r--app/Models/DatabaseDAOPGSQL.php5
-rw-r--r--app/Models/DatabaseDAOSQLite.php5
-rw-r--r--app/Models/FeedDAO.php3
-rw-r--r--app/Models/FeedDAOSQLite.php3
-rw-r--r--app/Models/ReadingMode.php55
-rw-r--r--app/Models/TagDAO.php3
-rw-r--r--app/Models/TagDAOSQLite.php3
-rw-r--r--app/Models/UserDAO.php13
-rw-r--r--cli/i18n/I18nCompletionValidator.php17
-rw-r--r--cli/i18n/I18nUsageValidator.php17
-rw-r--r--cli/i18n/I18nValidatorInterface.php13
-rw-r--r--lib/Minz/ActionException.php2
-rw-r--r--lib/Minz/Configuration.php2
-rw-r--r--lib/Minz/ConfigurationException.php2
-rw-r--r--lib/Minz/ControllerNotActionControllerException.php2
-rw-r--r--lib/Minz/ControllerNotExistException.php2
-rw-r--r--lib/Minz/CurrentPagePaginationException.php2
-rw-r--r--lib/Minz/Error.php4
-rw-r--r--lib/Minz/Exception.php2
-rw-r--r--lib/Minz/ExtensionException.php2
-rw-r--r--lib/Minz/FileNotExistException.php2
-rw-r--r--lib/Minz/Helper.php2
-rw-r--r--lib/Minz/Mailer.php3
-rw-r--r--lib/Minz/ModelPdo.php1
-rw-r--r--lib/Minz/PDOConnectionException.php2
-rw-r--r--lib/Minz/Pdo.php25
-rw-r--r--lib/Minz/PdoMysql.php8
-rw-r--r--lib/Minz/PdoPgsql.php3
-rw-r--r--lib/Minz/PdoSqlite.php8
-rw-r--r--lib/Minz/PermissionDeniedException.php2
-rw-r--r--lib/favicons.php9
-rw-r--r--lib/lib_date.php12
-rw-r--r--lib/lib_install.php9
-rw-r--r--tests/phpstan-next.txt38
46 files changed, 183 insertions, 169 deletions
diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php
index 2fcc5eda6..0e98d1e16 100644
--- a/app/Controllers/feedController.php
+++ b/app/Controllers/feedController.php
@@ -47,10 +47,11 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
$url = trim($url);
/** @var string|null $url */
- $url = Minz_ExtensionManager::callHook('check_url_before_add', $url);
- if (null === $url) {
+ $urlHooked = Minz_ExtensionManager::callHook('check_url_before_add', $url);
+ if ($urlHooked === $url) {
throw new FreshRSS_FeedNotAdded_Exception($url);
}
+ $url = $urlHooked;
$cat = null;
if ($cat_id > 0) {
diff --git a/app/Controllers/tagController.php b/app/Controllers/tagController.php
index b8db23f3e..69844f7bc 100644
--- a/app/Controllers/tagController.php
+++ b/app/Controllers/tagController.php
@@ -126,7 +126,8 @@ class FreshRSS_tag_Controller extends FreshRSS_ActionController {
$sourceId = Minz_Request::param('id_tag');
if ($targetName == '' || $sourceId == '') {
- return Minz_Error::error(400);
+ Minz_Error::error(400);
+ return;
}
$tagDAO = FreshRSS_Factory::createTagDao();
diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php
index 89489e590..f49406b13 100644
--- a/app/Controllers/userController.php
+++ b/app/Controllers/userController.php
@@ -431,11 +431,13 @@ class FreshRSS_user_Controller extends FreshRSS_ActionController {
} elseif (FreshRSS_Auth::hasAccess()) {
$user_config = FreshRSS_Context::$user_conf;
} else {
- return Minz_Error::error(403);
+ Minz_Error::error(403);
+ return;
}
if (!FreshRSS_UserDAO::exists($username) || $user_config === null) {
- return Minz_Error::error(404);
+ Minz_Error::error(404);
+ return;
}
if ($user_config->email_validation_token === '') {
diff --git a/app/Exceptions/AlreadySubscribedException.php b/app/Exceptions/AlreadySubscribedException.php
index 33b9f9555..c2b11d3a0 100644
--- a/app/Exceptions/AlreadySubscribedException.php
+++ b/app/Exceptions/AlreadySubscribedException.php
@@ -1,14 +1,16 @@
<?php
class FreshRSS_AlreadySubscribed_Exception extends Exception {
+
+ /** @var string */
private $feedName = '';
- public function __construct($url, $feedName) {
+ public function __construct(string $url, string $feedName) {
parent::__construct('Already subscribed! ' . $url, 2135);
$this->feedName = $feedName;
}
- public function feedName() {
+ public function feedName(): string {
return $this->feedName;
}
}
diff --git a/app/Exceptions/BadUrlException.php b/app/Exceptions/BadUrlException.php
index d2509e4ba..748a619d6 100644
--- a/app/Exceptions/BadUrlException.php
+++ b/app/Exceptions/BadUrlException.php
@@ -2,7 +2,7 @@
class FreshRSS_BadUrl_Exception extends FreshRSS_Feed_Exception {
- public function __construct($url) {
+ public function __construct(string $url) {
parent::__construct('`' . $url . '` is not a valid URL');
}
diff --git a/app/Exceptions/FeedNotAddedException.php b/app/Exceptions/FeedNotAddedException.php
index 59fa74b16..b10e93f05 100644
--- a/app/Exceptions/FeedNotAddedException.php
+++ b/app/Exceptions/FeedNotAddedException.php
@@ -1,14 +1,16 @@
<?php
class FreshRSS_FeedNotAdded_Exception extends Exception {
+
+ /** @var string */
private $url = '';
- public function __construct($url) {
+ public function __construct(string $url) {
parent::__construct('Feed not added! ' . $url, 2147);
$this->url = $url;
}
- public function url() {
+ public function url(): string {
return $this->url;
}
}
diff --git a/app/Exceptions/ZipException.php b/app/Exceptions/ZipException.php
index 9ed40c4cb..ecf546533 100644
--- a/app/Exceptions/ZipException.php
+++ b/app/Exceptions/ZipException.php
@@ -1,14 +1,16 @@
<?php
class FreshRSS_Zip_Exception extends Exception {
+
+ /** @var int */
private $zipErrorCode = 0;
- public function __construct($zipErrorCode) {
+ public function __construct(int $zipErrorCode) {
parent::__construct('ZIP error!', 2141);
$this->zipErrorCode = $zipErrorCode;
}
- public function zipErrorCode() {
+ public function zipErrorCode(): int {
return $this->zipErrorCode;
}
}
diff --git a/app/Mailers/UserMailer.php b/app/Mailers/UserMailer.php
index 4450bd96c..c722a5520 100644
--- a/app/Mailers/UserMailer.php
+++ b/app/Mailers/UserMailer.php
@@ -10,7 +10,7 @@ class FreshRSS_User_Mailer extends Minz_Mailer {
*/
protected $view;
- public function send_email_need_validation($username, $user_config) {
+ public function send_email_need_validation(string $username, FreshRSS_UserConfiguration $user_config): bool {
Minz_Translate::reset($user_config->language);
$this->view->_path('user_mailer/email_need_validation.txt.php');
diff --git a/app/Models/BooleanSearch.php b/app/Models/BooleanSearch.php
index 279040a5a..f2e16f972 100644
--- a/app/Models/BooleanSearch.php
+++ b/app/Models/BooleanSearch.php
@@ -10,10 +10,11 @@ class FreshRSS_BooleanSearch {
/** @var array<FreshRSS_BooleanSearch|FreshRSS_Search> */
private $searches = array();
- /** @var string 'AND' or 'OR' or 'AND NOT' */
+ /** @var 'AND'|'OR'|'AND NOT' */
private $operator;
- public function __construct(string $input, int $level = 0, $operator = 'AND') {
+ /** @param 'AND'|'OR'|'AND NOT' $operator */
+ public function __construct(string $input, int $level = 0, string $operator = 'AND') {
$this->operator = $operator;
$input = trim($input);
if ($input == '') {
@@ -221,7 +222,7 @@ class FreshRSS_BooleanSearch {
return false;
}
- private function parseOrSegments(string $input) {
+ private function parseOrSegments(string $input): void {
$input = trim($input);
if ($input == '') {
return;
@@ -258,13 +259,13 @@ class FreshRSS_BooleanSearch {
return $this->searches;
}
- /** @return string 'AND' or 'OR' depending on how this BooleanSearch should be combined */
+ /** @return 'AND'|'OR'|'AND NOT' depending on how this BooleanSearch should be combined */
public function operator(): string {
return $this->operator;
}
/** @param FreshRSS_BooleanSearch|FreshRSS_Search $search */
- public function add($search) {
+ public function add($search): void {
$this->searches[] = $search;
}
diff --git a/app/Models/CategoryDAO.php b/app/Models/CategoryDAO.php
index 02845ebe7..dd97bd6cc 100644
--- a/app/Models/CategoryDAO.php
+++ b/app/Models/CategoryDAO.php
@@ -75,7 +75,8 @@ class FreshRSS_CategoryDAO extends Minz_ModelPdo {
return false;
}
- protected function autoUpdateDb(array $errorInfo) {
+ /** @param array<string> $errorInfo */
+ protected function autoUpdateDb(array $errorInfo): bool {
if (isset($errorInfo[0])) {
if ($errorInfo[0] === FreshRSS_DatabaseDAO::ER_BAD_FIELD_ERROR || $errorInfo[0] === FreshRSS_DatabaseDAOPGSQL::UNDEFINED_COLUMN) {
$errorLines = explode("\n", $errorInfo[2], 2); // The relevant column name is on the first line, other lines are noise
diff --git a/app/Models/CategoryDAOSQLite.php b/app/Models/CategoryDAOSQLite.php
index 363ffb427..870106f20 100644
--- a/app/Models/CategoryDAOSQLite.php
+++ b/app/Models/CategoryDAOSQLite.php
@@ -2,7 +2,8 @@
class FreshRSS_CategoryDAOSQLite extends FreshRSS_CategoryDAO {
- protected function autoUpdateDb(array $errorInfo) {
+ /** @param array<string> $errorInfo */
+ protected function autoUpdateDb(array $errorInfo): bool {
if ($tableInfo = $this->pdo->query("PRAGMA table_info('category')")) {
$columns = $tableInfo->fetchAll(PDO::FETCH_COLUMN, 1);
foreach (['kind', 'lastUpdate', 'error', 'attributes'] as $column) {
diff --git a/app/Models/DatabaseDAO.php b/app/Models/DatabaseDAO.php
index bf9cbb2d3..28dd36cd9 100644
--- a/app/Models/DatabaseDAO.php
+++ b/app/Models/DatabaseDAO.php
@@ -63,13 +63,15 @@ class FreshRSS_DatabaseDAO extends Minz_ModelPdo {
return count(array_keys($tables, true, true)) == count($tables);
}
+ /** @return array<array<string,string|bool>> */
public function getSchema(string $table): array {
$sql = 'DESC `_' . $table . '`';
$stm = $this->pdo->query($sql);
return $this->listDaoToSchema($stm->fetchAll(PDO::FETCH_ASSOC));
}
- public function checkTable(string $table, $schema): bool {
+ /** @param array<string> $schema */
+ public function checkTable(string $table, array $schema): bool {
$columns = $this->getSchema($table);
$ok = (count($columns) == count($schema));
@@ -120,6 +122,10 @@ class FreshRSS_DatabaseDAO extends Minz_ModelPdo {
));
}
+ /**
+ * @param array<string,string> $dao
+ * @return array<string,string|bool>
+ */
public function daoToSchema(array $dao): array {
return array(
'name' => $dao['Field'],
@@ -129,7 +135,11 @@ class FreshRSS_DatabaseDAO extends Minz_ModelPdo {
);
}
- public function listDaoToSchema($listDAO): array {
+ /**
+ * @param array<array<string,string>> $listDAO
+ * @return array<array<string,string|bool>>
+ */
+ public function listDaoToSchema(array $listDAO): array {
$list = array();
foreach ($listDAO as $dao) {
@@ -185,14 +195,14 @@ class FreshRSS_DatabaseDAO extends Minz_ModelPdo {
return $ok;
}
- public function minorDbMaintenance() {
+ public function minorDbMaintenance(): void {
$catDAO = FreshRSS_Factory::createCategoryDao();
$catDAO->resetDefaultCategoryName();
$this->ensureCaseInsensitiveGuids();
}
- private static function stdError($error): bool {
+ private static function stdError(string $error): bool {
if (defined('STDERR')) {
fwrite(STDERR, $error . "\n");
}
diff --git a/app/Models/DatabaseDAOPGSQL.php b/app/Models/DatabaseDAOPGSQL.php
index 6ff706250..b1db0f347 100644
--- a/app/Models/DatabaseDAOPGSQL.php
+++ b/app/Models/DatabaseDAOPGSQL.php
@@ -33,6 +33,7 @@ class FreshRSS_DatabaseDAOPGSQL extends FreshRSS_DatabaseDAOSQLite {
return count(array_keys($tables, true, true)) == count($tables);
}
+ /** @return array<array<string,string|bool>> */
public function getSchema(string $table): array {
$sql = 'select column_name as field, data_type as type, column_default as default, is_nullable as null from INFORMATION_SCHEMA.COLUMNS where table_name = ?';
$stm = $this->pdo->prepare($sql);
@@ -40,6 +41,10 @@ class FreshRSS_DatabaseDAOPGSQL extends FreshRSS_DatabaseDAOSQLite {
return $this->listDaoToSchema($stm->fetchAll(PDO::FETCH_ASSOC));
}
+ /**
+ * @param array<string,string> $dao
+ * @return array<string,string|bool>
+ */
public function daoToSchema(array $dao): array {
return array(
'name' => $dao['field'],
diff --git a/app/Models/DatabaseDAOSQLite.php b/app/Models/DatabaseDAOSQLite.php
index e5a6f5a04..3fab1134d 100644
--- a/app/Models/DatabaseDAOSQLite.php
+++ b/app/Models/DatabaseDAOSQLite.php
@@ -25,6 +25,7 @@ class FreshRSS_DatabaseDAOSQLite extends FreshRSS_DatabaseDAO {
return count(array_keys($tables, true, true)) == count($tables);
}
+ /** @return array<array<string,string|bool>> */
public function getSchema(string $table): array {
$sql = 'PRAGMA table_info(' . $table . ')';
$stm = $this->pdo->query($sql);
@@ -45,6 +46,10 @@ class FreshRSS_DatabaseDAOSQLite extends FreshRSS_DatabaseDAO {
));
}
+ /**
+ * @param array<string,string> $dao
+ * @return array<string,string|bool>
+ */
public function daoToSchema(array $dao): array {
return [
'name' => $dao['name'],
diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php
index 1047a218b..2a123e0db 100644
--- a/app/Models/FeedDAO.php
+++ b/app/Models/FeedDAO.php
@@ -19,7 +19,8 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo {
return false;
}
- protected function autoUpdateDb(array $errorInfo) {
+ /** @param array<string> $errorInfo */
+ protected function autoUpdateDb(array $errorInfo): bool {
if (isset($errorInfo[0])) {
if ($errorInfo[0] === FreshRSS_DatabaseDAO::ER_BAD_FIELD_ERROR || $errorInfo[0] === FreshRSS_DatabaseDAOPGSQL::UNDEFINED_COLUMN) {
$errorLines = explode("\n", $errorInfo[2], 2); // The relevant column name is on the first line, other lines are noise
diff --git a/app/Models/FeedDAOSQLite.php b/app/Models/FeedDAOSQLite.php
index a4432ea62..08a352d5f 100644
--- a/app/Models/FeedDAOSQLite.php
+++ b/app/Models/FeedDAOSQLite.php
@@ -2,7 +2,8 @@
class FreshRSS_FeedDAOSQLite extends FreshRSS_FeedDAO {
- protected function autoUpdateDb(array $errorInfo) {
+ /** @param array<string> $errorInfo */
+ protected function autoUpdateDb(array $errorInfo): bool {
if ($tableInfo = $this->pdo->query("PRAGMA table_info('feed')")) {
$columns = $tableInfo->fetchAll(PDO::FETCH_COLUMN, 1);
foreach (['attributes', 'kind'] as $column) {
diff --git a/app/Models/ReadingMode.php b/app/Models/ReadingMode.php
index ddb413315..6f2fc889c 100644
--- a/app/Models/ReadingMode.php
+++ b/app/Models/ReadingMode.php
@@ -28,12 +28,9 @@ class FreshRSS_ReadingMode {
/**
* ReadingMode constructor.
- * @param string $id
- * @param string $title
- * @param string[] $urlParams
- * @param bool $active
+ * @param array<string> $urlParams
*/
- public function __construct($id, $title, $urlParams, $active) {
+ public function __construct(string $id, string $title, array $urlParams, bool $active) {
$this->id = $id;
$this->name = _i($id);
$this->title = $title;
@@ -41,41 +38,24 @@ class FreshRSS_ReadingMode {
$this->isActive = $active;
}
- /**
- * @return string
- */
- public function getId() {
+ public function getId(): string {
return $this->id;
}
- /**
- * @return string
- */
- public function getName() {
+ public function getName(): string {
return $this->name;
}
- /**
- * @param string $name
- * @return FreshRSS_ReadingMode
- */
- public function setName($name) {
+ public function setName(string $name): FreshRSS_ReadingMode {
$this->name = $name;
return $this;
}
- /**
- * @return string
- */
- public function getTitle() {
+ public function getTitle(): string {
return $this->title;
}
- /**
- * @param string $title
- * @return FreshRSS_ReadingMode
- */
- public function setTitle($title) {
+ public function setTitle(string $title): FreshRSS_ReadingMode {
$this->title = $title;
return $this;
}
@@ -83,40 +63,31 @@ class FreshRSS_ReadingMode {
/**
* @return array<string>
*/
- public function getUrlParams() {
+ public function getUrlParams(): array {
return $this->urlParams;
}
/**
* @param array<string> $urlParams
- * @return FreshRSS_ReadingMode
*/
- public function setUrlParams($urlParams) {
+ public function setUrlParams(array $urlParams): FreshRSS_ReadingMode {
$this->urlParams = $urlParams;
return $this;
}
- /**
- * @return bool
- */
- public function isActive() {
+ public function isActive(): bool {
return $this->isActive;
}
- /**
- * @param bool $isActive
- * @return FreshRSS_ReadingMode
- */
- public function setIsActive($isActive) {
+ public function setIsActive(bool $isActive): FreshRSS_ReadingMode {
$this->isActive = $isActive;
return $this;
}
/**
- * Returns the built-in reading modes.
- * return ReadingMode[]
+ * @return array<FreshRSS_ReadingMode> the built-in reading modes
*/
- public static function getReadingModes() {
+ public static function getReadingModes(): array {
$actualView = Minz_Request::actionName();
$defaultCtrl = Minz_Request::defaultControllerName();
$isDefaultCtrl = Minz_Request::controllerName() === $defaultCtrl;
diff --git a/app/Models/TagDAO.php b/app/Models/TagDAO.php
index ca927ef38..8dc392160 100644
--- a/app/Models/TagDAO.php
+++ b/app/Models/TagDAO.php
@@ -30,7 +30,8 @@ class FreshRSS_TagDAO extends Minz_ModelPdo {
return $ok;
}
- protected function autoUpdateDb(array $errorInfo) {
+ /** @param array<string> $errorInfo */
+ protected function autoUpdateDb(array $errorInfo): bool {
if (isset($errorInfo[0])) {
if ($errorInfo[0] === FreshRSS_DatabaseDAO::ER_BAD_TABLE_ERROR || $errorInfo[0] === FreshRSS_DatabaseDAOPGSQL::UNDEFINED_TABLE) {
if (stripos($errorInfo[2], 'tag') !== false) {
diff --git a/app/Models/TagDAOSQLite.php b/app/Models/TagDAOSQLite.php
index 530669699..910455546 100644
--- a/app/Models/TagDAOSQLite.php
+++ b/app/Models/TagDAOSQLite.php
@@ -6,7 +6,8 @@ class FreshRSS_TagDAOSQLite extends FreshRSS_TagDAO {
return 'OR IGNORE';
}
- protected function autoUpdateDb(array $errorInfo) {
+ /** @param array<string> $errorInfo */
+ protected function autoUpdateDb(array $errorInfo): bool {
if ($tableInfo = $this->pdo->query("SELECT sql FROM sqlite_master where name='tag'")) {
$showCreate = $tableInfo->fetchColumn();
if (stripos($showCreate, 'tag') === false) {
diff --git a/app/Models/UserDAO.php b/app/Models/UserDAO.php
index 9f91df80e..8ba50cc29 100644
--- a/app/Models/UserDAO.php
+++ b/app/Models/UserDAO.php
@@ -1,7 +1,8 @@
<?php
class FreshRSS_UserDAO extends Minz_ModelPdo {
- public function createUser() {
+
+ public function createUser(): bool {
require(APP_PATH . '/SQL/install.sql.' . $this->pdo->dbType() . '.php');
try {
@@ -21,7 +22,7 @@ class FreshRSS_UserDAO extends Minz_ModelPdo {
}
}
- public function deleteUser() {
+ public function deleteUser(): bool {
if (defined('STDERR')) {
fwrite(STDERR, 'Deleting SQL data for user “' . $this->current_user . "”…\n");
}
@@ -38,18 +39,18 @@ class FreshRSS_UserDAO extends Minz_ModelPdo {
}
}
- public static function exists($username) {
+ public static function exists(string $username): bool {
return is_dir(USERS_PATH . '/' . $username);
}
- public static function touch($username = '') {
+ public static function touch(string $username = ''): bool {
if (!FreshRSS_user_Controller::checkUsername($username)) {
$username = Minz_User::name() ?? Minz_User::INTERNAL_USER;
}
return touch(USERS_PATH . '/' . $username . '/config.php');
}
- public static function mtime($username) {
- return @filemtime(USERS_PATH . '/' . $username . '/config.php');
+ public static function mtime(string $username): int {
+ return @(int)filemtime(USERS_PATH . '/' . $username . '/config.php');
}
}
diff --git a/cli/i18n/I18nCompletionValidator.php b/cli/i18n/I18nCompletionValidator.php
index 000629f8d..3903e18cd 100644
--- a/cli/i18n/I18nCompletionValidator.php
+++ b/cli/i18n/I18nCompletionValidator.php
@@ -4,18 +4,27 @@ require_once __DIR__ . '/I18nValidatorInterface.php';
class I18nCompletionValidator implements I18nValidatorInterface {
+ /** @var array<string,array<string,I18nValue>> */
private $reference;
+ /** @var array<string,array<string,I18nValue>> */
private $language;
+ /** @var int */
private $totalEntries = 0;
+ /** @var int */
private $passEntries = 0;
+ /** @var string */
private $result = '';
- public function __construct($reference, $language) {
+ /**
+ * @param array<string,array<string,I18nValue>> $reference
+ * @param array<string,array<string,I18nValue>> $language
+ */
+ public function __construct(array $reference, array $language) {
$this->reference = $reference;
$this->language = $language;
}
- public function displayReport() {
+ public function displayReport(): string {
if ($this->passEntries > $this->totalEntries) {
throw new \RuntimeException('The number of translated strings cannot be higher than the number of strings');
}
@@ -25,11 +34,11 @@ class I18nCompletionValidator implements I18nValidatorInterface {
return sprintf('Translation is %5.1f%% complete.', $this->passEntries / $this->totalEntries * 100) . PHP_EOL;
}
- public function displayResult() {
+ public function displayResult(): string {
return $this->result;
}
- public function validate() {
+ public function validate(): bool {
foreach ($this->reference as $file => $data) {
foreach ($data as $refKey => $refValue) {
$this->totalEntries++;
diff --git a/cli/i18n/I18nUsageValidator.php b/cli/i18n/I18nUsageValidator.php
index 681e17326..f507fbac3 100644
--- a/cli/i18n/I18nUsageValidator.php
+++ b/cli/i18n/I18nUsageValidator.php
@@ -4,18 +4,27 @@ require_once __DIR__ . '/I18nValidatorInterface.php';
class I18nUsageValidator implements I18nValidatorInterface {
+ /** @var array<string> */
private $code;
+ /** @var array<string,array<string,string>> */
private $reference;
+ /** @var int */
private $totalEntries = 0;
+ /** @var int */
private $failedEntries = 0;
+ /** @var string */
private $result = '';
- public function __construct($reference, $code) {
+ /**
+ * @param array<string,array<string,string>> $reference
+ * @param array<string> $code
+ */
+ public function __construct(array $reference, array $code) {
$this->code = $code;
$this->reference = $reference;
}
- public function displayReport() {
+ public function displayReport(): string {
if ($this->failedEntries > $this->totalEntries) {
throw new \RuntimeException('The number of unused strings cannot be higher than the number of strings');
}
@@ -25,11 +34,11 @@ class I18nUsageValidator implements I18nValidatorInterface {
return sprintf('%5.1f%% of translation keys are unused.', $this->failedEntries / $this->totalEntries * 100) . PHP_EOL;
}
- public function displayResult() {
+ public function displayResult(): string {
return $this->result;
}
- public function validate() {
+ public function validate(): bool {
foreach ($this->reference as $file => $data) {
foreach ($data as $key => $value) {
$this->totalEntries++;
diff --git a/cli/i18n/I18nValidatorInterface.php b/cli/i18n/I18nValidatorInterface.php
index d5681912b..e6f5f7cdd 100644
--- a/cli/i18n/I18nValidatorInterface.php
+++ b/cli/i18n/I18nValidatorInterface.php
@@ -5,21 +5,14 @@ interface I18nValidatorInterface {
/**
* Display the validation result.
* Empty if there are no errors.
- *
- * @return array
*/
- public function displayResult();
+ public function displayResult(): string;
- /**
- * @return bool
- */
- public function validate();
+ public function validate(): bool;
/**
* Display the validation report.
- *
- * @return string
*/
- public function displayReport();
+ public function displayReport(): string;
}
diff --git a/lib/Minz/ActionException.php b/lib/Minz/ActionException.php
index 53f0aab04..3c08b4892 100644
--- a/lib/Minz/ActionException.php
+++ b/lib/Minz/ActionException.php
@@ -1,6 +1,6 @@
<?php
class Minz_ActionException extends Minz_Exception {
- public function __construct ($controller_name, $action_name, $code = self::ERROR) {
+ public function __construct(string $controller_name, string $action_name, int $code = self::ERROR) {
// Just for security, as we are not supposed to get non-alphanumeric characters.
$action_name = rawurlencode($action_name);
diff --git a/lib/Minz/Configuration.php b/lib/Minz/Configuration.php
index 6d4aed0ab..a9a4ae03a 100644
--- a/lib/Minz/Configuration.php
+++ b/lib/Minz/Configuration.php
@@ -8,7 +8,7 @@
* @property-read string $environment
* @property-read array<string> $extensions_enabled
* @property-read string $mailer
- * @property-read string $smtp
+ * @property-read array<string|int|bool> $smtp
* @property string $title
*/
class Minz_Configuration {
diff --git a/lib/Minz/ConfigurationException.php b/lib/Minz/ConfigurationException.php
index f294c3341..498420a67 100644
--- a/lib/Minz/ConfigurationException.php
+++ b/lib/Minz/ConfigurationException.php
@@ -1,7 +1,7 @@
<?php
class Minz_ConfigurationException extends Minz_Exception {
- public function __construct($error, $code = self::ERROR) {
+ public function __construct(string $error, int $code = self::ERROR) {
$message = 'Configuration error: ' . $error;
parent::__construct($message, $code);
}
diff --git a/lib/Minz/ControllerNotActionControllerException.php b/lib/Minz/ControllerNotActionControllerException.php
index 5cf418404..19e5df1b4 100644
--- a/lib/Minz/ControllerNotActionControllerException.php
+++ b/lib/Minz/ControllerNotActionControllerException.php
@@ -1,6 +1,6 @@
<?php
class Minz_ControllerNotActionControllerException extends Minz_Exception {
- public function __construct ($controller_name, $code = self::ERROR) {
+ public function __construct(string $controller_name, int $code = self::ERROR) {
$message = 'Controller `' . $controller_name . '` isn’t instance of ActionController';
parent::__construct ($message, $code);
diff --git a/lib/Minz/ControllerNotExistException.php b/lib/Minz/ControllerNotExistException.php
index a024e1cbd..2d2178974 100644
--- a/lib/Minz/ControllerNotExistException.php
+++ b/lib/Minz/ControllerNotExistException.php
@@ -1,6 +1,6 @@
<?php
class Minz_ControllerNotExistException extends Minz_Exception {
- public function __construct ($code = self::ERROR) {
+ public function __construct(int $code = self::ERROR) {
$message = 'Controller not found!';
parent::__construct ($message, $code);
}
diff --git a/lib/Minz/CurrentPagePaginationException.php b/lib/Minz/CurrentPagePaginationException.php
index 3e3d9d1b4..973913afb 100644
--- a/lib/Minz/CurrentPagePaginationException.php
+++ b/lib/Minz/CurrentPagePaginationException.php
@@ -1,6 +1,6 @@
<?php
class Minz_CurrentPagePaginationException extends Minz_Exception {
- public function __construct ($page) {
+ public function __construct(int $page) {
$message = 'Page number `' . $page . '` doesn\'t exist';
parent::__construct ($message, self::ERROR);
diff --git a/lib/Minz/Error.php b/lib/Minz/Error.php
index 3162c6f99..e23499a10 100644
--- a/lib/Minz/Error.php
+++ b/lib/Minz/Error.php
@@ -19,7 +19,7 @@ class Minz_Error {
* > $logs['notice']
* @param bool $redirect indique s'il faut forcer la redirection (les logs ne seront pas transmis)
*/
- public static function error ($code = 404, $logs = array (), $redirect = true) {
+ public static function error(int $code = 404, array $logs = [], bool $redirect = true): void {
$logs = self::processLogs ($logs);
$error_filename = APP_PATH . '/Controllers/errorController.php';
@@ -52,7 +52,7 @@ class Minz_Error {
* @param array<string,string>|string $logs logs sorted by category (error, warning, notice)
* @return array<string> list of matching logs, without the category, according to environment preferences (production / development)
*/
- private static function processLogs ($logs) {
+ private static function processLogs($logs) {
$conf = Minz_Configuration::get('system');
$env = $conf->environment;
$logs_ok = array ();
diff --git a/lib/Minz/Exception.php b/lib/Minz/Exception.php
index b5e71e0d8..f2d3b876b 100644
--- a/lib/Minz/Exception.php
+++ b/lib/Minz/Exception.php
@@ -4,7 +4,7 @@ class Minz_Exception extends Exception {
const WARNING = 10;
const NOTICE = 20;
- public function __construct ($message, $code = self::ERROR) {
+ public function __construct(string $message, int $code = self::ERROR) {
if ($code != Minz_Exception::ERROR
&& $code != Minz_Exception::WARNING
&& $code != Minz_Exception::NOTICE) {
diff --git a/lib/Minz/ExtensionException.php b/lib/Minz/ExtensionException.php
index b86a97798..c5bba60a9 100644
--- a/lib/Minz/ExtensionException.php
+++ b/lib/Minz/ExtensionException.php
@@ -1,7 +1,7 @@
<?php
class Minz_ExtensionException extends Minz_Exception {
- public function __construct ($message, $extension_name = false, $code = self::ERROR) {
+ public function __construct(string $message, ?string $extension_name = null, int $code = self::ERROR) {
if ($extension_name) {
$message = 'An error occurred in `' . $extension_name . '` extension with the message: ' . $message;
} else {
diff --git a/lib/Minz/FileNotExistException.php b/lib/Minz/FileNotExistException.php
index f97f161af..b467a5208 100644
--- a/lib/Minz/FileNotExistException.php
+++ b/lib/Minz/FileNotExistException.php
@@ -1,6 +1,6 @@
<?php
class Minz_FileNotExistException extends Minz_Exception {
- public function __construct ($file_name, $code = self::ERROR) {
+ public function __construct(string $file_name, int $code = self::ERROR) {
$message = 'File not found: `' . $file_name.'`';
parent::__construct ($message, $code);
diff --git a/lib/Minz/Helper.php b/lib/Minz/Helper.php
index 2c011e1bf..3e09c4758 100644
--- a/lib/Minz/Helper.php
+++ b/lib/Minz/Helper.php
@@ -12,6 +12,8 @@ class Minz_Helper {
/**
* Wrapper for htmlspecialchars.
* Force UTf-8 value and can be used on array too.
+ * @param string|array<string> $var
+ * @return string|array<string>
*/
public static function htmlspecialchars_utf8($var) {
if (is_array($var)) {
diff --git a/lib/Minz/Mailer.php b/lib/Minz/Mailer.php
index 92e396f99..ba434ec8f 100644
--- a/lib/Minz/Mailer.php
+++ b/lib/Minz/Mailer.php
@@ -32,8 +32,11 @@ class Minz_Mailer {
*/
protected $view;
+ /** @var string */
private $mailer;
+ /** @var array<string|int|bool> */
private $smtp_config;
+ /** @var int */
private $debug_level;
/**
diff --git a/lib/Minz/ModelPdo.php b/lib/Minz/ModelPdo.php
index b8c1ad89b..0e813ddca 100644
--- a/lib/Minz/ModelPdo.php
+++ b/lib/Minz/ModelPdo.php
@@ -12,6 +12,7 @@ class Minz_ModelPdo {
/**
* Shares the connection to the database between all instances.
+ * @var bool
*/
public static $usesSharedPdo = true;
diff --git a/lib/Minz/PDOConnectionException.php b/lib/Minz/PDOConnectionException.php
index 11e4d1029..2b015607e 100644
--- a/lib/Minz/PDOConnectionException.php
+++ b/lib/Minz/PDOConnectionException.php
@@ -1,6 +1,6 @@
<?php
class Minz_PDOConnectionException extends Minz_Exception {
- public function __construct ($error, $user, $code = self::ERROR) {
+ public function __construct(string $error, string $user, int $code = self::ERROR) {
$message = 'Access to database is denied for `' . $user . '`: ' . $error;
parent::__construct ($message, $code);
diff --git a/lib/Minz/Pdo.php b/lib/Minz/Pdo.php
index 8c9cd9076..2efff61d4 100644
--- a/lib/Minz/Pdo.php
+++ b/lib/Minz/Pdo.php
@@ -6,18 +6,20 @@
*/
abstract class Minz_Pdo extends PDO {
- public function __construct(string $dsn, $username = null, $passwd = null, $options = null) {
+ /** @param array<int,int|string>|null $options */
+ public function __construct(string $dsn, ?string $username = null, ?string $passwd = null, ?array $options = null) {
parent::__construct($dsn, $username, $passwd, $options);
$this->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
- abstract public function dbType();
+ abstract public function dbType(): string;
+ /** @var string */
private $prefix = '';
public function prefix(): string {
return $this->prefix;
}
- public function setPrefix(string $prefix) {
+ public function setPrefix(string $prefix): void {
$this->prefix = $prefix;
}
@@ -33,6 +35,10 @@ abstract class Minz_Pdo extends PDO {
}
// PHP8+: PDO::lastInsertId(?string $name = null): string|false
+ /**
+ * @param string|null $name
+ * @return string|false
+ */
#[\ReturnTypeWillChange]
public function lastInsertId($name = null) {
if ($name != null) {
@@ -42,6 +48,11 @@ abstract class Minz_Pdo extends PDO {
}
// PHP8+: PDO::prepare(string $query, array $options = []): PDOStatement|false
+ /**
+ * @param string $statement
+ * @param array<int,string>|null $driver_options
+ * @return PDOStatement|false
+ */
#[\ReturnTypeWillChange]
public function prepare($statement, $driver_options = []) {
$statement = $this->preSql($statement);
@@ -49,15 +60,19 @@ abstract class Minz_Pdo extends PDO {
}
// PHP8+: PDO::exec(string $statement): int|false
+ /**
+ * @param string $statement
+ * @return int|false
+ */
#[\ReturnTypeWillChange]
public function exec($statement) {
$statement = $this->preSql($statement);
return parent::exec($statement);
}
- // PHP8+: PDO::query(string $query, ?int $fetchMode = null, mixed ...$fetchModeArgs): PDOStatement|false
+ /** @return PDOStatement|false */
#[\ReturnTypeWillChange]
- public function query($query, $fetch_mode = null, ...$fetch_mode_args) {
+ public function query(string $query, ?int $fetch_mode = null, ...$fetch_mode_args) {
$query = $this->preSql($query);
return $fetch_mode ? parent::query($query, $fetch_mode, ...$fetch_mode_args) : parent::query($query);
}
diff --git a/lib/Minz/PdoMysql.php b/lib/Minz/PdoMysql.php
index b66cccf28..ee411d949 100644
--- a/lib/Minz/PdoMysql.php
+++ b/lib/Minz/PdoMysql.php
@@ -6,7 +6,8 @@
*/
class Minz_PdoMysql extends Minz_Pdo {
- public function __construct(string $dsn, $username = null, $passwd = null, $options = null) {
+ /** @param array<int,int|string>|null $options */
+ public function __construct(string $dsn, ?string $username = null, ?string $passwd = null, ?array $options = null) {
parent::__construct($dsn, $username, $passwd, $options);
$this->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
}
@@ -15,7 +16,10 @@ class Minz_PdoMysql extends Minz_Pdo {
return 'mysql';
}
- // PHP8+: PDO::lastInsertId(?string $name = null): string|false
+ /**
+ * @param string|null $name
+ * @return string|false
+ */
#[\ReturnTypeWillChange]
public function lastInsertId($name = null) {
return parent::lastInsertId(); //We discard the name, only used by PostgreSQL
diff --git a/lib/Minz/PdoPgsql.php b/lib/Minz/PdoPgsql.php
index cae0fe476..b239d3544 100644
--- a/lib/Minz/PdoPgsql.php
+++ b/lib/Minz/PdoPgsql.php
@@ -6,7 +6,8 @@
*/
class Minz_PdoPgsql extends Minz_Pdo {
- public function __construct(string $dsn, $username = null, $passwd = null, $options = null) {
+ /** @param array<int,int|string>|null $options */
+ public function __construct(string $dsn, ?string $username = null, ?string $passwd = null, ?array $options = null) {
parent::__construct($dsn, $username, $passwd, $options);
$this->exec("SET NAMES 'UTF8';");
}
diff --git a/lib/Minz/PdoSqlite.php b/lib/Minz/PdoSqlite.php
index 2c90413a1..479879ffe 100644
--- a/lib/Minz/PdoSqlite.php
+++ b/lib/Minz/PdoSqlite.php
@@ -6,7 +6,8 @@
*/
class Minz_PdoSqlite extends Minz_Pdo {
- public function __construct(string $dsn, $username = null, $passwd = null, $options = null) {
+ /** @param array<int,int|string>|null $options */
+ public function __construct(string $dsn, ?string $username = null, ?string $passwd = null, ?array $options = null) {
parent::__construct($dsn, $username, $passwd, $options);
$this->exec('PRAGMA foreign_keys = ON;');
}
@@ -15,7 +16,10 @@ class Minz_PdoSqlite extends Minz_Pdo {
return 'sqlite';
}
- // PHP8+: PDO::lastInsertId(?string $name = null): string|false
+ /**
+ * @param string|null $name
+ * @return string|false
+ */
#[\ReturnTypeWillChange]
public function lastInsertId($name = null) {
return parent::lastInsertId(); //We discard the name, only used by PostgreSQL
diff --git a/lib/Minz/PermissionDeniedException.php b/lib/Minz/PermissionDeniedException.php
index 61be530d3..91a4b310e 100644
--- a/lib/Minz/PermissionDeniedException.php
+++ b/lib/Minz/PermissionDeniedException.php
@@ -1,6 +1,6 @@
<?php
class Minz_PermissionDeniedException extends Minz_Exception {
- public function __construct ($file_name, $code = self::ERROR) {
+ public function __construct(string $file_name, int $code = self::ERROR) {
$message = 'Permission is denied for `' . $file_name.'`';
parent::__construct ($message, $code);
diff --git a/lib/favicons.php b/lib/favicons.php
index fd03f61c8..abaa5e63a 100644
--- a/lib/favicons.php
+++ b/lib/favicons.php
@@ -2,7 +2,7 @@
const FAVICONS_DIR = DATA_PATH . '/favicons/';
const DEFAULT_FAVICON = PUBLIC_PATH . '/themes/icons/default_favicon.ico';
-function isImgMime($content) {
+function isImgMime(string $content): bool {
//Based on https://github.com/ArthurHoaro/favicon/blob/3a4f93da9bb24915b21771eb7873a21bde26f5d1/src/Favicon/Favicon.php#L311-L319
if ($content == '') {
return false;
@@ -21,7 +21,8 @@ function isImgMime($content) {
return $isImage;
}
-function downloadHttp(&$url, $curlOptions = array()) {
+/** @param array<int,int|bool> $curlOptions */
+function downloadHttp(string &$url, array $curlOptions = []): string {
syslog(LOG_INFO, 'FreshRSS Favicon GET ' . $url);
$url = checkUrl($url);
if (!$url) {
@@ -49,7 +50,7 @@ function downloadHttp(&$url, $curlOptions = array()) {
return $info['http_code'] == 200 ? $response : '';
}
-function searchFavicon(&$url) {
+function searchFavicon(string &$url): string {
$dom = new DOMDocument();
$html = downloadHttp($url);
if ($html != '' && @$dom->loadHTML($html, LIBXML_NONET | LIBXML_NOERROR | LIBXML_NOWARNING)) {
@@ -84,7 +85,7 @@ function searchFavicon(&$url) {
return '';
}
-function download_favicon($url, $dest) {
+function download_favicon(string $url, string $dest): bool {
$url = trim($url);
$favicon = searchFavicon($url);
if ($favicon == '') {
diff --git a/lib/lib_date.php b/lib/lib_date.php
index cb1f1d1e2..00356927f 100644
--- a/lib/lib_date.php
+++ b/lib/lib_date.php
@@ -42,13 +42,13 @@ function example($dateInterval) {
}
*/
-function _dateFloor($isoDate) {
+function _dateFloor(string $isoDate): string {
$x = explode('T', $isoDate, 2);
$t = isset($x[1]) ? str_pad($x[1], 6, '0') : '000000';
return str_pad($x[0], 8, '01') . 'T' . $t;
}
-function _dateCeiling($isoDate) {
+function _dateCeiling(string $isoDate): string {
$x = explode('T', $isoDate, 2);
$t = isset($x[1]) && strlen($x[1]) > 1 ? str_pad($x[1], 6, '59') : '235959';
switch (strlen($x[0])) {
@@ -62,11 +62,11 @@ function _dateCeiling($isoDate) {
}
}
-function _noDelimit($isoDate) {
+function _noDelimit(?string $isoDate): ?string {
return $isoDate === null || $isoDate === '' ? null : str_replace(array('-', ':'), '', $isoDate); //FIXME: Bug with negative time zone
}
-function _dateRelative($d1, $d2) {
+function _dateRelative(?string $d1, ?string $d2): ?string {
if ($d2 === null) {
return $d1 !== null && $d1[0] !== 'P' ? $d1 : null;
} elseif ($d2 !== '' && $d2[0] != 'P' && $d1 !== null && $d1[0] !== 'P') {
@@ -81,10 +81,10 @@ function _dateRelative($d1, $d2) {
/**
* Parameter $dateInterval is a string containing an ISO 8601 time interval.
- * Returns an array with the minimum and maximum Unix timestamp of this interval,
+ * @return array{int|null|false,int|null|false} an array with the minimum and maximum Unix timestamp of this interval,
* or null if open interval, or false if error.
*/
-function parseDateInterval($dateInterval) {
+function parseDateInterval(string $dateInterval) {
$dateInterval = trim($dateInterval);
$dateInterval = str_replace('--', '/', $dateInterval);
$dateInterval = strtoupper($dateInterval);
diff --git a/lib/lib_install.php b/lib/lib_install.php
index 931de21a2..18f4a732a 100644
--- a/lib/lib_install.php
+++ b/lib/lib_install.php
@@ -3,7 +3,8 @@
Minz_Configuration::register('default_system', join_path(FRESHRSS_PATH, 'config.default.php'));
Minz_Configuration::register('default_user', join_path(FRESHRSS_PATH, 'config-user.default.php'));
-function checkRequirements($dbType = '') {
+/** @return array<string,string> */
+function checkRequirements(string $dbType = ''): array {
$php = version_compare(PHP_VERSION, FRESHRSS_MIN_PHP_VERSION) >= 0;
$curl = extension_loaded('curl');
$pdo_mysql = extension_loaded('pdo_mysql');
@@ -74,11 +75,11 @@ function checkRequirements($dbType = '') {
);
}
-function generateSalt() {
+function generateSalt(): string {
return sha1(uniqid('' . mt_rand(), true).implode('', stat(__FILE__)));
}
-function initDb() {
+function initDb(): string {
$conf = FreshRSS_Context::$system_conf;
$db = $conf->db;
if (empty($db['pdo_options'])) {
@@ -115,7 +116,7 @@ function initDb() {
return $databaseDAO->testConnection();
}
-function setupMigrations() {
+function setupMigrations(): bool {
$migrations_path = APP_PATH . '/migrations';
$migrations_version_path = DATA_PATH . '/applied_migrations.txt';
diff --git a/tests/phpstan-next.txt b/tests/phpstan-next.txt
index 5670b37df..52b3b823c 100644
--- a/tests/phpstan-next.txt
+++ b/tests/phpstan-next.txt
@@ -8,81 +8,43 @@
./app/Controllers/feedController.php
./app/Controllers/updateController.php
./app/Controllers/userController.php
-./app/Exceptions/AlreadySubscribedException.php
-./app/Exceptions/BadUrlException.php
-./app/Exceptions/FeedNotAddedException.php
-./app/Exceptions/ZipException.php
./app/install.php
-./app/Mailers/UserMailer.php
./app/Models/Auth.php
-./app/Models/BooleanSearch.php
./app/Models/Category.php
./app/Models/CategoryDAO.php
-./app/Models/CategoryDAOSQLite.php
./app/Models/ConfigurationSetter.php
-./app/Models/DatabaseDAO.php
-./app/Models/DatabaseDAOPGSQL.php
-./app/Models/DatabaseDAOSQLite.php
./app/Models/Entry.php
./app/Models/Feed.php
./app/Models/FeedDAO.php
-./app/Models/FeedDAOSQLite.php
./app/Models/FilterAction.php
./app/Models/FormAuth.php
-./app/Models/ReadingMode.php
./app/Models/Search.php
./app/Models/Share.php
./app/Models/TagDAO.php
-./app/Models/TagDAOSQLite.php
./app/Models/Themes.php
-./app/Models/UserDAO.php
./app/Models/View.php
./app/Services/ExportService.php
./app/Services/ImportService.php
./cli/_cli.php
./cli/_update-or-create-user.php
./cli/check.translation.php
-./cli/i18n/I18nCompletionValidator.php
./cli/i18n/I18nData.php
./cli/i18n/I18nFile.php
-./cli/i18n/I18nUsageValidator.php
-./cli/i18n/I18nValidatorInterface.php
./cli/i18n/I18nValue.php
./cli/manipulate.translation.php
./lib/core-extensions/Google-Groups/extension.php
./lib/core-extensions/Tumblr-GDPR/extension.php
-./lib/favicons.php
./lib/http-conditional.php
-./lib/lib_date.php
-./lib/lib_install.php
./lib/Minz/ActionController.php
-./lib/Minz/ActionException.php
./lib/Minz/Configuration.php
-./lib/Minz/ConfigurationException.php
-./lib/Minz/ControllerNotActionControllerException.php
-./lib/Minz/ControllerNotExistException.php
-./lib/Minz/CurrentPagePaginationException.php
./lib/Minz/Dispatcher.php
-./lib/Minz/Error.php
-./lib/Minz/Exception.php
./lib/Minz/Extension.php
-./lib/Minz/ExtensionException.php
./lib/Minz/ExtensionManager.php
-./lib/Minz/FileNotExistException.php
./lib/Minz/FrontController.php
-./lib/Minz/Helper.php
./lib/Minz/Log.php
-./lib/Minz/Mailer.php
./lib/Minz/Migrator.php
./lib/Minz/ModelArray.php
-./lib/Minz/ModelPdo.php
./lib/Minz/Paginator.php
-./lib/Minz/Pdo.php
-./lib/Minz/PDOConnectionException.php
-./lib/Minz/PdoMysql.php
-./lib/Minz/PdoPgsql.php
-./lib/Minz/PdoSqlite.php
-./lib/Minz/PermissionDeniedException.php
./lib/Minz/Request.php
./lib/Minz/Session.php
./lib/Minz/Translate.php