Upload via GUI (30 Dateien)

This commit is contained in:
2026-11-01 11:17:41 +00:00
parent 53f8bf0577
commit c3b9948fa2
30 changed files with 5237 additions and 0 deletions
+74
View File
@@ -0,0 +1,74 @@
<?php
/**
* Baut aus einer JSON-Datei {"Deutscher Text": "English text", …} die Übersetzungsdateien (.po und .mo) des Plugins.
* php wordpress-plugin/tools/build-mo.php wordpress-plugin/tools/en.json
* Quellsprache des Plugins ist Deutsch, deshalb gibt es "Übersetzungen" nach Englisch (en_US, en_GB, …).
* Es wird kein gettext gebraucht: Das .mo-Format wird hier selbst geschrieben.
*/
if ($argc < 2) { fwrite(STDERR, "Aufruf: php build-mo.php <en.json>\n"); exit(1); }
$map = json_decode((string) file_get_contents($argv[1]), true);
if (!is_array($map)) { fwrite(STDERR, "Ungültiges JSON.\n"); exit(1); }
$missing = array_keys(array_filter($map, fn($v) => !is_string($v) || trim($v) === ''));
if ($missing) { fwrite(STDERR, count($missing) . " Texte ohne Übersetzung, z. B.: " . $missing[0] . "\n"); exit(1); }
foreach ($map as $de => $en) {
// Platzhalter (%s, %d) müssen übereinstimmen
preg_match_all('/%(?:\d+\$)?[sd]/', $de, $a);
preg_match_all('/%(?:\d+\$)?[sd]/', $en, $b);
if ($a[0] !== $b[0]) { fwrite(STDERR, "Platzhalter ungleich: $de\n"); exit(1); }
}
$dir = dirname(__DIR__) . '/deskhub-tickets/languages/';
@mkdir($dir, 0777, true);
function po_quote(string $s): string
{
return '"' . str_replace(["\\", "\"", "\n", "\t"], ['\\\\', '\\"', '\\n', '\\t'], $s) . '"';
}
function build_po(array $map, string $locale): string
{
$out = "# DeskHub Tickets: English translation (source language is German)\n"
. "msgid \"\"\nmsgstr \"\"\n"
. "\"Project-Id-Version: DeskHub Tickets 1.0.0\\n\"\n"
. "\"Language: $locale\\n\"\n"
. "\"MIME-Version: 1.0\\n\"\n"
. "\"Content-Type: text/plain; charset=UTF-8\\n\"\n"
. "\"Content-Transfer-Encoding: 8bit\\n\"\n"
. "\"Plural-Forms: nplurals=2; plural=(n != 1);\\n\"\n\n";
foreach ($map as $de => $en) {
$out .= 'msgid ' . po_quote($de) . "\nmsgstr " . po_quote($en) . "\n\n";
}
return $out;
}
function build_mo(array $map, string $locale): string
{
$entries = ['' => "Project-Id-Version: DeskHub Tickets 1.0.0\nLanguage: $locale\nMIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 8bit\nPlural-Forms: nplurals=2; plural=(n != 1);\n"] + $map;
ksort($entries, SORT_STRING);
$n = count($entries);
$ids = '';
$strs = '';
$idTable = [];
$strTable = [];
foreach ($entries as $id => $str) {
$idTable[] = [strlen($id), strlen($ids)];
$ids .= $id . "\0";
$strTable[] = [strlen($str), strlen($strs)];
$strs .= $str . "\0";
}
$headerSize = 28;
$idTableOffset = $headerSize;
$strTableOffset = $idTableOffset + $n * 8;
$idsOffset = $strTableOffset + $n * 8;
$strsOffset = $idsOffset + strlen($ids);
$mo = pack('V*', 0x950412de, 0, $n, $idTableOffset, $strTableOffset, 0, 0);
foreach ($idTable as [$len, $off]) $mo .= pack('VV', $len, $idsOffset + $off);
foreach ($strTable as [$len, $off]) $mo .= pack('VV', $len, $strsOffset + $off);
return $mo . $ids . $strs;
}
foreach (['en_US', 'en_GB', 'en_AU', 'en_CA', 'en_NZ', 'en_ZA'] as $locale) {
file_put_contents($dir . "deskhub-tickets-$locale.po", build_po($map, $locale));
file_put_contents($dir . "deskhub-tickets-$locale.mo", build_mo($map, $locale));
}
echo count($map) . " Texte, 6 Sprachvarianten in " . $dir . "\n";
+124
View File
@@ -0,0 +1,124 @@
{
"API-Schlüssel": "API key",
"Abteilung": "Department",
"Adresse des DeskHub-Servers": "DeskHub server address",
"Anfrage ohne weitere Angaben": "Request without further details",
"Beantwortet": "Answered",
"Besucher wählen ein Thema aus (Bezeichnung:Nummer des Hilfethemas)": "visitors choose a topic (label:number of the help topic)",
"Betreff": "Subject",
"Bitte Server-Adresse und API-Schlüssel eintragen.": "Please enter the server address and API key.",
"Bitte beschreiben Sie Ihr Anliegen.": "Please describe your request.",
"Bitte bestätigen Sie „%s“.": "Please confirm “%s”.",
"Bitte die Adresse Ihres DeskHub-Servers eintragen.": "Please enter the address of your DeskHub server.",
"Bitte füllen Sie das Feld „%s“ aus.": "Please fill in the field “%s”.",
"Bitte geben Sie Ihre Ticketnummer und die E-Mail-Adresse an, mit der Sie das Ticket gesendet haben.": "Please enter your ticket number and the email address you used to submit the ticket.",
"Bitte geben Sie Ihren Namen an (höchstens 120 Zeichen).": "Please enter your name (at most 120 characters).",
"Bitte geben Sie Ihren Namen an.": "Please enter your name.",
"Bitte geben Sie bei „%s“ ein gültiges Datum an.": "Please enter a valid date for “%s”.",
"Bitte geben Sie bei „%s“ eine Zahl an.": "Please enter a number for “%s”.",
"Bitte geben Sie eine gültige E-Mail-Adresse an.": "Please enter a valid email address.",
"Bitte geben Sie einen Betreff an (höchstens 255 Zeichen).": "Please enter a subject (at most 255 characters).",
"Bitte geben Sie einen Betreff an.": "Please enter a subject.",
"Bitte prüfen Sie Ihre Angaben.": "Please check your details.",
"Bitte stimmen Sie der Verarbeitung Ihrer Angaben zu.": "Please agree to the processing of your data.",
"Bitte wählen Sie bei „%s“ eine der angebotenen Möglichkeiten.": "Please choose one of the offered options for “%s”.",
"Bitte wählen Sie ein Thema aus.": "Please choose a topic.",
"Bitte wählen …": "Please choose …",
"Cloudflare Turnstile (optional)": "Cloudflare Turnstile (optional)",
"Dafür fehlt die Berechtigung.": "You do not have permission to do this.",
"Das Formular ist abgelaufen. Bitte laden Sie die Seite neu und versuchen Sie es noch einmal.": "The form has expired. Please reload the page and try again.",
"Das ging etwas zu schnell. Bitte prüfen Sie Ihre Angaben und senden Sie noch einmal ab.": "That was a bit too fast. Please check your details and submit again.",
"Dazu kommt ein unsichtbares Feld, das nur Roboter ausfüllen. Das Formular funktioniert auch mit Seiten-Cache.": "In addition there is an invisible field that only robots fill in. The form also works with page caching.",
"Der DeskHub-Server ist nicht erreichbar.": "The DeskHub server cannot be reached.",
"Der DeskHub-Server kennt die Formular-Schnittstelle noch nicht (bitte DeskHub aktualisieren). Bis dahin wird das einfache Formular ohne eigene Felder gezeigt. (Diese Meldung sehen nur Administratoren.)": "The DeskHub server does not know the form interface yet (please update DeskHub). Until then the simple form without custom fields is shown. (Only administrators see this message.)",
"Der DeskHub-Server kennt die Formular-Schnittstelle noch nicht.": "The DeskHub server does not know the form interface yet.",
"Der Schlüssel ist gültig, aber DeskHub lässt diese Adresse nicht zu. DeskHub meldet: %s": "The key is valid, but DeskHub does not allow this address. DeskHub says: %s",
"Der Server antwortet mit einem Fehler (%d).": "The server responded with an error (%d).",
"Der Server hat den API-Schlüssel abgelehnt. Bitte den Schlüssel prüfen: Er muss genau so eingetragen sein, aktiv sein und darf bei „Erlaubte IPs“ keine andere Adresse verlangen als die dieses WordPress-Servers (im Zweifel das Feld leer lassen).": "The server rejected the API key. Please check the key: it must be entered exactly like this, be active, and its “Allowed IPs” must not demand a different address than this WordPress server’s (if in doubt, leave that field empty).",
"Der Server hat die Anfrage abgelehnt.": "The server rejected the request.",
"Der Server hat eine unerwartete Antwort geliefert.": "The server returned an unexpected response.",
"Der Support ist gerade nicht erreichbar. Bitte versuchen Sie es später noch einmal.": "Support is currently not available. Please try again later.",
"Der Test legt kein Ticket an.": "The test does not create a ticket.",
"DeskHub Tickets": "DeskHub Tickets",
"DeskHub Tickets ist noch nicht eingerichtet (Einstellungen → DeskHub Tickets). Diese Meldung sehen nur Administratoren.": "DeskHub Tickets is not set up yet (Settings → DeskHub Tickets). Only administrators see this message.",
"DeskHub Tickets ist noch nicht eingerichtet: Bitte unter Einstellungen → DeskHub Tickets Server-Adresse und API-Schlüssel eintragen. (Diese Meldung sehen nur Administratoren.)": "DeskHub Tickets is not set up yet: please enter the server address and API key under Settings → DeskHub Tickets. (Only administrators see this message.)",
"DeskHub entscheidet": "DeskHub decides",
"Die Adresse, unter der Ihr DeskHub erreichbar ist. Nur https (http nur für lokale Tests).": "The address where your DeskHub can be reached. https only (http only for local tests).",
"Die Formulare werden beim nächsten Aufruf neu aus DeskHub geladen.": "The forms will be reloaded from DeskHub on the next request.",
"Die Nummern stehen in DeskHub bei der jeweiligen Abteilung, dem Hilfethema und der Priorität. 0 = DeskHub entscheidet (Standardabteilung, Regeln des Hilfethemas). Im Shortcode lassen sich die Werte je Formular überschreiben.": "The numbers are shown in DeskHub next to each department, help topic and priority. 0 = DeskHub decides (default department, rules of the help topic). The values can be overridden per form in the shortcode.",
"Die Server-Adresse ist ungültig.": "The server address is invalid.",
"Die Server-Adresse muss mit https beginnen.": "The server address must start with https.",
"Die Shortcodes funktionieren in Seiten und Beiträgen (im Block-Editor mit dem Block „Shortcode“).": "The shortcodes work in pages and posts (in the block editor use the “Shortcode” block).",
"Die Sicherheitsprüfung ist fehlgeschlagen. Bitte versuchen Sie es noch einmal.": "The security check failed. Please try again.",
"Die Ticketnummer wird automatisch darunter angezeigt.": "The ticket number is shown below it automatically.",
"E-Mail-Adresse": "Email address",
"Eigene Felder und Texte kommen aus DeskHub und werden 5 Minuten gemerkt. Nach einer Änderung dort hier neu laden.": "Custom fields and texts come from DeskHub and are remembered for 5 minutes. After a change there, reload them here.",
"Ein kostenloses Captcha ohne Rätsel. Beide Schlüssel eintragen, dann erscheint es im Formular. Dabei wird eine Verbindung zu Cloudflare aufgebaut: Das gehört in Ihre Datenschutzerklärung.": "A free captcha without puzzles. Enter both keys and it appears in the form. This connects to Cloudflare, so it belongs in your privacy policy.",
"Eingebaut": "Built in",
"Einstellungen": "Settings",
"Einwilligung (Datenschutz)": "Consent (data protection)",
"Formular": "Form",
"Formular zum Anlegen eines Tickets": "form for creating a ticket",
"Formulare neu laden": "Reload forms",
"Geheimer Schlüssel (Secret Key)": "Secret key",
"Geheimer Schlüssel gespeichert": "Secret key saved",
"Gelöst": "Resolved",
"Gerade sind sehr viele Anfragen eingegangen. Bitte versuchen Sie es in einer Minute noch einmal.": "A lot of requests have come in. Please try again in a minute.",
"Geschlossen": "Closed",
"Gesendet über das Formular auf %s": "Sent via the form on %s",
"Hilfethema": "Help topic",
"Höchstens": "At most",
"Ich habe die <a href=\"/datenschutz\">Datenschutzerklärung</a> gelesen und bin mit der Verarbeitung meiner Angaben einverstanden.": "I have read the <a href=\"/privacy\">privacy policy</a> and agree to the processing of my data.",
"Ihr Name": "Your name",
"Ihre Anfrage konnte leider nicht angenommen werden.": "Unfortunately your request could not be accepted.",
"Ihre E-Mail-Adresse": "Your email address",
"Ihre Nachricht": "Your message",
"Ihre Ticketnummer: %s": "Your ticket number: %s",
"In Bearbeitung": "In progress",
"In DeskHub unter <strong>Verwalten → API-Schlüssel</strong> einen Schlüssel erstellen. Er braucht das Recht „Tickets anlegen“, für die Statusabfrage zusätzlich „Tickets lesen“. Sicherer: den Schlüssel in der <code>wp-config.php</code> eintragen: <code>define('DESKHUB_TICKETS_API_KEY', 'dh_…');</code>": "In DeskHub create a key under <strong>Manage → API keys</strong>. It needs the right “Create tickets”, and for the status page also “Read tickets”. Safer: enter the key in <code>wp-config.php</code>: <code>define('DESKHUB_TICKETS_API_KEY', 'dh_…');</code>",
"Ja": "Yes",
"Mindestzeit bis zum Absenden": "Minimum time before submitting",
"Nein": "No",
"Nummern in DeskHub": "Numbers in DeskHub",
"Offen": "Open",
"Optional: Nach dem Absenden erscheint ein Link „Stand abfragen“ zu dieser Seite (dort steht der Shortcode [deskhub_status]).": "Optional: after submitting, a link “Check status” to this page appears (it contains the shortcode [deskhub_status]).",
"Priorität": "Priority",
"Schlüssel entfernen": "Remove key",
"Seite mit der Statusabfrage": "Page with the status lookup",
"Sekunden": "seconds",
"Sie": "You",
"Sie haben in der letzten Stunde schon mehrere Tickets gesendet. Bitte versuchen Sie es später noch einmal.": "You have already sent several tickets in the last hour. Please try again later.",
"So binden Sie es ein": "How to add it",
"Spamschutz": "Spam protection",
"Speichern": "Save",
"Speichern und Verbindung testen": "Save and test connection",
"Stand abfragen": "Check status",
"Statusabfrage mit Ticketnummer und E-Mail-Adresse": "status lookup with ticket number and email address",
"Support": "Support",
"Text nach dem Absenden": "Text after submitting",
"Ticket %s": "Ticket %s",
"Ticket absenden": "Submit ticket",
"Ticket-Voreinstellungen": "Ticket defaults",
"Ticketnummer": "Ticket number",
"Tickets je Besucher und Stunde (0 = unbegrenzt)": "tickets per visitor and hour (0 = unlimited)",
"Verbindet WordPress mit Ihrem DeskHub-Helpdesk: Besucher legen Tickets über ein Formular an und können den Stand abfragen.": "Connects WordPress to your DeskHub helpdesk: visitors create tickets through a form and can check the status.",
"Verbindung": "Connection",
"Verbindung steht, der Schlüssel ist gültig und darf Tickets lesen.": "Connection works, the key is valid and may read tickets.",
"Verbindung steht, der Schlüssel ist gültig. Er darf aber keine Tickets lesen: Die Statusabfrage funktioniert damit nicht (in DeskHub unter Verwalten → API-Schlüssel das Recht „Tickets lesen“ geben).": "Connection works, the key is valid. However it may not read tickets, so the status lookup will not work (in DeskHub give it the right “Read tickets” under Manage → API keys).",
"Verbindung steht.": "Connection works.",
"Vielen Dank! Wir melden uns so schnell wie möglich per E-Mail.": "Thank you! We will get back to you by email as soon as possible.",
"Wartet auf Ihre Antwort": "Waiting for your reply",
"Website-Schlüssel (Site Key)": "Site key",
"Wenn ausgefüllt, muss der Besucher dieses Kästchen anhaken. Erlaubt sind Links (a), fett und kursiv.": "If filled in, the visitor has to tick this box. Links (a), bold and italic are allowed.",
"Worum geht es?": "What is it about?",
"Zu dieser Kombination aus Ticketnummer und E-Mail-Adresse wurde nichts gefunden.": "Nothing was found for this combination of ticket number and email address.",
"Zu viele Abfragen. Bitte versuchen Sie es in einigen Minuten noch einmal.": "Too many lookups. Please try again in a few minutes.",
"Zuletzt geändert: %s": "Last changed: %s",
"aus der wp-config.php": "from wp-config.php",
"entfernen": "remove",
"gespeichert, zum Ändern neuen Schlüssel eintragen": "saved, enter a new key to change it",
"mit festen Voreinstellungen für dieses Formular": "with fixed defaults for this form",
"Akzentfarbe": "Accent color",
"Automatisch vom Theme übernehmen": "Take automatically from the theme",
"Schrift, Hintergrund und Rahmen übernimmt das Formular immer vom Theme. Die Akzentfarbe (Knopf, Hervorhebung) wird automatisch aus Knöpfen und Links der Seite gelesen; hier lässt sie sich fest vorgeben.": "The form always takes font, background and border from the theme. The accent color (button, highlights) is read automatically from buttons and links of the page; you can set it here."
}
@@ -0,0 +1,19 @@
<?php
/**
* Sammelt alle übersetzbaren Texte des Plugins (deutscher Quelltext) und schreibt sie als JSON-Gerüst.
* php wordpress-plugin/tools/extract-strings.php > texte.json
* Danach die englischen Werte eintragen und mit build-mo.php daraus languages/*.po und *.mo erzeugen.
*/
$root = dirname(__DIR__) . '/deskhub-tickets';
$strings = [];
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($root, FilesystemIterator::SKIP_DOTS));
foreach ($it as $f) {
if (substr($f->getPathname(), -4) !== '.php') continue;
$src = file_get_contents($f->getPathname());
// __('…', 'deskhub-tickets'), esc_html__(…), esc_attr__(…); Texte in einfachen Anführungszeichen mit \' darin
if (preg_match_all("/(?:__|esc_html__|esc_attr__)\\(\\s*'((?:[^'\\\\]|\\\\.)*)'\\s*,\\s*'deskhub-tickets'\\s*\\)/s", $src, $m)) {
foreach ($m[1] as $s) $strings[stripcslashes(str_replace("\\'", "'", $s))] = '';
}
}
ksort($strings);
echo json_encode($strings, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n";
+28
View File
@@ -0,0 +1,28 @@
<?php
/**
* Packt das WordPress-Plugin als ZIP (nur der Ordner deskhub-tickets, ohne Tests und Werkzeuge) nach release/.
* php wordpress-plugin/tools/pack.php
*/
$root = dirname(__DIR__);
$src = $root . '/deskhub-tickets';
$main = (string) file_get_contents($src . '/deskhub-tickets.php');
if (!preg_match('/^\s*\*\s*Version:\s*(\S+)/m', $main, $m)) { fwrite(STDERR, "Version nicht gefunden.\n"); exit(1); }
$version = $m[1];
$outDir = dirname($root) . '/release';
@mkdir($outDir, 0777, true);
$out = $outDir . "/deskhub-tickets-wordpress-$version.zip";
@unlink($out);
$files = [];
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($src, FilesystemIterator::SKIP_DOTS));
foreach ($it as $f) {
$rel = str_replace(chr(92), '/', substr($f->getPathname(), strlen($src) + 1));
$files[$rel] = $f->getPathname();
}
ksort($files);
$zip = new ZipArchive();
if ($zip->open($out, ZipArchive::CREATE) !== true) { fwrite(STDERR, "ZIP lässt sich nicht anlegen.\n"); exit(1); }
foreach ($files as $rel => $path) {
$zip->addFile($path, 'deskhub-tickets/' . $rel); // immer mit /, im Ordner deskhub-tickets (WordPress verlangt das)
}
$zip->close();
echo count($files) . " Dateien -> $out (" . filesize($out) . " Bytes)\n";