Upload folder via GUI - inc

This commit is contained in:
Git Manager GUI
2026-04-13 18:52:46 +02:00
parent 9c47501712
commit 09ac38e9fa
31 changed files with 2058 additions and 0 deletions

View File

@@ -0,0 +1,158 @@
<?php
if ( ! defined( 'ABSPATH' ) ) exit;
abstract class WMF_Field_Base {
public $type = '';
public $label = '';
public $icon = 'dashicons-edit';
public $category = 'standard';
public function defaults() {
return array(
'id' => '',
'type' => $this->type,
'label' => $this->label,
'name' => '',
'placeholder' => '',
'description' => '',
'required' => '0',
'css_class' => '',
'width' => 'full',
// Bedingte Logik
'conditional_logic' => '0',
'conditional_action' => 'show', // show|hide
'conditional_rules' => array(), // [{field,operator,value}]
'conditional_match' => 'all', // all|any
// Schritt (mehrstufige Formulare)
'step' => 0,
);
}
abstract public function render( $field, $value = '' );
public function validate( $value, $field ) {
if ( ! empty( $field['required'] ) && $field['required'] === '1' ) {
$empty = ( $value === '' || $value === null || $value === array() );
if ( $empty ) return sprintf( 'Das Feld „%s" ist ein Pflichtfeld.', $field['label'] );
}
return true;
}
public function sanitize( $value, $field ) {
return sanitize_text_field( (string) $value );
}
/* Einstellungs-Panel im Builder */
public function settings_panel( $field ) {
?>
<div class="wmf-field-setting">
<label>Bezeichnung</label>
<input type="text" data-setting="label" value="<?php echo esc_attr($field['label']??''); ?>" class="widefat">
</div>
<div class="wmf-field-setting">
<label>Feldname <span class="wmf-hint">(intern, nur a-z, 0-9, _)</span></label>
<input type="text" data-setting="name" value="<?php echo esc_attr($field['name']??''); ?>" class="widefat wmf-slug-input">
</div>
<div class="wmf-field-setting">
<label>Platzhaltertext</label>
<input type="text" data-setting="placeholder" value="<?php echo esc_attr($field['placeholder']??''); ?>" class="widefat">
</div>
<div class="wmf-field-setting">
<label>Hilfetext (unter dem Feld)</label>
<input type="text" data-setting="description" value="<?php echo esc_attr($field['description']??''); ?>" class="widefat">
</div>
<div class="wmf-field-setting wmf-field-inline">
<label><input type="checkbox" data-setting="required" value="1" <?php checked($field['required']??'0','1'); ?>> Pflichtfeld</label>
</div>
<div class="wmf-field-setting">
<label>Breite</label>
<select data-setting="width" class="widefat">
<option value="full" <?php selected($field['width']??'full','full'); ?>>Volle Breite</option>
<option value="half" <?php selected($field['width']??'full','half'); ?>>½ Breite</option>
<option value="third" <?php selected($field['width']??'full','third'); ?>>⅓ Breite</option>
</select>
</div>
<div class="wmf-field-setting">
<label>CSS-Klasse</label>
<input type="text" data-setting="css_class" value="<?php echo esc_attr($field['css_class']??''); ?>" class="widefat">
</div>
<hr class="wmf-settings-sep">
<div class="wmf-field-setting">
<label>Bedingte Logik</label>
<select data-setting="conditional_logic" class="widefat wmf-conditional-toggle">
<option value="0" <?php selected($field['conditional_logic']??'0','0'); ?>>Deaktiviert</option>
<option value="1" <?php selected($field['conditional_logic']??'0','1'); ?>>Aktiviert</option>
</select>
</div>
<div class="wmf-conditional-rules" style="<?php echo ($field['conditional_logic']??'0')==='1'?'':'display:none'; ?>">
<div class="wmf-field-setting">
<label>Dieses Feld</label>
<select data-setting="conditional_action" class="widefat">
<option value="show" <?php selected($field['conditional_action']??'show','show'); ?>>anzeigen</option>
<option value="hide" <?php selected($field['conditional_action']??'show','hide'); ?>>ausblenden</option>
</select>
</div>
<div class="wmf-field-setting">
<label>wenn</label>
<select data-setting="conditional_match" class="widefat">
<option value="all" <?php selected($field['conditional_match']??'all','all'); ?>>alle Bedingungen erfüllt sind</option>
<option value="any" <?php selected($field['conditional_match']??'all','any'); ?>>eine Bedingung erfüllt ist</option>
</select>
</div>
<div class="wmf-conditional-rule-list" data-field-id="<?php echo esc_attr($field['id']??''); ?>">
<?php
$rules = $field['conditional_rules'] ?? array();
if (empty($rules)) $rules = array(array('field'=>'','operator'=>'=','value'=>''));
foreach($rules as $rule): ?>
<div class="wmf-rule-row">
<select class="wmf-rule-field" data-setting-rule="field">
<option value="">— Feld —</option>
</select>
<select class="wmf-rule-op" data-setting-rule="operator">
<option value="=" <?php selected($rule['operator']??'=','='); ?>>ist</option>
<option value="!=" <?php selected($rule['operator']??'=','!='); ?>>ist nicht</option>
<option value="contains" <?php selected($rule['operator']??'=','contains'); ?>>enthält</option>
<option value="not_empty" <?php selected($rule['operator']??'=','not_empty'); ?>>ist ausgefüllt</option>
</select>
<input type="text" class="wmf-rule-value" data-setting-rule="value" value="<?php echo esc_attr($rule['value']??''); ?>" placeholder="Wert">
<button type="button" class="wmf-rule-remove">✕</button>
</div>
<?php endforeach; ?>
</div>
<button type="button" class="button wmf-add-rule">+ Bedingung hinzufügen</button>
</div>
<?php
}
protected function wrapper_classes( $field ) {
$cls = array( 'wmf-field', 'wmf-field-' . $this->type );
$w = $field['width'] ?? 'full';
if ( $w !== 'full' ) $cls[] = 'wmf-field-width-' . $w;
if ( ! empty($field['css_class']) ) $cls[] = $field['css_class'];
if ( !empty($field['required']) && $field['required']==='1' ) $cls[] = 'wmf-required';
if ( !empty($field['conditional_logic']) && $field['conditional_logic']==='1' ) $cls[] = 'wmf-has-condition';
return implode(' ', $cls);
}
protected function render_label( $field ) {
if ( empty($field['label']) ) return;
$req = (!empty($field['required']) && $field['required']==='1') ? ' <span class="wmf-required-mark" aria-hidden="true">*</span>' : '';
printf( '<label for="%s" class="wmf-label">%s%s</label>', esc_attr($field['id']), esc_html($field['label']), $req );
}
protected function render_description( $field ) {
if ( empty($field['description']) ) return;
printf( '<p class="wmf-description">%s</p>', esc_html($field['description']) );
}
protected function conditional_attrs( $field ) {
if ( empty($field['conditional_logic']) || $field['conditional_logic'] !== '1' ) return '';
return sprintf(
' data-condition="%s" data-condition-action="%s" data-condition-match="%s" data-condition-rules="%s"',
'1',
esc_attr($field['conditional_action'] ?? 'show'),
esc_attr($field['conditional_match'] ?? 'all'),
esc_attr(wp_json_encode($field['conditional_rules'] ?? array()))
);
}
}

