| 1 |
<?php |
| 2 |
|
| 3 |
class webling_form_shortcode { |
| 4 |
|
| 5 |
/** |
| 6 |
* Shortcode Handler for [webling_form] |
| 7 |
* |
| 8 |
* @param $atts array shortcode attributes |
| 9 |
* @return string HTML code for the from |
| 10 |
*/ |
| 11 |
public static function handler($atts) { |
| 12 |
|
| 13 |
global $wpdb; |
| 14 |
|
| 15 |
try { |
| 16 |
// filter shortcode attributes |
| 17 |
$attributes = shortcode_atts( array( |
| 18 |
'id' => null |
| 19 |
), $atts ); |
| 20 |
|
| 21 |
if (!$attributes['id']) { |
| 22 |
throw new Exception('No ID in shortcode'); |
| 23 |
} |
| 24 |
|
| 25 |
// Load form config |
| 26 |
$id = intval($attributes['id']); |
| 27 |
$config = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}webling_forms WHERE id = " . esc_sql($id), 'ARRAY_A'); |
| 28 |
if (!$config) { |
| 29 |
throw new Exception('No form with ID '.$id.' found'); |
| 30 |
} |
| 31 |
|
| 32 |
// Load form data |
| 33 |
try { |
| 34 |
|
| 35 |
if (isset($_REQUEST['webling_form_submitted'])) { |
| 36 |
if ($_REQUEST['webling_form_submitted'] == 'true') { |
| 37 |
return '<div class="webling-form webling-form__submitted '.esc_attr($config['class']).'">' |
| 38 |
. $config['confirmation_text'] |
| 39 |
. '</div>'; |
| 40 |
} else { |
| 41 |
return '<div class="webling-form webling-form__error '.esc_attr($config['class']).'">' |
| 42 |
. __('Sorry, Das Formular konnte nicht gesendet werden, beim Verarbeiten der Daten ist ein Fehler aufgetreten. Versuche es später noch einmal.', 'webling') |
| 43 |
. '</div>'; |
| 44 |
} |
| 45 |
|
| 46 |
} else { |
| 47 |
return '<div class="webling-form '.esc_attr($config['class']).'">' |
| 48 |
. self::get_html($config) |
| 49 |
. '</div>'; |
| 50 |
} |
| 51 |
|
| 52 |
} catch (\Webling\API\ClientException $exception) { |
| 53 |
throw new Exception('Connection Error: '.$exception->getMessage()); |
| 54 |
} |
| 55 |
} catch (Exception $exception) { |
| 56 |
if ( WP_DEBUG ) { |
| 57 |
trigger_error($exception->getMessage()); |
| 58 |
} |
| 59 |
return '<p class="webling-form__error">[webling_form] Fehler: '.$exception->getMessage().'</p>'; |
| 60 |
} |
| 61 |
|
| 62 |
} |
| 63 |
|
| 64 |
/** |
| 65 |
* @param $formconfig array - form configuration from database |
| 66 |
* @return string HTML Markup |
| 67 |
* @throws Exception |
| 68 |
*/ |
| 69 |
protected static function get_html($formconfig) { |
| 70 |
global $wpdb; |
| 71 |
global $wp; |
| 72 |
|
| 73 |
// load field definitions |
| 74 |
$definitions = WeblingApiHelper::Instance()->getMemberFieldDefinitionsById(); |
| 75 |
$sql = "SELECT * FROM {$wpdb->prefix}webling_form_fields WHERE form_id = " . esc_sql($formconfig['id']) . " ORDER BY `order` ASC"; |
| 76 |
$formfields = $wpdb->get_results($sql, 'ARRAY_A'); |
| 77 |
|
| 78 |
if (!is_array($formfields) || count($formfields) == 0) { |
| 79 |
throw new Exception('Keine Formularfelder konfiguriert'); |
| 80 |
} |
| 81 |
|
| 82 |
$html = ''; |
| 83 |
|
| 84 |
foreach ($formfields as $field) { |
| 85 |
switch ($field['field_name_position']){ |
| 86 |
case 'HIDDEN': |
| 87 |
$positionclass = 'webling-form__group--hidden'; |
| 88 |
break; |
| 89 |
case 'LEFT': |
| 90 |
$positionclass = 'webling-form__group--left'; |
| 91 |
break; |
| 92 |
case 'TOP': |
| 93 |
default: |
| 94 |
$positionclass = 'webling-form__group--top'; |
| 95 |
} |
| 96 |
|
| 97 |
$html .= '<div class="webling-form__group '.$positionclass.'">'; |
| 98 |
|
| 99 |
$html .= '<label for="webling-form-field-' . $field['id'] . '" class="webling-form__label">'; |
| 100 |
$html .= esc_html($field['field_name']); |
| 101 |
if ($field['required']) { |
| 102 |
$html .= ' <span class="webling-form__required">*</span>'; |
| 103 |
} |
| 104 |
$html .= '</label>'; |
| 105 |
|
| 106 |
$html .= '<div class="webling-form__field">'; |
| 107 |
$html .= self::getInputForType($field, $definitions); |
| 108 |
if ($field['description_text']) { |
| 109 |
$html .= '<small class="webling-form__description">'.esc_html($field['description_text']).'</small>'; |
| 110 |
} |
| 111 |
$html .= '</div>'; |
| 112 |
$html .= '</div>'; |
| 113 |
} |
| 114 |
|
| 115 |
$form = '<form action="?" method="post">'; |
| 116 |
$form .= '<input type="hidden" name="webling-form-id" value="'.$formconfig['id'].'"/>'; |
| 117 |
$form .= '<input type="hidden" name="webling-form-redirect" value="'.esc_attr(get_permalink()).'"/>'; |
| 118 |
$form .= $html; |
| 119 |
|
| 120 |
// add honeypot field ("display: none" via css) |
| 121 |
$form .= '<input type="text" id="webling-form-field_0" autocomplete="off" name="webling-form-field[0]" value=""/>'; |
| 122 |
|
| 123 |
$form .= '<p><input type="submit" value="'.esc_attr($formconfig['submit_button_text']).'" class="webling-form__submit"></p>'; |
| 124 |
$form .= '</form>'; |
| 125 |
|
| 126 |
return $form; |
| 127 |
} |
| 128 |
|
| 129 |
protected static function getInputForType($field, $definitions) { |
| 130 |
$datatype = $definitions[$field['webling_field_id']]['datatype']; |
| 131 |
$label = (isset($definitions[$field['webling_field_id']]['type']) ? $definitions[$field['webling_field_id']]['type'] : ''); |
| 132 |
$required = ($field['required'] ? 'required' : ''); |
| 133 |
$id = 'webling-form-field-'.$field['id']; |
| 134 |
$name = 'webling-form-field['.$field['id'].']'; |
| 135 |
$class = 'webling-form__input'; |
| 136 |
$placeholder = ($field['placeholder_text'] ? esc_attr($field['placeholder_text']) : ''); |
| 137 |
switch ($datatype){ |
| 138 |
case 'multienum': |
| 139 |
$options = []; |
| 140 |
if (isset($definitions[$field['webling_field_id']]['values'])) { |
| 141 |
foreach ($definitions[$field['webling_field_id']]['values'] as $value) { |
| 142 |
$options[] = '<div><label><input type="checkbox" class="webling-form__checkbox" name="'.$name.'['.base64_encode($value).']"/> '.esc_html($value).'</label></div>'; |
| 143 |
} |
| 144 |
} |
| 145 |
return '<div class="webling-form__multiselect" >'.implode($options).'</div>'; |
| 146 |
case 'enum': |
| 147 |
$options = []; |
| 148 |
if (isset($definitions[$field['webling_field_id']]['values'])) { |
| 149 |
|
| 150 |
if ($placeholder) { |
| 151 |
$options[] = '<option value="">'.esc_html($field['placeholder_text']).'</option>'; |
| 152 |
} |
| 153 |
foreach ($definitions[$field['webling_field_id']]['values'] as $value) { |
| 154 |
$options[] = '<option value="'.esc_attr($value).'">'.esc_html($value).'</option>'; |
| 155 |
} |
| 156 |
} |
| 157 |
return '<select name="' . $name . '" id="' . $id . '" class="webling-form__select" ' . $required . '>'.implode($options).'</select>'; |
| 158 |
case 'bool': |
| 159 |
return '<span>' |
| 160 |
. '<label>' |
| 161 |
. '<input type="checkbox" class="webling-form__checkbox" name="' . $name . '" id="' . $id . '" ' . $required . '> ' |
| 162 |
. esc_html($field['placeholder_text']).' ' |
| 163 |
.'</label></span>'; |
| 164 |
case 'date': |
| 165 |
return '<input type="date" name="' . $name . '" id="' . $id . '" placeholder="TT.MM.JJJJ" class="'.$class.'" ' . $required . '>'; |
| 166 |
case 'longtext': |
| 167 |
return '<textarea rows="6" name="' . $name . '" id="' . $id . '" placeholder="'.$placeholder.'" class="'.$class.'" '.$required.'></textarea>'; |
| 168 |
case 'int': |
| 169 |
return '<input type="number" step="1" name="'.$name.'" id="'.$id.'" placeholder="'.$placeholder.'" class="'.$class.'" '.$required.'>'; |
| 170 |
case 'numeric': |
| 171 |
return '<input type="number" step="any" name="'.$name.'" id="'.$id.'" placeholder="'.$placeholder.'" class="'.$class.'" '.$required.'>'; |
| 172 |
case 'text': |
| 173 |
switch ($label) { |
| 174 |
case 'phone': |
| 175 |
case 'mobile': |
| 176 |
return '<input type="tel" name="' . $name . '" id="' . $id . '" placeholder="' . $placeholder . '" class="'.$class.'" ' . $required . '>'; |
| 177 |
case 'url': |
| 178 |
return '<input type="url" name="' . $name . '" id="' . $id . '" placeholder="' . $placeholder . '" class="'.$class.'" ' . $required . '>'; |
| 179 |
case 'email': |
| 180 |
return '<input type="email" name="' . $name . '" id="' . $id . '" placeholder="' . $placeholder . '" class="'.$class.'" ' . $required . '>'; |
| 181 |
default: |
| 182 |
return '<input type="text" name="' . $name . '" id="' . $id . '" placeholder="' . $placeholder . '" class="'.$class.'" ' . $required . '>'; |
| 183 |
} |
| 184 |
case 'autoincrement': |
| 185 |
case 'image': |
| 186 |
case 'file': |
| 187 |
default: |
| 188 |
// autoincrement, images and files are currently not supported |
| 189 |
return ''; |
| 190 |
} |
| 191 |
} |
| 192 |
} |
| 193 |
|