Update from Git Manager GUI
This commit is contained in:
@@ -553,7 +553,6 @@ function wbf_admin_page() {
|
||||
['wbf-trash', 'fas fa-trash-can', 'Papierkorb', $deleted_count>0?$deleted_count:0, true],
|
||||
['wbf-export', 'fas fa-database', 'Export / Import'],
|
||||
['wbf-settings', 'fas fa-gear', 'Einstellungen'],
|
||||
['wbf-updates', 'fas fa-arrow-up-from-bracket', '🔔 Updates', $update_info ? 1 : 0],
|
||||
];
|
||||
foreach ($nav as $n):
|
||||
if ($n===null) { echo '<div class="wbf-nav__sep"></div>'; continue; }
|
||||
@@ -1079,6 +1078,10 @@ function wbf_admin_categories() {
|
||||
foreach ( $p->children as $c ) {
|
||||
$cd = wp_nonce_url( "?page=wbf-categories&delete_cat={$c->id}", "delete_cat_{$c->id}" );
|
||||
$crole = WBF_Roles::get( $c->min_role ?? 'member' );
|
||||
$clbadge = ( $c->min_role ?? 'member' ) !== 'member'
|
||||
? " <span style='color:" . esc_attr( $crole['color'] ) . ";font-size:.8em'>🔒 " . esc_html( $crole['label'] ) . "</span>" : '';
|
||||
$cguestbadge = ( (int)($c->guest_visible ?? 1) === 0 )
|
||||
? " <span style='color:#f59e0b;font-size:.8em'>👁 Nur eingeloggt</span>" : '';
|
||||
$reorder_c =
|
||||
'<form method="post" style="display:inline-flex;gap:2px">'
|
||||
. wp_nonce_field( 'wbf_reorder_nonce', '_wpnonce', true, false )
|
||||
@@ -1097,7 +1100,7 @@ function wbf_admin_categories() {
|
||||
echo "<tr>
|
||||
<td style='padding-left:2.5rem'>↳ " . esc_html( $c->name ) . "</td>
|
||||
<td>" . esc_html( $c->thread_count ) . "</td>
|
||||
<td>" . esc_html( $crole['label'] ) . "$clockbadge$cguestbadge</td>
|
||||
<td>" . esc_html( $crole['label'] ) . "$clbadge$cguestbadge</td>
|
||||
<td style='white-space:nowrap'>{$reorder_c} <a href='?page=wbf-categories&edit={$c->id}'>Bearbeiten</a> | <a href='" . esc_url( $cd ) . "' onclick='return confirm(\"Löschen?\")'>Löschen</a></td>
|
||||
</tr>";
|
||||
}
|
||||
@@ -1428,6 +1431,7 @@ function wbf_admin_members() {
|
||||
<td>
|
||||
<strong><?php echo esc_html( $m->display_name ); ?></strong><br>
|
||||
<small style="color:#999">@<?php echo esc_html( $m->username ); ?></small>
|
||||
<?php do_action( 'wbf_admin_user_row_extra', $m ); ?>
|
||||
</td>
|
||||
<td><?php echo esc_html( $m->email ); ?></td>
|
||||
<td>
|
||||
@@ -3039,38 +3043,93 @@ function wbf_admin_export() {
|
||||
|
||||
function wbf_admin_profile_fields() {
|
||||
|
||||
// ── Speichern ────────────────────────────────────────────────────────────
|
||||
// ── Kategorien speichern ─────────────────────────────────────────────────
|
||||
if ( isset($_POST['wbf_save_profile_fields']) && check_admin_referer('wbf_profile_fields_nonce') ) {
|
||||
|
||||
// Kategorien
|
||||
$cat_ids = $_POST['cat_id'] ?? [];
|
||||
$cat_names = $_POST['cat_name'] ?? [];
|
||||
$cat_icons = $_POST['cat_icon'] ?? [];
|
||||
$cats = [];
|
||||
foreach ( $cat_ids as $ci => $cid ) {
|
||||
$cid = sanitize_key( $cid );
|
||||
if ( ! $cid ) continue;
|
||||
$cats[] = [
|
||||
'id' => $cid,
|
||||
'name' => sanitize_text_field( $cat_names[$ci] ?? $cid ),
|
||||
'icon' => sanitize_text_field( $cat_icons[$ci] ?? '📋' ),
|
||||
];
|
||||
}
|
||||
// Neue Kategorie
|
||||
if ( ! empty( trim( $_POST['new_cat_name'] ?? '' ) ) ) {
|
||||
$new_name = sanitize_text_field( $_POST['new_cat_name'] );
|
||||
$new_icon = sanitize_text_field( $_POST['new_cat_icon'] ?? '📋' );
|
||||
$new_id = 'cat_' . sanitize_key( $new_name ) . '_' . time();
|
||||
$cats[] = [ 'id' => $new_id, 'name' => $new_name, 'icon' => $new_icon ];
|
||||
}
|
||||
WBF_DB::save_profile_field_categories( $cats );
|
||||
|
||||
// Felder
|
||||
$keys = $_POST['field_key'] ?? [];
|
||||
$labels = $_POST['field_label'] ?? [];
|
||||
$types = $_POST['field_type'] ?? [];
|
||||
$placeholders = $_POST['field_placeholder'] ?? [];
|
||||
$required = $_POST['field_required'] ?? [];
|
||||
$public = $_POST['field_public'] ?? [];
|
||||
$options = $_POST['field_options'] ?? [];
|
||||
$phs = $_POST['field_placeholder'] ?? [];
|
||||
$req = $_POST['field_required'] ?? [];
|
||||
$pub = $_POST['field_public'] ?? [];
|
||||
$opts = $_POST['field_options'] ?? [];
|
||||
$cats_f = $_POST['field_category'] ?? [];
|
||||
|
||||
$valid_cat_ids = array_column( $cats, 'id' );
|
||||
$fields = [];
|
||||
foreach ( $keys as $i => $raw_key ) {
|
||||
$key = sanitize_key( $raw_key );
|
||||
if ( ! $key ) continue;
|
||||
// Reservierte Keys sperren
|
||||
if ( in_array($key, ['username','email','password','display_name','bio','signature','avatar_url','role']) ) continue;
|
||||
$cat_id = sanitize_key( $cats_f[$i] ?? '' );
|
||||
if ( ! in_array( $cat_id, $valid_cat_ids ) ) $cat_id = '';
|
||||
$fields[] = [
|
||||
'key' => $key,
|
||||
'label' => sanitize_text_field( $labels[$i] ?? $key ),
|
||||
'type' => in_array($types[$i] ?? '', ['text','url','textarea','select','number']) ? $types[$i] : 'text',
|
||||
'placeholder' => sanitize_text_field( $placeholders[$i] ?? '' ),
|
||||
'required' => ! empty( $required[$i] ) ? 1 : 0,
|
||||
'public' => ! empty( $public[$i] ) ? 1 : 0,
|
||||
'options' => sanitize_textarea_field( $options[$i] ?? '' ),
|
||||
'type' => in_array($types[$i] ?? '', ['text','url','textarea','select','number','date']) ? $types[$i] : 'text',
|
||||
'placeholder' => sanitize_text_field( $phs[$i] ?? '' ),
|
||||
'required' => ! empty( $req[$i] ) ? 1 : 0,
|
||||
'public' => ! empty( $pub[$i] ) ? 1 : 0,
|
||||
'options' => sanitize_textarea_field( $opts[$i] ?? '' ),
|
||||
'category_id' => $cat_id,
|
||||
];
|
||||
}
|
||||
WBF_DB::save_profile_field_defs( $fields );
|
||||
echo '<div class="notice notice-success is-dismissible"><p>✅ Profilfelder gespeichert!</p></div>';
|
||||
echo '<div class="notice notice-success is-dismissible"><p>✅ Profilfelder & Kategorien gespeichert!</p></div>';
|
||||
}
|
||||
|
||||
// Kategorie löschen
|
||||
if ( isset($_GET['wbf_del_cat']) && check_admin_referer('wbf_del_cat') ) {
|
||||
$del_id = sanitize_key( $_GET['wbf_del_cat'] );
|
||||
$cats = WBF_DB::get_profile_field_categories();
|
||||
$cats = array_values( array_filter( $cats, fn($c) => $c['id'] !== $del_id ) );
|
||||
WBF_DB::save_profile_field_categories( $cats );
|
||||
// Felder dieser Kategorie auf "keine Kategorie" setzen
|
||||
$fields = WBF_DB::get_profile_field_defs();
|
||||
foreach ( $fields as &$f ) {
|
||||
if ( ($f['category_id'] ?? '') === $del_id ) $f['category_id'] = '';
|
||||
}
|
||||
WBF_DB::save_profile_field_defs( $fields );
|
||||
wp_safe_redirect( remove_query_arg(['wbf_del_cat','_wpnonce']) );
|
||||
exit;
|
||||
}
|
||||
|
||||
$fields = WBF_DB::get_profile_field_defs();
|
||||
$types = ['text'=>'Text','url'=>'URL/Link','textarea'=>'Mehrzeiliger Text','select'=>'Auswahlliste','number'=>'Zahl'];
|
||||
$cats = WBF_DB::get_profile_field_categories();
|
||||
$cat_map = array_column( $cats, null, 'id' );
|
||||
$type_opts = ['text'=>'Text','url'=>'URL/Link','textarea'=>'Mehrzeiliger Text','select'=>'Auswahlliste','number'=>'Zahl','date'=>'Datum (Alter)'];
|
||||
|
||||
// Felder nach Kategorie gruppieren
|
||||
$by_cat = [];
|
||||
foreach ( $fields as $f ) {
|
||||
$cid = $f['category_id'] ?? '';
|
||||
if ( ! $cid || ! isset($cat_map[$cid]) ) $cid = '__none__';
|
||||
$by_cat[$cid][] = $f;
|
||||
}
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1>👤 Benutzerdefinierte Profilfelder</h1>
|
||||
@@ -3079,111 +3138,233 @@ function wbf_admin_profile_fields() {
|
||||
<form method="post" id="wbfFieldsForm">
|
||||
<?php wp_nonce_field('wbf_profile_fields_nonce'); ?>
|
||||
|
||||
<table class="widefat" style="margin-bottom:1rem">
|
||||
<!-- ── Kategorien-Verwaltung ──────────────────────────────── -->
|
||||
<div style="background:#f0f4ff;border:1px solid #c7d3f8;border-radius:10px;padding:18px 20px;margin-bottom:22px">
|
||||
<h3 style="margin:0 0 14px;font-size:1rem;display:flex;align-items:center;gap:8px">
|
||||
🗂️ Kategorien verwalten
|
||||
</h3>
|
||||
<table class="widefat" style="margin-bottom:12px;background:#fff;border-radius:7px;overflow:hidden">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:140px">Schlüssel</th>
|
||||
<th style="width:160px">Bezeichnung</th>
|
||||
<th style="width:110px">Typ</th>
|
||||
<th>Platzhalter</th>
|
||||
<th style="width:110px">Optionen <small>(bei Auswahl)</small></th>
|
||||
<th style="width:70px;text-align:center">Pflicht</th>
|
||||
<th style="width:70px;text-align:center">Öffentlich</th>
|
||||
<tr style="background:#eef2ff">
|
||||
<th style="width:56px;padding:8px 10px">Icon</th>
|
||||
<th style="padding:8px 10px">Kategorie-Name</th>
|
||||
<th style="width:50px"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="wbfFieldRows">
|
||||
<tbody>
|
||||
<?php foreach ( $cats as $ci => $cat ): ?>
|
||||
<tr>
|
||||
<td style="padding:6px 10px">
|
||||
<input type="hidden" name="cat_id[]" value="<?php echo esc_attr($cat['id']); ?>">
|
||||
<input type="text" name="cat_icon[]" value="<?php echo esc_attr($cat['icon']); ?>"
|
||||
style="width:46px;text-align:center;font-size:1.1rem;padding:4px 2px;border:1px solid #d0d9f7;border-radius:5px">
|
||||
</td>
|
||||
<td style="padding:6px 10px">
|
||||
<input type="text" name="cat_name[]" value="<?php echo esc_attr($cat['name']); ?>"
|
||||
style="width:100%;max-width:340px;border:1px solid #d0d9f7;border-radius:5px;padding:5px 8px">
|
||||
</td>
|
||||
<td style="padding:6px 10px;text-align:center">
|
||||
<?php
|
||||
$rows = $fields;
|
||||
// Mindestens eine leere Zeile wenn noch keine Felder
|
||||
if ( empty($rows) ) $rows[] = ['key'=>'','label'=>'','type'=>'text','placeholder'=>'','required'=>0,'public'=>1,'options'=>''];
|
||||
foreach ( $rows as $i => $f ):
|
||||
$del_url = wp_nonce_url(
|
||||
add_query_arg(['page'=>'wbf-profile-fields','wbf_del_cat'=>$cat['id']], admin_url('admin.php')),
|
||||
'wbf_del_cat'
|
||||
); ?>
|
||||
<a href="<?php echo esc_url($del_url); ?>"
|
||||
onclick="return confirm('Kategorie löschen? Felder dieser Kategorie bleiben erhalten (ohne Kategorie).')"
|
||||
style="color:#dc2626;text-decoration:none;font-size:1.1rem;font-weight:700" title="Kategorie löschen">×</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<tr style="background:#f8faff">
|
||||
<td style="padding:6px 10px">
|
||||
<input type="text" name="new_cat_icon" value="" placeholder="📋"
|
||||
style="width:46px;text-align:center;font-size:1.1rem;padding:4px 2px;border:1px dashed #a5b4f8;border-radius:5px">
|
||||
</td>
|
||||
<td style="padding:6px 10px" colspan="2">
|
||||
<input type="text" name="new_cat_name" value="" placeholder="+ Neue Kategorie (Namen eingeben und speichern)"
|
||||
style="width:100%;max-width:380px;border:1px dashed #a5b4f8;border-radius:5px;padding:5px 8px;color:#555">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- ── Felder je Kategorie ───────────────────────────────── -->
|
||||
<?php
|
||||
// Alle Kategorien + "Ohne Kategorie" am Ende ausgeben
|
||||
$all_sections = $cats;
|
||||
if ( isset($by_cat['__none__']) ) {
|
||||
$all_sections[] = ['id'=>'__none__','name'=>'Ohne Kategorie','icon'=>'📋'];
|
||||
}
|
||||
foreach ( $all_sections as $cat ):
|
||||
$cid = $cat['id'];
|
||||
$c_fields = $by_cat[$cid] ?? [];
|
||||
?>
|
||||
<div class="wbf-cat-section" style="border:1px solid #e0e6f8;border-radius:10px;margin-bottom:16px;overflow:hidden">
|
||||
<div style="background:#eef2ff;padding:10px 16px;display:flex;align-items:center;gap:8px;cursor:pointer"
|
||||
onclick="this.nextElementSibling.style.display=this.nextElementSibling.style.display==='none'?'':'none'">
|
||||
<span style="font-size:1.1rem"><?php echo esc_html($cat['icon']); ?></span>
|
||||
<strong style="font-size:.95rem"><?php echo esc_html($cat['name']); ?></strong>
|
||||
<span style="color:#94a3b8;font-size:.8rem;margin-left:4px"><?php echo count($c_fields); ?> Feld<?php echo count($c_fields)!==1?'er':''; ?></span>
|
||||
</div>
|
||||
<div class="wbf-cat-body">
|
||||
<table class="widefat" style="border:none">
|
||||
<thead>
|
||||
<tr style="background:#f8faff">
|
||||
<th style="width:130px">Schlüssel</th>
|
||||
<th style="width:150px">Bezeichnung</th>
|
||||
<th style="width:105px">Typ</th>
|
||||
<th>Platzhalter</th>
|
||||
<th style="width:105px">Optionen</th>
|
||||
<th style="width:65px;text-align:center">Pflicht</th>
|
||||
<th style="width:70px;text-align:center">Öffentlich</th>
|
||||
<th style="width:130px">Kategorie</th>
|
||||
<th style="width:44px"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="wbf-field-rows">
|
||||
<?php
|
||||
if ( empty($c_fields) ):
|
||||
?>
|
||||
<tr class="wbf-no-fields-hint" style="background:#fafafa">
|
||||
<td colspan="9" style="color:#aaa;font-style:italic;font-size:.85rem;padding:10px 14px">
|
||||
Noch keine Felder in dieser Kategorie.
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
endif;
|
||||
foreach ( $c_fields as $i_f => $f ):
|
||||
$fi = 'fi_' . $f['key'];
|
||||
?>
|
||||
<tr class="wbf-field-row" style="background:#fff">
|
||||
<td>
|
||||
<td style="padding:6px 8px">
|
||||
<input type="text" name="field_key[]"
|
||||
value="<?php echo esc_attr($f['key']); ?>"
|
||||
placeholder="z.b. website"
|
||||
style="width:100%;font-family:monospace;font-size:.82rem"
|
||||
<?php echo $f['key'] ? 'readonly' : ''; ?>>
|
||||
<?php if ($f['key']): ?>
|
||||
<p style="font-size:.7rem;color:#999;margin:2px 0 0">Schlüssel kann nach Erstellung nicht geändert werden.</p>
|
||||
<p style="font-size:.68rem;color:#999;margin:2px 0 0">Nicht änderbar</p>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><input type="text" name="field_label[]" value="<?php echo esc_attr($f['label']); ?>" placeholder="Website" style="width:100%"></td>
|
||||
<td>
|
||||
<td style="padding:6px 8px">
|
||||
<input type="text" name="field_label[]" value="<?php echo esc_attr($f['label']); ?>" placeholder="Website" style="width:100%">
|
||||
</td>
|
||||
<td style="padding:6px 8px">
|
||||
<select name="field_type[]" style="width:100%" onchange="wbfToggleOptions(this)">
|
||||
<?php foreach ($types as $val=>$lbl): ?>
|
||||
<?php foreach ($type_opts as $val=>$lbl): ?>
|
||||
<option value="<?php echo $val; ?>" <?php selected($f['type']??'text',$val); ?>><?php echo $lbl; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
<td><input type="text" name="field_placeholder[]" value="<?php echo esc_attr($f['placeholder']??''); ?>" placeholder="https://..." style="width:100%"></td>
|
||||
<td>
|
||||
<td style="padding:6px 8px">
|
||||
<input type="text" name="field_placeholder[]" value="<?php echo esc_attr($f['placeholder']??''); ?>" placeholder="https://..." style="width:100%">
|
||||
</td>
|
||||
<td style="padding:6px 8px">
|
||||
<textarea name="field_options[]" rows="2"
|
||||
placeholder="Option 1 Option 2 Option 3"
|
||||
placeholder="Option 1 Option 2"
|
||||
style="width:100%;font-size:.78rem;<?php echo ($f['type']??'text')==='select'?'':'display:none'; ?>"
|
||||
class="wbf-options-field"><?php echo esc_textarea($f['options']??''); ?></textarea>
|
||||
<span class="wbf-options-placeholder" style="color:#ccc;font-size:.75rem;<?php echo ($f['type']??'text')==='select'?'display:none':''; ?>">—</span>
|
||||
</td>
|
||||
<td style="text-align:center">
|
||||
<input type="checkbox" name="field_required[<?php echo $i; ?>]" value="1" <?php checked($f['required']??0,1); ?>>
|
||||
<td style="text-align:center;padding:6px 8px">
|
||||
<input type="checkbox" name="field_required[<?php echo $fi; ?>]" value="1" <?php checked($f['required']??0,1); ?>>
|
||||
</td>
|
||||
<td style="text-align:center">
|
||||
<input type="checkbox" name="field_public[<?php echo $i; ?>]" value="1" <?php checked($f['public']??1,1); ?>>
|
||||
<td style="text-align:center;padding:6px 8px">
|
||||
<input type="checkbox" name="field_public[<?php echo $fi; ?>]" value="1" <?php checked($f['public']??1,1); ?>>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="button" onclick="this.closest('tr').remove()" style="color:#dc2626;border-color:#fca5a5">✕</button>
|
||||
<td style="padding:6px 8px">
|
||||
<select name="field_category[]" style="width:100%;font-size:.82rem">
|
||||
<option value="">— Ohne —</option>
|
||||
<?php foreach ($cats as $co): ?>
|
||||
<option value="<?php echo esc_attr($co['id']); ?>" <?php selected($f['category_id']??'',$co['id']); ?>>
|
||||
<?php echo esc_html($co['icon'].' '.$co['name']); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
<td style="padding:6px 8px">
|
||||
<button type="button" class="button" onclick="wbfRemoveRow(this)" style="color:#dc2626;border-color:#fca5a5;padding:2px 7px">✕</button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<div style="padding:10px 14px">
|
||||
<button type="button" class="button" onclick="wbfAddField(this,'<?php echo esc_attr($cid); ?>')" style="font-size:.82rem">
|
||||
+ Feld hinzufügen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<div style="display:flex;gap:.75rem;align-items:center;margin-bottom:1.5rem">
|
||||
<button type="button" class="button" id="wbfAddField">+ Feld hinzufügen</button>
|
||||
<?php submit_button('💾 Felder speichern','primary','wbf_save_profile_fields',false); ?>
|
||||
<div style="display:flex;gap:.75rem;align-items:center;margin:1rem 0 1.5rem">
|
||||
<?php submit_button('💾 Felder & Kategorien speichern','primary','wbf_save_profile_fields',false); ?>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<hr>
|
||||
<h3>ℹ️ Hinweise</h3>
|
||||
<ul style="color:#555;line-height:1.8;font-size:.9rem">
|
||||
<ul style="color:#555;line-height:1.9;font-size:.9rem">
|
||||
<li><strong>Schlüssel</strong>: Einmalig, nur Kleinbuchstaben/Zahlen/Unterstrich. Kann nach dem ersten Speichern nicht mehr geändert werden.</li>
|
||||
<li><strong>Typ URL</strong>: Wird automatisch als klickbarer Link dargestellt.</li>
|
||||
<li><strong>Typ Datum (Alter)</strong>: Speichert das Geburtsdatum und zeigt nur das Alter an.</li>
|
||||
<li><strong>Typ Auswahlliste</strong>: Trage die Optionen zeilenweise ins Optionen-Feld ein.</li>
|
||||
<li><strong>Öffentlich</strong>: Wenn deaktiviert, sieht nur der Nutzer selbst das Feld in seinem Profil.</li>
|
||||
<li><strong>Pflicht</strong>: Verhindert das Speichern wenn das Feld leer ist.</li>
|
||||
<li><strong>Kategorie</strong>: Felder werden im Profil nach Kategorie gruppiert dargestellt.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var wbfRowCount = <?php echo count($fields) ?: 1; ?>;
|
||||
document.getElementById('wbfAddField').addEventListener('click', function() {
|
||||
var wbfRowCount = <?php echo count($fields) + 100; ?>;
|
||||
|
||||
function wbfRemoveRow(btn) {
|
||||
var tr = btn.closest('tr');
|
||||
tr.remove();
|
||||
}
|
||||
|
||||
function wbfAddField(btn, catId) {
|
||||
var i = wbfRowCount++;
|
||||
var tbody = btn.closest('.wbf-cat-body').querySelector('.wbf-field-rows');
|
||||
// Remove "no fields" hint row if present
|
||||
var hint = tbody.querySelector('.wbf-no-fields-hint');
|
||||
if (hint) hint.remove();
|
||||
|
||||
// Build category <options>
|
||||
var cats = <?php echo json_encode( array_values($cats) ); ?>;
|
||||
var catOpts = '<option value="">— Ohne —</option>';
|
||||
cats.forEach(function(c) {
|
||||
var sel = (c.id === catId) ? ' selected' : '';
|
||||
catOpts += '<option value="' + c.id + '"' + sel + '>' + c.icon + ' ' + c.name + '</option>';
|
||||
});
|
||||
|
||||
var tr = document.createElement('tr');
|
||||
tr.className = 'wbf-field-row';
|
||||
tr.style.background = '#fff';
|
||||
tr.innerHTML = `
|
||||
<td><input type="text" name="field_key[]" placeholder="mein_feld" style="width:100%;font-family:monospace;font-size:.82rem"></td>
|
||||
<td><input type="text" name="field_label[]" placeholder="Mein Feld" style="width:100%"></td>
|
||||
<td><select name="field_type[]" style="width:100%" onchange="wbfToggleOptions(this)">
|
||||
<option value="text">Text</option>
|
||||
<option value="url">URL/Link</option>
|
||||
<option value="textarea">Mehrzeiliger Text</option>
|
||||
<option value="select">Auswahlliste</option>
|
||||
<option value="number">Zahl</option>
|
||||
</select></td>
|
||||
<td><input type="text" name="field_placeholder[]" placeholder="..." style="width:100%"></td>
|
||||
<td>
|
||||
<textarea name="field_options[]" rows="2" placeholder="Option 1 Option 2" style="width:100%;font-size:.78rem;display:none" class="wbf-options-field"></textarea>
|
||||
<span class="wbf-options-placeholder" style="color:#ccc;font-size:.75rem">—</span>
|
||||
</td>
|
||||
<td style="text-align:center"><input type="checkbox" name="field_required[${i}]" value="1"></td>
|
||||
<td style="text-align:center"><input type="checkbox" name="field_public[${i}]" value="1" checked></td>
|
||||
<td><button type="button" class="button" onclick="this.closest('tr').remove()" style="color:#dc2626;border-color:#fca5a5">✕</button></td>`;
|
||||
document.getElementById('wbfFieldRows').appendChild(tr);
|
||||
});
|
||||
tr.innerHTML =
|
||||
'<td style="padding:6px 8px"><input type="text" name="field_key[]" placeholder="mein_feld" style="width:100%;font-family:monospace;font-size:.82rem"></td>' +
|
||||
'<td style="padding:6px 8px"><input type="text" name="field_label[]" placeholder="Mein Feld" style="width:100%"></td>' +
|
||||
'<td style="padding:6px 8px"><select name="field_type[]" style="width:100%" onchange="wbfToggleOptions(this)">' +
|
||||
'<option value="text">Text</option>' +
|
||||
'<option value="url">URL/Link</option>' +
|
||||
'<option value="textarea">Mehrzeiliger Text</option>' +
|
||||
'<option value="select">Auswahlliste</option>' +
|
||||
'<option value="number">Zahl</option>' +
|
||||
'<option value="date">Datum (Alter)</option>' +
|
||||
'</select></td>' +
|
||||
'<td style="padding:6px 8px"><input type="text" name="field_placeholder[]" placeholder="..." style="width:100%"></td>' +
|
||||
'<td style="padding:6px 8px">' +
|
||||
'<textarea name="field_options[]" rows="2" placeholder="Option 1\nOption 2" style="width:100%;font-size:.78rem;display:none" class="wbf-options-field"></textarea>' +
|
||||
'<span class="wbf-options-placeholder" style="color:#ccc;font-size:.75rem">—</span>' +
|
||||
'</td>' +
|
||||
'<td style="text-align:center;padding:6px 8px"><input type="checkbox" name="field_required[new_' + i + ']" value="1"></td>' +
|
||||
'<td style="text-align:center;padding:6px 8px"><input type="checkbox" name="field_public[new_' + i + ']" value="1" checked></td>' +
|
||||
'<td style="padding:6px 8px"><select name="field_category[]" style="width:100%;font-size:.82rem">' + catOpts + '</select></td>' +
|
||||
'<td style="padding:6px 8px"><button type="button" class="button" onclick="wbfRemoveRow(this)" style="color:#dc2626;border-color:#fca5a5;padding:2px 7px">✕</button></td>';
|
||||
tbody.appendChild(tr);
|
||||
}
|
||||
|
||||
function wbfToggleOptions(sel) {
|
||||
var tr = sel.closest('tr');
|
||||
@@ -3550,26 +3731,34 @@ function wbf_admin_prefixes() {
|
||||
|
||||
<!-- Formular -->
|
||||
<div style="background:#fff;border:1px solid #e5e7eb;border-radius:10px;padding:18px">
|
||||
<h3 style="margin:0 0 14px;font-size:.95rem"><?php echo $edit ? 'Bearbeiten: '.esc_html($edit->label) : 'Neuer Präfix'; ?></h3>
|
||||
<?php
|
||||
// PHP 8 safe: extract values once — avoids null->property warnings
|
||||
$px_label = $edit ? $edit->label : '';
|
||||
$px_color = $edit ? $edit->color : '#ffffff';
|
||||
$px_bg = $edit ? $edit->bg_color : '#475569';
|
||||
$px_order = $edit ? (int) $edit->sort_order : 0;
|
||||
$px_id = $edit ? (int) $edit->id : 0;
|
||||
?>
|
||||
<h3 style="margin:0 0 14px;font-size:.95rem"><?php echo $edit ? 'Bearbeiten: '.esc_html($px_label) : 'Neuer Präfix'; ?></h3>
|
||||
<form method="post">
|
||||
<?php wp_nonce_field('wbf_prefix_nonce'); ?>
|
||||
<?php if ($edit): ?><input type="hidden" name="prefix_id" value="<?php echo (int)$edit->id; ?>"><?php endif; ?>
|
||||
<?php if ($edit): ?><input type="hidden" name="prefix_id" value="<?php echo $px_id; ?>"><?php endif; ?>
|
||||
<table class="form-table" style="margin:0">
|
||||
<tr>
|
||||
<th style="padding:6px 10px 6px 0;width:110px">Label *</th>
|
||||
<td><input type="text" name="label" value="<?php echo esc_attr($edit->label ?? ''); ?>" class="regular-text" required placeholder="z.B. GELÖST"></td>
|
||||
<td><input type="text" name="label" value="<?php echo esc_attr($px_label); ?>" style="width:100%;box-sizing:border-box" required placeholder="z.B. GELÖST"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style="padding:6px 10px 6px 0">Textfarbe</th>
|
||||
<td><input type="color" name="color" value="<?php echo esc_attr($edit->color ?? '#ffffff'); ?>"></td>
|
||||
<td><input type="color" name="color" value="<?php echo esc_attr($px_color); ?>"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style="padding:6px 10px 6px 0">Hintergrund</th>
|
||||
<td><input type="color" name="bg_color" value="<?php echo esc_attr($edit->bg_color ?? '#475569'); ?>"></td>
|
||||
<td><input type="color" name="bg_color" value="<?php echo esc_attr($px_bg); ?>"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style="padding:6px 10px 6px 0">Reihenfolge</th>
|
||||
<td><input type="number" name="sort_order" value="<?php echo (int)($edit->sort_order ?? 0); ?>" class="small-text"></td>
|
||||
<td><input type="number" name="sort_order" value="<?php echo $px_order; ?>" class="small-text"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div style="margin-top:12px;display:flex;gap:8px">
|
||||
|
||||
@@ -130,6 +130,13 @@ function wbf_admin_settings() {
|
||||
// rules_content separat (nicht in $fields, da textarea mit eigener Behandlung)
|
||||
$settings['rules_content'] = sanitize_textarea_field( $_POST['rules_content'] ?? '' );
|
||||
|
||||
// Checkbox-Felder explizit als '0' speichern wenn nicht angehakt,
|
||||
// damit array_filter(...,'strlen') sie nicht wegwirft und der Default '1' greift.
|
||||
$checkbox_fields = ['maintenance_mode', 'rules_enabled', 'rules_accept_required'];
|
||||
foreach ( $checkbox_fields as $cb ) {
|
||||
$settings[$cb] = isset($_POST[$cb]) && $_POST[$cb] === '1' ? '1' : '0';
|
||||
}
|
||||
|
||||
// ignore_blocked_roles: kommagetrennte Liste der gewählten Rollen-Keys
|
||||
$all_role_keys = array_keys( WBF_Roles::get_all() );
|
||||
$checked_roles = array_intersect(
|
||||
|
||||
Reference in New Issue
Block a user