View File

@@ -0,0 +1,23 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_Checkbox extends WMF_Field_Base {
public $type='checkbox'; public $label='Kontrollkästchen'; public $icon='dashicons-yes-alt'; public $category='auswahl';
public function defaults() { return array_merge(parent::defaults(),array('options'=>array(array('label'=>'Option 1','value'=>'option_1')),'layout'=>'vertical')); }
public function render($field,$value='') {
$checked=is_array($value)?$value:($value?array($value):array()); ?>
<div class="<?php echo esc_attr($this->wrapper_classes($field)); ?>"<?php echo $this->conditional_attrs($field); ?> data-field-id="<?php echo esc_attr($field['id']); ?>">
<?php $this->render_label($field); ?>
<div class="wmf-checkbox-group wmf-layout-<?php echo esc_attr($field['layout']??'vertical'); ?>">
<?php foreach($field['options']??array() as $opt): ?>
<label class="wmf-checkbox-label">
<input type="checkbox" name="wmf_fields[<?php echo esc_attr($field['id']); ?>][]" value="<?php echo esc_attr($opt['value']); ?>" <?php echo in_array($opt['value'],$checked)?'checked':''; ?>>
<span><?php echo esc_html($opt['label']); ?></span>
</label>
<?php endforeach; ?>
</div>
<?php $this->render_description($field); ?>
<span class="wmf-field-error-msg"></span>
</div><?php
}
public function sanitize($v,$f) { return is_array($v)?array_map('sanitize_text_field',$v):array(); }
}

