From e48108e0c993978378676733573f351e720345ac Mon Sep 17 00:00:00 2001 From: Michael Gasperini <163041857+TheStreamCode@users.noreply.github.com> Date: Wed, 28 Oct 2026 21:32:12 +0100 Subject: [PATCH 1/2] fix(i18n): correct relative-time and email translations and Italian terminology Render the elapsed-time suffix with sprintf('%s ago') so French, Spanish, and German can place the time before the marker, add the missing preposition in the Italian and French email subjects, use a valid German compound, and correct the French folder-move message. Align the four localized READMEs with the 3.5.0 fail-closed storage behavior and standardize Italian terminology (archiviazione, elenco, Gestione file). Regenerate the POT with wp i18n make-pot so it includes the missing notification string and current file:line references. --- README.de.md | 4 +- README.es.md | 4 +- README.fr.md | 4 +- README.it.md | 4 +- includes/class-mstv-helpers.php | 6 +- includes/class-mstv-i18n.php | 46 +-- languages/mikesoft-teamvault.pot | 641 ++++++++++++++++--------------- 7 files changed, 364 insertions(+), 345 deletions(-) diff --git a/README.de.md b/README.de.md index 46143de..93afb39 100644 --- a/README.de.md +++ b/README.de.md @@ -86,8 +86,8 @@ Private Dateien werden nie über öffentliche Medien-URLs ausgeliefert: Download - Der optionale Whitelist-Modus fügt eine zweite Autorisierungsebene für ausgewählte Benutzer hinzu. - Ordnerberechtigungen beschränken den Zugriff auf die gewährten Benutzer, Gruppen und Aktionen, mit Vererbung von übergeordneten Ordnern. Ordner ohne Regeln behalten das capability-basierte Verhalten, und Administratoren behalten immer vollen Zugriff. - Einstellungen, Gruppen, Kontingente, Benachrichtigungen, Berichte, Protokolle, Whitelist-Verwaltung, Wartungswerkzeuge und Datenkontrollen bei der Deinstallation erfordern `manage_options`. -- Der Standardspeicher ist `wp-content/uploads/private-documents/` und wird durch serverseitige Deny-Dateien geschützt: die generierte `.htaccess` unter Apache und LiteSpeed, die `web.config` unter IIS und eine äquivalente Nginx-Regel, die direkte Anfragen an diesen Pfad verweigert. -- Für besonders sensible Deployments ist ein eigener Speicherpfad außerhalb des öffentlichen Webroots zu bevorzugen. Das Speicher-Widget zeigt nur die Nutzung durch TeamVault. +- Der Standardspeicher ist `wp-content/uploads/private-documents/` und wird durch serverseitige Deny-Dateien geschützt: die generierte `.htaccess` unter Apache und LiteSpeed, die `web.config` unter IIS und eine äquivalente Nginx-Regel, die direkte Anfragen verweigert. Uploads werden abgelehnt, wenn diese Dateien nicht erstellt werden können. +- Empfohlen: ein eigener Speicherpfad außerhalb des öffentlichen Webroots, insbesondere bei Nginx, das `.htaccess` ignoriert. Das Speicher-Widget zeigt nur die Nutzung durch TeamVault. Siehe [`SECURITY.md`](SECURITY.md) für die Meldung von Schwachstellen. diff --git a/README.es.md b/README.es.md index fe4520b..0fe0e62 100644 --- a/README.es.md +++ b/README.es.md @@ -86,8 +86,8 @@ Los archivos privados nunca se sirven mediante URL públicas de medios: las desc - La lista de permitidos opcional añade una segunda capa de autorización para los usuarios seleccionados. - Los permisos por carpeta limitan el acceso a los usuarios, grupos y acciones concedidos, con herencia desde las carpetas principales. Las carpetas sin reglas mantienen el comportamiento basado en la capability, y los administradores conservan siempre el acceso completo. - Los ajustes, grupos, cuotas, notificaciones, informes, registros, gestión de la lista de permitidos, herramientas de mantenimiento y controles de datos al desinstalar requieren `manage_options`. -- El almacenamiento predeterminado es `wp-content/uploads/private-documents/` y está protegido con archivos de denegación a nivel de servidor: el archivo `.htaccess` generado en Apache y LiteSpeed, el archivo `web.config` en IIS y una regla Nginx equivalente que deniega las solicitudes directas a esa ruta. -- Para despliegues de alta sensibilidad, prefiere una ruta de almacenamiento personalizada fuera de la raíz web pública. El widget de almacenamiento muestra solo el uso de TeamVault. +- El almacenamiento predeterminado es `wp-content/uploads/private-documents/` y está protegido con archivos de denegación a nivel de servidor: el archivo `.htaccess` generado en Apache y LiteSpeed, el archivo `web.config` en IIS y una regla Nginx equivalente que deniega las solicitudes directas. Las subidas se rechazan cuando estos archivos no se pueden crear. +- Recomendado: una ruta de almacenamiento personalizada fuera de la raíz web pública, especialmente en Nginx, que ignora `.htaccess`. El widget de almacenamiento muestra solo el uso de TeamVault. Consulta [`SECURITY.md`](SECURITY.md) para reportar vulnerabilidades. diff --git a/README.fr.md b/README.fr.md index e40b189..c3969ea 100644 --- a/README.fr.md +++ b/README.fr.md @@ -86,8 +86,8 @@ Les fichiers privés ne sont jamais servis par des URL de médias publiques : le - La liste d'autorisation facultative ajoute une seconde couche d'autorisation pour les utilisateurs sélectionnés. - Les autorisations par dossier limitent l'accès aux utilisateurs, groupes et actions accordés, avec héritage depuis les dossiers parents. Les dossiers sans règles conservent le comportement basé sur la capacité, et les administrateurs conservent toujours un accès complet. - Les réglages, groupes, quotas, notifications, rapports, journaux, gestion de la liste d'autorisation, outils de maintenance et contrôles des données à la désinstallation exigent `manage_options`. -- Le stockage par défaut est `wp-content/uploads/private-documents/` et il est protégé par des fichiers de refus au niveau du serveur : le fichier `.htaccess` généré sur Apache et LiteSpeed, le fichier `web.config` sur IIS et une règle Nginx équivalente qui refuse les requêtes directes vers ce chemin. -- Pour les déploiements à haute sensibilité, préférez un chemin de stockage personnalisé en dehors de la racine web publique. Le widget de stockage affiche uniquement l'utilisation de TeamVault. +- Le stockage par défaut est `wp-content/uploads/private-documents/` et il est protégé par des fichiers de refus au niveau du serveur : le fichier `.htaccess` généré sur Apache et LiteSpeed, le fichier `web.config` sur IIS et une règle Nginx équivalente qui refuse les requêtes directes. Les téléversements sont refusés lorsque ces fichiers ne peuvent pas être créés. +- Recommandé : un chemin de stockage personnalisé en dehors de la racine web publique, en particulier sur Nginx, qui ignore `.htaccess`. Le widget de stockage affiche uniquement l'utilisation de TeamVault. Consultez [`SECURITY.md`](SECURITY.md) pour signaler une vulnérabilité. diff --git a/README.it.md b/README.it.md index 7d743b0..d50f0df 100644 --- a/README.it.md +++ b/README.it.md @@ -86,8 +86,8 @@ I file privati non vengono mai serviti tramite URL pubblici dei media: download - La modalità whitelist opzionale aggiunge un secondo livello di autorizzazione per gli utenti selezionati. - I permessi per cartella limitano l'accesso agli utenti, ai gruppi e alle azioni concessi, con ereditarietà dalle cartelle padre. Le cartelle senza regole mantengono il comportamento basato sulla capability e gli Amministratori conservano sempre l'accesso completo. - Impostazioni, gruppi, quote, notifiche, report, registri, gestione della whitelist, strumenti di manutenzione e controlli sui dati alla disinstallazione richiedono `manage_options`. -- L'archiviazione predefinita è `wp-content/uploads/private-documents/` ed è protetta con file di deny a livello di server: il file `.htaccess` generato su Apache e LiteSpeed, il file `web.config` su IIS e una regola Nginx equivalente che nega le richieste dirette a quel percorso. -- Per installazioni ad alta sensibilità, preferisci un percorso di archiviazione personalizzato all'esterno della webroot pubblica. Il widget di archiviazione mostra solo l'utilizzo di TeamVault. +- L'archiviazione predefinita è `wp-content/uploads/private-documents/` ed è protetta con file di deny a livello di server: il file `.htaccess` generato su Apache e LiteSpeed, il file `web.config` su IIS e una regola Nginx equivalente che nega le richieste dirette. I caricamenti vengono rifiutati quando questi file non possono essere creati. +- Consigliato: un percorso di archiviazione personalizzato all'esterno della webroot pubblica, soprattutto su Nginx, che ignora `.htaccess`. Il widget di archiviazione mostra solo l'utilizzo di TeamVault. Consulta [`SECURITY.md`](SECURITY.md) per le segnalazioni di vulnerabilità. diff --git a/includes/class-mstv-helpers.php b/includes/class-mstv-helpers.php index 0378c2c..cfa34f7 100644 --- a/includes/class-mstv-helpers.php +++ b/includes/class-mstv-helpers.php @@ -180,7 +180,11 @@ public static function human_time_diff_mysql(string $mysqlTime): string if ($time === false) { return ''; } - return human_time_diff($time, time()) . ' ' . __('ago', 'mikesoft-teamvault'); + return sprintf( + /* translators: %s: time elapsed, for example "5 mins". */ + __('%s ago', 'mikesoft-teamvault'), + human_time_diff($time, time()) + ); } public static function build_breadcrumb(array $folders, int $currentFolderId): array diff --git a/includes/class-mstv-i18n.php b/includes/class-mstv-i18n.php index c7f7298..c7dbd10 100644 --- a/includes/class-mstv-i18n.php +++ b/includes/class-mstv-i18n.php @@ -34,7 +34,7 @@ class MSTV_I18n 'Save notifications' => 'Salva notifiche', 'Specific users' => 'Utenti specifici', 'Uploaded: %s' => 'Caricato: %s', - '[%1$s] TeamVault: %2$d %3$s event(s)' => '[%1$s] TeamVault: %2$d evento/i %3$s', + '[%1$s] TeamVault: %2$d %3$s event(s)' => '[%1$s] TeamVault: %2$d evento/i di %3$s', 'access denied' => 'accesso negato', 'delete' => 'eliminazione', 'download' => 'download', @@ -98,7 +98,7 @@ class MSTV_I18n 'Action' => 'Azione', 'Activity Log' => 'Log Attività', 'Add your current account to the whitelist before enabling it, otherwise you will lock yourself out.' => 'Aggiungi il tuo account corrente alla whitelist prima di abilitarla, altrimenti resterai bloccato fuori.', - 'ago' => 'fa', + '%s ago' => '%s fa', 'Allowed extensions' => 'Estensioni consentite', 'An error occurred. Please try again.' => 'Si è verificato un errore. Riprova.', 'Your session has expired. Reload the page to continue.' => 'La sessione è scaduta. Ricarica la pagina per continuare.', @@ -116,7 +116,7 @@ class MSTV_I18n 'Choose the plugin interface language. Automatic follows the WordPress language.' => 'Scegli la lingua dell\'interfaccia del plugin. Automatica segue la lingua di WordPress.', 'Close' => 'Chiudi', 'Collapse' => 'Comprimi', - 'Comma-separated list of allowed file extensions for upload.' => 'Lista delle estensioni file consentite per il caricamento, separate da virgola.', + 'Comma-separated list of allowed file extensions for upload.' => 'Elenco delle estensioni file consentite per il caricamento, separate da virgola.', 'Configure the plugin options for private document management.' => 'Configura le opzioni del plugin per la gestione dei documenti privati.', 'Confirm' => 'Conferma', 'Contains subfolders' => 'Contiene sottocartelle', @@ -159,16 +159,16 @@ class MSTV_I18n 'The file name contains multiple extensions, which is not allowed for security reasons.' => 'Il nome del file contiene più estensioni, non consentito per motivi di sicurezza.', 'The file is too large (%1$s). The maximum allowed size is %2$s.' => 'Il file è troppo grande (%1$s). La dimensione massima consentita è %2$s.', 'File' => 'File', - 'File Manager' => 'File Manager', + 'File Manager' => 'Gestione file', 'Files' => 'File', 'File moved successfully.' => 'File spostato con successo.', 'Folder moved successfully.' => 'Cartella spostata con successo.', 'File not found in the filesystem.' => 'File non trovato nel filesystem.', 'File not found.' => 'File non trovato.', 'File uploaded successfully.' => 'File caricato con successo.', - 'File missing from storage' => 'File mancante nello storage', + 'File missing from storage' => 'File mancante nell\'archiviazione', 'Filter' => 'Filtra', - 'Found %d database records whose files are missing from the private storage directory.' => 'Trovati %d record nel database i cui file sono mancanti nella directory di storage privata.', + 'Found %d database records whose files are missing from the private storage directory.' => 'Trovati %d record nel database i cui file sono mancanti nella directory di archiviazione privata.', 'files' => 'file', 'Folder' => 'Cartella', 'Folder already exists.' => 'Cartella già esistente.', @@ -180,7 +180,7 @@ class MSTV_I18n 'Grid view' => 'Vista griglia', 'History of operations performed on private documents.' => 'Storico delle operazioni effettuate sui documenti privati.', 'Home' => 'Home', - 'If enabled, users still need the plugin capability and must also be present in this list. Include your current account before saving to avoid locking yourself out.' => 'Se abilitato, gli utenti devono comunque avere la capability del plugin ed essere presenti in questa lista. Includi il tuo account corrente prima di salvare per evitare di restare bloccato fuori.', + 'If enabled, users still need the plugin capability and must also be present in this list. Include your current account before saving to avoid locking yourself out.' => 'Se abilitato, gli utenti devono comunque avere la capability del plugin ed essere presenti in questo elenco. Includi il tuo account corrente prima di salvare per evitare di restare bloccato fuori.', 'If enabled, PDFs will be displayed directly in the browser. Some browsers may not support this feature.' => 'Se abilitato, i PDF verranno visualizzati direttamente nel browser. Alcuni browser potrebbero non supportare questa funzione.', 'If enabled, uninstalling the plugin will remove all files, folders, logs and settings. This action is irreversible.' => 'Se abilitato, quando il plugin viene disinstallato verranno eliminati tutti i file, le cartelle, i log e le impostazioni. Questa azione è irreversibile.', 'Information' => 'Informazioni', @@ -193,14 +193,14 @@ class MSTV_I18n 'IP' => 'IP', 'Italian' => 'Italiano', 'Item deleted successfully.' => 'Elemento eliminato con successo.', - 'List view' => 'Vista lista', + 'List view' => 'Vista elenco', 'Loading...' => 'Caricamento...', 'Log' => 'Log', 'Maintenance' => 'Manutenzione', 'Maximum file size (bytes)' => 'Dimensione massima file (byte)', 'Maximum size allowed for each file.' => 'Dimensione massima consentita per ogni file.', 'Missing' => 'Mancante', - 'Missing from storage' => 'Mancante nello storage', + 'Missing from storage' => 'Mancante nell\'archiviazione', 'Missing security token.' => 'Token di sicurezza mancante.', 'Move' => 'Sposta', 'Move to...' => 'Sposta in...', @@ -233,7 +233,7 @@ class MSTV_I18n 'This server runs Nginx, which ignores .htaccess. Confirm that a server rule denies direct requests to the private storage directory, or set a custom storage path outside the public webroot (recommended).' => 'Questo server usa Nginx, che ignora .htaccess. Verifica che una regola del server neghi le richieste dirette alla directory di archiviazione privata, oppure imposta un percorso di archiviazione personalizzato all\'esterno della webroot pubblica (consigliato).', 'Upload refused: TeamVault could not create the protection files (%s) in the private storage directory. Make the directory writable, or use a storage path outside the public webroot, then retry.' => 'Caricamento rifiutato: TeamVault non ha potuto creare i file di protezione (%s) nella directory di archiviazione privata. Rendi la directory scrivibile, oppure usa un percorso di archiviazione all\'esterno della webroot pubblica, poi riprova.', 'directory not writable' => 'directory non scrivibile', - 'Reindex storage' => 'Reindicizza storage', + 'Reindex storage' => 'Reindicizza archiviazione', 'Restore folder and file records that still exist on disk but are missing from the database.' => 'Ripristina i record di cartelle e file che esistono ancora sul disco ma mancano nel database.', 'Record upload, download, delete and move operations for files.' => 'Registra le operazioni di upload, download, eliminazione e spostamento dei file.', 'Remove' => 'Rimuovi', @@ -254,13 +254,13 @@ class MSTV_I18n 'Skipped %d unsafe or disallowed files.' => 'Saltati %d file non sicuri o non consentiti.', 'Sort by' => 'Ordina per', 'Status' => 'Stato', - 'Storage directory:' => 'Directory storage:', + 'Storage directory:' => 'Directory di archiviazione:', 'Storage' => 'Archiviazione', 'Server limit:' => 'Limite server:', 'Used by TeamVault' => 'Usato da TeamVault', 'Other usage' => 'Altro utilizzo', 'Capacity' => 'Capacità', - 'This record exists in the database, but the binary file is missing from the private storage directory.' => 'Questo record esiste nel database, ma il file binario manca nella directory di storage privata.', + 'This record exists in the database, but the binary file is missing from the private storage directory.' => 'Questo record esiste nel database, ma il file binario manca nella directory di archiviazione privata.', 'Temporary folder is missing.' => 'Cartella temporanea mancante.', 'TeamVault' => 'TeamVault', 'The file contains PHP code.' => 'Il file contiene codice PHP.', @@ -290,7 +290,7 @@ class MSTV_I18n 'Total' => 'Totale', 'Try a different keyword or clear the search.' => 'Prova una parola chiave diversa o cancella la ricerca.', 'Type' => 'Tipo', - 'Unable to initialize the storage directory.' => 'Impossibile inizializzare la directory di storage.', + 'Unable to initialize the storage directory.' => 'Impossibile inizializzare la directory di archiviazione.', 'Unable to create the folder.' => 'Impossibile creare la cartella.', 'Unable to create the ZIP file.' => 'Impossibile creare il file ZIP.', 'Unable to delete the folder from the filesystem.' => 'Impossibile eliminare la cartella dal filesystem.', @@ -306,7 +306,7 @@ class MSTV_I18n 'Unauthorized access. Please log in.' => 'Accesso non autorizzato. Effettua il login.', 'Uninstall' => 'Disinstallazione', 'Unknown upload error.' => 'Errore sconosciuto durante il caricamento.', - 'Use cleanup after a local migration if the private storage folder was not copied.' => 'Usa la pulizia dopo una migrazione locale se la cartella di storage privata non è stata copiata.', + 'Use cleanup after a local migration if the private storage folder was not copied.' => 'Usa la pulizia dopo una migrazione locale se la cartella di archiviazione privata non è stata copiata.', 'User Access' => 'Accesso utenti', 'Limit access to specific users' => 'Limita l\'accesso a utenti specifici', 'Upload' => 'Carica', @@ -314,13 +314,13 @@ class MSTV_I18n 'Upload stopped by a PHP extension.' => 'Caricamento interrotto da un\'estensione PHP.', 'Used' => 'Usato', 'User' => 'Utente', - 'User is already in the list' => 'Utente già presente nella lista', + 'User is already in the list' => 'Utente già presente nell\'elenco', 'User not found' => 'Utente non trovato', 'Warning:' => 'Attenzione:', 'Cleanup completed. Removed %d orphaned file records.' => 'Pulizia completata. Rimossi %d record file orfani.', 'Clean orphaned records' => 'Pulisci record orfani', - 'Reindex completed. Restored %1$d folders and %2$d files from storage.' => 'Reindicizzazione completata. Ripristinate %1$d cartelle e %2$d file dallo storage.', - 'Use this after an incomplete uninstall or a migration where the storage directory remained available.' => 'Usa questa funzione dopo una disinstallazione incompleta o una migrazione in cui la directory di storage è rimasta disponibile.', + 'Reindex completed. Restored %1$d folders and %2$d files from storage.' => 'Reindicizzazione completata. Ripristinate %1$d cartelle e %2$d file dall\'archiviazione.', + 'Use this after an incomplete uninstall or a migration where the storage directory remained available.' => 'Usa questa funzione dopo una disinstallazione incompleta o una migrazione in cui la directory di archiviazione è rimasta disponibile.', 'You do not have permission to access this page.' => 'Non hai i permessi per accedere a questa pagina.', 'You do not have permission to access this resource.' => 'Non hai i permessi necessari per accedere a questa risorsa.', 'ZipArchive is not available on this server. Contact the server administrator.' => 'ZipArchive non è disponibile su questo server. Contatta l\'amministratore del server.', @@ -356,7 +356,7 @@ class MSTV_I18n 'Save notifications' => 'Enregistrer les notifications', 'Specific users' => 'Utilisateurs spécifiques', 'Uploaded: %s' => 'Téléversé : %s', - '[%1$s] TeamVault: %2$d %3$s event(s)' => '[%1$s] TeamVault : %2$d événement(s) %3$s', + '[%1$s] TeamVault: %2$d %3$s event(s)' => '[%1$s] TeamVault : %2$d événement(s) de %3$s', 'access denied' => 'accès refusé', 'delete' => 'suppression', 'download' => 'téléchargement', @@ -420,7 +420,7 @@ class MSTV_I18n 'Action' => 'Action', 'Activity Log' => 'Journal d\'activité', 'Add your current account to the whitelist before enabling it, otherwise you will lock yourself out.' => 'Ajoutez votre compte actuel à la liste blanche avant de l\'activer, sinon vous vous bloquerez l\'accès.', - 'ago' => 'il y a', + '%s ago' => 'il y a %s', 'Allowed extensions' => 'Extensions autorisées', 'An error occurred. Please try again.' => 'Une erreur s\'est produite. Veuillez réessayer.', 'Your session has expired. Reload the page to continue.' => 'Votre session a expiré. Rechargez la page pour continuer.', @@ -618,7 +618,7 @@ class MSTV_I18n 'Unable to delete the folder from the filesystem.' => 'Impossible de supprimer le dossier du système de fichiers.', 'Unable to move the file.' => 'Impossible de déplacer le fichier.', 'Unable to move the folder.' => 'Impossible de déplacer le dossier.', - 'You cannot move a folder into itself or one of its subfolders.' => 'Vous ne pouvez pas déplacer un dossier dans lui-même ou dans l\'un de ses sous-dossiers.', + 'You cannot move a folder into itself or one of its subfolders.' => 'Vous ne pouvez pas déplacer un dossier vers lui-même ou vers l\'un de ses sous-dossiers.', 'Unable to read the file.' => 'Impossible de lire le fichier.', 'Unable to read the ZIP file.' => 'Impossible de lire le fichier ZIP.', 'Unable to rename the folder.' => 'Impossible de renommer le dossier.', @@ -742,7 +742,7 @@ class MSTV_I18n 'Action' => 'Acción', 'Activity Log' => 'Registro de actividad', 'Add your current account to the whitelist before enabling it, otherwise you will lock yourself out.' => 'Añade tu cuenta actual a la lista blanca antes de activarla; de lo contrario, te quedarás sin acceso.', - 'ago' => 'hace', + '%s ago' => 'hace %s', 'Allowed extensions' => 'Extensiones permitidas', 'An error occurred. Please try again.' => 'Se ha producido un error. Inténtalo de nuevo.', 'Your session has expired. Reload the page to continue.' => 'La sesión ha caducado. Recarga la página para continuar.', @@ -1000,7 +1000,7 @@ class MSTV_I18n 'Save notifications' => 'Benachrichtigungen speichern', 'Specific users' => 'Bestimmte Benutzer', 'Uploaded: %s' => 'Hochgeladen: %s', - '[%1$s] TeamVault: %2$d %3$s event(s)' => '[%1$s] TeamVault: %2$d %3$s-Ereignis(se)', + '[%1$s] TeamVault: %2$d %3$s event(s)' => '[%1$s] TeamVault: %2$d Ereignis(se): %3$s', 'access denied' => 'Zugriff verweigert', 'delete' => 'Löschen', 'download' => 'Download', @@ -1064,7 +1064,7 @@ class MSTV_I18n 'Action' => 'Aktion', 'Activity Log' => 'Aktivitätsprotokoll', 'Add your current account to the whitelist before enabling it, otherwise you will lock yourself out.' => 'Fügen Sie Ihr aktuelles Konto zur Whitelist hinzu, bevor Sie diese aktivieren, sonst sperren Sie sich selbst aus.', - 'ago' => 'vor', + '%s ago' => 'vor %s', 'Allowed extensions' => 'Erlaubte Dateiendungen', 'An error occurred. Please try again.' => 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.', 'Your session has expired. Reload the page to continue.' => 'Ihre Sitzung ist abgelaufen. Laden Sie die Seite neu, um fortzufahren.', diff --git a/languages/mikesoft-teamvault.pot b/languages/mikesoft-teamvault.pot index 33d0ceb..f5b691d 100644 --- a/languages/mikesoft-teamvault.pot +++ b/languages/mikesoft-teamvault.pot @@ -1,4 +1,5 @@ -# /work/pot-comment.txt +# Copyright (C) 2026 Mikesoft +# This file is distributed under the GPL-2.0-or-later. msgid "" msgstr "" "Project-Id-Version: Mikesoft TeamVault 3.5.0\n" @@ -8,168 +9,180 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2026-10-22T10:45:00+00:00\n" +"POT-Creation-Date: 2026-10-28T20:22:56+00:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "X-Generator: WP-CLI 2.12.0\n" "X-Domain: mikesoft-teamvault\n" #. Plugin Name of the plugin -#: mikesoft-teamvault.php:3 +#: mikesoft-teamvault.php msgid "Mikesoft TeamVault" msgstr "" #. Plugin URI of the plugin -#: mikesoft-teamvault.php:4 +#: mikesoft-teamvault.php msgid "https://github.com/TheStreamCode/mikesoft-teamvault" msgstr "" #. Description of the plugin -#: mikesoft-teamvault.php:5 +#: mikesoft-teamvault.php msgid "Private shared document management separated from the WordPress Media Library with secure access control, preview and drag-and-drop." msgstr "" #. Author of the plugin -#: mikesoft-teamvault.php:7 +#: mikesoft-teamvault.php msgid "Mikesoft" msgstr "" #. Author URI of the plugin -#: mikesoft-teamvault.php:8 +#: mikesoft-teamvault.php msgid "https://mikesoft.it" msgstr "" -#: admin/views/file-manager-page.php:14 -#: includes/class-mstv-assets.php:118 -#: includes/class-mstv-assets.php:159 +#: admin/views/file-manager-page.php:10 +#: includes/class-mstv-admin.php:153 +#: includes/class-mstv-admin.php:154 +msgid "File Manager" +msgstr "" + +#: admin/views/file-manager-page.php:15 +#: includes/class-mstv-assets.php:145 +#: includes/class-mstv-assets.php:186 msgid "New folder" msgstr "" -#: admin/views/file-manager-page.php:21 -#: includes/class-mstv-assets.php:117 +#: admin/views/file-manager-page.php:22 +#: includes/class-mstv-assets.php:144 msgid "Search files..." msgstr "" -#: admin/views/file-manager-page.php:26 -#: admin/views/file-manager-page.php:139 +#: admin/views/file-manager-page.php:27 +#: admin/views/file-manager-page.php:142 #: admin/views/groups-page.php:23 #: admin/views/notifications-page.php:19 #: admin/views/quotas-page.php:24 -#: includes/class-mstv-assets.php:162 +#: includes/class-mstv-assets.php:189 msgid "Loading..." msgstr "" -#: admin/views/file-manager-page.php:30 -#: includes/class-mstv-assets.php:170 -#: includes/class-mstv-assets.php:174 +#: admin/views/file-manager-page.php:31 +#: includes/class-mstv-assets.php:197 +#: includes/class-mstv-assets.php:201 msgid "Storage" msgstr "" -#: admin/views/file-manager-page.php:35 -#: includes/class-mstv-assets.php:176 +#: admin/views/file-manager-page.php:36 +#: includes/class-mstv-assets.php:203 msgid "Used by TeamVault" msgstr "" -#: admin/views/file-manager-page.php:44 +#: admin/views/file-manager-page.php:45 msgid "Folders" msgstr "" -#: admin/views/file-manager-page.php:54 -#: includes/class-mstv-assets.php:151 +#: admin/views/file-manager-page.php:55 +#: includes/class-mstv-assets.php:178 msgid "Home" msgstr "" -#: admin/views/file-manager-page.php:60 +#: admin/views/file-manager-page.php:61 msgid "Filter" msgstr "" #: admin/views/file-manager-page.php:68 -#: admin/views/file-manager-page.php:85 -#: includes/class-mstv-assets.php:127 -#: includes/class-mstv-assets.php:141 +#: includes/class-mstv-assets.php:167 +msgid "Sort by" +msgstr "" + +#: admin/views/file-manager-page.php:70 +#: admin/views/file-manager-page.php:88 +#: includes/class-mstv-assets.php:154 +#: includes/class-mstv-assets.php:168 msgid "Name" msgstr "" -#: admin/views/file-manager-page.php:69 -#: admin/views/file-manager-page.php:86 -#: includes/class-mstv-assets.php:142 +#: admin/views/file-manager-page.php:71 +#: admin/views/file-manager-page.php:89 +#: includes/class-mstv-assets.php:169 msgid "Date" msgstr "" -#: admin/views/file-manager-page.php:70 -#: admin/views/file-manager-page.php:87 -#: includes/class-mstv-assets.php:128 -#: includes/class-mstv-assets.php:143 +#: admin/views/file-manager-page.php:72 +#: admin/views/file-manager-page.php:90 +#: includes/class-mstv-assets.php:155 +#: includes/class-mstv-assets.php:170 msgid "Size" msgstr "" -#: admin/views/file-manager-page.php:89 -msgid "Order" -msgstr "" - -#: admin/views/file-manager-page.php:96 +#: admin/views/file-manager-page.php:76 +#: admin/views/file-manager-page.php:99 #: admin/views/logs-page.php:65 msgid "Per page" msgstr "" -#: admin/views/file-manager-page.php:105 -#: includes/class-mstv-assets.php:138 +#: admin/views/file-manager-page.php:92 +msgid "Order" +msgstr "" + +#: admin/views/file-manager-page.php:108 +#: includes/class-mstv-assets.php:165 msgid "Grid view" msgstr "" -#: admin/views/file-manager-page.php:113 -#: includes/class-mstv-assets.php:139 +#: admin/views/file-manager-page.php:116 +#: includes/class-mstv-assets.php:166 msgid "List view" msgstr "" -#: admin/views/file-manager-page.php:125 -#: includes/class-mstv-assets.php:185 +#: admin/views/file-manager-page.php:128 +#: includes/class-mstv-assets.php:212 msgid "Export" msgstr "" -#: admin/views/file-manager-page.php:131 +#: admin/views/file-manager-page.php:134 #: admin/views/logs-page.php:9 -#: includes/class-mstv-assets.php:204 +#: includes/class-mstv-assets.php:231 msgid "Upload" msgstr "" -#: admin/views/file-manager-page.php:150 -#: includes/class-mstv-assets.php:158 +#: admin/views/file-manager-page.php:153 +#: includes/class-mstv-assets.php:185 msgid "Select a file or folder to view details" msgstr "" -#: admin/views/file-manager-page.php:162 -#: includes/class-mstv-assets.php:112 +#: admin/views/file-manager-page.php:165 +#: includes/class-mstv-assets.php:139 msgid "Drag files here to upload them" msgstr "" -#: admin/views/file-manager-page.php:163 -#: includes/class-mstv-assets.php:113 +#: admin/views/file-manager-page.php:166 +#: includes/class-mstv-assets.php:140 msgid "or" msgstr "" -#: admin/views/file-manager-page.php:164 -#: includes/class-mstv-assets.php:114 +#: admin/views/file-manager-page.php:167 +#: includes/class-mstv-assets.php:141 msgid "Browse files" msgstr "" -#: admin/views/file-manager-page.php:174 -#: admin/views/file-manager-page.php:190 -#: includes/class-mstv-assets.php:126 +#: admin/views/file-manager-page.php:177 +#: admin/views/file-manager-page.php:193 +#: includes/class-mstv-assets.php:153 msgid "Close" msgstr "" -#: admin/views/file-manager-page.php:187 +#: admin/views/file-manager-page.php:190 #: admin/views/reports-page.php:37 #: admin/views/settings-page.php:209 -#: includes/class-mstv-assets.php:122 +#: includes/class-mstv-assets.php:149 msgid "Preview" msgstr "" -#: admin/views/file-manager-page.php:201 +#: admin/views/file-manager-page.php:204 #: admin/views/logs-page.php:10 #: admin/views/reports-page.php:38 -#: includes/class-mstv-assets.php:121 -#: includes/class-mstv-assets.php:205 +#: includes/class-mstv-assets.php:148 +#: includes/class-mstv-assets.php:232 msgid "Download" msgstr "" @@ -182,23 +195,23 @@ msgid "Organize users into departments or teams, then grant folder access to a w msgstr "" #: admin/views/groups-page.php:16 -#: includes/class-mstv-assets.php:222 +#: includes/class-mstv-assets.php:250 msgid "New group" msgstr "" #: admin/views/logs-page.php:11 -#: includes/class-mstv-assets.php:120 -#: includes/class-mstv-assets.php:206 +#: includes/class-mstv-assets.php:147 +#: includes/class-mstv-assets.php:233 msgid "Delete" msgstr "" #: admin/views/logs-page.php:12 -#: includes/class-mstv-assets.php:119 +#: includes/class-mstv-assets.php:146 msgid "Rename" msgstr "" #: admin/views/logs-page.php:13 -#: includes/class-mstv-assets.php:123 +#: includes/class-mstv-assets.php:150 msgid "Move" msgstr "" @@ -208,19 +221,19 @@ msgstr "" #: admin/views/logs-page.php:36 #: admin/views/reports-page.php:21 -#: includes/class-mstv-assets.php:133 +#: includes/class-mstv-assets.php:160 msgid "File" msgstr "" #: admin/views/logs-page.php:37 #: admin/views/reports-page.php:22 -#: includes/class-mstv-assets.php:132 +#: includes/class-mstv-assets.php:159 msgid "Folder" msgstr "" #: admin/views/logs-page.php:43 -#: includes/class-mstv-admin.php:165 -#: includes/class-mstv-admin.php:166 +#: includes/class-mstv-admin.php:207 +#: includes/class-mstv-admin.php:208 msgid "Activity Log" msgstr "" @@ -258,7 +271,7 @@ msgstr "" #: admin/views/logs-page.php:96 #: admin/views/reports-page.php:20 -#: includes/class-mstv-assets.php:201 +#: includes/class-mstv-assets.php:228 msgid "User" msgstr "" @@ -268,7 +281,7 @@ msgid "Action" msgstr "" #: admin/views/logs-page.php:98 -#: includes/class-mstv-assets.php:129 +#: includes/class-mstv-assets.php:156 msgid "Type" msgstr "" @@ -282,7 +295,7 @@ msgstr "" #: admin/views/logs-page.php:153 #: admin/views/logs-page.php:156 -#: includes/class-mstv-assets.php:146 +#: includes/class-mstv-assets.php:173 msgid "Previous" msgstr "" @@ -294,7 +307,7 @@ msgstr "" #: admin/views/logs-page.php:170 #: admin/views/logs-page.php:173 -#: includes/class-mstv-assets.php:147 +#: includes/class-mstv-assets.php:174 msgid "Next" msgstr "" @@ -431,17 +444,17 @@ msgid "Authorized users" msgstr "" #: admin/views/settings-page.php:140 -#: includes/class-mstv-assets.php:180 +#: includes/class-mstv-assets.php:207 msgid "Search users..." msgstr "" #: admin/views/settings-page.php:152 -#: includes/class-mstv-assets.php:184 +#: includes/class-mstv-assets.php:211 msgid "Remove" msgstr "" #: admin/views/settings-page.php:162 -#: includes/class-mstv-assets.php:181 +#: includes/class-mstv-assets.php:208 msgid "No users selected" msgstr "" @@ -588,7 +601,9 @@ msgstr "" msgid "TeamVault cannot write to the private storage directory, so uploads are refused. Make the directory writable by WordPress, then reload this page." msgstr "" +#. translators: %s: comma-separated list of protection files that could not be created. #: includes/class-mstv-admin.php:88 +#, php-format msgid "TeamVault could not create the protection files (%s) that block direct web access to the private storage directory. Uploads are refused until the directory is writable and the files exist." msgstr "" @@ -596,97 +611,80 @@ msgstr "" msgid "This server runs Nginx, which ignores .htaccess. Confirm that a server rule denies direct requests to the private storage directory, or set a custom storage path outside the public webroot (recommended)." msgstr "" -#: includes/class-mstv-rest-controller.php:1033 -msgid "A file with this storage path already exists." -msgstr "" - -#: includes/class-mstv-storage.php:175 -msgid "Upload refused: TeamVault could not create the protection files (%s) in the private storage directory. Make the directory writable, or use a storage path outside the public webroot, then retry." -msgstr "" - -#: includes/class-mstv-storage.php:177 -msgid "directory not writable" -msgstr "" - -#: includes/class-mstv-admin.php:111 -#: includes/class-mstv-admin.php:112 -msgid "File Manager" -msgstr "" - -#: includes/class-mstv-admin.php:120 -#: includes/class-mstv-admin.php:121 +#: includes/class-mstv-admin.php:162 +#: includes/class-mstv-admin.php:163 msgid "Settings" msgstr "" -#: includes/class-mstv-admin.php:129 -#: includes/class-mstv-admin.php:130 -#: includes/class-mstv-assets.php:243 +#: includes/class-mstv-admin.php:171 +#: includes/class-mstv-admin.php:172 +#: includes/class-mstv-assets.php:272 msgid "Groups" msgstr "" -#: includes/class-mstv-admin.php:138 -#: includes/class-mstv-admin.php:139 +#: includes/class-mstv-admin.php:180 +#: includes/class-mstv-admin.php:181 msgid "Quotas" msgstr "" -#: includes/class-mstv-admin.php:147 -#: includes/class-mstv-admin.php:148 +#: includes/class-mstv-admin.php:189 +#: includes/class-mstv-admin.php:190 msgid "Notifications" msgstr "" -#: includes/class-mstv-admin.php:156 -#: includes/class-mstv-admin.php:157 +#: includes/class-mstv-admin.php:198 +#: includes/class-mstv-admin.php:199 msgid "Reports" msgstr "" -#: includes/class-mstv-admin.php:219 -#: includes/class-mstv-admin.php:229 -#: includes/class-mstv-admin.php:251 #: includes/class-mstv-admin.php:261 #: includes/class-mstv-admin.php:271 -#: includes/class-mstv-admin.php:281 -#: includes/class-mstv-admin.php:291 -#: includes/class-mstv-admin.php:316 -#: includes/class-mstv-admin.php:382 -#: includes/class-mstv-admin.php:405 -#: includes/class-mstv-admin.php:472 -#: includes/class-mstv-admin.php:495 -#: includes/class-mstv-admin.php:582 +#: includes/class-mstv-admin.php:293 +#: includes/class-mstv-admin.php:303 +#: includes/class-mstv-admin.php:313 +#: includes/class-mstv-admin.php:323 +#: includes/class-mstv-admin.php:333 +#: includes/class-mstv-admin.php:358 +#: includes/class-mstv-admin.php:424 +#: includes/class-mstv-admin.php:447 +#: includes/class-mstv-admin.php:514 +#: includes/class-mstv-admin.php:537 +#: includes/class-mstv-admin.php:624 msgid "You do not have permission to access this page." msgstr "" -#: includes/class-mstv-admin.php:321 -#: includes/class-mstv-admin.php:387 -#: includes/class-mstv-admin.php:410 -#: includes/class-mstv-admin.php:477 -#: includes/class-mstv-admin.php:500 +#: includes/class-mstv-admin.php:363 +#: includes/class-mstv-admin.php:429 +#: includes/class-mstv-admin.php:452 +#: includes/class-mstv-admin.php:519 +#: includes/class-mstv-admin.php:542 #: includes/class-mstv-auth.php:131 msgid "Invalid security token." msgstr "" -#: includes/class-mstv-admin.php:428 -#: includes/class-mstv-admin.php:442 +#: includes/class-mstv-admin.php:470 +#: includes/class-mstv-admin.php:484 #: includes/class-mstv-download.php:41 #: includes/class-mstv-preview.php:44 -#: includes/class-mstv-rest-controller.php:1061 -#: includes/class-mstv-rest-controller.php:1094 -#: includes/class-mstv-rest-controller.php:1148 -#: includes/class-mstv-storage.php:313 -#: includes/class-mstv-storage.php:366 +#: includes/class-mstv-rest-controller.php:1082 +#: includes/class-mstv-rest-controller.php:1115 +#: includes/class-mstv-rest-controller.php:1169 +#: includes/class-mstv-storage.php:335 +#: includes/class-mstv-storage.php:388 msgid "File not found." msgstr "" -#: includes/class-mstv-admin.php:428 -#: includes/class-mstv-admin.php:442 -#: includes/class-mstv-admin.php:495 -#: includes/class-mstv-admin.php:582 +#: includes/class-mstv-admin.php:470 +#: includes/class-mstv-admin.php:484 +#: includes/class-mstv-admin.php:537 +#: includes/class-mstv-admin.php:624 #: includes/class-mstv-download.php:33 #: includes/class-mstv-download.php:42 #: includes/class-mstv-download.php:53 #: includes/class-mstv-download.php:64 #: includes/class-mstv-download.php:72 -#: includes/class-mstv-download.php:114 -#: includes/class-mstv-download.php:133 +#: includes/class-mstv-download.php:115 +#: includes/class-mstv-download.php:134 #: includes/class-mstv-export.php:43 #: includes/class-mstv-export.php:51 #: includes/class-mstv-export.php:61 @@ -713,431 +711,431 @@ msgstr "" msgid "Error" msgstr "" -#: includes/class-mstv-assets.php:95 +#: includes/class-mstv-assets.php:122 msgid "Are you sure you want to delete this item?" msgstr "" -#: includes/class-mstv-assets.php:96 +#: includes/class-mstv-assets.php:123 msgid "Are you sure you want to delete this folder? It must be empty." msgstr "" -#: includes/class-mstv-assets.php:97 +#: includes/class-mstv-assets.php:124 msgid "File uploaded successfully." msgstr "" -#: includes/class-mstv-assets.php:98 +#: includes/class-mstv-assets.php:125 msgid "Error while uploading the file." msgstr "" -#: includes/class-mstv-assets.php:99 +#: includes/class-mstv-assets.php:126 msgid "Uploading..." msgstr "" -#: includes/class-mstv-assets.php:100 +#: includes/class-mstv-assets.php:127 msgid "Upload cancelled." msgstr "" -#: includes/class-mstv-assets.php:101 +#: includes/class-mstv-assets.php:128 msgid "\"{fileName}\" ({fileSize}) exceeds the maximum allowed size of {maxSize}." msgstr "" -#: includes/class-mstv-assets.php:102 +#: includes/class-mstv-assets.php:129 msgid "Item deleted successfully." msgstr "" -#: includes/class-mstv-assets.php:103 +#: includes/class-mstv-assets.php:130 msgid "Error while deleting." msgstr "" -#: includes/class-mstv-assets.php:104 +#: includes/class-mstv-assets.php:131 msgid "Renamed successfully." msgstr "" -#: includes/class-mstv-assets.php:105 +#: includes/class-mstv-assets.php:132 msgid "Error while renaming." msgstr "" -#: includes/class-mstv-assets.php:106 +#: includes/class-mstv-assets.php:133 msgid "File moved successfully." msgstr "" -#: includes/class-mstv-assets.php:107 +#: includes/class-mstv-assets.php:134 msgid "Error while moving the file." msgstr "" -#: includes/class-mstv-assets.php:108 +#: includes/class-mstv-assets.php:135 msgid "Folder moved successfully." msgstr "" -#: includes/class-mstv-assets.php:109 +#: includes/class-mstv-assets.php:136 msgid "Error while moving the folder." msgstr "" -#: includes/class-mstv-assets.php:110 +#: includes/class-mstv-assets.php:137 msgid "Folder created successfully." msgstr "" -#: includes/class-mstv-assets.php:111 +#: includes/class-mstv-assets.php:138 msgid "Error while creating the folder." msgstr "" -#: includes/class-mstv-assets.php:115 +#: includes/class-mstv-assets.php:142 msgid "This folder is empty" msgstr "" -#: includes/class-mstv-assets.php:116 +#: includes/class-mstv-assets.php:143 msgid "Upload files or create a new folder to get started" msgstr "" -#: includes/class-mstv-assets.php:124 +#: includes/class-mstv-assets.php:151 msgid "Cancel" msgstr "" -#: includes/class-mstv-assets.php:125 +#: includes/class-mstv-assets.php:152 msgid "Confirm" msgstr "" -#: includes/class-mstv-assets.php:130 +#: includes/class-mstv-assets.php:157 msgid "Availability" msgstr "" -#: includes/class-mstv-assets.php:131 +#: includes/class-mstv-assets.php:158 msgid "Created" msgstr "" -#: includes/class-mstv-assets.php:134 +#: includes/class-mstv-assets.php:161 msgid "files" msgstr "" -#: includes/class-mstv-assets.php:135 +#: includes/class-mstv-assets.php:162 msgid "folders" msgstr "" -#: includes/class-mstv-assets.php:136 +#: includes/class-mstv-assets.php:163 msgid "Missing" msgstr "" -#: includes/class-mstv-assets.php:137 +#: includes/class-mstv-assets.php:164 msgid "selected" msgstr "" -#: includes/class-mstv-assets.php:140 -msgid "Sort by" -msgstr "" - -#: includes/class-mstv-assets.php:144 +#: includes/class-mstv-assets.php:171 msgid "Ascending" msgstr "" -#: includes/class-mstv-assets.php:145 +#: includes/class-mstv-assets.php:172 msgid "Descending" msgstr "" -#: includes/class-mstv-assets.php:148 +#: includes/class-mstv-assets.php:175 msgid "Page" msgstr "" -#: includes/class-mstv-assets.php:149 +#: includes/class-mstv-assets.php:176 msgid "of" msgstr "" -#: includes/class-mstv-assets.php:150 +#: includes/class-mstv-assets.php:177 msgid "results" msgstr "" -#: includes/class-mstv-assets.php:152 +#: includes/class-mstv-assets.php:179 msgid "Open" msgstr "" -#: includes/class-mstv-assets.php:153 +#: includes/class-mstv-assets.php:180 msgid "Status" msgstr "" -#: includes/class-mstv-assets.php:154 +#: includes/class-mstv-assets.php:181 msgid "Contains subfolders" msgstr "" -#: includes/class-mstv-assets.php:155 +#: includes/class-mstv-assets.php:182 msgid "No subfolders" msgstr "" -#: includes/class-mstv-assets.php:156 +#: includes/class-mstv-assets.php:183 msgid "Expand" msgstr "" -#: includes/class-mstv-assets.php:157 +#: includes/class-mstv-assets.php:184 msgid "Collapse" msgstr "" -#: includes/class-mstv-assets.php:160 +#: includes/class-mstv-assets.php:187 msgid "Move to..." msgstr "" -#: includes/class-mstv-assets.php:161 +#: includes/class-mstv-assets.php:188 msgid "Select destination" msgstr "" -#: includes/class-mstv-assets.php:163 +#: includes/class-mstv-assets.php:190 msgid "An error occurred. Please try again." msgstr "" -#: includes/class-mstv-assets.php:164 +#: includes/class-mstv-assets.php:191 msgid "Your session has expired. Reload the page to continue." msgstr "" -#: includes/class-mstv-assets.php:165 +#: includes/class-mstv-assets.php:192 msgid "No results found" msgstr "" -#: includes/class-mstv-assets.php:166 +#: includes/class-mstv-assets.php:193 msgid "Try a different keyword or clear the search." msgstr "" -#: includes/class-mstv-assets.php:167 +#: includes/class-mstv-assets.php:194 msgid "File missing from storage" msgstr "" -#: includes/class-mstv-assets.php:168 +#: includes/class-mstv-assets.php:195 msgid "This record exists in the database, but the binary file is missing from the private storage directory." msgstr "" -#: includes/class-mstv-assets.php:169 +#: includes/class-mstv-assets.php:196 msgid "Missing from storage" msgstr "" -#: includes/class-mstv-assets.php:171 -#: includes/class-mstv-assets.php:231 +#: includes/class-mstv-assets.php:198 +#: includes/class-mstv-assets.php:259 msgid "Used" msgstr "" -#: includes/class-mstv-assets.php:172 +#: includes/class-mstv-assets.php:199 msgid "Free" msgstr "" -#: includes/class-mstv-assets.php:173 +#: includes/class-mstv-assets.php:200 msgid "Total" msgstr "" -#: includes/class-mstv-assets.php:175 +#: includes/class-mstv-assets.php:202 msgid "TeamVault" msgstr "" -#: includes/class-mstv-assets.php:177 +#: includes/class-mstv-assets.php:204 msgid "Other usage" msgstr "" -#: includes/class-mstv-assets.php:178 +#: includes/class-mstv-assets.php:205 msgid "Available" msgstr "" -#: includes/class-mstv-assets.php:179 +#: includes/class-mstv-assets.php:206 msgid "Capacity" msgstr "" -#: includes/class-mstv-assets.php:182 +#: includes/class-mstv-assets.php:209 msgid "User not found" msgstr "" -#: includes/class-mstv-assets.php:183 +#: includes/class-mstv-assets.php:210 msgid "User is already in the list" msgstr "" -#: includes/class-mstv-assets.php:186 +#: includes/class-mstv-assets.php:213 msgid "Export All" msgstr "" -#: includes/class-mstv-assets.php:187 +#: includes/class-mstv-assets.php:214 msgid "Export Folder" msgstr "" -#: includes/class-mstv-assets.php:188 +#: includes/class-mstv-assets.php:215 msgid "Create a ZIP archive with the full private document library." msgstr "" -#: includes/class-mstv-assets.php:189 +#: includes/class-mstv-assets.php:216 msgid "Export Selected Folders" msgstr "" -#: includes/class-mstv-assets.php:190 +#: includes/class-mstv-assets.php:217 msgid "Choose one or more folders to include in the ZIP archive." msgstr "" -#: includes/class-mstv-assets.php:191 +#: includes/class-mstv-assets.php:218 msgid "Select at least one folder to export." msgstr "" -#: includes/class-mstv-assets.php:192 +#: includes/class-mstv-assets.php:219 msgid "Exporting..." msgstr "" -#: includes/class-mstv-assets.php:193 +#: includes/class-mstv-assets.php:220 msgid "No folders available for selective export." msgstr "" -#: includes/class-mstv-assets.php:194 +#: includes/class-mstv-assets.php:221 msgid "Error during export" msgstr "" -#: includes/class-mstv-assets.php:196 +#: includes/class-mstv-assets.php:223 msgid "Permissions" msgstr "" -#: includes/class-mstv-assets.php:197 +#: includes/class-mstv-assets.php:224 msgid "Custom permissions" msgstr "" -#: includes/class-mstv-assets.php:198 +#: includes/class-mstv-assets.php:225 msgid "Folder permissions" msgstr "" -#: includes/class-mstv-assets.php:199 +#: includes/class-mstv-assets.php:226 msgid "Grant access to specific users or groups. With no rules, the folder follows the default access (capability and optional whitelist)." msgstr "" -#: includes/class-mstv-assets.php:200 +#: includes/class-mstv-assets.php:227 msgid "User / Group" msgstr "" -#: includes/class-mstv-assets.php:202 +#: includes/class-mstv-assets.php:229 msgid "Group" msgstr "" -#: includes/class-mstv-assets.php:203 +#: includes/class-mstv-assets.php:230 msgid "View" msgstr "" -#: includes/class-mstv-assets.php:207 +#: includes/class-mstv-assets.php:234 msgid "Manage" msgstr "" -#: includes/class-mstv-assets.php:208 +#: includes/class-mstv-assets.php:235 msgid "No explicit rules. Default access applies." msgstr "" -#: includes/class-mstv-assets.php:209 +#: includes/class-mstv-assets.php:236 msgid "No groups available" msgstr "" -#: includes/class-mstv-assets.php:210 +#: includes/class-mstv-assets.php:237 msgid "Add" msgstr "" -#: includes/class-mstv-assets.php:211 +#: includes/class-mstv-assets.php:238 msgid "Reset" msgstr "" -#: includes/class-mstv-assets.php:212 +#: includes/class-mstv-assets.php:239 msgid "Remove all permission rules for this folder?" msgstr "" -#: includes/class-mstv-assets.php:213 +#: includes/class-mstv-assets.php:240 msgid "Save permissions" msgstr "" -#: includes/class-mstv-assets.php:214 +#: includes/class-mstv-assets.php:241 msgid "Permissions updated." msgstr "" -#: includes/class-mstv-assets.php:215 +#: includes/class-mstv-assets.php:242 msgid "This user or group is already in the list." msgstr "" -#: includes/class-mstv-assets.php:216 +#: includes/class-mstv-assets.php:243 msgid "Heads up: some folders have rules but the Home (root) folder has none. Any folder without a rule in its parent chain stays accessible to every vault user. Add a rule on Home to restrict the default access." msgstr "" -#: includes/class-mstv-assets.php:218 +#: includes/class-mstv-assets.php:245 msgid "No groups yet. Create one to organize document access." msgstr "" -#: includes/class-mstv-assets.php:247 -msgid "Members" +#: includes/class-mstv-assets.php:246 +msgid "members" msgstr "" -#: includes/class-mstv-assets.php:219 -msgid "members" +#: includes/class-mstv-assets.php:247 +msgid "Members" msgstr "" -#: includes/class-mstv-assets.php:220 +#: includes/class-mstv-assets.php:248 msgid "Group name" msgstr "" -#: includes/class-mstv-assets.php:221 +#: includes/class-mstv-assets.php:249 msgid "Description" msgstr "" -#: includes/class-mstv-assets.php:223 +#: includes/class-mstv-assets.php:251 msgid "Edit group" msgstr "" -#: includes/class-mstv-assets.php:224 +#: includes/class-mstv-assets.php:252 #: includes/class-mstv-rest-governance.php:154 #: includes/class-mstv-rest-governance.php:201 msgid "The group name cannot be empty." msgstr "" -#: includes/class-mstv-assets.php:225 +#: includes/class-mstv-assets.php:253 msgid "Group saved." msgstr "" -#: includes/class-mstv-assets.php:226 +#: includes/class-mstv-assets.php:254 msgid "Delete this group? Members and its folder permissions will be removed." msgstr "" -#: includes/class-mstv-assets.php:227 +#: includes/class-mstv-assets.php:255 msgid "Group deleted." msgstr "" -#: includes/class-mstv-assets.php:229 +#: includes/class-mstv-assets.php:257 msgid "No quotas set. All users have unlimited storage." msgstr "" -#: includes/class-mstv-assets.php:230 +#: includes/class-mstv-assets.php:258 msgid "Limit" msgstr "" -#: includes/class-mstv-assets.php:232 +#: includes/class-mstv-assets.php:260 msgid "Save quotas" msgstr "" -#: includes/class-mstv-assets.php:233 +#: includes/class-mstv-assets.php:261 msgid "Quotas updated." msgstr "" -#: includes/class-mstv-assets.php:235 -#: includes/class-mstv-assets.php:239 +#: includes/class-mstv-assets.php:263 +#: includes/class-mstv-assets.php:267 msgid "Events" msgstr "" -#: includes/class-mstv-assets.php:236 +#: includes/class-mstv-assets.php:264 msgid "Last access" msgstr "" -#: includes/class-mstv-assets.php:238 +#: includes/class-mstv-assets.php:266 msgid "Enable email notifications" msgstr "" -#: includes/class-mstv-assets.php:240 +#: includes/class-mstv-assets.php:268 msgid "Recipients" msgstr "" -#: includes/class-mstv-assets.php:241 +#: includes/class-mstv-assets.php:269 msgid "All administrators" msgstr "" -#: includes/class-mstv-assets.php:242 +#: includes/class-mstv-assets.php:270 +msgid "Only notify people who can access the folder" +msgstr "" + +#: includes/class-mstv-assets.php:271 msgid "Specific users" msgstr "" -#: includes/class-mstv-assets.php:244 +#: includes/class-mstv-assets.php:273 msgid "Access denied" msgstr "" -#: includes/class-mstv-assets.php:245 +#: includes/class-mstv-assets.php:274 msgid "Save notifications" msgstr "" -#: includes/class-mstv-assets.php:246 +#: includes/class-mstv-assets.php:275 msgid "Notification settings saved." msgstr "" @@ -1172,8 +1170,8 @@ msgstr "" msgid "File not found in the filesystem." msgstr "" -#: includes/class-mstv-download.php:113 -#: includes/class-mstv-download.php:132 +#: includes/class-mstv-download.php:114 +#: includes/class-mstv-download.php:133 #: includes/class-mstv-preview.php:124 #: includes/class-mstv-preview.php:155 msgid "Unable to read the file." @@ -1199,17 +1197,17 @@ msgid "Error while creating the ZIP file." msgstr "" #: includes/class-mstv-export.php:144 -#: includes/class-mstv-rest-controller.php:677 -#: includes/class-mstv-rest-controller.php:734 -#: includes/class-mstv-rest-controller.php:779 -#: includes/class-mstv-rest-controller.php:1194 -#: includes/class-mstv-rest-controller.php:1198 -#: includes/class-mstv-rest-controller.php:1204 -#: includes/class-mstv-rest-controller.php:1208 -#: includes/class-mstv-rest-governance.php:574 -#: includes/class-mstv-storage.php:276 -#: includes/class-mstv-storage.php:403 -#: includes/class-mstv-storage.php:460 +#: includes/class-mstv-rest-controller.php:683 +#: includes/class-mstv-rest-controller.php:740 +#: includes/class-mstv-rest-controller.php:785 +#: includes/class-mstv-rest-controller.php:1215 +#: includes/class-mstv-rest-controller.php:1219 +#: includes/class-mstv-rest-controller.php:1225 +#: includes/class-mstv-rest-controller.php:1229 +#: includes/class-mstv-rest-governance.php:580 +#: includes/class-mstv-storage.php:298 +#: includes/class-mstv-storage.php:425 +#: includes/class-mstv-storage.php:482 msgid "Folder not found." msgstr "" @@ -1219,53 +1217,55 @@ msgstr "" msgid "Unable to read the ZIP file." msgstr "" -#: includes/class-mstv-helpers.php:183 -msgid "ago" +#. translators: %s: time elapsed, for example "5 mins". +#: includes/class-mstv-helpers.php:185 +#, php-format +msgid "%s ago" msgstr "" #. translators: %s: file name. -#: includes/class-mstv-notifications.php:52 +#: includes/class-mstv-notifications.php:58 #, php-format msgid "Uploaded: %s" msgstr "" #. translators: %s: file name. -#: includes/class-mstv-notifications.php:62 +#: includes/class-mstv-notifications.php:68 #, php-format msgid "Downloaded: %s" msgstr "" #. translators: %s: file name. -#: includes/class-mstv-notifications.php:72 +#: includes/class-mstv-notifications.php:78 #, php-format msgid "Deleted: %s" msgstr "" #. translators: 1: user login, 2: attempted action, 3: folder id. -#: includes/class-mstv-notifications.php:83 +#: includes/class-mstv-notifications.php:89 #, php-format msgid "Access denied for %1$s (action: %2$s, folder: %3$s)" msgstr "" #. translators: 1: site name, 2: number of events, 3: event label. -#: includes/class-mstv-notifications.php:121 +#: includes/class-mstv-notifications.php:152 #, php-format msgid "[%1$s] TeamVault: %2$d %3$s event(s)" msgstr "" -#: includes/class-mstv-notifications.php:140 +#: includes/class-mstv-notifications.php:167 msgid "upload" msgstr "" -#: includes/class-mstv-notifications.php:142 +#: includes/class-mstv-notifications.php:169 msgid "download" msgstr "" -#: includes/class-mstv-notifications.php:144 +#: includes/class-mstv-notifications.php:171 msgid "delete" msgstr "" -#: includes/class-mstv-notifications.php:146 +#: includes/class-mstv-notifications.php:173 msgid "access denied" msgstr "" @@ -1280,50 +1280,55 @@ msgstr "" msgid "Upload blocked: this would exceed the storage quota (%1$s). Already used: %2$s; this file: %3$s." msgstr "" -#: includes/class-mstv-rest-controller.php:75 +#: includes/class-mstv-rest-controller.php:74 msgid "You do not have permission to perform this action." msgstr "" -#: includes/class-mstv-rest-controller.php:156 -#: includes/class-mstv-rest-governance.php:600 -#: includes/class-mstv-storage.php:109 +#: includes/class-mstv-rest-controller.php:155 +#: includes/class-mstv-rest-governance.php:606 +#: includes/class-mstv-storage.php:113 msgid "Unable to save the changes. Please try again." msgstr "" -#: includes/class-mstv-rest-controller.php:633 -#: includes/class-mstv-storage.php:251 +#: includes/class-mstv-rest-controller.php:632 +#: includes/class-mstv-rest-controller.php:653 +#: includes/class-mstv-storage.php:273 msgid "Folder already exists." msgstr "" #. translators: %s: maximum allowed file size (e.g. "50 MB"). -#: includes/class-mstv-rest-controller.php:916 +#: includes/class-mstv-rest-controller.php:922 #, php-format msgid "The file exceeds the maximum allowed size (%s). Please upload a smaller file." msgstr "" -#: includes/class-mstv-rest-controller.php:921 +#: includes/class-mstv-rest-controller.php:927 #: includes/class-mstv-validator.php:379 msgid "No file uploaded." msgstr "" -#: includes/class-mstv-rest-controller.php:926 -#: includes/class-mstv-storage.php:83 -#: includes/class-mstv-storage.php:157 -#: includes/class-mstv-storage.php:206 +#: includes/class-mstv-rest-controller.php:932 +#: includes/class-mstv-storage.php:87 +#: includes/class-mstv-storage.php:161 +#: includes/class-mstv-storage.php:228 msgid "Unable to initialize the storage directory." msgstr "" -#: includes/class-mstv-rest-controller.php:969 +#: includes/class-mstv-rest-controller.php:975 #: includes/class-mstv-validator.php:146 msgid "The file name cannot be empty." msgstr "" -#: includes/class-mstv-rest-controller.php:980 -#: includes/class-mstv-storage.php:183 +#: includes/class-mstv-rest-controller.php:986 +#: includes/class-mstv-storage.php:205 msgid "Unable to save the file." msgstr "" -#: includes/class-mstv-rest-controller.php:1069 +#: includes/class-mstv-rest-controller.php:1033 +msgid "A file with this storage path already exists." +msgstr "" + +#: includes/class-mstv-rest-controller.php:1090 msgid "The name cannot be empty." msgstr "" @@ -1333,11 +1338,11 @@ msgstr "" msgid "Group not found." msgstr "" -#: includes/class-mstv-rest-governance.php:377 +#: includes/class-mstv-rest-governance.php:383 msgid "Home (root)" msgstr "" -#: includes/class-mstv-rest-governance.php:588 +#: includes/class-mstv-rest-governance.php:594 msgid "You do not have permission to manage this folder." msgstr "" @@ -1349,76 +1354,86 @@ msgstr "" msgid "Add your current account to the whitelist before enabling it, otherwise you will lock yourself out." msgstr "" -#: includes/class-mstv-storage.php:171 +#. translators: %s: comma-separated list of protection files that could not be created. +#: includes/class-mstv-storage.php:175 +#, php-format +msgid "Upload refused: TeamVault could not create the protection files (%s) in the private storage directory. Make the directory writable, or use a storage path outside the public webroot, then retry." +msgstr "" + +#: includes/class-mstv-storage.php:177 +msgid "directory not writable" +msgstr "" + +#: includes/class-mstv-storage.php:193 msgid "Invalid destination path." msgstr "" -#: includes/class-mstv-storage.php:215 -#: includes/class-mstv-storage.php:411 +#: includes/class-mstv-storage.php:237 +#: includes/class-mstv-storage.php:433 msgid "Invalid folder name." msgstr "" -#: includes/class-mstv-storage.php:225 -#: includes/class-mstv-storage.php:478 +#: includes/class-mstv-storage.php:247 +#: includes/class-mstv-storage.php:500 msgid "Parent folder not found." msgstr "" -#: includes/class-mstv-storage.php:236 -#: includes/class-mstv-storage.php:498 +#: includes/class-mstv-storage.php:258 +#: includes/class-mstv-storage.php:520 msgid "Invalid folder path." msgstr "" -#: includes/class-mstv-storage.php:259 +#: includes/class-mstv-storage.php:281 msgid "Unable to create the folder." msgstr "" -#: includes/class-mstv-storage.php:284 +#: includes/class-mstv-storage.php:306 msgid "The folder contains subfolders. Delete the subfolders first." msgstr "" -#: includes/class-mstv-storage.php:292 +#: includes/class-mstv-storage.php:314 msgid "The folder contains files. Delete the files first." msgstr "" -#: includes/class-mstv-storage.php:300 +#: includes/class-mstv-storage.php:322 msgid "Unable to delete the folder from the filesystem." msgstr "" -#: includes/class-mstv-storage.php:321 -#: includes/class-mstv-storage.php:329 +#: includes/class-mstv-storage.php:343 +#: includes/class-mstv-storage.php:351 msgid "Unable to delete the files from the filesystem." msgstr "" -#: includes/class-mstv-storage.php:376 +#: includes/class-mstv-storage.php:398 msgid "The file is already in the destination folder." msgstr "" -#: includes/class-mstv-storage.php:384 +#: includes/class-mstv-storage.php:406 msgid "Unable to move the file." msgstr "" -#: includes/class-mstv-storage.php:425 +#: includes/class-mstv-storage.php:447 msgid "The new name is identical to the current name." msgstr "" -#: includes/class-mstv-storage.php:432 -#: includes/class-mstv-storage.php:505 +#: includes/class-mstv-storage.php:454 +#: includes/class-mstv-storage.php:527 msgid "A folder with this name already exists." msgstr "" -#: includes/class-mstv-storage.php:440 +#: includes/class-mstv-storage.php:462 msgid "Unable to rename the folder." msgstr "" -#: includes/class-mstv-storage.php:468 +#: includes/class-mstv-storage.php:490 msgid "The folder is already in the destination folder." msgstr "" -#: includes/class-mstv-storage.php:486 +#: includes/class-mstv-storage.php:508 msgid "You cannot move a folder into itself or one of its subfolders." msgstr "" -#: includes/class-mstv-storage.php:513 +#: includes/class-mstv-storage.php:535 msgid "Unable to move the folder." msgstr "" From b7f37dbbc02a7161eb57a5d684baecae13e1e3bd Mon Sep 17 00:00:00 2001 From: Michael Gasperini <163041857+TheStreamCode@users.noreply.github.com> Date: Wed, 28 Oct 2026 21:32:18 +0100 Subject: [PATCH 2/2] docs(i18n): document the WP-CLI POT workflow and translation precedence Replace the stale load_plugin_textdomain() description, drop the Plural-Forms and custom-extractor notes, document that installed language packs win over the bundled fallback maps, and record the terminology decisions. Add the POT regeneration step to the release checklist and point listing-translation work at the interface-translation guide. --- docs/developer/i18n.md | 67 +++++++++++++++++++++++++------------- docs/maintainer/release.md | 23 +++++++------ 2 files changed, 57 insertions(+), 33 deletions(-) diff --git a/docs/developer/i18n.md b/docs/developer/i18n.md index ec4f546..2a538bd 100644 --- a/docs/developer/i18n.md +++ b/docs/developer/i18n.md @@ -7,41 +7,62 @@ translators can collaborate in GlotPress instead of editing PHP. - All user-facing strings use the `mikesoft-teamvault` text domain (`__()`, `esc_html__()`, `esc_attr__()`, `esc_html_e()` …). -- `MSTV_I18n::init()` (runs on `init` via `MSTV_Bootstrap::init_services()`) - loads community language packs with the standard call: - - ```php - load_plugin_textdomain('mikesoft-teamvault', false, dirname(plugin_basename(__FILE__), 2) . '/languages'); - ``` - - (`__FILE__` is `includes/class-mstv-i18n.php`, hence dirname level 2.) -- `languages/mikesoft-teamvault.pot` is the translatable-string template - shipped for GlotPress import. +- There is no `load_plugin_textdomain()` call: the plugin is hosted on + WordPress.org and requires WordPress 6.0, so WordPress auto-loads the + GlotPress language packs from `WP_LANG_DIR` (WordPress 4.6+ behavior); + see + [How to internationalize your plugin](https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/#plugins-on-wordpress-org). +- `languages/mikesoft-teamvault.pot` is the translatable-string template, + generated with WP-CLI and shipped for GlotPress import. - The hardcoded it/fr/es/de maps in `includes/class-mstv-i18n.php` stay as a **runtime fallback** (via the `gettext` filter) so the bundled interface languages keep working when no language pack is installed. They are not the translation source of truth — GlotPress is. +- Precedence: an installed language pack always wins over the bundled map, so + the "Interface language" setting selects the fallback only and cannot + override a locale that ships a pack. This is deliberate (GlotPress + translations are reviewed by locale editors) and covered by + `tests/PDMI18nRuntimeTest.php`. Forcing a different locale on sites that do + have a pack would need a `plugin_locale` filter, which is not implemented. ## Regenerating the POT -Preferred (requires wp-cli): - ```sh wp i18n make-pot . languages/mikesoft-teamvault.pot --domain=mikesoft-teamvault ``` -The committed POT was produced with an equivalent extractor (same function -set and `mikesoft-teamvault` domain filter, `#: file:line` references, -`Plural-Forms: nplurals=2; plural=(n != 1);`) because wp-cli was unavailable; -re-running `wp i18n make-pot` is welcome to normalize it. +The command runs in the plugin directory without a WordPress installation. +The committed POT is the raw WP-CLI output: plugin header metadata, +`#: file:line` references, `#. translators:` comments, and `#, php-format` +flags for strings with placeholders. Regenerate it whenever user-facing +strings change, and before a release, so translators see the current set with +correct references. ## GlotPress handoff -1. Import the updated `.pot` into the - [WordPress.org plugin GlotPress project](https://translate.wordpress.org/projects/wp-plugins/mikesoft-teamvault/) - on release. +1. Release the plugin. WordPress.org extracts the strings from the released + plugin, so the + [plugin GlotPress project](https://translate.wordpress.org/projects/wp-plugins/mikesoft-teamvault/) + updates on its own; import the committed `.pot` manually only when a + refresh is needed. 2. Approved translations ship automatically as WordPress.org language packs - into `wp-content/languages/plugins/` — no bundled `.po`/`.mo` files needed. -3. Keep the fallback maps in sync only until GlotPress coverage for a locale - is complete; the maps must always cover every `mikesoft-teamvault` string - (guarded by `tests/PdmI18nCoverageTest.php`). + into `wp-content/languages/plugins/` — no bundled `.po`/`.mo` files + needed. +3. Keep the fallback maps in sync until GlotPress coverage for a locale is + complete; the maps must always cover every `mikesoft-teamvault` string + (guarded by `tests/PdmI18nCoverageTest.php`, and the pack-over-map + precedence by `tests/PDMI18nRuntimeTest.php`). + +## Terminology + +Decisions to keep the bundled locales internally consistent: + +- "Vault" names the TeamVault workspace. Italian, Spanish, and German keep the + English word; French uses "coffre". Do not mix the two forms inside one + locale. +- Italian renders "storage" as "archiviazione" everywhere, including labels + such as "Directory di archiviazione" and "Reindicizza archiviazione". +- Italian uses "elenco" (not "lista") and "Gestione file" for the File Manager + screen. +- Event labels follow the WordPress Italian convention: "upload" is + "caricamento", "download" stays "download". diff --git a/docs/maintainer/release.md b/docs/maintainer/release.md index 656dadf..49973f3 100644 --- a/docs/maintainer/release.md +++ b/docs/maintainer/release.md @@ -28,16 +28,17 @@ The deploy script already validates plugin version and stable tag alignment. 2. Update `Stable tag` and the current release entry in `readme.txt`. 3. Add the full release entry to `changelog.txt`. 4. Update the current plugin version and latest release summary in every localized `README*.md`. -5. Run `composer validate --strict`, `composer audit --locked`, and `composer ci` from `mikesoft-teamvault-src/`. -6. Run the JavaScript syntax checks and `node --test tests/plugin-check-output.test.mjs`. -7. Run `Invoke-Pester .\deployment\DeployWordPressOrg.Tests.ps1` from the workspace root. -8. Run WordPress Plugin Check against the clean runtime payload. -9. Smoke test the file browser REST endpoint with plain permalinks when REST URL handling changes. -10. Confirm `.wordpress-org/assets/` contains the expected public assets. -11. Build the release ZIP and verify that repository-only files and sensitive local files are absent. -12. Commit the release on a maintainer branch, open an internal pull request, wait for required CI and CodeQL checks, merge into protected `main`, and publish the matching GitHub tag and release with the ZIP attached. -13. Run the WordPress.org deployment script from the workspace root. -14. Verify the public GitHub release and the WordPress.org `trunk` and version tag. +5. If user-facing strings changed, regenerate `languages/mikesoft-teamvault.pot` with `wp i18n make-pot` (see `docs/developer/i18n.md`). +6. Run `composer validate --strict`, `composer audit --locked`, and `composer ci` from `mikesoft-teamvault-src/`. +7. Run the JavaScript syntax checks and `node --test tests/plugin-check-output.test.mjs`. +8. Run `Invoke-Pester .\deployment\DeployWordPressOrg.Tests.ps1` from the workspace root. +9. Run WordPress Plugin Check against the clean runtime payload. +10. Smoke test the file browser REST endpoint with plain permalinks when REST URL handling changes. +11. Confirm `.wordpress-org/assets/` contains the expected public assets. +12. Build the release ZIP and verify that repository-only files and sensitive local files are absent. +13. Commit the release on a maintainer branch, open an internal pull request, wait for required CI and CodeQL checks, merge into protected `main`, and publish the matching GitHub tag and release with the ZIP attached. +14. Run the WordPress.org deployment script from the workspace root. +15. Verify the public GitHub release and the WordPress.org `trunk` and version tag. ## Changelog Policy @@ -53,6 +54,8 @@ Keep the shipped `readme.txt` in English. WordPress.org localizes plugin listing For Italian listing copy, translate the plugin readme strings in the plugin's Development Readme project on translate.wordpress.org and wait for locale validation. +Interface translations are handled separately: the bundled fallback maps, the POT workflow, and the pack-over-map precedence are documented in `docs/developer/i18n.md`. + ## Deployment Command From the workspace root: