aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--doku.php2
-rw-r--r--inc/infoutils.php15
-rw-r--r--lib/plugins/authldap/lang/cs/settings.php3
-rw-r--r--lib/plugins/config/lang/cs/lang.php6
-rw-r--r--lib/plugins/extension/Extension.php4
-rw-r--r--lib/plugins/extension/ExtensionApiResponse.php96
-rw-r--r--lib/plugins/extension/lang/cs/lang.php39
-rw-r--r--lib/plugins/extension/remote.php149
8 files changed, 294 insertions, 20 deletions
diff --git a/doku.php b/doku.php
index 919ba56ed..cb0a985eb 100644
--- a/doku.php
+++ b/doku.php
@@ -13,7 +13,7 @@ use dokuwiki\ChangeLog\PageChangeLog;
use dokuwiki\Extension\Event;
// update message version - always use a string to avoid localized floats!
-$updateVersion = "56";
+$updateVersion = "57";
// xdebug_start_profiling();
diff --git a/inc/infoutils.php b/inc/infoutils.php
index 6319b94d9..a25839282 100644
--- a/inc/infoutils.php
+++ b/inc/infoutils.php
@@ -184,7 +184,7 @@ function getRuntimeVersions()
if (getenv('KUBERNETES_SERVICE_HOST')) {
$data['container'] = 'Kubernetes';
- } elseif (file_exists('/.dockerenv')) {
+ } elseif (@file_exists('/.dockerenv')) {
$data['container'] = 'Docker';
}
@@ -199,14 +199,16 @@ function getRuntimeVersions()
*/
function getOsRelease()
{
+ $reader = fn($file) => @parse_ini_string(preg_replace('/#.*$/m', '', file_get_contents($file)));
+
$osRelease = [];
- if (file_exists('/etc/os-release')) {
+ if (@file_exists('/etc/os-release')) {
// pretty much any common Linux distribution has this
- $osRelease = parse_ini_file('/etc/os-release');
- } elseif (file_exists('/etc/synoinfo.conf') && file_exists('/etc/VERSION')) {
+ $osRelease = $reader('/etc/os-release');
+ } elseif (@file_exists('/etc/synoinfo.conf') && @file_exists('/etc/VERSION')) {
// Synology DSM has its own way
- $synoInfo = parse_ini_file('/usr/lib/synoinfo.conf');
- $synoVersion = parse_ini_file('/etc/VERSION');
+ $synoInfo = $reader('/etc/synoinfo.conf');
+ $synoVersion = $reader('/etc/VERSION');
$osRelease['NAME'] = 'Synology DSM';
$osRelease['ID'] = 'synology';
$osRelease['ID_LIKE'] = 'linux';
@@ -218,6 +220,7 @@ function getOsRelease()
return $osRelease;
}
+
/**
* Run a few sanity checks
*
diff --git a/lib/plugins/authldap/lang/cs/settings.php b/lib/plugins/authldap/lang/cs/settings.php
index 1bdaf29ba..19d41507f 100644
--- a/lib/plugins/authldap/lang/cs/settings.php
+++ b/lib/plugins/authldap/lang/cs/settings.php
@@ -3,7 +3,7 @@
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
- * @author Petr Kajzar <petr.kajzar@lf1.cuni.cz>
+ * @author Petr Kajzar <petr.kajzar@centrum.cz>
* @author mkucera66 <mkucera66@seznam.cz>
* @author Jaroslav Lichtblau <jlichtblau@seznam.cz>
* @author Martin Růžička <martinr@post.cz>
@@ -26,6 +26,7 @@ $lang['groupscope'] = 'Omezení rozsahu vyhledávání skupiny';
$lang['userkey'] = 'Atribut označující uživatelské jméno; musí být konzistetní s uživatelským filtrem.';
$lang['groupkey'] = 'Atribut členství uživatele ve skupinách (namísto standardních AD skupin), tj. skupina z oddělení nebo telefonní číslo';
$lang['modPass'] = 'Může být LDAP heslo změněno přes dokuwiki?';
+$lang['modPassPlain'] = 'Odesílat aktualizace hesel na server LDAP v prostém textu (namísto jejich zabezpečení nakonfigurovaným algoritmem před přenosem)?';
$lang['debug'] = 'Zobrazit dodatečné debugovací informace';
$lang['deref_o_0'] = 'LDAP_DEREF_NEVER';
$lang['deref_o_1'] = 'LDAP_DEREF_SEARCHING';
diff --git a/lib/plugins/config/lang/cs/lang.php b/lib/plugins/config/lang/cs/lang.php
index 8e1241ed7..f23e7c4a3 100644
--- a/lib/plugins/config/lang/cs/lang.php
+++ b/lib/plugins/config/lang/cs/lang.php
@@ -3,8 +3,8 @@
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
- * @author Martin Růžička <martinr@post.cz>
* @author Petr Kajzar <petr.kajzar@centrum.cz>
+ * @author Martin Růžička <martinr@post.cz>
* @author Aleksandr Selivanov <alexgearbox@yandex.ru>
* @author Robert Surý <rsurycz@seznam.cz>
* @author Martin Hořínek <hev@hev.cz>
@@ -141,6 +141,7 @@ $lang['mailreturnpath'] = 'E-mailová adresa příjemce pro oznámení o
$lang['mailprefix'] = 'Předpona předmětu e-mailu, která se bude používat pro automatické e-maily';
$lang['htmlmail'] = 'Posílat e-maily v HTML (hezčí ale větší). Při vypnutí budou posílány jen textové e-maily.';
$lang['dontlog'] = 'Zakázat protokolování pro tyto typy záznamů.';
+$lang['logretain'] = 'Kolik dní uchovávat protokoly.';
$lang['sitemap'] = 'Generovat Google sitemap (interval ve dnech)';
$lang['rss_type'] = 'Typ XML kanálu';
$lang['rss_linkto'] = 'XML kanál odkazuje na';
@@ -175,13 +176,14 @@ $lang['search_fragment_o_exact'] = 'přesný';
$lang['search_fragment_o_starts_with'] = 'začíná s';
$lang['search_fragment_o_ends_with'] = 'končí s';
$lang['search_fragment_o_contains'] = 'obsahuje';
-$lang['trustedproxy'] = 'Důvěřovat proxy serverům odpovídajícím tomuto regulárním výrazu ohledně skutečné IP adresy klienta, kterou hlásí. Výchozí hodnota odpovídá místním sítím. Ponechejte prázdné, pokud nechcete důvěřovat žádné proxy.';
$lang['_feature_flags'] = 'Feature flags';
$lang['defer_js'] = 'Odložit spuštění javascriptu až po zpracování HTML kódu stránky. Zlepšuje vnímanou rychlost načtení stránky, ale může narušit funkci některých zásuvných modulů.';
$lang['hidewarnings'] = 'Nezobrazovat žádná varování PHP. To může usnadnit přechod na PHP8+. Varování budou stále zaznamenána v protokolu chyb a měla by být hlášena.';
$lang['dnslookups'] = 'DokuWiki zjišťuje DNS jména pro vzdálené IP adresy uživatelů, kteří editují stránky. Pokud máte pomalý, nebo nefunkční DNS server, nebo nepotřebujete tuto funkci, tak tuto volbu zrušte.';
$lang['jquerycdn'] = 'Mají být skripty jQuery a jQuery UI načítány z CDN?
Vzniknou tím další HTTP dotazy, ale soubory se mohou načíst rychleji a uživatelé je už mohou mít ve vyrovnávací paměti.';
+$lang['trustedproxies'] = 'Čárkou oddělený seznam důvěryhodných proxy serverů, ze kterých se načítá hlavička X-Forwarded-For. Každá položka v poli může být buď adresa IPv4 nebo IPv6, nebo rozsah IPv4 nebo IPv6 CIDR (např. 10.0.0.0/8). Pokud nechcete důvěřovat žádnému proxy serveru, ponechte prázdné pole.';
+$lang['realip'] = 'Důvěřovat záhlaví X-Real-IP. Tuto funkci povolte pouze v případě, že váš server tuto hlavičku zapisuje, jinak může dojít k jejímu podvržení.';
$lang['jquerycdn_o_0'] = 'Bez CDN, pouze lokální doručení';
$lang['jquerycdn_o_jquery'] = 'CDN na code.jquery.com';
$lang['jquerycdn_o_cdnjs'] = 'CDN na cdnjs.com';
diff --git a/lib/plugins/extension/Extension.php b/lib/plugins/extension/Extension.php
index 763b348c2..6de7a92f6 100644
--- a/lib/plugins/extension/Extension.php
+++ b/lib/plugins/extension/Extension.php
@@ -507,7 +507,9 @@ class Extension
{
$last = $this->getManager()->getDownloadURL();
if (!$last) return false;
- return $last !== $this->getDownloadURL();
+ $url = $this->getDownloadURL();
+ if (!$url) return false;
+ return $last !== $url;
}
/**
diff --git a/lib/plugins/extension/ExtensionApiResponse.php b/lib/plugins/extension/ExtensionApiResponse.php
new file mode 100644
index 000000000..c684e770f
--- /dev/null
+++ b/lib/plugins/extension/ExtensionApiResponse.php
@@ -0,0 +1,96 @@
+<?php
+
+namespace dokuwiki\plugin\extension;
+
+use dokuwiki\Remote\Response\ApiResponse;
+
+class ExtensionApiResponse extends ApiResponse
+{
+ protected Extension $extension;
+
+ /** @var string The type of this extension ("plugin" or "template") */
+ public $type;
+
+ /** @var string The id of this extension (templates are prefixed with "template") */
+ public $id;
+
+ /** @var string The base name of this extension */
+ public $base;
+
+ /** @var string The display name of this extension */
+ public $name;
+
+ /** @var string The installed version/date of this extension */
+ public $version;
+
+ /** @var string The author of this extension */
+ public $author;
+
+ /** @var string The description of this extension */
+ public $description;
+
+ /** @var bool Whether this extension is installed */
+ public $isInstalled;
+
+ /** @var bool Whether this extension is enabled */
+ public $isEnabled;
+
+ /** @var bool Whether an update is available */
+ public $updateAvailable;
+
+ /** @var bool Whether this extension is bundled with DokuWiki */
+ public $isBundled;
+
+ /** @var bool Whether this extension is under git control */
+ public $isGitControlled;
+
+ /** @var string[] Notices for this extension */
+ public $notices;
+
+ /** @var string Documentation URL for this extension */
+ public $url;
+
+ /** @var string[] The component types this plugin provides */
+ public $componentTypes;
+
+ /** @var string The last available remote update date */
+ public $lastUpdate;
+
+ /** @var string The download URL for this extension */
+ public string $downloadURL;
+
+ /**
+ * Constructor
+ *
+ * @param Extension $extension The extension to create the response for
+ */
+ public function __construct(Extension $extension)
+ {
+ $this->extension = $extension;
+ $this->type = $extension->getType();
+ $this->id = $extension->getId();
+ $this->base = $extension->getBase();
+ $this->name = $extension->getDisplayName();
+ $this->version = $extension->getInstalledVersion();
+ $this->author = $extension->getAuthor();
+ $this->description = $extension->getDescription();
+ $this->isInstalled = $extension->isInstalled();
+ $this->isEnabled = $extension->isEnabled();
+ $this->updateAvailable = $extension->isUpdateAvailable();
+ $this->isBundled = $extension->isBundled();
+ $this->isGitControlled = $extension->isGitControlled();
+ $this->componentTypes = $extension->getComponentTypes();
+ $this->lastUpdate = $extension->getLastUpdate();
+ $this->url = $extension->getURL();
+ $this->downloadURL = $extension->getDownloadURL();
+
+ // Add notices
+ $this->notices = array_merge(...array_values(Notice::list($extension)));
+ }
+
+ /** @inheritdoc */
+ public function __toString()
+ {
+ return $this->extension->getId();
+ }
+}
diff --git a/lib/plugins/extension/lang/cs/lang.php b/lib/plugins/extension/lang/cs/lang.php
index 3a1dc48ac..8cf586d5a 100644
--- a/lib/plugins/extension/lang/cs/lang.php
+++ b/lib/plugins/extension/lang/cs/lang.php
@@ -3,9 +3,9 @@
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
+ * @author Petr Kajzar <petr.kajzar@centrum.cz>
* @author Tomáš Heger <heger.tomas@gmail.com>
* @author Martin Růžička <martinr@post.cz>
- * @author Petr Kajzar <petr.kajzar@lf1.cuni.cz>
* @author Viktor Zavadil <vzavadil@newps.cz>
* @author Jaroslav Lichtblau <jlichtblau@seznam.cz>
* @author Turkislav <turkislav@blabla.com>
@@ -16,9 +16,6 @@ $lang['tab_templates'] = 'Instalované šablony';
$lang['tab_search'] = 'Vyhledat a instalovat';
$lang['tab_install'] = 'Ruční instalace';
$lang['notimplemented'] = 'Tato vychytávka není dosud implementována';
-$lang['notinstalled'] = 'Toto rozšíření není instalováno';
-$lang['alreadyenabled'] = 'Toto rozšíření je již povoleno';
-$lang['alreadydisabled'] = 'Toto rozšíření je již vypnuto';
$lang['pluginlistsaveerror'] = 'Došlo k chybě při ukládání seznamu zásuvných modulů';
$lang['unknownauthor'] = 'Neznámý autor';
$lang['unknownversion'] = 'Neznámá verze';
@@ -34,6 +31,8 @@ $lang['js']['display_viewoptions'] = 'Zobrazit možnosti:';
$lang['js']['display_enabled'] = 'povolené';
$lang['js']['display_disabled'] = 'zakázané';
$lang['js']['display_updatable'] = 'aktualizovatelné';
+$lang['js']['close'] = 'Kliknutím zavřete';
+$lang['js']['filter'] = 'Zobrazit pouze aktualizovatelná rozšíření';
$lang['search_for'] = 'Hledat rozšíření:';
$lang['search'] = 'Hledat';
$lang['extensionby'] = '<strong>%s</strong> od %s';
@@ -72,23 +71,40 @@ $lang['msg_enabled'] = 'Zásuvný modul %s povolen';
$lang['msg_disabled'] = 'Zásuvný modul %s zakázán';
$lang['msg_delete_success'] = 'Rozšíření %s odinstalováno';
$lang['msg_delete_failed'] = 'Odinstalování rozšíření %s selhalo';
-$lang['msg_template_install_success'] = 'Šablona %s úspěšně nainstalována';
-$lang['msg_template_update_success'] = 'Šablona %s úspěšně aktualizována';
-$lang['msg_plugin_install_success'] = 'Zásuvný modul %s úspěšně nainstalován.';
-$lang['msg_plugin_update_success'] = 'Zásuvný modul %s úspěšně aktualizován.';
+$lang['msg_install_success'] = 'Rozšíření %s bylo úspěšně nainstalováno';
+$lang['msg_update_success'] = 'Rozšíření %s bylo úspěšně aktualizováno';
$lang['msg_upload_failed'] = 'Nahrávání souboru selhalo';
$lang['msg_nooverwrite'] = 'Rozšíření %s již existuje, proto nebylo přepsáno; pro přepsání zatrhněte příslušnou možnost';
$lang['missing_dependency'] = 'Chybějící nebo zakázaná závislost: %s';
+$lang['found_conflict'] = 'Toto rozšíření je označeno jako konfliktní s následujícími nainstalovanými rozšířeními: %s';
$lang['security_issue'] = 'Bezpečnostní problém: %s';
$lang['security_warning'] = 'Bezpečnostní varování: %s';
+$lang['update_message'] = 'Aktualizační zpráva: %s';
$lang['wrong_folder'] = 'Zásuvný modul nesprávně nainstalován: Přejmenujte adresář modulu "%s" na "%s".';
-$lang['url_change'] = "URL se změnila: URL pro stahování se změnila od poslední aktualizace. Před další aktualizací tohoto rozšíření ověřte správnost nové URL.\nNová: %s\nStará: %s";
+$lang['url_change'] = 'URL se změnila: URL pro stahování se změnila od poslední aktualizace. Před další aktualizací tohoto rozšíření ověřte správnost nové URL.
+Nová: %s
+Stará: %s';
$lang['error_badurl'] = 'Adresy URL by měly začínat s http nebo https';
$lang['error_dircreate'] = 'Nelze vytvořit dočasný adresář pro přijetí stahování';
$lang['error_download'] = 'Nelze stáhnout soubor: %s';
$lang['error_decompress'] = 'Selhalo rozbalení staženého souboru. Toto je nejspíš důsledek poškození souboru při přenosu, zkuste soubor stáhnout znovu; případně nemusel být rozpoznán formát sbaleného souboru a bude třeba přistoupit k ruční instalaci. ';
$lang['error_findfolder'] = 'Nelze rozpoznat adresář pro rozšíření, je třeba stáhnout a instalovat ručně';
$lang['error_copy'] = 'Došlo k chybě kopírování souborů při pokusu nainstalovat soubory do adresáře <em>%s</em>: může být plný disk nebo špatně nastavena přístupová práva. Tato chyba mohla zapříčinit pouze částečnou instalaci zásuvného modulu a uvést wiki do nestabilního stavu.';
+$lang['error_copy_read'] = 'Nepodařilo se načíst adresář %s';
+$lang['error_copy_mkdir'] = 'Nepodařilo se vytvořit adresář %s';
+$lang['error_copy_copy'] = 'Nepodařilo se zkopírovat %s do %s';
+$lang['error_archive_read'] = 'Nepodařilo se otevřít archiv %s pro čtení';
+$lang['error_archive_extract'] = 'Nepodařilo se rozbalit archiv %s: %s';
+$lang['error_uninstall_protected'] = 'Rozšíření %s je chráněno a nelze jej odinstalovat';
+$lang['error_uninstall_dependants'] = 'Rozšíření %s je stále vyžadováno %s, a proto jej nelze odinstalovat';
+$lang['error_disable_protected'] = 'Rozšíření %s je chráněno a nelze jej zakázat';
+$lang['error_disable_dependants'] = 'Rozšíření %s je stále vyžadováno %s, a proto jej nelze zakázat';
+$lang['error_nourl'] = 'Pro rozšíření %s nebyla nalezena žádná adresa URL pro stahování';
+$lang['error_notinstalled'] = 'Rozšíření %s není nainstalováno';
+$lang['error_alreadyenabled'] = 'Rozšíření %s již bylo povoleno';
+$lang['error_alreadydisabled'] = 'Rozšíření %s již bylo zakázáno';
+$lang['error_minphp'] = 'Rozšíření %s vyžaduje alespoň PHP %s, ale tato wiki používá PHP %s.';
+$lang['error_maxphp'] = 'Rozšíření %s podporuje pouze PHP do %s, ale tato wiki používá PHP %s.';
$lang['noperms'] = 'Nelze zapisovat do adresáře pro rozšíření';
$lang['notplperms'] = 'Nelze zapisovat do odkládacího adresáře';
$lang['nopluginperms'] = 'Nelze zapisovat do adresáře se zásuvnými moduly';
@@ -96,5 +112,10 @@ $lang['git'] = 'Toto rozšíření bylo nainstalováno přes g
$lang['auth'] = 'Tento ověřovací zásuvný modul není povolen v nastavení, zvažte jeho deaktivaci.';
$lang['install_url'] = 'Nainstalovat z URL:';
$lang['install_upload'] = 'Nahrát rozšíření:';
+$lang['repo_badresponse'] = 'Úložiště zásuvných modulů vrátilo neplatnou odpověď.';
$lang['repo_error'] = 'Nelze kontaktovat repozitář se zásuvnými moduly. Ujistěte se, že váš server může kontaktovat www.dokuwiki.org a zkontrolujte nastavení proxy.';
$lang['nossl'] = 'Použité PHP pravděpodobně nepodporuje SSL. Stažení mnoha DokuWiki rozšíření nebude fungovat.';
+$lang['popularity_high'] = 'Toto je jedno z nejoblíbenějších rozšíření';
+$lang['popularity_medium'] = 'Toto rozšíření je poměrně oblíbené';
+$lang['popularity_low'] = 'Toto rozšíření vzbudilo určitý zájem';
+$lang['details'] = 'Podrobnosti';
diff --git a/lib/plugins/extension/remote.php b/lib/plugins/extension/remote.php
new file mode 100644
index 000000000..4eb84a829
--- /dev/null
+++ b/lib/plugins/extension/remote.php
@@ -0,0 +1,149 @@
+<?php
+
+use dokuwiki\Extension\RemotePlugin;
+use dokuwiki\plugin\extension\Extension;
+use dokuwiki\plugin\extension\ExtensionApiResponse;
+use dokuwiki\plugin\extension\Installer;
+use dokuwiki\plugin\extension\Local;
+use dokuwiki\plugin\extension\Repository;
+use dokuwiki\Remote\AccessDeniedException;
+
+/**
+ * DokuWiki Plugin extension (Remote Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class remote_plugin_extension extends RemotePlugin
+{
+ /**
+ * List installed extensions
+ *
+ * This lists all installed extensions. The list is not sorted in any way.
+ *
+ * @return ExtensionApiResponse[] The list of installed extensions and their details
+ */
+ public function list()
+ {
+ if (!auth_isadmin()) {
+ throw new AccessDeniedException('Only admins are allowed to access extensions', 114);
+ }
+
+ $extensions = (new Local())->getExtensions();
+ Repository::getInstance()->initExtensions(array_keys($extensions));
+
+ return array_values(
+ array_map(
+ static fn($extension) => new ExtensionApiResponse($extension),
+ $extensions
+ )
+ );
+ }
+
+ /**
+ * Search for extensions in the repository
+ *
+ * @param string $query The keyword(s) to search for
+ * @param int $max Maximum number of results (default 10)
+ * @return ExtensionApiResponse[] List of matching extensions
+ */
+ public function search($query, $max = 10)
+ {
+ if (!auth_isadmin()) {
+ throw new AccessDeniedException('Only admins are allowed to access extensions', 114);
+ }
+
+ $repo = Repository::getInstance();
+ $result = $repo->searchExtensions($query);
+
+ if ($max > 0) {
+ $result = array_slice($result, 0, $max);
+ }
+
+ return array_values(
+ array_map(
+ static fn($extension) => new ExtensionApiResponse($extension),
+ $result
+ )
+ );
+ }
+
+ /**
+ * Enable a specific extension
+ *
+ * @param string $extension Extension ID to enable
+ * @return bool Success status
+ */
+ public function enable($extension)
+ {
+ if (!auth_isadmin()) {
+ throw new AccessDeniedException('Only admins are allowed to manage extensions', 114);
+ }
+
+ $ext = Extension::createFromId($extension);
+ $ext->enable();
+ return true;
+ }
+
+ /**
+ * Disable a specific extension
+ *
+ * @param string $extension Extension ID to disable
+ * @return bool Success status
+ */
+ public function disable($extension)
+ {
+ if (!auth_isadmin()) {
+ throw new AccessDeniedException('Only admins are allowed to manage extensions', 114);
+ }
+
+ $ext = Extension::createFromId($extension);
+ $ext->disable();
+ return true;
+ }
+
+ /**
+ * Install a specific extension
+ *
+ * This will also install dependencies, so more than the given extension may be installed.
+ *
+ * @param string $extension Extension ID or download URL
+ * @return string[] List of installed extensions
+ */
+ public function install($extension)
+ {
+ if (!auth_isadmin()) {
+ throw new AccessDeniedException('Only admins are allowed to manage extensions', 114);
+ }
+
+ $installer = new Installer(true);
+ $installer->installFromId($extension);
+
+ return array_keys(
+ array_filter(
+ $installer->getProcessed(),
+ static fn($status) => (
+ $status == Installer::STATUS_INSTALLED || $status == Installer::STATUS_UPDATED
+ )
+ )
+ );
+ }
+
+ /**
+ * Uninstall a specific extension
+ *
+ * @param string $extension Extension ID to uninstall
+ * @return bool Success status
+ */
+ public function uninstall($extension)
+ {
+ if (!auth_isadmin()) {
+ throw new AccessDeniedException('Only admins are allowed to manage extensions', 114);
+ }
+
+ $ext = Extension::createFromId($extension);
+ $installer = new Installer();
+ $installer->uninstall($ext);
+ return true;
+ }
+}