View File

@@ -0,0 +1,14 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_Date extends WMF_Field_Base {
public $type='date'; public $label='Datum'; public $icon='dashicons-calendar-alt';
public function defaults() { return array_merge(parent::defaults(),array('min_date'=>'','max_date'=>'')); }
public function render($field,$value='') { ?>
<div class="<?php echo esc_attr($this->wrapper_classes($field)); ?>"<?php echo $this->conditional_attrs($field); ?> data-field-id="<?php echo esc_attr($field['id']); ?>">
<?php $this->render_label($field); ?>
<input type="date" id="<?php echo esc_attr($field['id']); ?>" name="wmf_fields[<?php echo esc_attr($field['id']); ?>]" value="<?php echo esc_attr($value); ?>" <?php echo!empty($field['min_date'])?'min="'.esc_attr($field['min_date']).'"':''; ?> <?php echo!empty($field['max_date'])?'max="'.esc_attr($field['max_date']).'"':''; ?> <?php echo(!empty($field['required'])&&$field['required']==='1')?'required':''; ?> class="wmf-input">
<?php $this->render_description($field); ?>
<span class="wmf-field-error-msg"></span>
</div><?php
}
}

View File

@@ -0,0 +1,13 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_Divider extends WMF_Field_Base {
public $type='divider'; public $label='Trennlinie / Abschnitt'; public $icon='dashicons-minus'; public $category='layout';
public function render($field,$value='') { ?>
<div class="<?php echo esc_attr($this->wrapper_classes($field)); ?>"<?php echo $this->conditional_attrs($field); ?>>
<?php if(!empty($field['label'])): ?><h4 class="wmf-section-title"><?php echo esc_html($field['label']); ?></h4><?php else: ?><hr class="wmf-divider"><?php endif; ?>
<?php $this->render_description($field); ?>
</div><?php
}
public function validate($v,$f) { return true; }
public function sanitize($v,$f) { return ''; }
}

View File

@@ -0,0 +1,19 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_Email extends WMF_Field_Base {
public $type='email'; public $label='E-Mail'; public $icon='dashicons-email-alt';
public function render($field,$value='') { ?>
<div class="<?php echo esc_attr($this->wrapper_classes($field)); ?>"<?php echo $this->conditional_attrs($field); ?> data-field-id="<?php echo esc_attr($field['id']); ?>">
<?php $this->render_label($field); ?>
<input type="email" id="<?php echo esc_attr($field['id']); ?>" name="wmf_fields[<?php echo esc_attr($field['id']); ?>]" value="<?php echo esc_attr($value); ?>" placeholder="<?php echo esc_attr($field['placeholder']??''); ?>" <?php echo(!empty($field['required'])&&$field['required']==='1')?'required':''; ?> class="wmf-input" autocomplete="email">
<?php $this->render_description($field); ?>
<span class="wmf-field-error-msg"></span>
</div><?php
}
public function validate($value,$field) {
$base=parent::validate($value,$field); if($base!==true) return $base;
if($value!==''&&!is_email($value)) return sprintf('Bitte geben Sie eine gültige E-Mail-Adresse für „%s" ein.',$field['label']);
return true;
}
public function sanitize($value,$field) { return sanitize_email($value); }
}

View File

