aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.fr.md4
-rw-r--r--README.md4
-rw-r--r--app/Controllers/extensionController.php19
-rw-r--r--app/Models/View.php5
-rw-r--r--app/i18n/cs/admin.php1
-rw-r--r--app/i18n/de/admin.php1
-rw-r--r--app/i18n/el/admin.php1
-rw-r--r--app/i18n/en-US/admin.php1
-rw-r--r--app/i18n/en/admin.php1
-rw-r--r--app/i18n/es/admin.php1
-rw-r--r--app/i18n/fa/admin.php1
-rw-r--r--app/i18n/fi/admin.php1
-rw-r--r--app/i18n/fr/admin.php1
-rw-r--r--app/i18n/he/admin.php1
-rw-r--r--app/i18n/hu/admin.php1
-rw-r--r--app/i18n/id/admin.php1
-rw-r--r--app/i18n/it/admin.php1
-rw-r--r--app/i18n/ja/admin.php1
-rw-r--r--app/i18n/ko/admin.php1
-rw-r--r--app/i18n/lv/admin.php1
-rw-r--r--app/i18n/nl/admin.php1
-rw-r--r--app/i18n/oc/admin.php1
-rw-r--r--app/i18n/pl/admin.php1
-rw-r--r--app/i18n/pt-BR/admin.php1
-rw-r--r--app/i18n/pt-PT/admin.php1
-rw-r--r--app/i18n/ru/admin.php1
-rw-r--r--app/i18n/sk/admin.php1
-rw-r--r--app/i18n/tr/admin.php1
-rw-r--r--app/i18n/uk/admin.php1
-rw-r--r--app/i18n/zh-CN/admin.php1
-rw-r--r--app/i18n/zh-TW/admin.php1
-rw-r--r--app/views/extension/index.phtml2
-rw-r--r--lib/Minz/Extension.php4
-rw-r--r--lib/Minz/ExtensionManager.php9
-rw-r--r--p/themes/base-theme/frss.css4
-rw-r--r--p/themes/base-theme/frss.rtl.css4
36 files changed, 67 insertions, 15 deletions
diff --git a/README.fr.md b/README.fr.md
index 3fc79e0f8..b3d13f130 100644
--- a/README.fr.md
+++ b/README.fr.md
@@ -233,7 +233,7 @@ Voir le [dépôt dédié à ces extensions](https://github.com/FreshRSS/Extensio
| English (United States) (en-US) | ■■■■■■■■■■ 100% | [contribuer](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fen-US+%2F%28TODO%7CDIRTY%29%24%2F) |
| Español (es) | ■■■■■■■■・・ 88% | [contribuer](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fes+%2F%28TODO%7CDIRTY%29%24%2F) |
| فارسی (fa) | ■■■■■■■■■・ 94% | [contribuer](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Ffa+%2F%28TODO%7CDIRTY%29%24%2F) |
-| Suomi (fi) | ■■■■■■■■■・ 97% | [contribuer](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Ffi+%2F%28TODO%7CDIRTY%29%24%2F) |
+| Suomi (fi) | ■■■■■■■■■・ 96% | [contribuer](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Ffi+%2F%28TODO%7CDIRTY%29%24%2F) |
| Français (fr) | ■■■■■■■■■■ 100% | [contribuer](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Ffr+%2F%28TODO%7CDIRTY%29%24%2F) |
| עברית (he) | ■■■■・・・・・・ 44% | [contribuer](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fhe+%2F%28TODO%7CDIRTY%29%24%2F) |
| Magyar (hu) | ■■■■■■■■■・ 96% | [contribuer](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fhu+%2F%28TODO%7CDIRTY%29%24%2F) |
@@ -241,7 +241,7 @@ Voir le [dépôt dédié à ces extensions](https://github.com/FreshRSS/Extensio
| Italiano (it) | ■■■■■■■■■・ 97% | [contribuer](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fit+%2F%28TODO%7CDIRTY%29%24%2F) |
| 日本語 (ja) | ■■■■■■■■■・ 92% | [contribuer](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fja+%2F%28TODO%7CDIRTY%29%24%2F) |
| 한국어 (ko) | ■■■■■■■■・・ 85% | [contribuer](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fko+%2F%28TODO%7CDIRTY%29%24%2F) |
-| Latviešu (lv) | ■■■■■■■■・・ 80% | [contribuer](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Flv+%2F%28TODO%7CDIRTY%29%24%2F) |
+| Latviešu (lv) | ■■■■■■■・・・ 79% | [contribuer](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Flv+%2F%28TODO%7CDIRTY%29%24%2F) |
| Nederlands (nl) | ■■■■■■■■■・ 96% | [contribuer](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fnl+%2F%28TODO%7CDIRTY%29%24%2F) |
| Occitan (oc) | ■■■■■■■・・・ 78% | [contribuer](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Foc+%2F%28TODO%7CDIRTY%29%24%2F) |
| Polski (pl) | ■■■■■■■■■■ 100% | [contribuer](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fpl+%2F%28TODO%7CDIRTY%29%24%2F) |
diff --git a/README.md b/README.md
index 3dad8ef27..35fcd0989 100644
--- a/README.md
+++ b/README.md
@@ -129,7 +129,7 @@ See the [repository dedicated to those extensions](https://github.com/FreshRSS/E
| English (United States) (en-US) | ■■■■■■■■■■ 100% | [contribute](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fen-US+%2F%28TODO%7CDIRTY%29%24%2F) |
| Español (es) | ■■■■■■■■・・ 88% | [contribute](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fes+%2F%28TODO%7CDIRTY%29%24%2F) |
| فارسی (fa) | ■■■■■■■■■・ 94% | [contribute](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Ffa+%2F%28TODO%7CDIRTY%29%24%2F) |
-| Suomi (fi) | ■■■■■■■■■・ 97% | [contribute](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Ffi+%2F%28TODO%7CDIRTY%29%24%2F) |
+| Suomi (fi) | ■■■■■■■■■・ 96% | [contribute](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Ffi+%2F%28TODO%7CDIRTY%29%24%2F) |
| Français (fr) | ■■■■■■■■■■ 100% | [contribute](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Ffr+%2F%28TODO%7CDIRTY%29%24%2F) |
| עברית (he) | ■■■■・・・・・・ 44% | [contribute](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fhe+%2F%28TODO%7CDIRTY%29%24%2F) |
| Magyar (hu) | ■■■■■■■■■・ 96% | [contribute](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fhu+%2F%28TODO%7CDIRTY%29%24%2F) |
@@ -137,7 +137,7 @@ See the [repository dedicated to those extensions](https://github.com/FreshRSS/E
| Italiano (it) | ■■■■■■■■■・ 97% | [contribute](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fit+%2F%28TODO%7CDIRTY%29%24%2F) |
| 日本語 (ja) | ■■■■■■■■■・ 92% | [contribute](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fja+%2F%28TODO%7CDIRTY%29%24%2F) |
| 한국어 (ko) | ■■■■■■■■・・ 85% | [contribute](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fko+%2F%28TODO%7CDIRTY%29%24%2F) |
-| Latviešu (lv) | ■■■■■■■■・・ 80% | [contribute](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Flv+%2F%28TODO%7CDIRTY%29%24%2F) |
+| Latviešu (lv) | ■■■■■■■・・・ 79% | [contribute](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Flv+%2F%28TODO%7CDIRTY%29%24%2F) |
| Nederlands (nl) | ■■■■■■■■■・ 96% | [contribute](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fnl+%2F%28TODO%7CDIRTY%29%24%2F) |
| Occitan (oc) | ■■■■■■■・・・ 78% | [contribute](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Foc+%2F%28TODO%7CDIRTY%29%24%2F) |
| Polski (pl) | ■■■■■■■■■■ 100% | [contribute](https://github.com/search?q=repo%3AFreshRSS%2FFreshRSS+path%3Aapp%2Fi18n%2Fpl+%2F%28TODO%7CDIRTY%29%24%2F) |
diff --git a/app/Controllers/extensionController.php b/app/Controllers/extensionController.php
index 39b5e858a..c0e85edbc 100644
--- a/app/Controllers/extensionController.php
+++ b/app/Controllers/extensionController.php
@@ -3,6 +3,8 @@ declare(strict_types=1);
/**
* The controller to manage extensions.
+ *
+ * @phpstan-type ExtensionFullMetadata array{name:string,entrypoint:string,author:string,description:string,version:string,type:'system'|'user',url:string,method:string,directory:string,compatibility:string}
*/
class FreshRSS_extension_Controller extends FreshRSS_ActionController {
/**
@@ -40,7 +42,7 @@ class FreshRSS_extension_Controller extends FreshRSS_ActionController {
/**
* Fetch extension list from GitHub
- * @return list<array{name:string,author:string,description:string,version:string,entrypoint:string,type:'system'|'user',url:string,method:string,directory:string}>
+ * @phpstan-return list<ExtensionFullMetadata>
*/
protected function getAvailableExtensionList(): array {
$extensionListUrl = 'https://raw.githubusercontent.com/FreshRSS/Extensions/master/extensions.json';
@@ -82,7 +84,10 @@ class FreshRSS_extension_Controller extends FreshRSS_ActionController {
if (isset($extension['version']) && is_numeric($extension['version'])) {
$extension['version'] = (string)$extension['version'];
}
- $keys = ['author', 'description', 'directory', 'entrypoint', 'method', 'name', 'type', 'url', 'version'];
+ if (!array_key_exists('compatibility', $extension)) {
+ $extension['compatibility'] = '✔';
+ }
+ $keys = ['author', 'description', 'directory', 'entrypoint', 'method', 'name', 'type', 'url', 'version', 'compatibility'];
$extension = array_intersect_key($extension, array_flip($keys)); // Keep only valid keys
$extension = array_filter($extension, 'is_string');
foreach ($keys as $key) {
@@ -93,10 +98,16 @@ class FreshRSS_extension_Controller extends FreshRSS_ActionController {
if (!in_array($extension['type'], ['system', 'user'], true) || trim($extension['name']) === '') {
continue;
}
- /** @var array{name:string,author:string,description:string,version:string,entrypoint:string,type:'system'|'user',url:string,method:string,directory:string} $extension */
+ /** @var ExtensionFullMetadata $extension */
$extensions[] = $extension;
}
- return $extensions;
+
+ return array_map(static function (array $extension) {
+ if ($extension['compatibility'] !== '✔') {
+ $extension['compatibility'] = version_compare($extension['compatibility'], FRESHRSS_VERSION, '>=') ? '✔' : '✘';
+ }
+ return $extension;
+ }, $extensions);
}
/**
diff --git a/app/Models/View.php b/app/Models/View.php
index cf5c30e15..b251e95ed 100644
--- a/app/Models/View.php
+++ b/app/Models/View.php
@@ -1,6 +1,9 @@
<?php
declare(strict_types=1);
+/**
+ * @phpstan-import-type ExtensionFullMetadata from FreshRSS_extension_Controller
+ */
class FreshRSS_View extends Minz_View {
// Main views
@@ -123,7 +126,7 @@ class FreshRSS_View extends Minz_View {
public bool $selectorSuccess;
// Extensions
- /** @var array<array{name:string,author:string,description:string,version:string,entrypoint:string,type:'system'|'user',url:string,method:string,directory:string}> */
+ /** @var list<ExtensionFullMetadata> */
public array $available_extensions;
public ?Minz_Extension $ext_details = null;
/** @var array{system:array<Minz_Extension>,user:array<Minz_Extension>} */
diff --git a/app/i18n/cs/admin.php b/app/i18n/cs/admin.php
index 6bf067a4c..ca71625d1 100644
--- a/app/i18n/cs/admin.php
+++ b/app/i18n/cs/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Nejsou naistalována žádná rozšíření',
'empty_list_help' => 'Check the logs to determine the reason behind the empty extension list.', // TODO
'enabled' => 'Povoleno',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Nainstalováno',
'name' => 'Název',
'no_configure_view' => 'Toto rozšíření nemá žádná nastavení.',
diff --git a/app/i18n/de/admin.php b/app/i18n/de/admin.php
index a9ec4fd7f..081cd9dd9 100644
--- a/app/i18n/de/admin.php
+++ b/app/i18n/de/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Es gibt keine installierte Erweiterung.',
'empty_list_help' => 'Siehe Protokolle für weitere Infos, warum die Erweiterungsliste leer ist.',
'enabled' => 'Aktiviert',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Installiert',
'name' => 'Name', // IGNORE
'no_configure_view' => 'Diese Erweiterung kann nicht konfiguriert werden.',
diff --git a/app/i18n/el/admin.php b/app/i18n/el/admin.php
index a1e687b58..a9b1bd6bb 100644
--- a/app/i18n/el/admin.php
+++ b/app/i18n/el/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Δεν υπάρχουν εγκατεστημένες επεκτάσεις',
'empty_list_help' => 'Check the logs to determine the reason behind the empty extension list.', // TODO
'enabled' => 'Ενεργοποιημένες',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Εγκατεστημένες',
'name' => 'Όνομα',
'no_configure_view' => 'Αυτή η επέκταση δεν μπορεί να ρυθμιστεί.',
diff --git a/app/i18n/en-US/admin.php b/app/i18n/en-US/admin.php
index 29185b462..30aa5a0e8 100644
--- a/app/i18n/en-US/admin.php
+++ b/app/i18n/en-US/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'There are no installed extensions', // IGNORE
'empty_list_help' => 'Check the logs to determine the reason behind the empty extension list.', // IGNORE
'enabled' => 'Enabled', // IGNORE
+ 'is_compatible' => 'Is compatible', // IGNORE
'latest' => 'Installed', // IGNORE
'name' => 'Name', // IGNORE
'no_configure_view' => 'This extension cannot be configured.', // IGNORE
diff --git a/app/i18n/en/admin.php b/app/i18n/en/admin.php
index 10f1c0c4b..e5fa4245a 100644
--- a/app/i18n/en/admin.php
+++ b/app/i18n/en/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'There are no installed extensions',
'empty_list_help' => 'Check the logs to determine the reason behind the empty extension list.',
'enabled' => 'Enabled',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Installed',
'name' => 'Name',
'no_configure_view' => 'This extension cannot be configured.',
diff --git a/app/i18n/es/admin.php b/app/i18n/es/admin.php
index aceba49e4..7ef5a6d32 100644
--- a/app/i18n/es/admin.php
+++ b/app/i18n/es/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'No hay extensiones instaladas',
'empty_list_help' => 'Check the logs to determine the reason behind the empty extension list.', // TODO
'enabled' => 'Activado',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Instalado',
'name' => 'Nombre',
'no_configure_view' => 'Esta extensión no puede ser configurada.',
diff --git a/app/i18n/fa/admin.php b/app/i18n/fa/admin.php
index 43e7e0827..47aac7077 100644
--- a/app/i18n/fa/admin.php
+++ b/app/i18n/fa/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => ' هیچ برنامه افزودنی نصب شده ای وجود ندارد',
'empty_list_help' => 'لاگ‌ها را بررسی کنید تا دلیل خالی بودن لیست افزونه‌ها مشخص شود',
'enabled' => ' فعال است',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => ' نصب شده است',
'name' => ' نام',
'no_configure_view' => ' این برنامه افزودنی قابل پیکربندی نیست.',
diff --git a/app/i18n/fi/admin.php b/app/i18n/fi/admin.php
index 3f37d65e9..0e05c6357 100644
--- a/app/i18n/fi/admin.php
+++ b/app/i18n/fi/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Asennettuja laajennuksia ei ole',
'empty_list_help' => 'Voit tarkistaa lokeista, miksi laajennusluettelo on tyhjä.',
'enabled' => 'Käytössä',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Asennettu',
'name' => 'Nimi',
'no_configure_view' => 'Tätä laajennusta ei voi määrittää.',
diff --git a/app/i18n/fr/admin.php b/app/i18n/fr/admin.php
index f2ae5b771..47c4c55d7 100644
--- a/app/i18n/fr/admin.php
+++ b/app/i18n/fr/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Aucune extension installée',
'empty_list_help' => 'Vérifiez les logs pour déterminer pourquoi la liste des extensions est vide.',
'enabled' => 'Activée',
+ 'is_compatible' => 'Est compatible',
'latest' => 'Installée',
'name' => 'Nom',
'no_configure_view' => 'Cette extension n’a pas à être configurée',
diff --git a/app/i18n/he/admin.php b/app/i18n/he/admin.php
index 3d8bb52b9..c1f526967 100644
--- a/app/i18n/he/admin.php
+++ b/app/i18n/he/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'There is no installed extension',
'empty_list_help' => 'Check the logs to determine the reason behind the empty extension list.', // TODO
'enabled' => 'Enabled', // TODO
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Installed', // TODO
'name' => 'Name', // TODO
'no_configure_view' => 'This extension cannot be configured.', // TODO
diff --git a/app/i18n/hu/admin.php b/app/i18n/hu/admin.php
index d8b00de2d..7781cae46 100644
--- a/app/i18n/hu/admin.php
+++ b/app/i18n/hu/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Nincsenek telepített kiegészítők',
'empty_list_help' => 'Ellenőrizd a naplókat, hogy megállapítsd az üres bővítménylista mögött meghúzódó okot.',
'enabled' => 'Bekapcsolva',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Telepítve',
'name' => 'Név',
'no_configure_view' => 'Ezt a kiegészítőt nem lehet konfigurálni.',
diff --git a/app/i18n/id/admin.php b/app/i18n/id/admin.php
index 806a4cafb..78f6dcf5d 100644
--- a/app/i18n/id/admin.php
+++ b/app/i18n/id/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Tidak ada ekstensi yang terpasang',
'empty_list_help' => 'Periksa log untuk menemukan alasan daftar ekstensi yang kosong.',
'enabled' => 'Diaktifkan',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Terpasang',
'name' => 'Nama',
'no_configure_view' => 'Ekstensi ini tidak dapat dikonfigurasi.',
diff --git a/app/i18n/it/admin.php b/app/i18n/it/admin.php
index a06e373cb..574a58618 100644
--- a/app/i18n/it/admin.php
+++ b/app/i18n/it/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Non ci sono estensioni installate',
'empty_list_help' => 'Controllare i log per determinare il motivo della lista estensioni vuota.',
'enabled' => 'Abilitata',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Installato',
'name' => 'Nome',
'no_configure_view' => 'Questa estensioni non può essere configurata.',
diff --git a/app/i18n/ja/admin.php b/app/i18n/ja/admin.php
index fc2e9f5e6..f3a462804 100644
--- a/app/i18n/ja/admin.php
+++ b/app/i18n/ja/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'インストールされている拡張機能はありません',
'empty_list_help' => '拡張機能リストが表示されない原因を特定するために、ログを確認してください。',
'enabled' => '有効',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'インストール済み',
'name' => '名前',
'no_configure_view' => 'この拡張機能は設定できません.',
diff --git a/app/i18n/ko/admin.php b/app/i18n/ko/admin.php
index 8f3f4cec2..434e401ff 100644
--- a/app/i18n/ko/admin.php
+++ b/app/i18n/ko/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => '설치된 확장 기능이 없습니다',
'empty_list_help' => 'Check the logs to determine the reason behind the empty extension list.', // TODO
'enabled' => '활성화됨',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => '설치됨',
'name' => '이름',
'no_configure_view' => '이 확장 기능은 설정이 없습니다.',
diff --git a/app/i18n/lv/admin.php b/app/i18n/lv/admin.php
index 87b32b875..544911cc1 100644
--- a/app/i18n/lv/admin.php
+++ b/app/i18n/lv/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Nav instalētu paplašinājumu',
'empty_list_help' => 'Check the logs to determine the reason behind the empty extension list.', // TODO
'enabled' => 'Ieslēgts',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Instalēts',
'name' => 'Vārds',
'no_configure_view' => 'Šo paplašinājumu nevar konfigurēt.',
diff --git a/app/i18n/nl/admin.php b/app/i18n/nl/admin.php
index 760391c7d..b80169c97 100644
--- a/app/i18n/nl/admin.php
+++ b/app/i18n/nl/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Er zijn geïnstalleerde uitbreidingen',
'empty_list_help' => 'Controleer de logbestanden om de reden voor de lege extensielijst te achterhalen.',
'enabled' => 'Ingeschakeld',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Geïnstalleerd',
'name' => 'Naam',
'no_configure_view' => 'Deze uitbreiding kan niet worden geconfigureerd.',
diff --git a/app/i18n/oc/admin.php b/app/i18n/oc/admin.php
index 430fe385e..fcb547ba6 100644
--- a/app/i18n/oc/admin.php
+++ b/app/i18n/oc/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Cap d’extensions pas installadas',
'empty_list_help' => 'Check the logs to determine the reason behind the empty extension list.', // TODO
'enabled' => 'Activada',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Installada',
'name' => 'Nom',
'no_configure_view' => 'Aquesta extension se pòt pas configurar.',
diff --git a/app/i18n/pl/admin.php b/app/i18n/pl/admin.php
index 8a6b656dd..7fde007be 100644
--- a/app/i18n/pl/admin.php
+++ b/app/i18n/pl/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Brak zainstalowanych rozszerzeń',
'empty_list_help' => 'Sprawdź dziennik, aby ustalić powód pustej listy rozszerzeń.',
'enabled' => 'Włączone',
+ 'is_compatible' => 'Jest kompatybilne',
'latest' => 'Zainstalowane',
'name' => 'Nazwa',
'no_configure_view' => 'To rozszerzenie nie jest konfigurowalne.',
diff --git a/app/i18n/pt-BR/admin.php b/app/i18n/pt-BR/admin.php
index b6e0f5476..341663977 100644
--- a/app/i18n/pt-BR/admin.php
+++ b/app/i18n/pt-BR/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Não há extensões instaladas',
'empty_list_help' => 'Check the logs to determine the reason behind the empty extension list.', // TODO
'enabled' => 'Habilitada',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Instalado',
'name' => 'Nome',
'no_configure_view' => 'Esta extensão não pode ser configurada.',
diff --git a/app/i18n/pt-PT/admin.php b/app/i18n/pt-PT/admin.php
index d05403ceb..117a3cc5c 100644
--- a/app/i18n/pt-PT/admin.php
+++ b/app/i18n/pt-PT/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Não existem extensões instaladas',
'empty_list_help' => 'Check the logs to determine the reason behind the empty extension list.', // TODO
'enabled' => 'Habilitada',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Instalado',
'name' => 'Nome',
'no_configure_view' => 'Esta extensão não pode ser configurada.',
diff --git a/app/i18n/ru/admin.php b/app/i18n/ru/admin.php
index 6a559f712..d472cf84d 100644
--- a/app/i18n/ru/admin.php
+++ b/app/i18n/ru/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Нет установленных расширений',
'empty_list_help' => 'Check the logs to determine the reason behind the empty extension list.', // TODO
'enabled' => 'Включены',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Установлено',
'name' => 'Название',
'no_configure_view' => 'Это расширение не требует настройки.',
diff --git a/app/i18n/sk/admin.php b/app/i18n/sk/admin.php
index ec861eca9..25c62db0f 100644
--- a/app/i18n/sk/admin.php
+++ b/app/i18n/sk/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Žiadne nainštalované rozšírenia',
'empty_list_help' => 'Check the logs to determine the reason behind the empty extension list.', // TODO
'enabled' => 'Povolené',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Nainštalované',
'name' => 'Názov',
'no_configure_view' => 'Toto rozšírenie nemá nastavenia.',
diff --git a/app/i18n/tr/admin.php b/app/i18n/tr/admin.php
index df6ef2c4f..6a1c110f6 100644
--- a/app/i18n/tr/admin.php
+++ b/app/i18n/tr/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Yüklü eklenti yok',
'empty_list_help' => 'Eklenti listesinin neden boş olduğunu belirlemek için günlükleri kontrol edin.',
'enabled' => 'Etkin',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Yüklü',
'name' => 'İsim',
'no_configure_view' => 'Bu eklenti yapılandırılamaz.',
diff --git a/app/i18n/uk/admin.php b/app/i18n/uk/admin.php
index 7126d901c..14bbd6d71 100644
--- a/app/i18n/uk/admin.php
+++ b/app/i18n/uk/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => 'Розширень не встановлено',
'empty_list_help' => 'Щоб виявити причину порожнього списку розширень, перегляньте журнали.',
'enabled' => 'Увімкнено',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => 'Встановлено',
'name' => 'Назва',
'no_configure_view' => 'Розширення не налаштовується.',
diff --git a/app/i18n/zh-CN/admin.php b/app/i18n/zh-CN/admin.php
index d1e3a3b4f..70a80c09e 100644
--- a/app/i18n/zh-CN/admin.php
+++ b/app/i18n/zh-CN/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => '没有已安装的扩展',
'empty_list_help' => 'Check the logs to determine the reason behind the empty extension list.', // TODO
'enabled' => '已启用',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => '已安装',
'name' => '名称',
'no_configure_view' => '此扩展无法配置。',
diff --git a/app/i18n/zh-TW/admin.php b/app/i18n/zh-TW/admin.php
index 88ad2f0eb..72bf32210 100644
--- a/app/i18n/zh-TW/admin.php
+++ b/app/i18n/zh-TW/admin.php
@@ -118,6 +118,7 @@ return array(
'empty_list' => '沒有已安裝的擴充功能',
'empty_list_help' => 'Check the logs to determine the reason behind the empty extension list.', // TODO
'enabled' => '已啟用',
+ 'is_compatible' => 'Is compatible', // TODO
'latest' => '已安裝',
'name' => '名稱',
'no_configure_view' => '此擴充功能不能配置。',
diff --git a/app/views/extension/index.phtml b/app/views/extension/index.phtml
index 24b72e920..fa1ddeaa1 100644
--- a/app/views/extension/index.phtml
+++ b/app/views/extension/index.phtml
@@ -48,6 +48,7 @@
<th><?= _t('admin.extensions.version') ?></th>
<th><?= _t('admin.extensions.author') ?></th>
<th><?= _t('admin.extensions.description') ?></th>
+ <th><?= _t('admin.extensions.is_compatible') ?></th>
</tr>
<?php foreach ($this->available_extensions as $ext) { ?>
<tr>
@@ -68,6 +69,7 @@
<?php } ?>
<?php } ?>
</td>
+ <td><?= $ext['compatibility'] ?></td>
</tr>
<?php } ?>
</table>
diff --git a/lib/Minz/Extension.php b/lib/Minz/Extension.php
index a35272b03..51088a7a9 100644
--- a/lib/Minz/Extension.php
+++ b/lib/Minz/Extension.php
@@ -3,6 +3,8 @@ declare(strict_types=1);
/**
* The extension base class.
+ *
+ * @phpstan-type ExtensionMetadata array{name:string,entrypoint:string,author?:string,description?:string,version?:string,type?:'system'|'user',path:string}
*/
abstract class Minz_Extension {
private string $name;
@@ -41,7 +43,7 @@ abstract class Minz_Extension {
* - version: a version for the current extension.
* - type: "system" or "user" (default).
*
- * @param array{'name':string,'entrypoint':string,'path':string,'author'?:string,'description'?:string,'version'?:string,'type'?:'system'|'user'} $meta_info
+ * @param ExtensionMetadata $meta_info
* contains information about the extension.
*/
final public function __construct(array $meta_info) {
diff --git a/lib/Minz/ExtensionManager.php b/lib/Minz/ExtensionManager.php
index dac2e1d60..f1d5d0c25 100644
--- a/lib/Minz/ExtensionManager.php
+++ b/lib/Minz/ExtensionManager.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
* An extension manager to load extensions present in CORE_EXTENSIONS_PATH and THIRDPARTY_EXTENSIONS_PATH.
*
* @todo see coding style for methods!!
+ * @phpstan-import-type ExtensionMetadata from Minz_Extension
*/
final class Minz_ExtensionManager {
@@ -81,7 +82,7 @@ final class Minz_ExtensionManager {
continue;
}
$meta_raw_content = file_get_contents($metadata_filename) ?: '';
- /** @var array{'name':string,'entrypoint':string,'path':string,'author'?:string,'description'?:string,'version'?:string,'type'?:'system'|'user'}|null $meta_json */
+ /** @var ExtensionMetadata|null $meta_json */
$meta_json = json_decode($meta_raw_content, true);
if (!is_array($meta_json) || !self::isValidMetadata($meta_json)) {
// metadata.json is not a json file? Invalid!
@@ -109,8 +110,7 @@ final class Minz_ExtensionManager {
* If the extension class name is `TestExtension`, entry point will be `Test`.
* `entry_point` must be composed of alphanumeric characters.
*
- * @param array{'name':string,'entrypoint':string,'path':string,'author'?:string,'description'?:string,'version'?:string,'type'?:'system'|'user'} $meta
- * is an array of values.
+ * @param ExtensionMetadata $meta is an array of values.
* @return bool true if the array is valid, false else.
*/
private static function isValidMetadata(array $meta): bool {
@@ -121,8 +121,7 @@ final class Minz_ExtensionManager {
/**
* Load the extension source code based on info metadata.
*
- * @param array{'name':string,'entrypoint':string,'path':string,'author'?:string,'description'?:string,'version'?:string,'type'?:'system'|'user'} $info
- * an array containing information about extension.
+ * @param ExtensionMetadata $info an array containing information about extension.
* @return Minz_Extension|null an extension inheriting from Minz_Extension.
*/
private static function load(array $info): ?Minz_Extension {
diff --git a/p/themes/base-theme/frss.css b/p/themes/base-theme/frss.css
index 48c8147e3..856c94305 100644
--- a/p/themes/base-theme/frss.css
+++ b/p/themes/base-theme/frss.css
@@ -433,6 +433,10 @@ button.as-link[disabled] {
overflow-x: auto;
}
+.table-wrapper th {
+ white-space: nowrap;
+}
+
table {
margin: 0.5rem 0;
max-width: 100%;
diff --git a/p/themes/base-theme/frss.rtl.css b/p/themes/base-theme/frss.rtl.css
index e1cc66066..bdf964607 100644
--- a/p/themes/base-theme/frss.rtl.css
+++ b/p/themes/base-theme/frss.rtl.css
@@ -433,6 +433,10 @@ button.as-link[disabled] {
overflow-x: auto;
}
+.table-wrapper th {
+ white-space: nowrap;
+}
+
table {
margin: 0.5rem 0;
max-width: 100%;