280 lines
19 KiB
PHP
280 lines
19 KiB
PHP
<?php
|
||
/**
|
||
* Einstellungsseite (Einstellungen → DeskHub Tickets).
|
||
*/
|
||
|
||
if (!defined('ABSPATH')) {
|
||
exit;
|
||
}
|
||
|
||
class Deskhub_Tickets_Settings
|
||
{
|
||
const PAGE = 'deskhub-tickets';
|
||
const GROUP = 'deskhub_tickets';
|
||
|
||
public static function init(): void
|
||
{
|
||
add_action('admin_menu', [__CLASS__, 'menu']);
|
||
add_action('admin_init', [__CLASS__, 'register']);
|
||
add_action('admin_post_deskhub_tickets_clear_cache', [__CLASS__, 'handle_clear_cache']);
|
||
add_filter('plugin_action_links_' . plugin_basename(DESKHUB_TICKETS_FILE), [__CLASS__, 'action_links']);
|
||
}
|
||
|
||
public static function menu(): void
|
||
{
|
||
add_options_page(
|
||
__('DeskHub Tickets', 'deskhub-tickets'),
|
||
__('DeskHub Tickets', 'deskhub-tickets'),
|
||
'manage_options',
|
||
self::PAGE,
|
||
[__CLASS__, 'render']
|
||
);
|
||
}
|
||
|
||
public static function action_links(array $links): array
|
||
{
|
||
array_unshift($links, '<a href="' . esc_url(admin_url('options-general.php?page=' . self::PAGE)) . '">' . esc_html__('Einstellungen', 'deskhub-tickets') . '</a>');
|
||
return $links;
|
||
}
|
||
|
||
public static function register(): void
|
||
{
|
||
register_setting(self::GROUP, 'deskhub_tickets_options', [
|
||
'type' => 'array',
|
||
'sanitize_callback' => [__CLASS__, 'sanitize'],
|
||
'default' => [],
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* Prüft und bereinigt die abgeschickten Einstellungen. Der API-Schlüssel bleibt erhalten, wenn das Feld leer ist
|
||
* (er wird nie wieder in die Seite geschrieben).
|
||
*/
|
||
public static function sanitize($input): array
|
||
{
|
||
$input = is_array($input) ? $input : [];
|
||
$old = get_option('deskhub_tickets_options', []);
|
||
$old = array_merge(deskhub_tickets_defaults(), is_array($old) ? $old : []);
|
||
$out = deskhub_tickets_defaults();
|
||
|
||
$url = trim((string) ($input['server_url'] ?? ''));
|
||
if ($url === '') {
|
||
$out['server_url'] = '';
|
||
} else {
|
||
$norm = Deskhub_Tickets_Client::normalize_url($url);
|
||
if (is_wp_error($norm)) {
|
||
add_settings_error('deskhub_tickets_options', 'deskhub_url', $norm->get_error_message());
|
||
$out['server_url'] = (string) $old['server_url'];
|
||
} else {
|
||
$out['server_url'] = $norm;
|
||
}
|
||
}
|
||
|
||
if (!empty($input['clear_key'])) {
|
||
$out['api_key'] = '';
|
||
} else {
|
||
$key = trim((string) ($input['api_key'] ?? ''));
|
||
$key = preg_replace('/[^\x21-\x7E]/', '', $key);
|
||
$out['api_key'] = $key !== '' ? $key : (string) $old['api_key'];
|
||
}
|
||
|
||
foreach (['department_id', 'topic_id', 'priority_id'] as $f) {
|
||
$out[$f] = absint($input[$f] ?? 0);
|
||
}
|
||
$out['consent_text'] = wp_kses((string) ($input['consent_text'] ?? ''), [
|
||
'a' => ['href' => [], 'target' => [], 'rel' => []],
|
||
'strong' => [],
|
||
'em' => [],
|
||
]);
|
||
$accent = sanitize_hex_color((string) ($input['accent_color'] ?? ''));
|
||
$out['accent_color'] = empty($input['accent_auto']) && $accent ? $accent : '';
|
||
$out['success_text'] = mb_substr(sanitize_text_field((string) ($input['success_text'] ?? '')), 0, 500);
|
||
$out['status_page_url'] = esc_url_raw((string) ($input['status_page_url'] ?? ''));
|
||
$out['min_seconds'] = max(0, min(60, absint($input['min_seconds'] ?? 3)));
|
||
$out['rate_limit_per_hour'] = max(0, min(100, absint($input['rate_limit_per_hour'] ?? 5)));
|
||
$out['turnstile_site'] = sanitize_text_field((string) ($input['turnstile_site'] ?? ''));
|
||
$secret = trim(sanitize_text_field((string) ($input['turnstile_secret'] ?? '')));
|
||
$out['turnstile_secret'] = !empty($input['clear_turnstile']) ? '' : ($secret !== '' ? $secret : (string) $old['turnstile_secret']);
|
||
|
||
// „Speichern und Verbindung testen“: prüft gleich die Werte, die gerade gespeichert werden (nicht erst die schon gespeicherten)
|
||
if (!empty($_POST['dht_test_after']) && current_user_can('manage_options')) {
|
||
$key = deskhub_tickets_key_from_config() ? (string) DESKHUB_TICKETS_API_KEY : (string) $out['api_key'];
|
||
$url = defined('DESKHUB_TICKETS_SERVER') && DESKHUB_TICKETS_SERVER !== '' ? (string) DESKHUB_TICKETS_SERVER : (string) $out['server_url'];
|
||
$norm = Deskhub_Tickets_Client::normalize_url($url);
|
||
$result = (is_wp_error($norm) || trim($key) === '')
|
||
? ['ok' => false, 'message' => __('Bitte Server-Adresse und API-Schlüssel eintragen.', 'deskhub-tickets'), 'canRead' => false]
|
||
: (new Deskhub_Tickets_Client($norm, trim($key)))->test_connection();
|
||
set_transient('deskhub_tickets_test_' . get_current_user_id(), $result, 120);
|
||
}
|
||
return $out;
|
||
}
|
||
|
||
/** „Formulare neu laden“: leert den Zwischenspeicher der Kundenformulare aus DeskHub. */
|
||
public static function handle_clear_cache(): void
|
||
{
|
||
if (!current_user_can('manage_options')) {
|
||
wp_die(esc_html__('Dafür fehlt die Berechtigung.', 'deskhub-tickets'), '', ['response' => 403]);
|
||
}
|
||
check_admin_referer('deskhub_tickets_clear_cache');
|
||
Deskhub_Tickets_Client::clear_form_cache();
|
||
set_transient('deskhub_tickets_test_' . get_current_user_id(), ['ok' => true, 'message' => __('Die Formulare werden beim nächsten Aufruf neu aus DeskHub geladen.', 'deskhub-tickets'), 'canRead' => true], 120);
|
||
wp_safe_redirect(admin_url('options-general.php?page=' . self::PAGE . '&dht_tested=1'));
|
||
exit;
|
||
}
|
||
|
||
public static function render(): void
|
||
{
|
||
if (!current_user_can('manage_options')) {
|
||
return;
|
||
} $o = deskhub_tickets_options();
|
||
$name = 'deskhub_tickets_options';
|
||
$keyFromConfig = deskhub_tickets_key_from_config();
|
||
$hasKey = trim((string) $o['api_key']) !== '';
|
||
$hasSecret = trim((string) $o['turnstile_secret']) !== '';
|
||
$topicList = [];
|
||
$cl = Deskhub_Tickets_Client::from_settings();
|
||
if ($cl) {
|
||
$tl = $cl->get_topics();
|
||
$topicList = is_array($tl) ? $tl : [];
|
||
}
|
||
$tk = 'deskhub_tickets_test_' . get_current_user_id();
|
||
$test = get_transient($tk); // Ergebnis von „Speichern und Verbindung testen“ bzw. „Formulare neu laden“ (wird nur einmal gezeigt)
|
||
delete_transient($tk);
|
||
?>
|
||
<div class="wrap">
|
||
<h1><?php echo esc_html__('DeskHub Tickets', 'deskhub-tickets'); ?></h1>
|
||
<p><?php echo esc_html__('Verbindet WordPress mit Ihrem DeskHub-Helpdesk: Besucher legen Tickets über ein Formular an und können den Stand abfragen.', 'deskhub-tickets'); ?></p>
|
||
|
||
<?php if (is_array($test)): ?>
|
||
<div class="notice <?php echo !empty($test['ok']) ? 'notice-success' : 'notice-error'; ?>"><p><?php echo esc_html((string) $test['message']); ?></p></div>
|
||
<?php endif; ?>
|
||
<?php settings_errors('deskhub_tickets_options'); ?>
|
||
|
||
<form method="post" action="options.php">
|
||
<?php settings_fields(self::GROUP); ?>
|
||
<h2><?php echo esc_html__('Verbindung', 'deskhub-tickets'); ?></h2>
|
||
<table class="form-table" role="presentation">
|
||
<tr>
|
||
<th scope="row"><label for="dht_server"><?php echo esc_html__('Adresse des DeskHub-Servers', 'deskhub-tickets'); ?></label></th>
|
||
<td>
|
||
<input type="text" id="dht_server" class="regular-text" name="<?php echo esc_attr($name); ?>[server_url]" value="<?php echo esc_attr((string) $o['server_url']); ?>" placeholder="https://support.example.de" autocomplete="off">
|
||
<p class="description"><?php echo esc_html__('Die Adresse, unter der Ihr DeskHub erreichbar ist. Nur https (http nur für lokale Tests).', 'deskhub-tickets'); ?></p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th scope="row"><label for="dht_key"><?php echo esc_html__('API-Schlüssel', 'deskhub-tickets'); ?></label></th>
|
||
<td>
|
||
<?php if ($keyFromConfig): ?>
|
||
<input type="text" class="regular-text" value="<?php echo esc_attr__('aus der wp-config.php', 'deskhub-tickets'); ?>" disabled>
|
||
<?php else: ?>
|
||
<input type="password" id="dht_key" class="regular-text" name="<?php echo esc_attr($name); ?>[api_key]" value="" autocomplete="new-password" placeholder="<?php echo $hasKey ? esc_attr__('gespeichert, zum Ändern neuen Schlüssel eintragen', 'deskhub-tickets') : 'dh_…'; ?>">
|
||
<?php if ($hasKey): ?>
|
||
<label style="margin-left:8px"><input type="checkbox" name="<?php echo esc_attr($name); ?>[clear_key]" value="1"> <?php echo esc_html__('Schlüssel entfernen', 'deskhub-tickets'); ?></label>
|
||
<?php endif; ?>
|
||
<?php endif; ?>
|
||
<p class="description"><?php echo wp_kses(
|
||
__('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>', 'deskhub-tickets'),
|
||
['strong' => [], 'code' => []]
|
||
); ?></p>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
<h2><?php echo esc_html__('Ticket-Voreinstellungen', 'deskhub-tickets'); ?></h2>
|
||
<table class="form-table" role="presentation">
|
||
<tr>
|
||
<th scope="row"><?php echo esc_html__('Nummern in DeskHub', 'deskhub-tickets'); ?></th>
|
||
<td>
|
||
<label><?php echo esc_html__('Abteilung', 'deskhub-tickets'); ?> <input type="number" min="0" class="small-text" name="<?php echo esc_attr($name); ?>[department_id]" value="<?php echo esc_attr((string) (int) $o['department_id']); ?>"></label>
|
||
<label style="margin-left:12px"><?php echo esc_html__('Hilfethema', 'deskhub-tickets'); ?> <?php if ($topicList): ?>
|
||
<select name="<?php echo esc_attr($name); ?>[topic_id]">
|
||
<option value="0"><?php echo esc_html__('DeskHub entscheidet', 'deskhub-tickets'); ?></option>
|
||
<?php foreach ($topicList as $tp): ?><option value="<?php echo (int) $tp['id']; ?>" <?php selected((int) $o['topic_id'], (int) $tp['id']); ?>><?php echo esc_html((string) $tp['path']); ?> (<?php echo (int) $tp['id']; ?>)</option><?php endforeach; ?>
|
||
</select>
|
||
<?php else: ?><input type="number" min="0" class="small-text" name="<?php echo esc_attr($name); ?>[topic_id]" value="<?php echo esc_attr((string) (int) $o['topic_id']); ?>"><?php endif; ?></label>
|
||
<label style="margin-left:12px"><?php echo esc_html__('Priorität', 'deskhub-tickets'); ?> <input type="number" min="0" class="small-text" name="<?php echo esc_attr($name); ?>[priority_id]" value="<?php echo esc_attr((string) (int) $o['priority_id']); ?>"></label>
|
||
<p class="description"><?php echo esc_html__('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.', 'deskhub-tickets'); ?></p>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
<h2><?php echo esc_html__('Formular', 'deskhub-tickets'); ?></h2>
|
||
<table class="form-table" role="presentation">
|
||
<tr>
|
||
<th scope="row"><label for="dht_consent"><?php echo esc_html__('Einwilligung (Datenschutz)', 'deskhub-tickets'); ?></label></th>
|
||
<td>
|
||
<textarea id="dht_consent" class="large-text" rows="3" name="<?php echo esc_attr($name); ?>[consent_text]" placeholder="<?php echo esc_attr__('Ich habe die <a href="/datenschutz">Datenschutzerklärung</a> gelesen und bin mit der Verarbeitung meiner Angaben einverstanden.', 'deskhub-tickets'); ?>"><?php echo esc_textarea((string) $o['consent_text']); ?></textarea>
|
||
<p class="description"><?php echo esc_html__('Wenn ausgefüllt, muss der Besucher dieses Kästchen anhaken. Erlaubt sind Links (a), fett und kursiv.', 'deskhub-tickets'); ?></p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th scope="row"><label for="dht_accent"><?php echo esc_html__('Akzentfarbe', 'deskhub-tickets'); ?></label></th>
|
||
<td>
|
||
<input type="color" id="dht_accent" name="<?php echo esc_attr($name); ?>[accent_color]" value="<?php echo esc_attr((string) $o['accent_color'] !== '' ? (string) $o['accent_color'] : '#0f6f6a'); ?>">
|
||
<label><input type="checkbox" name="<?php echo esc_attr($name); ?>[accent_auto]" value="1" <?php checked((string) $o['accent_color'] === ''); ?>> <?php echo esc_html__('Automatisch vom Theme übernehmen', 'deskhub-tickets'); ?></label>
|
||
<p class="description"><?php echo esc_html__('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.', 'deskhub-tickets'); ?></p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th scope="row"><label for="dht_success"><?php echo esc_html__('Text nach dem Absenden', 'deskhub-tickets'); ?></label></th>
|
||
<td>
|
||
<input type="text" id="dht_success" class="large-text" name="<?php echo esc_attr($name); ?>[success_text]" value="<?php echo esc_attr((string) $o['success_text']); ?>" placeholder="<?php echo esc_attr__('Vielen Dank! Wir melden uns so schnell wie möglich per E-Mail.', 'deskhub-tickets'); ?>">
|
||
<p class="description"><?php echo esc_html__('Die Ticketnummer wird automatisch darunter angezeigt.', 'deskhub-tickets'); ?></p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th scope="row"><label for="dht_status_url"><?php echo esc_html__('Seite mit der Statusabfrage', 'deskhub-tickets'); ?></label></th>
|
||
<td>
|
||
<input type="url" id="dht_status_url" class="regular-text" name="<?php echo esc_attr($name); ?>[status_page_url]" value="<?php echo esc_attr((string) $o['status_page_url']); ?>" placeholder="https://ihre-seite.de/ticket-status">
|
||
<p class="description"><?php echo esc_html__('Optional: Nach dem Absenden erscheint ein Link „Stand abfragen“ zu dieser Seite (dort steht der Shortcode [deskhub_status]).', 'deskhub-tickets'); ?></p>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
<h2><?php echo esc_html__('Spamschutz', 'deskhub-tickets'); ?></h2>
|
||
<table class="form-table" role="presentation">
|
||
<tr>
|
||
<th scope="row"><?php echo esc_html__('Eingebaut', 'deskhub-tickets'); ?></th>
|
||
<td>
|
||
<label><?php echo esc_html__('Mindestzeit bis zum Absenden', 'deskhub-tickets'); ?> <input type="number" min="0" max="60" class="small-text" name="<?php echo esc_attr($name); ?>[min_seconds]" value="<?php echo esc_attr((string) (int) $o['min_seconds']); ?>"> <?php echo esc_html__('Sekunden', 'deskhub-tickets'); ?></label><br>
|
||
<label><?php echo esc_html__('Höchstens', 'deskhub-tickets'); ?> <input type="number" min="0" max="100" class="small-text" name="<?php echo esc_attr($name); ?>[rate_limit_per_hour]" value="<?php echo esc_attr((string) (int) $o['rate_limit_per_hour']); ?>"> <?php echo esc_html__('Tickets je Besucher und Stunde (0 = unbegrenzt)', 'deskhub-tickets'); ?></label>
|
||
<p class="description"><?php echo esc_html__('Dazu kommt ein unsichtbares Feld, das nur Roboter ausfüllen. Das Formular funktioniert auch mit Seiten-Cache.', 'deskhub-tickets'); ?></p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th scope="row"><?php echo esc_html__('Cloudflare Turnstile (optional)', 'deskhub-tickets'); ?></th>
|
||
<td>
|
||
<input type="text" class="regular-text" name="<?php echo esc_attr($name); ?>[turnstile_site]" value="<?php echo esc_attr((string) $o['turnstile_site']); ?>" placeholder="<?php echo esc_attr__('Website-Schlüssel (Site Key)', 'deskhub-tickets'); ?>" autocomplete="off"><br>
|
||
<input type="password" class="regular-text" style="margin-top:6px" name="<?php echo esc_attr($name); ?>[turnstile_secret]" value="" placeholder="<?php echo $hasSecret ? esc_attr__('Geheimer Schlüssel gespeichert', 'deskhub-tickets') : esc_attr__('Geheimer Schlüssel (Secret Key)', 'deskhub-tickets'); ?>" autocomplete="new-password">
|
||
<?php if ($hasSecret): ?><label style="margin-left:8px"><input type="checkbox" name="<?php echo esc_attr($name); ?>[clear_turnstile]" value="1"> <?php echo esc_html__('entfernen', 'deskhub-tickets'); ?></label><?php endif; ?>
|
||
<p class="description"><?php echo esc_html__('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.', 'deskhub-tickets'); ?></p>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
<p class="submit">
|
||
<button type="submit" name="submit" class="button button-primary" value="1"><?php echo esc_html__('Speichern', 'deskhub-tickets'); ?></button>
|
||
<button type="submit" name="dht_test_after" class="button" value="1"><?php echo esc_html__('Speichern und Verbindung testen', 'deskhub-tickets'); ?></button>
|
||
<span class="description" style="margin-left:8px"><?php echo esc_html__('Der Test legt kein Ticket an.', 'deskhub-tickets'); ?></span>
|
||
</p>
|
||
</form>
|
||
|
||
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" style="margin:-8px 0 24px">
|
||
<input type="hidden" name="action" value="deskhub_tickets_clear_cache">
|
||
<?php wp_nonce_field('deskhub_tickets_clear_cache'); ?>
|
||
<button type="submit" class="button"><?php echo esc_html__('Formulare neu laden', 'deskhub-tickets'); ?></button>
|
||
<span class="description"><?php echo esc_html__('Eigene Felder und Texte kommen aus DeskHub und werden 5 Minuten gemerkt. Nach einer Änderung dort hier neu laden.', 'deskhub-tickets'); ?></span>
|
||
</form>
|
||
|
||
<h2><?php echo esc_html__('So binden Sie es ein', 'deskhub-tickets'); ?></h2>
|
||
<p><?php echo esc_html__('Die Shortcodes funktionieren in Seiten und Beiträgen (im Block-Editor mit dem Block „Shortcode“).', 'deskhub-tickets'); ?></p>
|
||
<ul style="list-style:disc;margin-left:22px">
|
||
<li><code>[deskhub_ticket]</code> – <?php echo esc_html__('Formular zum Anlegen eines Tickets', 'deskhub-tickets'); ?></li>
|
||
<li><code>[deskhub_ticket department="2" topic="5" priority="1"]</code> – <?php echo esc_html__('mit festen Voreinstellungen für dieses Formular', 'deskhub-tickets'); ?></li>
|
||
<li><code>[deskhub_ticket topics="Rechnung:3,Technik:4"]</code> – <?php echo esc_html__('Besucher wählen ein Thema aus (Bezeichnung:Nummer des Hilfethemas)', 'deskhub-tickets'); ?></li>
|
||
<li><code>[deskhub_status]</code> – <?php echo esc_html__('Statusabfrage mit Ticketnummer und E-Mail-Adresse', 'deskhub-tickets'); ?></li>
|
||
</ul>
|
||
</div>
|
||
<?php
|
||
}
|
||
}
|