@@ -0,0 +1,64 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_File extends WMF_Field_Base {
public $type='file'; public $label='Datei-Upload'; public $icon='dashicons-upload';
public function defaults() { return array_merge(parent::defaults(),array('allowed_types'=>'jpg,jpeg,png,pdf,doc,docx','max_size_mb'=>'5','multiple'=>'0','save_to_media'=>'1')); }
public function render($field,$value='') { ?>
<div class="<?php echo esc_attr($this->wrapper_classes($field)); ?>"<?php echo $this->conditional_attrs($field); ?> data-field-id="<?php echo esc_attr($field['id']); ?>">
<?php $this->render_label($field); ?>
<input type="file" id="<?php echo esc_attr($field['id']); ?>" name="wmf_files[<?php echo esc_attr($field['id']); ?>]<?php echo(!empty($field['multiple'])&&$field['multiple']==='1')?'[]':''; ?>" accept="<?php echo esc_attr($this->accept_attr($field)); ?>" <?php echo(!empty($field['multiple'])&&$field['multiple']==='1')?'multiple':''; ?> <?php echo(!empty($field['required'])&&$field['required']==='1')?'required':''; ?> class="wmf-input wmf-file-input">
<p class="wmf-description">Erlaubt: <?php echo esc_html($field['allowed_types']??''); ?> — Max. <?php echo esc_html($field['max_size_mb']??5); ?> MB</p>
<?php $this->render_description($field); ?>
<span class="wmf-field-error-msg"></span>
</div><?php
}
private function accept_attr($field) {
$types=array_map('trim',explode(',',$field['allowed_types']??''));
return implode(',',array_map(fn($t)=>'.'.$t,$types));
}
public function validate($value,$field) {
$key=$field['id'];
if(!isset($_FILES['wmf_files']['error'][$key])) return true;
$err=$_FILES['wmf_files']['error'][$key];
if(is_array($err)) $err=array_filter($err,fn($e)=>$e!==UPLOAD_ERR_NO_FILE);
if(empty($err)||$err===UPLOAD_ERR_NO_FILE) {
if(!empty($field['required'])&&$field['required']==='1') return sprintf('Bitte laden Sie eine Datei für „%s" hoch.',$field['label']);
return true;
}
$max=intval($field['max_size_mb']??5)*1024*1024;
$sizes=$_FILES['wmf_files']['size'][$key];
if(is_array($sizes)) { foreach($sizes as $s) if($s>$max) return sprintf('Max. %s MB erlaubt.',$field['max_size_mb']??5); }
elseif($sizes>$max) return sprintf('Max. %s MB erlaubt.',$field['max_size_mb']??5);
return true;
}
public function sanitize($v,$f) { return $v; }
public static function handle_upload($field,$form_id) {
$key=$field['id'];
if(!isset($_FILES['wmf_files']['tmp_name'][$key])) return array();
require_once ABSPATH.'wp-admin/includes/image.php';
require_once ABSPATH.'wp-admin/includes/file.php';
require_once ABSPATH.'wp-admin/includes/media.php';
$tmp=$_FILES['wmf_files']['tmp_name'][$key];
$names=$_FILES['wmf_files']['name'][$key];
$results=array();
if(!is_array($tmp)) { $tmp=array($tmp); $names=array($names); }
foreach($tmp as $i=>$t) {
if(empty($t)||!is_uploaded_file($t)) continue;
$upload=wp_handle_upload(array(
'tmp_name'=>$t,'name'=>$names[$i],'type'=>mime_content_type($t),'error'=>0,'size'=>filesize($t)
),array('test_form'=>false));
if(isset($upload['url'])) {
if(!empty($field['save_to_media'])&&$field['save_to_media']==='1') {
$att=array('post_mime_type'=>$upload['type'],'post_title'=>sanitize_file_name($names[$i]),'post_content'=>'','post_status'=>'inherit');
$att_id=wp_insert_attachment($att,$upload['file']);
wp_update_attachment_metadata($att_id,wp_generate_attachment_metadata($att_id,$upload['file']));
$results[]=array('url'=>$upload['url'],'attachment_id'=>$att_id,'name'=>$names[$i]);
} else {
$results[]=array('url'=>$upload['url'],'name'=>$names[$i]);
}
}
}
return $results;
}
}

View File

