plugin_file = $plugin_file;
$this->settings = $settings;
}
public function hook()
{
add_action('init', array($this, 'register'));
add_action('init', array($this, 'listen'));
add_action('wp_enqueue_scripts', array($this, 'assets'));
}
public function register()
{
// register post type
register_post_type('html-form', array(
'labels' => array(
'name' => 'HTML Forms',
'singular_name' => 'HTML Form',
),
'public' => false
)
);
add_shortcode('hf_form', array($this, 'shortcode'));
// enable shortcodes in text widgets
add_filter( 'widget_text', 'shortcode_unautop' );
add_filter( 'widget_text', 'do_shortcode', 11 );
}
public function assets()
{
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
wp_enqueue_script('html-forms', plugins_url('assets/js/public'. $suffix .'.js', $this->plugin_file), array(), HTML_FORMS_VERSION, true);
wp_localize_script('html-forms', 'hf_js_vars', array(
'ajax_url' => admin_url('admin-ajax.php'),
));
if( $this->settings['load_stylesheet'] ) {
wp_enqueue_style( 'html-forms', plugins_url( 'assets/css/forms' . $suffix . '.css', $this->plugin_file ), array(), HTML_FORMS_VERSION );
}
}
/**
* @param Form $form
* @param array $data
* @return string
*/
private function validate_form(Form $form, array $data)
{
$honeypot_key = sprintf( '_hf_h%d', $form->ID );
if( ! isset( $data[$honeypot_key] ) || $data[$honeypot_key] !== "" ) {
return 'spam';
}
/**
* This filter allows you to perform your own form validation.
*
* Return a non-empty string if you want to raise an error.
* Error codes with a specific error message are: "required_field_missing", "invalid_email", and "error"
*
* @param string $error_code
* @param Form $form
* @param array $data
*/
$error = apply_filters( 'hf_validate_form', '', $form, $data );
if( ! empty( $error ) ) {
return $error;
}
$required_fields = $form->get_required_fields();
foreach ($required_fields as $field_name) {
$value = hf_array_get( $data, $field_name );
if ( empty( $value ) ) {
return 'required_field_missing';
}
}
$email_fields = $form->get_email_fields();
foreach ($email_fields as $field_name) {
$value = hf_array_get( $data, $field_name );
if ( ! empty( $value ) && ! is_email( $value ) ) {
return 'invalid_email';
}
}
// all good: no errors!
return '';
}
public function sanitize( $value )
{
if (is_string($value)) {
// strip all HTML tags & whitespace
$value = trim(strip_tags($value));
// convert & back to &
$value = html_entity_decode($value, ENT_NOQUOTES);
} elseif (is_array($value)) {
$new_value = array();
foreach($value as $key => $sub_value) {
// skip empty values
if(empty($sub_value)) {
continue;
}
// sanitize key
$key = trim(strip_tags($key));
// sanitize sub value
$new_value[$key] = $this->sanitize($sub_value);
}
$value = $new_value;
} elseif (is_object($value)) {
$vars = get_object_vars($value);
$new_value = new \StdClass();
foreach ($vars as $key => $sub_value) {
// skip empty values
if(empty($sub_value)) {
continue;
}
// sanitize key
$key = trim(strip_tags($key));
// sanitize sub value
$new_value->{$key} = $this->sanitize($sub_value);
}
$value = $new_value;
}
return $value;
}
public function listen() {
// only respond to AJAX requests with _hf_form_id set.
if (empty($_POST['_hf_form_id'])
|| empty( $_SERVER['HTTP_X_REQUESTED_WITH'] )
|| strtolower( $_SERVER['HTTP_X_REQUESTED_WITH'] ) !== strtolower( 'XMLHttpRequest' ) ) {
return;
}
$data = $_POST;
$form_id = (int) $data['_hf_form_id'];
$form = hf_get_form($form_id);
$error_code = $this->validate_form($form, $data);
if (empty( $error_code ) ) {
// filter out all field names starting with _
$data = array_filter( $data, function( $k ) {
return ! empty( $k ) && $k[0] !== '_';
}, ARRAY_FILTER_USE_KEY );
// strip slashes
$data = stripslashes_deep( $data );
// sanitize data: strip tags etc.
$data = $this->sanitize( $data );
// save form submission
$submission = new Submission();
$submission->form_id = $form_id;
$submission->data = $data;
$submission->ip_address = sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
$submission->user_agent = sanitize_text_field( $_SERVER['HTTP_USER_AGENT'] );
$submission->referer_url = sanitize_text_field( $_SERVER['HTTP_REFERER'] );
$submission->save();
// process form actions
foreach( $form->settings['actions'] as $action_settings ) {
/**
* Processes the specified form action and passes related data.
*
* @param array $action_settings
* @param Submission $submission
* @param Form $form
*/
do_action('hf_process_form_action_' . $action_settings['type'], $action_settings, $submission, $form );
}
/**
* General purpose hook after all form actions have been processed.
*
* @param Submission $submission
* @param Form $form
*/
do_action( 'hf_form_success', $submission, $form );
$response = array(
'message' => array(
'type' => 'success',
'text' => $form->messages['success'],
),
'hide_form' => (bool)$form->settings['hide_after_success'],
);
if (!empty($form->settings['redirect_url'])) {
$response['redirect_url'] = $form->settings['redirect_url'];
}
} else {
$response = array(
'message' => array(
'type' => 'warning',
'text' => isset( $form->messages[ $error_code ] ) ? $form->messages[ $error_code ] : $form->messages['error'],
),
'error' => $error_code,
);
/**
* General purpose hook for when a form error occurred
*
* @param string $error_code
* @param Form $form
* @param array $data
*/
do_action( 'hf_form_error', $error_code, $form, $data );
}
send_origin_headers();
send_nosniff_header();
nocache_headers();
wp_send_json($response, 200);
exit;
}
public function shortcode($attributes = array(), $content = '')
{
$form = hf_get_form($attributes['slug']);
return $form . $content;
}
}