646 lines
No EOL
22 KiB
PHP
646 lines
No EOL
22 KiB
PHP
<?php
|
||
/**
|
||
* Plugin Name: Donau2Space – KI-Erklärbuttons (ChatGPT, Grok, Perplexity)
|
||
* Description: Buttons unter Content oder per Shortcode. Admin-Einstellungen: Prompt, Hint-Text, Kategorie-Ausschluss, Einfügemodus, Post Types (inkl. Seiten), Styling (CSS-Variablen).
|
||
* Version: 1.4.1
|
||
* Author: Donau2Space
|
||
*/
|
||
|
||
if (!defined('ABSPATH')) exit;
|
||
|
||
define('D2S_KI_OPT_PROMPT', 'd2s_ki_prompt_prefix');
|
||
define('D2S_KI_OPT_HINT', 'd2s_ki_hint_text');
|
||
|
||
define('D2S_KI_OPT_EXCL_CATS', 'd2s_ki_excluded_category_ids');
|
||
define('D2S_KI_OPT_MODE', 'd2s_ki_insertion_mode'); // auto | shortcode | both
|
||
define('D2S_KI_OPT_POST_TYPES', 'd2s_ki_post_types'); // array of allowed post types
|
||
define('D2S_KI_OPT_STYLE', 'd2s_ki_style'); // associative array
|
||
|
||
/* =========================
|
||
* Defaults
|
||
* ========================= */
|
||
|
||
function d2s_ki_default_prompt_prefix(): string {
|
||
return 'Kannst du mir den Blogartikel ganz einfach erklären und die wichtigsten Punkte auflisten?';
|
||
}
|
||
|
||
function d2s_ki_default_hint_text(): string {
|
||
return 'Wenn du beim Lesen denkst „Worum geht’s hier eigentlich genau?“ – dann lass dir’s von der KI in einfachen Worten erklären.';
|
||
}
|
||
|
||
function d2s_ki_default_mode(): string {
|
||
return 'auto'; // auto | shortcode | both
|
||
}
|
||
|
||
function d2s_ki_default_post_types(): array {
|
||
return ['post']; // user can add 'page' in admin
|
||
}
|
||
|
||
function d2s_ki_default_style(): array {
|
||
return [
|
||
'gpt_bg' => '#10a37f',
|
||
'gpt_fg' => '#ffffff',
|
||
'grok_bg' => '#000000',
|
||
'grok_fg' => '#ffffff',
|
||
'pplx_bg' => '#1557ff',
|
||
'pplx_fg' => '#ffffff',
|
||
|
||
'radius' => '999px',
|
||
'pad_y' => '0.65rem',
|
||
'pad_x' => '1rem',
|
||
'gap' => '0.5rem',
|
||
'shadow' => '0 6px 20px rgba(0,0,0,.12)',
|
||
'shadow_h' => '0 8px 26px rgba(0,0,0,.18)',
|
||
'scale_h' => '1.02',
|
||
];
|
||
}
|
||
|
||
/* =========================
|
||
* Option getters
|
||
* ========================= */
|
||
|
||
function d2s_ki_get_prompt_prefix(): string {
|
||
$v = get_option(D2S_KI_OPT_PROMPT, d2s_ki_default_prompt_prefix());
|
||
$v = is_string($v) ? trim(wp_strip_all_tags($v)) : '';
|
||
return $v !== '' ? $v : d2s_ki_default_prompt_prefix();
|
||
}
|
||
|
||
function d2s_ki_get_hint_text(): string {
|
||
$v = get_option(D2S_KI_OPT_HINT, d2s_ki_default_hint_text());
|
||
$v = is_string($v) ? trim(wp_strip_all_tags($v)) : '';
|
||
return $v !== '' ? $v : d2s_ki_default_hint_text();
|
||
}
|
||
|
||
function d2s_ki_get_excluded_cat_ids(): array {
|
||
$v = get_option(D2S_KI_OPT_EXCL_CATS, []);
|
||
if (!is_array($v)) return [];
|
||
return array_values(array_filter(array_map('intval', $v), fn($id) => $id > 0));
|
||
}
|
||
|
||
function d2s_ki_get_mode(): string {
|
||
$v = get_option(D2S_KI_OPT_MODE, d2s_ki_default_mode());
|
||
$allowed = ['auto','shortcode','both'];
|
||
return in_array($v, $allowed, true) ? $v : d2s_ki_default_mode();
|
||
}
|
||
|
||
function d2s_ki_get_post_types(): array {
|
||
$v = get_option(D2S_KI_OPT_POST_TYPES, d2s_ki_default_post_types());
|
||
if (!is_array($v)) $v = d2s_ki_default_post_types();
|
||
$v = array_values(array_filter(array_map('sanitize_key', $v)));
|
||
|
||
$existing = get_post_types(['public' => true], 'names');
|
||
$v = array_values(array_filter($v, fn($pt) => isset($existing[$pt])));
|
||
return $v ?: d2s_ki_default_post_types();
|
||
}
|
||
|
||
function d2s_ki_get_style(): array {
|
||
$v = get_option(D2S_KI_OPT_STYLE, d2s_ki_default_style());
|
||
if (!is_array($v)) $v = [];
|
||
return array_merge(d2s_ki_default_style(), $v);
|
||
}
|
||
|
||
/* =========================
|
||
* Logic: Should display?
|
||
* ========================= */
|
||
|
||
function d2s_ki_is_allowed_on_post(int $post_id, string $context = 'auto'): bool {
|
||
if (!$post_id) return false;
|
||
|
||
$pt = get_post_type($post_id);
|
||
if (!$pt) return false;
|
||
|
||
$allowed_pts = d2s_ki_get_post_types();
|
||
if (!in_array($pt, $allowed_pts, true)) return false;
|
||
|
||
if ($pt === 'post') {
|
||
$excluded = d2s_ki_get_excluded_cat_ids();
|
||
if ($excluded && has_category($excluded, $post_id)) return false;
|
||
}
|
||
|
||
$mode = d2s_ki_get_mode();
|
||
if ($context === 'auto' && !in_array($mode, ['auto','both'], true)) return false;
|
||
if ($context === 'shortcode' && !in_array($mode, ['shortcode','both'], true)) return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
/* =========================
|
||
* Prompt + Providers
|
||
* ========================= */
|
||
|
||
/**
|
||
* Prompt bauen:
|
||
* - Promptprefix
|
||
* - LEERZEILE
|
||
* - URL
|
||
*
|
||
* Vorteil: immer sauber getrennt (kein "…?https://")
|
||
*/
|
||
function d2s_ki_build_prompt(string $post_url): string {
|
||
$prefix = trim(d2s_ki_get_prompt_prefix());
|
||
|
||
// Falls jemand im Prefix am Ende ein Satzzeichen ohne Leerzeichen hat: egal, wir trennen fix.
|
||
// 2 Zeilen sind in Chat-UIs super lesbar.
|
||
return $prefix . "\n\n" . $post_url;
|
||
}
|
||
|
||
function d2s_ki_providers(string $prompt): array {
|
||
$q = http_build_query(['q' => $prompt], '', '&', PHP_QUERY_RFC3986);
|
||
|
||
return [
|
||
[
|
||
'key' => 'chatgpt',
|
||
'name' => 'Mit ChatGPT erklären lassen',
|
||
'href' => 'https://chatgpt.com/?' . $q,
|
||
'title' => 'Öffnet ChatGPT mit vorbefüllter Nachricht',
|
||
'icon' => '💬',
|
||
],
|
||
[
|
||
'key' => 'grok',
|
||
'name' => 'Mit Grok erklären lassen',
|
||
'href' => 'https://grok.com/?' . $q,
|
||
'title' => 'Öffnet Grok mit vorbefüllter Nachricht',
|
||
'icon' => '🧠',
|
||
],
|
||
[
|
||
'key' => 'perplexity',
|
||
'name' => 'Mit Perplexity erklären lassen',
|
||
'href' => 'https://www.perplexity.ai/search?' . $q,
|
||
'title' => 'Öffnet Perplexity mit vorbefüllter Anfrage',
|
||
'icon' => '🔎',
|
||
],
|
||
];
|
||
}
|
||
|
||
/* =========================
|
||
* Rendering
|
||
* ========================= */
|
||
|
||
function d2s_ki_render_markup(int $post_id): string {
|
||
$post_url = get_permalink($post_id);
|
||
$prompt = d2s_ki_build_prompt($post_url);
|
||
$links = d2s_ki_providers($prompt);
|
||
$hint = d2s_ki_get_hint_text();
|
||
|
||
ob_start(); ?>
|
||
<div class="d2s-ki-buttons" aria-label="Erklär-Buttons">
|
||
<?php foreach ($links as $lnk): ?>
|
||
<a
|
||
href="<?php echo esc_url($lnk['href']); ?>"
|
||
class="d2s-ki-btn d2s-ki-<?php echo esc_attr($lnk['key']); ?>"
|
||
onclick="window.open('<?php echo esc_js($lnk['href']); ?>', '_blank', 'noopener,noreferrer'); return false;"
|
||
title="<?php echo esc_attr($lnk['title']); ?>"
|
||
aria-label="<?php echo esc_attr($lnk['title']); ?>"
|
||
>
|
||
<span class="d2s-ki-icon"><?php echo esc_html($lnk['icon']); ?></span>
|
||
<span class="d2s-ki-text"><?php echo esc_html($lnk['name']); ?></span>
|
||
</a>
|
||
<?php endforeach; ?>
|
||
|
||
<?php if ($hint !== ''): ?>
|
||
<small class="d2s-ki-hint"><?php echo esc_html($hint); ?></small>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|
||
|
||
/**
|
||
* Auto insertion: under content
|
||
*/
|
||
function d2s_ki_render_buttons($content) {
|
||
if (!is_singular()) return $content;
|
||
|
||
$post_id = (int) get_queried_object_id();
|
||
if (!d2s_ki_is_allowed_on_post($post_id, 'auto')) return $content;
|
||
|
||
return $content . d2s_ki_render_markup($post_id);
|
||
}
|
||
add_filter('the_content', 'd2s_ki_render_buttons', 20);
|
||
|
||
/**
|
||
* Shortcode: [d2s_ki_buttons]
|
||
*/
|
||
function d2s_ki_shortcode() {
|
||
if (!is_singular()) return '';
|
||
|
||
$post_id = (int) get_queried_object_id();
|
||
if (!d2s_ki_is_allowed_on_post($post_id, 'shortcode')) return '';
|
||
|
||
return d2s_ki_render_markup($post_id);
|
||
}
|
||
add_shortcode('d2s_ki_buttons', 'd2s_ki_shortcode');
|
||
|
||
/* =========================
|
||
* Assets: style.css + CSS vars
|
||
* ========================= */
|
||
|
||
function d2s_ki_enqueue_assets() {
|
||
if (!is_singular()) return;
|
||
|
||
$post_id = (int) get_queried_object_id();
|
||
$pt = get_post_type($post_id);
|
||
$allowed_pts = d2s_ki_get_post_types();
|
||
if (!$pt || !in_array($pt, $allowed_pts, true)) return;
|
||
|
||
wp_enqueue_style(
|
||
'd2s-ki-buttons',
|
||
plugin_dir_url(__FILE__) . 'assets/style.css',
|
||
[],
|
||
'1.4.1'
|
||
);
|
||
|
||
$s = d2s_ki_get_style();
|
||
|
||
$vars = [
|
||
'--d2s-gpt-bg' => $s['gpt_bg'],
|
||
'--d2s-gpt-fg' => $s['gpt_fg'],
|
||
'--d2s-grok-bg' => $s['grok_bg'],
|
||
'--d2s-grok-fg' => $s['grok_fg'],
|
||
'--d2s-pplx-bg' => $s['pplx_bg'],
|
||
'--d2s-pplx-fg' => $s['pplx_fg'],
|
||
'--d2s-radius' => $s['radius'],
|
||
'--d2s-pad-y' => $s['pad_y'],
|
||
'--d2s-pad-x' => $s['pad_x'],
|
||
'--d2s-gap' => $s['gap'],
|
||
'--d2s-shadow' => $s['shadow'],
|
||
'--d2s-shadow-h' => $s['shadow_h'],
|
||
'--d2s-scale-h' => $s['scale_h'],
|
||
];
|
||
|
||
$css = ":root{\n";
|
||
foreach ($vars as $k => $v) {
|
||
if ($v === '' || $v === null) continue;
|
||
$css .= " {$k}: {$v};\n";
|
||
}
|
||
$css .= "}\n";
|
||
|
||
wp_add_inline_style('d2s-ki-buttons', $css);
|
||
}
|
||
add_action('wp_enqueue_scripts', 'd2s_ki_enqueue_assets');
|
||
|
||
/* =========================
|
||
* Admin Settings Page
|
||
* ========================= */
|
||
|
||
function d2s_ki_admin_menu() {
|
||
add_options_page(
|
||
'D2S KI-Erklärbuttons',
|
||
'D2S KI-Erklärbuttons',
|
||
'manage_options',
|
||
'd2s-ki-buttons',
|
||
'd2s_ki_admin_page_render'
|
||
);
|
||
}
|
||
add_action('admin_menu', 'd2s_ki_admin_menu');
|
||
|
||
function d2s_ki_admin_init() {
|
||
|
||
register_setting('d2s_ki_buttons_settings', D2S_KI_OPT_PROMPT, [
|
||
'type' => 'string',
|
||
'sanitize_callback' => 'd2s_ki_sanitize_textline_required',
|
||
'default' => d2s_ki_default_prompt_prefix(),
|
||
]);
|
||
|
||
register_setting('d2s_ki_buttons_settings', D2S_KI_OPT_HINT, [
|
||
'type' => 'string',
|
||
'sanitize_callback' => 'd2s_ki_sanitize_textline_required',
|
||
'default' => d2s_ki_default_hint_text(),
|
||
]);
|
||
|
||
register_setting('d2s_ki_buttons_settings', D2S_KI_OPT_EXCL_CATS, [
|
||
'type' => 'array',
|
||
'sanitize_callback' => 'd2s_ki_sanitize_excluded_categories',
|
||
'default' => [],
|
||
]);
|
||
|
||
register_setting('d2s_ki_buttons_settings', D2S_KI_OPT_MODE, [
|
||
'type' => 'string',
|
||
'sanitize_callback' => 'd2s_ki_sanitize_mode',
|
||
'default' => d2s_ki_default_mode(),
|
||
]);
|
||
|
||
register_setting('d2s_ki_buttons_settings', D2S_KI_OPT_POST_TYPES, [
|
||
'type' => 'array',
|
||
'sanitize_callback' => 'd2s_ki_sanitize_post_types',
|
||
'default' => d2s_ki_default_post_types(),
|
||
]);
|
||
|
||
register_setting('d2s_ki_buttons_settings', D2S_KI_OPT_STYLE, [
|
||
'type' => 'array',
|
||
'sanitize_callback' => 'd2s_ki_sanitize_style',
|
||
'default' => d2s_ki_default_style(),
|
||
]);
|
||
|
||
add_settings_section(
|
||
'd2s_ki_main',
|
||
'Allgemein',
|
||
'__return_false',
|
||
'd2s-ki-buttons'
|
||
);
|
||
|
||
add_settings_field(
|
||
'd2s_ki_prompt_prefix',
|
||
'Prompt-Text (Prefix)',
|
||
'd2s_ki_field_prompt_prefix',
|
||
'd2s-ki-buttons',
|
||
'd2s_ki_main'
|
||
);
|
||
|
||
add_settings_field(
|
||
'd2s_ki_hint_text',
|
||
'Hint-Text unter den Buttons',
|
||
'd2s_ki_field_hint_text',
|
||
'd2s-ki-buttons',
|
||
'd2s_ki_main'
|
||
);
|
||
|
||
add_settings_field(
|
||
'd2s_ki_mode',
|
||
'Einfüge-Modus',
|
||
'd2s_ki_field_mode',
|
||
'd2s-ki-buttons',
|
||
'd2s_ki_main'
|
||
);
|
||
|
||
add_settings_field(
|
||
'd2s_ki_post_types',
|
||
'Anzeigen auf',
|
||
'd2s_ki_field_post_types',
|
||
'd2s-ki-buttons',
|
||
'd2s_ki_main'
|
||
);
|
||
|
||
add_settings_field(
|
||
'd2s_ki_excluded_cats',
|
||
'Kategorien ausschließen (nur Posts)',
|
||
'd2s_ki_field_excluded_categories',
|
||
'd2s-ki-buttons',
|
||
'd2s_ki_main'
|
||
);
|
||
|
||
add_settings_section(
|
||
'd2s_ki_style',
|
||
'Styling',
|
||
'__return_false',
|
||
'd2s-ki-buttons'
|
||
);
|
||
|
||
add_settings_field(
|
||
'd2s_ki_style_colors',
|
||
'Farben',
|
||
'd2s_ki_field_style_colors',
|
||
'd2s-ki-buttons',
|
||
'd2s_ki_style'
|
||
);
|
||
|
||
add_settings_field(
|
||
'd2s_ki_style_layout',
|
||
'Layout',
|
||
'd2s_ki_field_style_layout',
|
||
'd2s-ki-buttons',
|
||
'd2s_ki_style'
|
||
);
|
||
|
||
add_settings_field(
|
||
'd2s_ki_style_fx',
|
||
'Effekte',
|
||
'd2s_ki_field_style_fx',
|
||
'd2s-ki-buttons',
|
||
'd2s_ki_style'
|
||
);
|
||
}
|
||
add_action('admin_init', 'd2s_ki_admin_init');
|
||
|
||
/* ===== Sanitizers ===== */
|
||
|
||
function d2s_ki_sanitize_textline_required($v): string {
|
||
if (!is_string($v)) $v = '';
|
||
$v = trim(wp_strip_all_tags($v));
|
||
return $v !== '' ? $v : '—';
|
||
}
|
||
|
||
function d2s_ki_sanitize_excluded_categories($v): array {
|
||
if (!is_array($v)) return [];
|
||
return array_values(array_unique(array_filter(array_map('intval', $v), fn($id) => $id > 0)));
|
||
}
|
||
|
||
function d2s_ki_sanitize_mode($v): string {
|
||
$allowed = ['auto','shortcode','both'];
|
||
return in_array($v, $allowed, true) ? $v : d2s_ki_default_mode();
|
||
}
|
||
|
||
function d2s_ki_sanitize_post_types($v): array {
|
||
if (!is_array($v)) $v = [];
|
||
$v = array_values(array_filter(array_map('sanitize_key', $v)));
|
||
|
||
$existing = get_post_types(['public' => true], 'names');
|
||
$v = array_values(array_filter($v, fn($pt) => isset($existing[$pt])));
|
||
|
||
return $v ?: d2s_ki_default_post_types();
|
||
}
|
||
|
||
function d2s_ki_sanitize_hex_color_or_empty($v): string {
|
||
$v = is_string($v) ? trim($v) : '';
|
||
if ($v === '') return '';
|
||
$c = sanitize_hex_color($v);
|
||
return $c ? $c : '';
|
||
}
|
||
|
||
function d2s_ki_sanitize_css_len($v, string $fallback): string {
|
||
$v = is_string($v) ? trim($v) : '';
|
||
if ($v === '') return $fallback;
|
||
if (preg_match('/^[0-9.\s%a-zA-Z()+,-]+$/', $v)) return $v;
|
||
return $fallback;
|
||
}
|
||
|
||
function d2s_ki_sanitize_css_value($v, string $fallback): string {
|
||
$v = is_string($v) ? trim($v) : '';
|
||
if ($v === '') return $fallback;
|
||
if (preg_match('/^[0-9.\s%a-zA-Z()+,\/-]+$/', $v)) return $v;
|
||
return $fallback;
|
||
}
|
||
|
||
function d2s_ki_sanitize_style($v): array {
|
||
$d = d2s_ki_default_style();
|
||
if (!is_array($v)) $v = [];
|
||
|
||
return [
|
||
'gpt_bg' => d2s_ki_sanitize_hex_color_or_empty($v['gpt_bg'] ?? $d['gpt_bg']) ?: $d['gpt_bg'],
|
||
'gpt_fg' => d2s_ki_sanitize_hex_color_or_empty($v['gpt_fg'] ?? $d['gpt_fg']) ?: $d['gpt_fg'],
|
||
'grok_bg' => d2s_ki_sanitize_hex_color_or_empty($v['grok_bg'] ?? $d['grok_bg']) ?: $d['grok_bg'],
|
||
'grok_fg' => d2s_ki_sanitize_hex_color_or_empty($v['grok_fg'] ?? $d['grok_fg']) ?: $d['grok_fg'],
|
||
'pplx_bg' => d2s_ki_sanitize_hex_color_or_empty($v['pplx_bg'] ?? $d['pplx_bg']) ?: $d['pplx_bg'],
|
||
'pplx_fg' => d2s_ki_sanitize_hex_color_or_empty($v['pplx_fg'] ?? $d['pplx_fg']) ?: $d['pplx_fg'],
|
||
|
||
'radius' => d2s_ki_sanitize_css_len($v['radius'] ?? '', $d['radius']),
|
||
'pad_y' => d2s_ki_sanitize_css_len($v['pad_y'] ?? '', $d['pad_y']),
|
||
'pad_x' => d2s_ki_sanitize_css_len($v['pad_x'] ?? '', $d['pad_x']),
|
||
'gap' => d2s_ki_sanitize_css_len($v['gap'] ?? '', $d['gap']),
|
||
|
||
'shadow' => d2s_ki_sanitize_css_value($v['shadow'] ?? '', $d['shadow']),
|
||
'shadow_h' => d2s_ki_sanitize_css_value($v['shadow_h'] ?? '', $d['shadow_h']),
|
||
'scale_h' => d2s_ki_sanitize_css_value($v['scale_h'] ?? '', $d['scale_h']),
|
||
];
|
||
}
|
||
|
||
/* ===== Admin Fields ===== */
|
||
|
||
function d2s_ki_field_prompt_prefix() {
|
||
$val = d2s_ki_get_prompt_prefix();
|
||
echo '<textarea name="'.esc_attr(D2S_KI_OPT_PROMPT).'" rows="3" style="width:100%;max-width:760px;">'.esc_textarea($val).'</textarea>';
|
||
echo '<p class="description">Wird an die KI übergeben. Die URL wird automatisch in einer neuen Zeile angehängt.</p>';
|
||
}
|
||
|
||
function d2s_ki_field_hint_text() {
|
||
$val = d2s_ki_get_hint_text();
|
||
echo '<textarea name="'.esc_attr(D2S_KI_OPT_HINT).'" rows="2" style="width:100%;max-width:760px;">'.esc_textarea($val).'</textarea>';
|
||
echo '<p class="description">Text unter den Buttons. Leer lassen (oder „—“) um ihn praktisch auszublenden.</p>';
|
||
}
|
||
|
||
function d2s_ki_field_mode() {
|
||
$mode = d2s_ki_get_mode();
|
||
$opts = [
|
||
'auto' => 'Automatisch unter Content einfügen',
|
||
'shortcode' => 'Nur per Shortcode (du platzierst es selbst)',
|
||
'both' => 'Beides (Auto + Shortcode)',
|
||
];
|
||
echo '<select name="'.esc_attr(D2S_KI_OPT_MODE).'" style="min-width:360px;">';
|
||
foreach ($opts as $k => $label) {
|
||
echo '<option value="'.esc_attr($k).'" '.selected($mode, $k, false).'>'.esc_html($label).'</option>';
|
||
}
|
||
echo '</select>';
|
||
echo '<p class="description">Shortcode: <code>[d2s_ki_buttons]</code></p>';
|
||
}
|
||
|
||
function d2s_ki_field_post_types() {
|
||
$selected = d2s_ki_get_post_types();
|
||
$pts = get_post_types(['public' => true], 'objects');
|
||
|
||
echo '<div style="max-width:760px;padding:12px;border:1px solid #dcdcde;background:#fff;">';
|
||
foreach ($pts as $pt) {
|
||
if ($pt->name === 'attachment') continue;
|
||
$checked = in_array($pt->name, $selected, true) ? 'checked' : '';
|
||
echo '<label style="display:block;margin:6px 0;">';
|
||
echo '<input type="checkbox" name="'.esc_attr(D2S_KI_OPT_POST_TYPES).'[]" value="'.esc_attr($pt->name).'" '.$checked.'> ';
|
||
echo esc_html($pt->labels->singular_name) . ' <span style="opacity:.6;">(' . esc_html($pt->name) . ')</span>';
|
||
echo '</label>';
|
||
}
|
||
echo '</div>';
|
||
echo '<p class="description">Für Seiten: <strong>page</strong> aktivieren.</p>';
|
||
}
|
||
|
||
function d2s_ki_field_excluded_categories() {
|
||
$selected = d2s_ki_get_excluded_cat_ids();
|
||
$cats = get_categories(['hide_empty' => false]);
|
||
|
||
if (!$cats) {
|
||
echo '<em>Keine Kategorien gefunden.</em>';
|
||
return;
|
||
}
|
||
|
||
echo '<div style="max-width:760px;padding:12px;border:1px solid #dcdcde;background:#fff;">';
|
||
echo '<p class="description" style="margin-top:0;">Häkchen setzen = Buttons werden in dieser Kategorie <strong>nicht</strong> angezeigt (nur Posts).</p>';
|
||
|
||
foreach ($cats as $cat) {
|
||
$id = (int)$cat->term_id;
|
||
$checked = in_array($id, $selected, true) ? 'checked' : '';
|
||
echo '<label style="display:block;margin:6px 0;">';
|
||
echo '<input type="checkbox" name="'.esc_attr(D2S_KI_OPT_EXCL_CATS).'[]" value="'.esc_attr($id).'" '.$checked.'> ';
|
||
echo esc_html($cat->name) . ' <span style="opacity:.6;">(' . esc_html($cat->slug) . ')</span>';
|
||
echo '</label>';
|
||
}
|
||
echo '</div>';
|
||
}
|
||
|
||
function d2s_ki_field_style_colors() {
|
||
$s = d2s_ki_get_style();
|
||
$name = D2S_KI_OPT_STYLE;
|
||
|
||
echo '<table class="widefat striped" style="max-width:760px;"><tbody>';
|
||
|
||
$rows = [
|
||
['ChatGPT Hintergrund', "{$name}[gpt_bg]", $s['gpt_bg']],
|
||
['ChatGPT Text', "{$name}[gpt_fg]", $s['gpt_fg']],
|
||
['Grok Hintergrund', "{$name}[grok_bg]", $s['grok_bg']],
|
||
['Grok Text', "{$name}[grok_fg]", $s['grok_fg']],
|
||
['Perplexity Hintergrund', "{$name}[pplx_bg]", $s['pplx_bg']],
|
||
['Perplexity Text', "{$name}[pplx_fg]", $s['pplx_fg']],
|
||
];
|
||
|
||
foreach ($rows as [$label, $field, $val]) {
|
||
echo '<tr>';
|
||
echo '<th style="width:260px;">'.esc_html($label).'</th>';
|
||
echo '<td><input type="text" name="'.esc_attr($field).'" value="'.esc_attr($val).'" class="regular-text" placeholder="#rrggbb" /> ';
|
||
echo '<span style="display:inline-block;width:18px;height:18px;border:1px solid #ccc;vertical-align:middle;background:'.esc_attr($val).';"></span>';
|
||
echo '</td>';
|
||
echo '</tr>';
|
||
}
|
||
|
||
echo '</tbody></table>';
|
||
}
|
||
|
||
function d2s_ki_field_style_layout() {
|
||
$s = d2s_ki_get_style();
|
||
$name = D2S_KI_OPT_STYLE;
|
||
|
||
echo '<table class="widefat striped" style="max-width:760px;"><tbody>';
|
||
|
||
$rows = [
|
||
['Border-Radius', "{$name}[radius]", $s['radius'], 'z.B. 999px / 14px'],
|
||
['Padding Y', "{$name}[pad_y]", $s['pad_y'], 'z.B. 0.65rem'],
|
||
['Padding X', "{$name}[pad_x]", $s['pad_x'], 'z.B. 1rem'],
|
||
['Gap', "{$name}[gap]", $s['gap'], 'z.B. 0.5rem'],
|
||
];
|
||
|
||
foreach ($rows as [$label, $field, $val, $hint]) {
|
||
echo '<tr>';
|
||
echo '<th style="width:260px;">'.esc_html($label).'</th>';
|
||
echo '<td><input type="text" name="'.esc_attr($field).'" value="'.esc_attr($val).'" class="regular-text" placeholder="'.esc_attr($hint).'" /></td>';
|
||
echo '</tr>';
|
||
}
|
||
|
||
echo '</tbody></table>';
|
||
}
|
||
|
||
function d2s_ki_field_style_fx() {
|
||
$s = d2s_ki_get_style();
|
||
$name = D2S_KI_OPT_STYLE;
|
||
|
||
echo '<table class="widefat striped" style="max-width:760px;"><tbody>';
|
||
|
||
$rows = [
|
||
['Shadow', "{$name}[shadow]", $s['shadow'], 'z.B. 0 6px 20px rgba(0,0,0,.12)'],
|
||
['Shadow Hover', "{$name}[shadow_h]", $s['shadow_h'], 'z.B. 0 8px 26px rgba(0,0,0,.18)'],
|
||
['Scale Hover', "{$name}[scale_h]", $s['scale_h'], 'z.B. 1.02'],
|
||
];
|
||
|
||
foreach ($rows as [$label, $field, $val, $hint]) {
|
||
echo '<tr>';
|
||
echo '<th style="width:260px;">'.esc_html($label).'</th>';
|
||
echo '<td><input type="text" name="'.esc_attr($field).'" value="'.esc_attr($val).'" style="width:100%;max-width:520px;" placeholder="'.esc_attr($hint).'" /></td>';
|
||
echo '</tr>';
|
||
}
|
||
|
||
echo '</tbody></table>';
|
||
}
|
||
|
||
function d2s_ki_admin_page_render() {
|
||
if (!current_user_can('manage_options')) return;
|
||
|
||
echo '<div class="wrap">';
|
||
echo '<h1>D2S KI-Erklärbuttons</h1>';
|
||
echo '<form method="post" action="options.php">';
|
||
|
||
settings_fields('d2s_ki_buttons_settings');
|
||
do_settings_sections('d2s-ki-buttons');
|
||
submit_button('Speichern');
|
||
|
||
echo '</form>';
|
||
|
||
echo '<hr />';
|
||
echo '<h2>Info</h2>';
|
||
echo '<p><strong>Shortcode:</strong> <code>[d2s_ki_buttons]</code></p>';
|
||
echo '<p><strong>Prompt-Beispiel (Trennung):</strong><br><code>' . esc_html(d2s_ki_get_prompt_prefix()) . "\\n\\nhttps://example.com/dein-artikel/</code></p>";
|
||
echo '</div>';
|
||
}
|