@@ -0,0 +1,34 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_GDPR extends WMF_Field_Base {
public $type='gdpr'; public $label='DSGVO-Zustimmung'; public $icon='dashicons-shield'; public $category='auswahl';
public function defaults() {
return array_merge(parent::defaults(),array(
'required' => '1',
'gdpr_text' => 'Ich stimme der <a href="/datenschutz" target="_blank">Datenschutzerklärung</a> zu.',
'error_message' => 'Bitte stimmen Sie der Datenschutzerklärung zu.',
));
}
public function render($field,$value='') { ?>
<div class="<?php echo esc_attr($this->wrapper_classes($field)); ?> wmf-gdpr-wrap"<?php echo $this->conditional_attrs($field); ?> data-field-id="<?php echo esc_attr($field['id']); ?>">
<label class="wmf-gdpr-label">
<input type="checkbox" name="wmf_fields[<?php echo esc_attr($field['id']); ?>]" value="1" <?php checked($value,'1'); ?> <?php echo(!empty($field['required'])&&$field['required']==='1')?'required':''; ?> class="wmf-gdpr-checkbox">
<span class="wmf-gdpr-text"><?php echo wp_kses_post($field['gdpr_text']??''); ?></span>
</label>
<span class="wmf-field-error-msg"></span>
</div><?php
}
public function validate($value,$field) {
if(!empty($field['required'])&&$field['required']==='1'&&$value!=='1') {
return $field['error_message']??'Bitte stimmen Sie der Datenschutzerklärung zu.';
}
return true;
}
public function sanitize($v,$f) { return $v==='1'?'1':'0'; }
public function settings_panel($field) {
parent::settings_panel($field); ?>
<div class="wmf-field-setting"><label>DSGVO-Text (HTML erlaubt)</label><textarea data-setting="gdpr_text" class="widefat" rows="3"><?php echo esc_textarea($field['gdpr_text']??''); ?></textarea></div>
<div class="wmf-field-setting"><label>Fehlermeldung</label><input type="text" data-setting="error_message" value="<?php echo esc_attr($field['error_message']??''); ?>" class="widefat"></div>
<?php
}
}

View File

@@ -0,0 +1,15 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_Hidden extends WMF_Field_Base {
public $type='hidden'; public $label='Verstecktes Feld'; public $icon='dashicons-hidden'; public $category='layout';
public function defaults() { return array_merge(parent::defaults(),array('default_value'=>'')); }
public function render($field,$value='') {
$v=$value?:($field['default_value']??'');
// Dynamic values
if($v==='{{user_ip}}') $v=wmf_get_client_ip();
if($v==='{{page_url}}') $v=home_url(add_query_arg(array()));
if($v==='{{date}}') $v=date('Y-m-d');
printf('<input type="hidden" name="wmf_fields[%s]" value="%s">',esc_attr($field['id']),esc_attr($v));
}
public function validate($v,$f) { return true; }
}

View File

@@ -0,0 +1,13 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_HTML extends WMF_Field_Base {
public $type='html'; public $label='HTML-Block'; public $icon='dashicons-editor-code'; public $category='layout';
public function defaults() { return array_merge(parent::defaults(),array('content'=>'')); }
public function render($field,$value='') { ?>
<div class="<?php echo esc_attr($this->wrapper_classes($field)); ?>"<?php echo $this->conditional_attrs($field); ?>>
<?php echo wp_kses_post($field['content']??''); ?>
</div><?php
}
public function validate($v,$f) { return true; }
public function sanitize($v,$f) { return ''; }
}

View File

@@ -0,0 +1,15 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_Number extends WMF_Field_Base {
public $type='number'; public $label='Zahl'; public $icon='dashicons-calculator';
public function defaults() { return array_merge(parent::defaults(),array('min'=>'','max'=>'','step'=>'1')); }
public function render($field,$value='') { ?>
<div class="<?php echo esc_attr($this->wrapper_classes($field)); ?>"<?php echo $this->conditional_attrs($field); ?> data-field-id="<?php echo esc_attr($field['id']); ?>">
<?php $this->render_label($field); ?>
<input type="number" id="<?php echo esc_attr($field['id']); ?>" name="wmf_fields[<?php echo esc_attr($field['id']); ?>]" value="<?php echo esc_attr($value); ?>" placeholder="<?php echo esc_attr($field['placeholder']??''); ?>" <?php echo!empty($field['min'])?'min="'.esc_attr($field['min']).'"':''; ?> <?php echo!empty($field['max'])?'max="'.esc_attr($field['max']).'"':''; ?> step="<?php echo esc_attr($field['step']??1); ?>" <?php echo(!empty($field['required'])&&$field['required']==='1')?'required':''; ?> class="wmf-input">
<?php $this->render_description($field); ?>
<span class="wmf-field-error-msg"></span>
</div><?php
}
public function sanitize($v,$f) { return is_numeric($v)?$v+0:''; }
}

