PluginProbe
HTML Forms – Simple WordPress Forms Plugin / 1.0.2
HTML Forms – Simple WordPress Forms Plugin v1.0.2
trunk 1.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.2.0 1.3.0 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.14 1.3.15 1.3.16 1.3.17 All 66 releases
html-forms / src / Forms.php

Forms.php in HTML Forms – Simple WordPress Forms Plugin 1.0.2, at src/Forms.php

266 lines 8.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace HTML_Forms;
4
5 class Forms
6 {
7
8 /**
9 * @var string
10 */
11 private $plugin_file;
12
13 /**
14 * @var array
15 */
16 private $settings;
17
18 /**
19 * Forms constructor.
20 *
21 * @param string $plugin_file
22 * @param array $settings
23 */
24 public function __construct($plugin_file, array $settings )
25 {
26 $this->plugin_file = $plugin_file;
27 $this->settings = $settings;
28 }
29
30 public function hook()
31 {
32 add_action('init', array($this, 'register'));
33 add_action('init', array($this, 'listen'));
34 add_action('wp_enqueue_scripts', array($this, 'assets'));
35 }
36
37 public function register()
38 {
39 // register post type
40 register_post_type('html-form', array(
41 'labels' => array(
42 'name' => 'HTML Forms',
43 'singular_name' => 'HTML Form',
44 ),
45 'public' => false
46 )
47 );
48
49 add_shortcode('hf_form', array($this, 'shortcode'));
50
51 // enable shortcodes in text widgets
52 add_filter( 'widget_text', 'shortcode_unautop' );
53 add_filter( 'widget_text', 'do_shortcode', 11 );
54 }
55
56 public function assets()
57 {
58 $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
59 $assets_url = plugins_url( 'assets/', $this->plugin_file );
60
61 wp_enqueue_script('html-forms', $assets_url . "js/public{$suffix}.js", array(), HTML_FORMS_VERSION, true);
62 wp_localize_script('html-forms', 'hf_js_vars', array(
63 'ajax_url' => admin_url('admin-ajax.php'),
64 ));
65
66 if( $this->settings['load_stylesheet'] ) {
67 wp_enqueue_style( 'html-forms', "css/forms{$suffix}.css", array(), HTML_FORMS_VERSION );
68 }
69 }
70
71 /**
72 * @param Form $form
73 * @param array $data
74 * @return string
75 */
76 private function validate_form(Form $form, array $data)
77 {
78 // validate honeypot field
79 $honeypot_key = sprintf( '_hf_h%d', $form->ID );
80 if( ! isset( $data[$honeypot_key] ) || $data[$honeypot_key] !== "" ) {
81 return 'spam';
82 }
83
84 // validate size of POST array
85 if( count( $data ) > substr_count( strtolower( $form->get_html() ), 'name=' ) && apply_filters( 'hf_validate_form_request_size', true ) ) {
86 return 'spam';
87 }
88
89 $required_fields = $form->get_required_fields();
90 foreach ($required_fields as $field_name) {
91 $value = hf_array_get( $data, $field_name );
92 if ( empty( $value ) ) {
93 return 'required_field_missing';
94 }
95 }
96
97 $email_fields = $form->get_email_fields();
98 foreach ($email_fields as $field_name) {
99 $value = hf_array_get( $data, $field_name );
100 if ( ! empty( $value ) && ! is_email( $value ) ) {
101 return 'invalid_email';
102 }
103 }
104
105 /**
106 * This filter allows you to perform your own form validation.
107 *
108 * Return a non-empty string if you want to raise an error.
109 * Error codes with a specific error message are: "required_field_missing", "invalid_email", and "error"
110 *
111 * @param string $error_code
112 * @param Form $form
113 * @param array $data
114 */
115 $error = apply_filters( 'hf_validate_form', '', $form, $data );
116 if( ! empty( $error ) ) {
117 return $error;
118 }
119
120 // all good: no errors!
121 return '';
122 }
123
124 public function sanitize( $value )
125 {
126 if (is_string($value)) {
127 // strip all HTML tags & whitespace
128 $value = trim(strip_tags($value));
129
130 // convert &amp; back to &
131 $value = html_entity_decode($value, ENT_NOQUOTES);
132 } elseif ( is_array($value) || is_object($value) ) {
133 $new_value = array();
134 $vars = is_array( $value ) ? $value : get_object_vars( $value );
135
136 foreach($vars as $key => $sub_value) {
137 // skip empty values
138 if(empty($sub_value)) {
139 continue;
140 }
141
142 // sanitize key
143 $key = trim(strip_tags($key));
144
145 // sanitize sub value
146 $new_value[$key] = $this->sanitize($sub_value);
147 }
148 $value = is_object( $value ) ? (object) $new_value : $new_value;
149 }
150
151 return $value;
152 }
153
154 public function listen()
155 {
156 // only respond to AJAX requests with _hf_form_id set.
157 if (empty($_POST['_hf_form_id'])
158 || empty( $_SERVER['HTTP_X_REQUESTED_WITH'] )
159 || strtolower( $_SERVER['HTTP_X_REQUESTED_WITH'] ) !== strtolower( 'XMLHttpRequest' ) ) {
160 return;
161 }
162
163 $data = $_POST;
164 $form_id = (int) $data['_hf_form_id'];
165 $form = hf_get_form($form_id);
166 $error_code = $this->validate_form($form, $data);
167
168 if (empty( $error_code ) ) {
169
170 // filter out all field names starting with _
171 $data = array_filter( $data, function( $k ) {
172 return ! empty( $k ) && $k[0] !== '_';
173 }, ARRAY_FILTER_USE_KEY );
174
175 // strip slashes
176 $data = stripslashes_deep( $data );
177
178 // sanitize data: strip tags etc.
179 $data = $this->sanitize( $data );
180
181 // save form submission
182 $submission = new Submission();
183 $submission->form_id = $form_id;
184 $submission->data = $data;
185 $submission->ip_address = sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
186 $submission->user_agent = sanitize_text_field( $_SERVER['HTTP_USER_AGENT'] );
187 $submission->referer_url = sanitize_text_field( $_SERVER['HTTP_REFERER'] );
188 $submission->save();
189
190 // process form actions
191 foreach( $form->settings['actions'] as $action_settings ) {
192 /**
193 * Processes the specified form action and passes related data.
194 *
195 * @param array $action_settings
196 * @param Submission $submission
197 * @param Form $form
198 */
199 do_action('hf_process_form_action_' . $action_settings['type'], $action_settings, $submission, $form );
200 }
201
202 /**
203 * General purpose hook after all form actions have been processed.
204 *
205 * @param Submission $submission
206 * @param Form $form
207 */
208 do_action( 'hf_form_success', $submission, $form );
209 } else {
210
211 /**
212 * General purpose hook for when a form error occurred
213 *
214 * @param string $error_code
215 * @param Form $form
216 * @param array $data
217 */
218 do_action( 'hf_form_error', $error_code, $form, $data );
219 }
220
221 $response = $this->get_response_for_error_code( $error_code, $form );
222
223 send_origin_headers();
224 send_nosniff_header();
225 nocache_headers();
226
227 wp_send_json($response, 200);
228 exit;
229 }
230
231 private function get_response_for_error_code( $error_code, Form $form )
232 {
233 // return success response for empty error code string or spam (to trick bots)
234 if( $error_code === "" || $error_code === "spam" ) {
235 $response = array(
236 'message' => array(
237 'type' => 'success',
238 'text' => $form->messages['success'],
239 ),
240 'hide_form' => (bool)$form->settings['hide_after_success'],
241 );
242
243 if (!empty($form->settings['redirect_url'])) {
244 $response['redirect_url'] = $form->settings['redirect_url'];
245 }
246
247 return $response;
248 }
249
250 // return error response
251 return $response = array(
252 'message' => array(
253 'type' => 'warning',
254 'text' => isset( $form->messages[ $error_code ] ) ? $form->messages[ $error_code ] : $form->messages['error'],
255 ),
256 'error' => $error_code,
257 );
258 }
259
260 public function shortcode($attributes = array(), $content = '')
261 {
262 $form = hf_get_form($attributes['slug']);
263 return $form . $content;
264 }
265 }
266