PluginProbe
bBlocks – Essential Gutenberg Blocks & Patterns Collection / trunk
bBlocks – Essential Gutenberg Blocks & Patterns Collection vtrunk
2.1.6 2.1.5 2.1.4 2.1.3 2.1.2 2.1.1 2.1.0 2.0.43 2.0.42 2.0.41 2.0.40 2.0.39 2.0.38 trunk 1.0 1.1 1.2 1.3 1.4 1.5 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 All 106 releases
b-blocks / includes / blocks / form / FormHandler.php

FormHandler.php in bBlocks – Essential Gutenberg Blocks & Patterns Collection trunk, at includes/blocks/form/FormHandler.php

329 lines 10.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 require_once B_BLOCKS_DIR_PATH . 'includes/blocks/form/Helper.php';
3 require_once B_BLOCKS_DIR_PATH . 'includes/blocks/form/Sanitizer.php';
4 class BBlocksFormHandler{
5 function __construct(){
6 add_action('wp_ajax_nopriv_b_form_submit', [$this, 'b_form_submit']);
7 // add_action('wp_ajax_b_form_submit', [$this, 'b_form_submit']);
8 }
9
10 function b_form_submit(){
11
12 // verify nonce
13 if ( ! isset( $_POST['_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_nonce'] ) ), 'wp_ajax' ) ) {
14 wp_send_json_error([ 'message' => __( 'Something went wrong.', 'b-blocks' ) ]);
15 }
16 // sanitize field data and validate and create wp user_error
17
18 // $userEmail = $this->sanitize_array($_POST['userEmail']) ?? null;
19 // $adminEmail = $this->sanitize_array($_POST['adminEmail']) ?? null;
20
21 $payload = [
22 'username' => sanitize_text_field($_POST['username'] ?? null),
23 'email' => sanitize_email($_POST['email'] ?? null),
24 'password' => sanitize_text_field($_POST['password'] ?? null),
25 'first_name' => sanitize_text_field($_POST['first_name'] ?? null),
26 'last_name' => sanitize_text_field($_POST['last_name'] ?? null),
27 'user_url' => sanitize_text_field($_POST['user_url'] ?? null),
28 'current_post_id' => sanitize_text_field($_POST['current_post_id'] ?? ''),
29 'formId' => sanitize_text_field($_POST['formId'] ?? ''),
30 'rememberme' => sanitize_text_field($_POST['rememberme'] ?? ''),
31 ];
32
33 $form_type = sanitize_text_field( $_POST['type'] ?? '' );
34
35 if($form_type === 'register'){
36 return $this->register_user($payload);
37 }
38
39 if($form_type === 'login'){
40 return $this->login_user($payload);
41 }
42
43 if($form_type === 'logout'){
44 return $this->logout_user();
45 }
46
47 wp_send_json_error([
48 'message' => __( 'Something went wrong.', 'b-blocks' )
49 ]);
50 }
51
52 function sanitize_array($array){
53 if(!is_array($array)){
54 return [];
55 }
56
57 foreach($array as $key => $value){
58 if(strpos($key, 'secret_key') !== false && strlen($value) == 32){
59 $value = sanitize_text_field(str_replace('<', '&lt;', $value) );
60 $value = sanitize_text_field($value);
61 $array[$key] = str_replace(['&lt;', '&gt;', '&amp;'], [ '<', '>', '&'], $value);
62 }else {
63 if(is_array($value)){
64 $array[$key] = $this->sanitize_array($value);
65 }else {
66 $array[$key] =$value == 'true' ? true : ($value == 'false' ? false : sanitize_text_field($value));
67 }
68 }
69 }
70 return $array;
71 }
72
73
74 function register_user($payload){
75
76 if ( !get_option( 'users_can_register' ) ) {
77 wp_send_json_error([
78 'message' => __( 'User registration is turned off. Turn it on to allow user registration.', 'b-blocks' )
79 ]);
80 }
81
82 $block_data = BBlocksFormHelper::get_form_data($payload['current_post_id'], $payload['formId'], 'b-blocks/form-builder');
83
84 if ( ( $block_data['attributes']['form']['formType'] ?? '' ) !== 'register' ) {
85 wp_send_json_error([
86 'message' => __( 'Something went wrong.', 'b-blocks' )
87 ]);
88 }
89
90
91 // $this->send_user_email($user_mail, $payload);
92 // $this->send_admin_email($admin_mail, $payload);
93
94 // wp_send_json_success([
95 // 'message' => __( 'User registered successfully.', 'b-blocks' )
96 // ]);
97
98 $error = $this->validate_registration_data($payload, BBlocksFormHelper::get_password_requirements($block_data['innerBlocks']));
99 if($error){
100 wp_send_json_error([
101 'message' => $error
102 ]);
103 }
104 // ====================== ROLE FIX START ======================
105 $requested_role = sanitize_text_field(
106 $block_data['attributes']['formOptions']['userRole'] ?? 'subscriber'
107 );
108
109 $safe_role = 'subscriber';
110
111 $post_id = intval($payload['current_post_id'] ?? 0);
112 if ($post_id) {
113 $post_author_id = (int) get_post_field('post_author', $post_id);
114
115 if (user_can($post_author_id, 'promote_users') || user_can($post_author_id, 'manage_options')) {
116 $allowed_roles = ['subscriber', 'contributor', 'author', 'editor'];
117
118 if (in_array($requested_role, $allowed_roles, true) &&
119 array_key_exists($requested_role, wp_roles()->roles)) {
120 $safe_role = $requested_role;
121 }
122 }
123 }
124 // ====================== ROLE FIX END ======================
125
126 $user_id = wp_create_user( $payload['username'], $payload['password'], $payload['email'] );
127
128 if(is_wp_error($user_id)){
129 wp_send_json_error($user_id->get_error_message());
130 }
131
132 $user = new \WP_User($user_id);
133 $user->set_role($safe_role);
134
135 // $role = ( $block_data['attributes']['formOptions']['userRole'] ?? '' );
136 // if (
137 // ! empty( $role ) &&
138 // strtolower( $role ) !== 'default' &&
139 // array_key_exists( $role, wp_roles()->roles )
140 // ) {
141 // $user = new \WP_User( $user_id );
142 // $user->set_role( $role );
143 // }
144
145
146 if( $user_id ){ // sent mail after create account
147 wp_update_user([
148 'ID' => $user_id,
149 'first_name' => $payload['first_name'],
150 'last_name' => $payload['last_name'],
151 'user_url' => $payload['user_url']
152 ]);
153 }
154
155 // handle custom fields;
156 $custom_fields = $this->get_custom_fields($_POST);
157 if ( ! empty( $block_data ) ) {
158 $sorted_fields = BBlocksFormHelper::sort_fields( $block_data['innerBlocks'], $custom_fields );
159 $schema = BBlocksFormHelper::generate_schema( $sorted_fields );
160 $sanitized_fields = BBlocksSanitizer::sanitize($schema, $custom_fields );
161
162 array_walk($sanitized_fields, function ( $value, $key ) use ( $user_id ) {
163 update_user_meta( $user_id, 'bblocks_' . $key, $value );
164 });
165 }
166
167 $user_data = get_userdata($user_id);
168
169 // wp_set_current_user( $user_id );
170 // wp_set_auth_cookie( $user_id );
171
172 // $user_mail= $block_data['attributes']['emailOptions']['user'] ?? null;
173 // $admin_mail= $block_data['attributes']['emailOptions']['admin'] ?? null;
174
175 // $this->send_user_email($user_mail, $payload);
176 // $this->send_admin_email($admin_mail, $payload);
177
178 wp_send_json_success( [ 'message' => __( 'User registered successfully.', 'b-blocks' ) ] );
179
180 }
181
182 function login_user($payload){
183 $block_data = BBlocksFormHelper::get_form_data( $payload['current_post_id'], $payload['formId'], 'b-blocks/form-builder' );
184
185
186
187 $username = $payload['username'];
188 $email = $payload['email'];
189 $password = $payload['password'];
190 $remember = isset( $payload['rememberme'] ) && $payload['rememberme'] === 'on';
191
192 if($email && !$username){
193 $username = $email;
194 }
195
196 $secure_cookie = is_ssl();
197 $user_signon = wp_signon( array(
198 'user_login' => $username,
199 'user_password' => $password,
200 'remember' => $remember,
201 ), $secure_cookie );
202
203 if ( is_wp_error( $user_signon ) ) {
204 wp_send_json_error( [ 'message' => $user_signon->get_error_message(),'errorCode'=>$user_signon->get_error_code()] );
205 }
206
207 wp_set_current_user( $user_signon->ID );
208
209 wp_send_json_success([
210 'message' => __( 'You have logged in successfully.', 'b-blocks' ),
211 ]);
212 }
213
214 function logout_user(){
215
216 }
217
218 private function validate_registration_data( $payload, $passwordRequirements ) {
219 if ( empty( $payload['username'] ) || ! validate_username( $payload['username'] ) ) {
220 return __( 'Invalid username.', 'b-blocks' );
221 } elseif ( username_exists( $payload['username'] ) ) {
222 return __( 'Username already exists.', 'b-blocks' );
223 }
224
225 if ( empty( $payload['email'] ) || ! is_email( $payload['email'] ) ) {
226 return __( 'Invalid email address.', 'b-blocks' );
227 } elseif ( email_exists( $payload['email'] ) ) {
228 return __( 'Email already exists.', 'b-blocks' );
229 }
230
231 if ( empty( $payload['password'] ) ) {
232 return __( 'Password is required.', 'b-blocks' );
233 }
234
235 if($passwordRequirements['isWeek']){
236 return null;
237 }
238
239 if($passwordRequirements['isLowerCase']){
240 if ( empty( $payload['password'] ) || ! preg_match( '/[a-z]/', $payload['password'] ) ) {
241 return __( 'Password must contain at least one lowercase letter.', 'b-blocks' );
242 }
243 }
244 if($passwordRequirements['isNumber']){
245 if ( empty( $payload['password'] ) || ! preg_match( '/[0-9]/', $payload['password'] ) ) {
246 return __( 'Password must contain at least one number.', 'b-blocks' );
247 }
248 }
249 if($passwordRequirements['isSpecialChar']){
250 if ( empty( $payload['password'] ) || ! preg_match( '/[^a-zA-Z0-9]/', $payload['password'] ) ) {
251 return __( 'Password must contain at least one special character.', 'b-blocks' );
252 }
253 }
254 if($passwordRequirements['isUpperCase']){
255 if ( empty( $payload['password'] ) || ! preg_match( '/[A-Z]/', $payload['password'] ) ) {
256 return __( 'Password must contain at least one uppercase letter.', 'b-blocks' );
257 }
258 }
259 if($passwordRequirements['minLength']){
260 if ( empty( $payload['password'] ) || strlen( $payload['password'] ) < $passwordRequirements['minLength'] ) {
261 /* translators: %d: minimum password length. */
262 return sprintf( __( 'Password must be at least %d characters.', 'b-blocks' ), (int) $passwordRequirements['minLength'] );
263 }
264 }
265
266 return null;
267 }
268
269 private function get_custom_fields( $form_data ) {
270 $reserved_keys = [ 'username', 'email', 'password', 'confirm_password', 'first_name', 'last_name', 'user_url', 'current_post_id', 'block_id', 'security', 'action' ];
271 return array_diff_key( $form_data, array_flip( $reserved_keys ) );
272 }
273
274 function send_user_email($user_email,$payload){
275 if(!$user_email){
276 return;
277 }
278
279 $template = $this->processEmailTemplate($user_email['mail']['message'], $payload);
280
281 $headers[] = 'Content-Type: text/html; charset=UTF-8';
282
283 $sent = wp_mail($payload['email'], $user_email['subject'], $template, $headers);
284
285 if(!$sent){
286 add_action('wp_mail_failed', function ($error) {
287 error_log('Failed to send email to user - ' . $error->get_error_message());
288 });
289 }
290 }
291 function send_admin_email($admin_email,$payload){
292 if(!$admin_email){
293 return;
294 }
295 $template = $this->processEmailTemplate($admin_email['mail']['message'], $payload);
296
297 $headers[] = 'Content-Type: text/html; charset=UTF-8';
298
299 $sent = wp_mail($admin_email['email'], $admin_email['subject'], $template, $headers);
300
301 if(!$sent){
302 add_action('wp_mail_failed', function ($error) {
303 error_log('Failed to send email to admin - ' . $error->get_error_message());
304 });
305 }
306 }
307
308
309 function processEmailTemplate($template,$data)
310 {
311 $processedTemplate = $template;
312
313 foreach ($data as $key => $value) {
314 $placeholder = '[' . $key . ']';
315 $value = isset($value) ? (string)$value : '';
316
317 $escapedPlaceholder = preg_quote($placeholder, '/');
318 $regex = '/' . $escapedPlaceholder . '/g';
319 $processedTemplate = preg_replace('/' . $escapedPlaceholder . '/', $value, $processedTemplate);
320 }
321
322 return $processedTemplate;
323 }
324
325
326 }
327
328 new BBlocksFormHandler();
329