View File

@@ -0,0 +1,13 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_Phone extends WMF_Field_Base {
public $type='phone'; public $label='Telefon'; public $icon='dashicons-phone';
public function render($field,$value='') { ?>
<div class="<?php echo esc_attr($this->wrapper_classes($field)); ?>"<?php echo $this->conditional_attrs($field); ?> data-field-id="<?php echo esc_attr($field['id']); ?>">
<?php $this->render_label($field); ?>
<input type="tel" id="<?php echo esc_attr($field['id']); ?>" name="wmf_fields[<?php echo esc_attr($field['id']); ?>]" value="<?php echo esc_attr($value); ?>" placeholder="<?php echo esc_attr($field['placeholder']??''); ?>" <?php echo(!empty($field['required'])&&$field['required']==='1')?'required':''; ?> class="wmf-input" autocomplete="tel">
<?php $this->render_description($field); ?>
<span class="wmf-field-error-msg"></span>
</div><?php
}
}

View File

@@ -0,0 +1,21 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_Radio extends WMF_Field_Base {
public $type='radio'; public $label='Radio-Buttons'; public $icon='dashicons-marker'; public $category='auswahl';
public function defaults() { return array_merge(parent::defaults(),array('options'=>array(array('label'=>'Option 1','value'=>'option_1')),'layout'=>'vertical')); }
public function render($field,$value='') { ?>
<div class="<?php echo esc_attr($this->wrapper_classes($field)); ?>"<?php echo $this->conditional_attrs($field); ?> data-field-id="<?php echo esc_attr($field['id']); ?>">
<?php $this->render_label($field); ?>
<div class="wmf-radio-group wmf-layout-<?php echo esc_attr($field['layout']??'vertical'); ?>">
<?php foreach($field['options']??array() as $opt): ?>
<label class="wmf-radio-label">
<input type="radio" name="wmf_fields[<?php echo esc_attr($field['id']); ?>]" value="<?php echo esc_attr($opt['value']); ?>" <?php checked($value,$opt['value']); ?> <?php echo(!empty($field['required'])&&$field['required']==='1')?'required':''; ?>>
<span><?php echo esc_html($opt['label']); ?></span>
</label>
<?php endforeach; ?>
</div>
<?php $this->render_description($field); ?>
<span class="wmf-field-error-msg"></span>
</div><?php
}
}

View File

@@ -0,0 +1,20 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_Range extends WMF_Field_Base {
public $type='range'; public $label='Schieberegler'; public $icon='dashicons-leftright'; public $category='auswahl';
public function defaults() { return array_merge(parent::defaults(),array('min'=>'0','max'=>'100','step'=>'1','show_value'=>'1')); }
public function render($field,$value='') {
$val=$value!==''?$value:($field['min']??0); ?>
<div class="<?php echo esc_attr($this->wrapper_classes($field)); ?>"<?php echo $this->conditional_attrs($field); ?> data-field-id="<?php echo esc_attr($field['id']); ?>">
<?php $this->render_label($field); ?>
<div class="wmf-range-wrap">
<input type="range" id="<?php echo esc_attr($field['id']); ?>" name="wmf_fields[<?php echo esc_attr($field['id']); ?>]" value="<?php echo esc_attr($val); ?>" min="<?php echo esc_attr($field['min']??0); ?>" max="<?php echo esc_attr($field['max']??100); ?>" step="<?php echo esc_attr($field['step']??1); ?>" class="wmf-range-input">
<?php if(!empty($field['show_value'])&&$field['show_value']==='1'): ?>
<span class="wmf-range-value"><?php echo esc_html($val); ?></span>
<?php endif; ?>
</div>
<?php $this->render_description($field); ?>
</div><?php
}
public function sanitize($v,$f) { return is_numeric($v)?$v+0:$f['min']??0; }
}

View File

