PluginProbe
HTML Forms – Simple WordPress Forms Plugin / 1.0.5
HTML Forms – Simple WordPress Forms Plugin v1.0.5
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.5, at src/Forms.php

294 lines 9.0 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', $assets_url . "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 /**
125 * Sanitize array with values before saving. Can be called recursively.
126 *
127 * @param mixed $value
128 */
129 public function sanitize( $value )
130 {
131 if (is_string($value)) {
132 // strip all HTML tags & whitespace
133 $value = trim(strip_tags($value));
134
135 // convert &amp; back to &
136 $value = html_entity_decode($value, ENT_NOQUOTES);
137 } elseif ( is_array($value) || is_object($value) ) {
138 $new_value = array();
139 $vars = is_array( $value ) ? $value : get_object_vars( $value );
140
141 foreach($vars as $key => $sub_value) {
142 // skip empty values
143 if(empty($sub_value)) {
144 continue;
145 }
146
147 // sanitize key
148 $key = trim(strip_tags($key));
149
150 // sanitize sub value
151 $new_value[$key] = $this->sanitize($sub_value);
152 }
153 $value = is_object( $value ) ? (object) $new_value : $new_value;
154 }
155
156 return $value;
157 }
158
159 public function listen()
160 {
161 // only respond to AJAX requests with _hf_form_id set.
162 if (empty($_POST['_hf_form_id'])
163 || empty( $_SERVER['HTTP_X_REQUESTED_WITH'] )
164 || strtolower( $_SERVER['HTTP_X_REQUESTED_WITH'] ) !== strtolower( 'XMLHttpRequest' ) ) {
165 return;
166 }
167
168 $data = $_POST;
169 $form_id = (int) $data['_hf_form_id'];
170 $form = hf_get_form($form_id);
171 $error_code = $this->validate_form($form, $data);
172
173 if (empty( $error_code ) ) {
174 // filter out all field names starting with _
175 foreach( $data as $key => $value ) {
176 if( strpos( $key, '_' ) === 0 ) {
177 unset( $data[$key] );
178 }
179 }
180
181 // strip slashes
182 $data = stripslashes_deep( $data );
183
184 // sanitize data: strip tags etc.
185 $data = $this->sanitize( $data );
186
187 // save form submission
188 $submission = new Submission();
189 $submission->form_id = $form_id;
190 $submission->data = $data;
191 $submission->ip_address = sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
192 $submission->user_agent = sanitize_text_field( $_SERVER['HTTP_USER_AGENT'] );
193 $submission->referer_url = sanitize_text_field( $_SERVER['HTTP_REFERER'] );
194 $submission->save();
195
196 // process form actions
197 foreach( $form->settings['actions'] as $action_settings ) {
198 /**
199 * Processes the specified form action and passes related data.
200 *
201 * @param array $action_settings
202 * @param Submission $submission
203 * @param Form $form
204 */
205 do_action('hf_process_form_action_' . $action_settings['type'], $action_settings, $submission, $form );
206 }
207
208 /**
209 * General purpose hook after all form actions have been processed.
210 *
211 * @param Submission $submission
212 * @param Form $form
213 */
214 do_action( 'hf_form_success', $submission, $form );
215 } else {
216
217 /**
218 * General purpose hook for when a form error occurred
219 *
220 * @param string $error_code
221 * @param Form $form
222 * @param array $data
223 */
224 do_action( 'hf_form_error', $error_code, $form, $data );
225 }
226
227 $response = $this->get_response_for_error_code( $error_code, $form );
228
229 // clear output, some plugin or hooked code might have thrown errors by now.
230 if( ob_get_level() > 0 ) {
231 ob_end_clean();
232 }
233
234 send_origin_headers();
235 send_nosniff_header();
236 nocache_headers();
237
238 wp_send_json($response, 200);
239 exit;
240 }
241
242 private function get_response_for_error_code( $error_code, Form $form )
243 {
244 // return success response for empty error code string or spam (to trick bots)
245 if( $error_code === "" || $error_code === "spam" ) {
246 $response = array(
247 'message' => array(
248 'type' => 'success',
249 'text' => $form->get_message( 'success' ),
250 ),
251 'hide_form' => (bool)$form->settings['hide_after_success'],
252 );
253
254 if (!empty($form->settings['redirect_url'])) {
255 $response['redirect_url'] = $form->settings['redirect_url'];
256 }
257
258 return $response;
259 }
260
261 // get error message
262 $message = $form->get_message( $error_code );
263 if( empty( $message ) ) {
264 $message = $form->get_message( 'error' );
265 }
266
267 // return error response
268 return $response = array(
269 'message' => array(
270 'type' => 'warning',
271 'text' => $message,
272 ),
273 'error' => $error_code,
274 );
275 }
276
277 public function shortcode($attributes = array(), $content = '')
278 {
279 $slug_or_id = empty( $attributes['id'] ) ? $attributes['slug'] : $attributes['id'];
280
281 try {
282 $form = hf_get_form( $slug_or_id );
283 } catch( \Exception $e ) {
284 if ( ! current_user_can( 'manage_options' ) ) {
285 return $content;
286 }
287
288 return sprintf( '<p><strong>%s</strong> %s</p>', __( 'Error:', 'html-forms' ), sprintf( __( 'No form found with slug %s', 'html-forms' ), $attributes['slug'] ) );
289 }
290
291 return $form . $content;
292 }
293 }
294