protected function sanitize_field_input($value, $instance) { $sanitized_value = trim($value); // Any alphanumeric character followed by alphanumeric or whitespace characters (except newline), // with optional colon and number. if (preg_match('/[\\w\\d]+[\\w\\d\\t\\r ]*(:\\d+)?/', $sanitized_value, $sanitized_matches)) { $sanitized_value = $sanitized_matches[0]; } else { $sanitized_value = 'default'; } static $widget_font_families; if (empty($widget_font_families)) { $widget_font_families = siteorigin_widgets_font_families(); } $keys = array_keys($widget_font_families); if (!in_array($sanitized_value, $keys)) { $sanitized_value = isset($this->default) ? $this->default : 'default'; } return $sanitized_value; }
/** * Render a form field * * @param string $name The field name * @param string $field The field attributes * @param mixed $value The current field value * @param array $all_values An array of all values at the same level as this field * @param array $repeater * @param bool $is_template */ function render_field($name, $field, $value, $all_values, $repeater = array(), $is_template = false) { if (is_null($value) && isset($field['default'])) { $value = $field['default']; } $wrapper_attributes = array('class' => array('siteorigin-widget-field', 'siteorigin-widget-field-type-' . $field['type'], 'siteorigin-widget-field-' . $name)); if (!empty($field['state_name'])) { $wrapper_attributes['class'][] = 'siteorigin-widget-field-state-' . $field['state_name']; } if (!empty($field['hidden'])) { $wrapper_attributes['class'][] = 'siteorigin-widget-field-is-hidden'; } if (!empty($field['optional'])) { $wrapper_attributes['class'][] = 'siteorigin-widget-field-is-optional'; } $wrapper_attributes['class'] = implode(' ', array_map('sanitize_html_class', $wrapper_attributes['class'])); if (!empty($field['state_emitter'])) { // State emitters create new states for the form $wrapper_attributes['data-state-emitter'] = json_encode($field['state_emitter']); } if (!empty($field['state_handler'])) { // State handlers decide what to do with form states $wrapper_attributes['data-state-handler'] = json_encode($field['state_handler']); } if (!empty($field['state_handler_initial'])) { // Initial state handlers are only run when the form is first loaded $wrapper_attributes['data-state-handler-initial'] = json_encode($field['state_handler_initial']); } ?> <div <?php foreach ($wrapper_attributes as $attr => $attr_val) { echo $attr . '="' . esc_attr($attr_val) . '" '; } ?> ><?php $field_id = $this->so_get_field_id($name, $repeater, $is_template); if ($field['type'] != 'repeater' && $field['type'] != 'checkbox' && $field['type'] != 'separator' && !empty($field['label'])) { ?> <label for="<?php echo $field_id; ?> " class="siteorigin-widget-field-label <?php if (empty($field['hide'])) { echo 'siteorigin-widget-section-visible'; } ?> "> <?php echo $field['label']; if (!empty($field['optional'])) { echo ' <span class="field-optional">(' . __('Optional', 'siteorigin-panels') . ')</span>'; } ?> </label> <?php } switch ($field['type']) { case 'text': ?> <input type="text" name="<?php echo $this->so_get_field_name($name, $repeater); ?> " id="<?php echo $field_id; ?> " value="<?php echo esc_attr($value); ?> " <?php if (!empty($field['placeholder'])) { echo 'placeholder="' . $field['placeholder'] . '"'; } ?> class="widefat siteorigin-widget-input" <?php if (!empty($field['readonly'])) { echo 'readonly'; } ?> /><?php break; case 'link': ?> <a href="#" class="select-content-button button-secondary"><?php _e('Select Content', 'siteorigin-widgets'); ?> </a> <div class="existing-content-selector"> <input type="text" placeholder="<?php esc_attr_e('Search Content', 'siteorigin-widgets'); ?> " class="content-text-search" /> <ul class="posts"></ul> <div class="buttons"> <a href="#" class="button-close button-secondary"><?php _e('Close', 'siteorigin-widgets'); ?> </a> </div> </div> <div class="url-input-wrapper"> <input type="text" name="<?php echo $this->so_get_field_name($name, $repeater); ?> " id="<?php echo $field_id; ?> " value="<?php echo esc_attr($value); ?> " <?php if (!empty($field['placeholder'])) { echo 'placeholder="' . $field['placeholder'] . '"'; } ?> class="widefat siteorigin-widget-input" <?php if (!empty($field['readonly'])) { echo 'readonly'; } ?> /> </div> <?php break; case 'color': ?> <input type="text" name="<?php echo $this->so_get_field_name($name, $repeater); ?> " id="<?php echo $field_id; ?> " value="<?php echo esc_attr($value); ?> " <?php if (!empty($field['placeholder'])) { echo 'placeholder="' . $field['placeholder'] . '"'; } ?> class="widefat siteorigin-widget-input siteorigin-widget-input-color" /><?php break; case 'number': ?> <input type="text" name="<?php echo $this->so_get_field_name($name, $repeater); ?> " id="<?php echo $field_id; ?> " value="<?php echo esc_attr($value); ?> " <?php if (!empty($field['placeholder'])) { echo 'placeholder="' . $field['placeholder'] . '"'; } ?> class="widefat siteorigin-widget-input siteorigin-widget-input-number" <?php if (!empty($field['readonly'])) { echo 'readonly'; } ?> /><?php break; case 'textarea': ?> <textarea type="text" name="<?php echo $this->so_get_field_name($name, $repeater); ?> " id="<?php echo $field_id; ?> " <?php if (!empty($field['placeholder'])) { echo 'placeholder="' . $field['placeholder'] . '"'; } ?> class="widefat siteorigin-widget-input" rows="<?php echo !empty($field['rows']) ? intval($field['rows']) : 4; ?> " <?php if (!empty($field['readonly'])) { echo 'readonly'; } ?> ><?php echo esc_textarea($value); ?> </textarea><?php break; case 'editor': // The editor field doesn't actually work yet, this is just a placeholder ?> <textarea type="text" name="<?php echo $this->so_get_field_name($name, $repeater); ?> " id="<?php echo $field_id; ?> " <?php if (!empty($field['placeholder'])) { echo 'placeholder="' . $field['placeholder'] . '"'; } ?> class="widefat siteorigin-widget-input siteorigin-widget-input-editor" rows="<?php echo !empty($field['rows']) ? intval($field['rows']) : 4; ?> " <?php if (!empty($field['readonly'])) { echo 'readonly'; } ?> ><?php echo esc_textarea($value); ?> </textarea><?php break; case 'slider': ?> <div class="siteorigin-widget-slider-value"><?php echo !empty($value) ? $value : 0; ?> </div> <div class="siteorigin-widget-slider-wrapper"> <div class="siteorigin-widget-value-slider"></div> </div> <input type="number" class="siteorigin-widget-input" name="<?php echo $this->so_get_field_name($name, $repeater); ?> " id="<?php echo $field_id; ?> " value="<?php echo !empty($value) ? esc_attr($value) : 0; ?> " min="<?php echo isset($field['min']) ? intval($field['min']) : 0; ?> " max="<?php echo isset($field['max']) ? intval($field['max']) : 100; ?> " /> <?php break; case 'select': ?> <select name="<?php echo $this->so_get_field_name($name, $repeater); ?> " id="<?php echo $field_id; ?> " class="siteorigin-widget-input"> <?php if (isset($field['prompt'])) { ?> <option value="default" disabled="disabled" selected="selected"><?php echo esc_html($field['prompt']); ?> </option> <?php } ?> <?php if (isset($field['options']) && !empty($field['options'])) { ?> <?php foreach ($field['options'] as $key => $val) { ?> <option value="<?php echo esc_attr($key); ?> " <?php selected($key, $value); ?> ><?php echo esc_html($val); ?> </option> <?php } ?> <?php } ?> </select> <?php break; case 'checkbox': ?> <label for="<?php echo $field_id; ?> "> <input type="checkbox" name="<?php echo $this->so_get_field_name($name, $repeater); ?> " id="<?php echo $field_id; ?> " class="siteorigin-widget-input" <?php checked(!empty($value)); ?> /> <?php echo $field['label']; ?> </label> <?php break; case 'radio': ?> <?php if (!isset($field['options']) || empty($field['options'])) { return; } ?> <?php foreach ($field['options'] as $k => $v) { ?> <label for="<?php echo $field_id . '-' . $k; ?> "> <input type="radio" name="<?php echo $this->so_get_field_name($name, $repeater); ?> " id="<?php echo $field_id . '-' . $k; ?> " class="siteorigin-widget-input" value="<?php echo esc_attr($k); ?> " <?php checked($k, $value); ?> > <?php echo esc_html($v); ?> </label> <?php } ?> <?php break; case 'media': if (version_compare(get_bloginfo('version'), '3.5', '<')) { printf(__('You need to <a href="%s">upgrade</a> to WordPress 3.5 to use media fields', 'siteorigin-widgets'), admin_url('update-core.php')); break; } if (!empty($value)) { if (is_array($value)) { $src = $value; } else { $post = get_post($value); $src = wp_get_attachment_image_src($value, 'thumbnail'); if (empty($src)) { $src = wp_get_attachment_image_src($value, 'thumbnail', true); } } } else { $src = array('', 0, 0); } $choose_title = empty($field['choose']) ? __('Choose Media', 'siteorigin-widgets') : $field['choose']; $update_button = empty($field['update']) ? __('Set Media', 'siteorigin-widgets') : $field['update']; $library = empty($field['library']) ? 'image' : $field['library']; ?> <div class="media-field-wrapper"> <div class="current"> <div class="thumbnail-wrapper"> <img src="<?php echo sow_esc_url($src[0]); ?> " class="thumbnail" <?php if (empty($src[0])) { echo "style='display:none'"; } ?> /> </div> <div class="title"><?php if (!empty($post)) { echo esc_attr($post->post_title); } ?> </div> </div> <a href="#" class="media-upload-button" data-choose="<?php echo esc_attr($choose_title); ?> " data-update="<?php echo esc_attr($update_button); ?> " data-library="<?php echo esc_attr($library); ?> "> <?php echo esc_html($choose_title); ?> </a> </div> <a href="#" class="media-remove-button <?php if (empty($value)) { echo 'remove-hide'; } ?> "><?php esc_html_e('Remove', 'siteorigin-widgets'); ?> </a> <?php if (!empty($field['fallback'])) { $v_name = $name; if (strpos($v_name, '][') !== false) { // Remove this splitter $v_name = substr($v_name, strpos($v_name, '][') + 2); } $fallback_url = !empty($all_values[$v_name . '_fallback']) ? $all_values[$v_name . '_fallback'] : ''; ?> <input type="text" value="<?php echo esc_url($fallback_url); ?> " placeholder="<?php esc_attr_e('External URL', 'siteorigin-widgets'); ?> " name="<?php echo $this->so_get_field_name($name . '_fallback', $repeater); ?> " class="media-fallback-external siteorigin-widget-input" /><?php } ?> <div class="clear"></div> <input type="hidden" value="<?php echo esc_attr(is_array($value) ? '-1' : $value); ?> " name="<?php echo $this->so_get_field_name($name, $repeater); ?> " class="siteorigin-widget-input" /> <?php break; case 'posts': siteorigin_widget_post_selector_admin_form_field(is_array($value) ? '' : $value, $this->so_get_field_name($name, $repeater)); break; case 'repeater': if (!isset($field['fields']) || empty($field['fields'])) { return; } ob_start(); $repeater[] = $name; foreach ($field['fields'] as $sub_field_name => $sub_field) { $this->render_field($sub_field_name, $sub_field, isset($value[$sub_field_name]) ? $value[$sub_field_name] : null, $value, $repeater, true); } $html = ob_get_clean(); $this->repeater_html[$name] = $html; $item_label = isset($field['item_label']) ? $field['item_label'] : null; if (!empty($item_label)) { // convert underscore naming convention to camelCase for javascript // and encode as json string $item_label = $this->underscores_to_camel_case($item_label); $item_label = json_encode($item_label); } $item_name = !empty($field['item_name']) ? $field['item_name'] : __('Item', 'siteorigin-widgets'); ?> <div class="siteorigin-widget-field-repeater" data-item-name="<?php echo esc_attr($item_name); ?> " data-repeater-name="<?php echo esc_attr($name); ?> " <?php echo !empty($item_label) ? 'data-item-label="' . esc_attr($item_label) . '"' : ''; ?> <?php echo !empty($field['scroll_count']) ? 'data-scroll-count="' . esc_attr($field['scroll_count']) . '"' : ''; ?> <?php if (!empty($field['readonly'])) { echo 'readonly'; } ?> > <div class="siteorigin-widget-field-repeater-top"> <div class="siteorigin-widget-field-repeater-expend"></div> <h3><?php echo $field['label']; ?> </h3> </div> <div class="siteorigin-widget-field-repeater-items"> <?php if (!empty($value)) { foreach ($value as $v) { ?> <div class="siteorigin-widget-field-repeater-item ui-draggable"> <div class="siteorigin-widget-field-repeater-item-top"> <div class="siteorigin-widget-field-expand"></div> <?php if (empty($field['readonly'])) { ?> <div class="siteorigin-widget-field-remove"></div> <?php } ?> <h4><?php echo esc_html($item_name); ?> </h4> </div> <div class="siteorigin-widget-field-repeater-item-form"> <?php foreach ($field['fields'] as $sub_field_name => $sub_field) { $this->render_field($sub_field_name, $sub_field, isset($v[$sub_field_name]) ? $v[$sub_field_name] : null, $v, $repeater); } ?> </div> </div> <?php } } ?> </div> <?php if (empty($field['readonly'])) { ?> <div class="siteorigin-widget-field-repeater-add"><?php _e('Add', 'siteorigin-widgets'); ?> </div> <?php } ?> </div> <?php break; case 'widget': // Create the extra form entries ?> <div class="siteorigin-widget-section <?php if (!empty($field['hide'])) { echo 'siteorigin-widget-section-hide'; } ?> "><?php if (!class_exists($field['class'])) { printf(__('%s does not exist', 'siteorigin-widgets'), $field['class']); echo '</div>'; break; } $sub_widget = new $field['class'](); if (!is_a($sub_widget, 'SiteOrigin_Widget')) { printf(__('%s is not a SiteOrigin Widget', 'siteorigin-widgets'), $field['class']); echo '</div>'; break; } foreach ($sub_widget->form_options($this) as $sub_name => $sub_field) { $this->render_field($name . '][' . $sub_name, $sub_field, isset($value[$sub_name]) ? $value[$sub_name] : null, $value, $repeater); } ?> </div><?php break; case 'icon': static $widget_icon_families; if (empty($widget_icon_families)) { $widget_icon_families = apply_filters('siteorigin_widgets_icon_families', array()); } list($value_family, $null) = !empty($value) ? explode('-', $value, 2) : array('fontawesome', ''); ?> <div class="siteorigin-widget-icon-selector siteorigin-widget-field-subcontainer"> <select class="siteorigin-widget-icon-family" > <?php foreach ($widget_icon_families as $family_id => $family_info) { ?> <option value="<?php echo esc_attr($family_id); ?> " <?php selected($value_family, $family_id); ?> ><?php echo esc_html($family_info['name']); ?> (<?php echo count($family_info['icons']); ?> )</option> <?php } ?> </select> <input type="hidden" name="<?php echo $this->so_get_field_name($name, $repeater); ?> " value="<?php echo esc_attr($value); ?> " class="siteorigin-widget-icon-icon siteorigin-widget-input" /> <div class="siteorigin-widget-icon-icons"></div> </div> <?php break; case 'font': static $widget_font_families; if (empty($widget_font_families)) { $widget_font_families = siteorigin_widgets_font_families(); } ?> <div class="siteorigin-widget-font-selector siteorigin-widget-field-subcontainer"> <select name="<?php echo $this->so_get_field_name($name, $repeater); ?> " id="<?php echo $field_id; ?> " class="siteorigin-widget-input"> <option value="default" selected="selected"><?php _e('Use theme font', 'siteorigin-widgets'); ?> </option> <?php foreach ($widget_font_families as $key => $val) { ?> <option value="<?php echo esc_attr($key); ?> " <?php selected($key, $value); ?> ><?php echo esc_html($val); ?> </option> <?php } ?> </select> </div> <?php break; case 'section': ?> <div class="siteorigin-widget-section <?php if (!empty($field['hide'])) { echo 'siteorigin-widget-section-hide'; } ?> "><?php if (!isset($field['fields']) || empty($field['fields'])) { return; } foreach ((array) $field['fields'] as $sub_name => $sub_field) { $this->render_field($name . '][' . $sub_name, $sub_field, isset($value[$sub_name]) ? $value[$sub_name] : null, $value, $repeater); } ?> </div><?php break; case 'bucket': // A bucket select and explore field ?> <input type="text" name="<?php echo $this->so_get_field_name($name, $repeater); ?> " id="<?php echo $field_id; ?> " value="<?php echo esc_attr($value); ?> " class="widefat siteorigin-widget-input" /><?php break; default: // We couldn't find the field, so lets give other plugins a chance to provide it echo apply_filters('siteorigin_widget_missing_field', __('Unknown Field', 'siteorigin-widgets'), $field, $value, $this); break; } if (!empty($field['description'])) { ?> <div class="siteorigin-widget-field-description"><?php echo wp_kses_post($field['description']); ?> </div><?php } ?> </div><?php }