@@ -0,0 +1,21 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_Rating extends WMF_Field_Base {
public $type='rating'; public $label='Bewertung (Sterne)'; public $icon='dashicons-star-filled'; public $category='auswahl';
public function defaults() { return array_merge(parent::defaults(),array('max_stars'=>'5','icon'=>'star')); }
public function render($field,$value='') {
$max=intval($field['max_stars']??5); ?>
<div class="<?php echo esc_attr($this->wrapper_classes($field)); ?>"<?php echo $this->conditional_attrs($field); ?> data-field-id="<?php echo esc_attr($field['id']); ?>">
<?php $this->render_label($field); ?>
<div class="wmf-rating" data-max="<?php echo $max; ?>">
<?php for($i=1;$i<=$max;$i++): ?>
<button type="button" class="wmf-star <?php echo $i<=intval($value)?'active':''; ?>" data-value="<?php echo $i; ?>" aria-label="<?php echo $i; ?> Stern">★</button>
<?php endfor; ?>
<input type="hidden" name="wmf_fields[<?php echo esc_attr($field['id']); ?>]" value="<?php echo esc_attr($value); ?>" class="wmf-rating-value">
</div>
<?php $this->render_description($field); ?>
<span class="wmf-field-error-msg"></span>
</div><?php
}
public function sanitize($v,$f) { return max(0,min(intval($f['max_stars']??5),intval($v))); }
}

View File

@@ -0,0 +1,23 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_Select extends WMF_Field_Base {
public $type='select'; public $label='Auswahlliste'; public $icon='dashicons-list-view'; public $category='auswahl';
public function defaults() { return array_merge(parent::defaults(),array('options'=>array(array('label'=>'Option 1','value'=>'option_1')),'multiple'=>'0')); }
public function render($field,$value='') {
$multi=!empty($field['multiple'])&&$field['multiple']==='1';
$name='wmf_fields['.esc_attr($field['id']).']'.($multi?'[]':''); ?>
<div class="<?php echo esc_attr($this->wrapper_classes($field)); ?>"<?php echo $this->conditional_attrs($field); ?> data-field-id="<?php echo esc_attr($field['id']); ?>">
<?php $this->render_label($field); ?>
<select id="<?php echo esc_attr($field['id']); ?>" name="<?php echo $name; ?>" class="wmf-input wmf-select" <?php echo $multi?'multiple':''; ?> <?php echo(!empty($field['required'])&&$field['required']==='1')?'required':''; ?>>
<?php if(!$multi): ?><option value=""><?php echo esc_html($field['placeholder']?:'— Bitte wählen —'); ?></option><?php endif; ?>
<?php foreach($field['options']??array() as $opt):
$sel=is_array($value)?in_array($opt['value'],$value):$value===$opt['value']; ?>
<option value="<?php echo esc_attr($opt['value']); ?>" <?php echo $sel?'selected':''; ?>><?php echo esc_html($opt['label']); ?></option>
<?php endforeach; ?>
</select>
<?php $this->render_description($field); ?>
<span class="wmf-field-error-msg"></span>
</div><?php
}
public function sanitize($v,$f) { return is_array($v)?array_map('sanitize_text_field',$v):sanitize_text_field($v); }
}

View File

@@ -0,0 +1,28 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_Signature extends WMF_Field_Base {
public $type='signature'; public $label='Unterschrift'; public $icon='dashicons-edit-page'; public $category='auswahl';
public function render($field,$value='') { ?>
<div class="<?php echo esc_attr($this->wrapper_classes($field)); ?>"<?php echo $this->conditional_attrs($field); ?> data-field-id="<?php echo esc_attr($field['id']); ?>">
<?php $this->render_label($field); ?>
<div class="wmf-signature-wrap">
<canvas class="wmf-signature-canvas" id="sig_<?php echo esc_attr($field['id']); ?>" width="400" height="150"></canvas>
<div class="wmf-signature-controls">
<button type="button" class="wmf-sig-clear button">Löschen</button>
</div>
<input type="hidden" name="wmf_fields[<?php echo esc_attr($field['id']); ?>]" value="<?php echo esc_attr($value); ?>" class="wmf-signature-data">
</div>
<?php $this->render_description($field); ?>
<span class="wmf-field-error-msg"></span>
</div><?php
}
public function validate($value,$field) {
if(!empty($field['required'])&&$field['required']==='1'&&empty($value)) return sprintf('Bitte unterschreiben Sie im Feld „%s".',$field['label']);
return true;
}
public function sanitize($v,$f) {
// Base64 PNG-Daten erlaubt, sonst leer
if(strpos($v,'data:image/png;base64,')===0) return sanitize_text_field($v);
return '';
}
}

