PluginProbe
HTML Forms – Simple WordPress Forms Plugin / 1.0.6
HTML Forms – Simple WordPress Forms Plugin v1.0.6
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.6, at src/Forms.php

318 lines 10.1 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 add_filter('hf_form_markup', 'hf_template');
36 }
37
38 public function register()
39 {
40 // register post type
41 register_post_type('html-form', array(
42 'labels' => array(
43 'name' => 'HTML Forms',
44 'singular_name' => 'HTML Form',
45 ),
46 'public' => false
47 )
48 );
49
50 add_shortcode('hf_form', array($this, 'shortcode'));
51
52 // enable shortcodes in text widgets
53 add_filter( 'widget_text', 'shortcode_unautop' );
54 add_filter( 'widget_text', 'do_shortcode', 11 );
55 }
56
57 public function assets()
58 {
59 $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
60 $assets_url = plugins_url( 'assets/', $this->plugin_file );
61
62 wp_enqueue_script('html-forms', $assets_url . "js/public{$suffix}.js", array(), HTML_FORMS_VERSION, true);
63 wp_localize_script('html-forms', 'hf_js_vars', array(
64 'ajax_url' => admin_url('admin-ajax.php'),
65 ));
66
67 if( $this->settings['load_stylesheet'] ) {
68 wp_enqueue_style( 'html-forms', $assets_url . "css/forms{$suffix}.css", array(), HTML_FORMS_VERSION );
69 }
70 }
71
72 /**
73 * @param Form $form
74 * @param array $data
75 * @return string
76 */
77 public function validate_form(Form $form, array $data)
78 {
79 // validate honeypot field
80 $honeypot_key = sprintf( '_hf_h%d', $form->ID );
81 if( ! isset( $data[$honeypot_key] ) || $data[$honeypot_key] !== "" ) {
82 return 'spam';
83 }
84
85 // validate size of POST array
86 if( count($data) > $form->get_field_count() && apply_filters( 'hf_validate_form_request_size', true ) ) {
87 return 'spam';
88 }
89
90 $required_fields = $form->get_required_fields();
91 foreach ($required_fields as $field_name) {
92 $value = hf_array_get( $data, $field_name );
93 if ( empty( $value ) ) {
94 return 'required_field_missing';
95 }
96 }
97
98 $email_fields = $form->get_email_fields();
99 foreach ($email_fields as $field_name) {
100 $value = hf_array_get( $data, $field_name );
101 if ( ! empty( $value ) && ! is_email( $value ) ) {
102 return 'invalid_email';
103 }
104 }
105
106 $error_code = '';
107
108 /**
109 * This filter allows you to perform your own form validation. The dynamic portion of the hook refers to the form slug.
110 *
111 * Return a non-empty string if you want to raise an error.
112 * Error codes with a specific error message are: "required_field_missing", "invalid_email", and "error"
113 *
114 * @param string $error_code
115 * @param Form $form
116 * @param array $data
117 */
118 $error_code = apply_filters( 'hf_validate_form_' . $form->slug, $error_code, $form, $data );
119
120 /**
121 * This filter allows you to perform your own form validation.
122 *
123 * Return a non-empty string if you want to raise an error.
124 * Error codes with a specific error message are: "required_field_missing", "invalid_email", and "error"
125 *
126 * @param string $error_code
127 * @param Form $form
128 * @param array $data
129 */
130 $error_code = apply_filters( 'hf_validate_form', $error_code, $form, $data );
131 if( ! empty( $error_code ) ) {
132 return $error_code;
133 }
134
135 // all good: no errors!
136 return '';
137 }
138
139 /**
140 * Sanitize array with values before saving. Can be called recursively.
141 *
142 * @param mixed $value
143 */
144 public function sanitize( $value )
145 {
146 if (is_string($value)) {
147 // strip all HTML tags & whitespace
148 $value = trim(strip_tags($value));
149
150 // convert &amp; back to &
151 $value = html_entity_decode($value, ENT_NOQUOTES);
152 } elseif ( is_array($value) || is_object($value) ) {
153 $new_value = array();
154 $vars = is_array( $value ) ? $value : get_object_vars( $value );
155
156 foreach($vars as $key => $sub_value) {
157 // skip empty values
158 if(empty($sub_value)) {
159 continue;
160 }
161
162 // sanitize key
163 $key = trim(strip_tags($key));
164
165 // sanitize sub value
166 $new_value[$key] = $this->sanitize($sub_value);
167 }
168 $value = is_object( $value ) ? (object) $new_value : $new_value;
169 }
170
171 return $value;
172 }
173
174 public function listen()
175 {
176 // only respond to AJAX requests with _hf_form_id set.
177 if (empty($_POST['_hf_form_id'])
178 || empty( $_SERVER['HTTP_X_REQUESTED_WITH'] )
179 || strtolower( $_SERVER['HTTP_X_REQUESTED_WITH'] ) !== strtolower( 'XMLHttpRequest' ) ) {
180 return;
181 }
182
183 $data = $_POST;
184 $form_id = (int) $data['_hf_form_id'];
185 $form = hf_get_form($form_id);
186 $error_code = $this->validate_form($form, $data);
187
188 if (empty( $error_code ) ) {
189 // filter out all field names starting with _
190 foreach( $data as $key => $value ) {
191 if( strpos( $key, '_' ) === 0 ) {
192 unset( $data[$key] );
193 }
194 }
195
196 // strip slashes
197 $data = stripslashes_deep( $data );
198
199 // sanitize data: strip tags etc.
200 $data = $this->sanitize( $data );
201
202 // save form submission
203 $submission = new Submission();
204 $submission->form_id = $form_id;
205 $submission->data = $data;
206 $submission->ip_address = sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
207 $submission->user_agent = sanitize_text_field( $_SERVER['HTTP_USER_AGENT'] );
208 $submission->referer_url = sanitize_text_field( $_SERVER['HTTP_REFERER'] );
209 $submission->save();
210
211 // process form actions
212 if ( isset( $form->settings['actions'] ) ) {
213 foreach( $form->settings['actions'] as $action_settings ) {
214 /**
215 * Processes the specified form action and passes related data.
216 *
217 * @param array $action_settings
218 * @param Submission $submission
219 * @param Form $form
220 */
221 do_action('hf_process_form_action_' . $action_settings['type'], $action_settings, $submission, $form );
222 }
223 }
224
225 /**
226 * General purpose hook after all form actions have been processed for this specific form. The dynamic portion of the hook refers to the form slug.
227 *
228 * @param Submission $submission
229 * @param Form $form
230 */
231 do_action( "hf_form_{$form->slug}_success", $submission, $form );
232
233 /**
234 * General purpose hook after all form actions have been processed.
235 *
236 * @param Submission $submission
237 * @param Form $form
238 */
239 do_action( 'hf_form_success', $submission, $form );
240 } else {
241 /**
242 * General purpose hook for when a form error occurred
243 *
244 * @param string $error_code
245 * @param Form $form
246 * @param array $data
247 */
248 do_action( 'hf_form_error', $error_code, $form, $data );
249 }
250
251 $response = $this->get_response_for_error_code( $error_code, $form );
252
253 // clear output, some plugin or hooked code might have thrown errors by now.
254 if( ob_get_level() > 0 ) {
255 ob_end_clean();
256 }
257
258 send_origin_headers();
259 send_nosniff_header();
260 nocache_headers();
261
262 wp_send_json($response, 200);
263 exit;
264 }
265
266 private function get_response_for_error_code( $error_code, Form $form )
267 {
268 // return success response for empty error code string or spam (to trick bots)
269 if( $error_code === "" || $error_code === "spam" ) {
270 $response = array(
271 'message' => array(
272 'type' => 'success',
273 'text' => $form->get_message( 'success' ),
274 ),
275 'hide_form' => (bool)$form->settings['hide_after_success'],
276 );
277
278 if (!empty($form->settings['redirect_url'])) {
279 $response['redirect_url'] = $form->settings['redirect_url'];
280 }
281
282 return $response;
283 }
284
285 // get error message
286 $message = $form->get_message( $error_code );
287 if( empty( $message ) ) {
288 $message = $form->get_message( 'error' );
289 }
290
291 // return error response
292 return $response = array(
293 'message' => array(
294 'type' => 'warning',
295 'text' => $message,
296 ),
297 'error' => $error_code,
298 );
299 }
300
301 public function shortcode($attributes = array(), $content = '')
302 {
303 $slug_or_id = empty( $attributes['id'] ) ? $attributes['slug'] : $attributes['id'];
304
305 try {
306 $form = hf_get_form( $slug_or_id );
307 } catch( \Exception $e ) {
308 if ( ! current_user_can( 'manage_options' ) ) {
309 return $content;
310 }
311
312 return sprintf( '<p><strong>%s</strong> %s</p>', __( 'Error:', 'html-forms' ), sprintf( __( 'No form found with slug %s', 'html-forms' ), $attributes['slug'] ) );
313 }
314
315 return $form . $content;
316 }
317 }
318