View File

@@ -0,0 +1,13 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_Text extends WMF_Field_Base {
public $type='text'; public $label='Textfeld'; public $icon='dashicons-editor-textcolor';
public function render($field,$value='') { ?>
<div class="<?php echo esc_attr($this->wrapper_classes($field)); ?>"<?php echo $this->conditional_attrs($field); ?> data-field-id="<?php echo esc_attr($field['id']); ?>">
<?php $this->render_label($field); ?>
<input type="text" id="<?php echo esc_attr($field['id']); ?>" name="wmf_fields[<?php echo esc_attr($field['id']); ?>]" value="<?php echo esc_attr($value); ?>" placeholder="<?php echo esc_attr($field['placeholder']??''); ?>" <?php echo(!empty($field['required'])&&$field['required']==='1')?'required':''; ?> class="wmf-input" autocomplete="on">
<?php $this->render_description($field); ?>
<span class="wmf-field-error-msg"></span>
</div><?php
}
}

View File

@@ -0,0 +1,22 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_Textarea extends WMF_Field_Base {
public $type='textarea'; public $label='Textbereich'; public $icon='dashicons-text';
public function defaults() { return array_merge(parent::defaults(),array('rows'=>'5','max_chars'=>'')); }
public function render($field,$value='') { ?>
<div class="<?php echo esc_attr($this->wrapper_classes($field)); ?>"<?php echo $this->conditional_attrs($field); ?> data-field-id="<?php echo esc_attr($field['id']); ?>">
<?php $this->render_label($field); ?>
<textarea id="<?php echo esc_attr($field['id']); ?>" name="wmf_fields[<?php echo esc_attr($field['id']); ?>]" placeholder="<?php echo esc_attr($field['placeholder']??''); ?>" rows="<?php echo intval($field['rows']??5); ?>" <?php echo(!empty($field['required'])&&$field['required']==='1')?'required':''; ?> <?php echo(!empty($field['max_chars']))?'maxlength="'.intval($field['max_chars']).'"':''; ?> class="wmf-input wmf-textarea"><?php echo esc_textarea($value); ?></textarea>
<?php if(!empty($field['max_chars'])): ?><div class="wmf-char-count"><span class="wmf-chars-used">0</span>/<?php echo intval($field['max_chars']); ?></div><?php endif; ?>
<?php $this->render_description($field); ?>
<span class="wmf-field-error-msg"></span>
</div><?php
}
public function sanitize($v,$f) { return sanitize_textarea_field($v); }
public function settings_panel($field) {
parent::settings_panel($field); ?>
<div class="wmf-field-setting"><label>Zeilen</label><input type="number" min="2" max="30" data-setting="rows" value="<?php echo esc_attr($field['rows']??5); ?>" class="small-text"></div>
<div class="wmf-field-setting"><label>Max. Zeichen (0 = unbegrenzt)</label><input type="number" min="0" data-setting="max_chars" value="<?php echo esc_attr($field['max_chars']??''); ?>" class="small-text"></div>
<?php
}
}

View File

@@ -0,0 +1,14 @@
<?php
if (!defined('ABSPATH')) exit;
class WMF_Field_URL extends WMF_Field_Base {
public $type='url'; public $label='Website-URL'; public $icon='dashicons-admin-site';
public function render($field,$value='') { ?>
<div class="<?php echo esc_attr($this->wrapper_classes($field)); ?>"<?php echo $this->conditional_attrs($field); ?> data-field-id="<?php echo esc_attr($field['id']); ?>">
<?php $this->render_label($field); ?>
<input type="url" id="<?php echo esc_attr($field['id']); ?>" name="wmf_fields[<?php echo esc_attr($field['id']); ?>]" value="<?php echo esc_attr($value); ?>" placeholder="<?php echo esc_attr($field['placeholder']??'https://'); ?>" <?php echo(!empty($field['required'])&&$field['required']==='1')?'required':''; ?> class="wmf-input">
<?php $this->render_description($field); ?>
<span class="wmf-field-error-msg"></span>
</div><?php
}
public function sanitize($v,$f) { return esc_url_raw($v); }
}