I'm trying to add some form validations to a site I'm working on. I was able to get the validations to work on the fields that are required but as I'm trying to adjust the code for the non-required fields that still need to be validated when there is user-input I'm running into some issues.
This works pretty flawlessly if the field is required but when I make the field not required, the form doesn't submit and puts out an error message if I leave the field blank.
add_action( 'elementor_pro/forms/validation', function ( $record, $ajax_handler ) {
$fields = $record->get_field( [
'id' => 'dot',
] );
if ( empty( $fields ) ) {
return;
}
$field = current( $fields );
if ( 1 !== preg_match( '/[1-9]{1}[0-9]{5,7}/', $field['value'] ) || $field['value'] == '123456' || $field['value'] == '12345678' ) {
$ajax_handler->add_error( $field['id'], 'Invalid DOT#' );
}
}, 10, 2 );
Related
I am trying to build a form where when a user enters their order ID and unique serial code in the elementor form their order status is changed to completed. Heres the code i have written but i keep getting an error. The form has 2 fields 'a' & 'b'. A= order id and B= serial code.
add_action( 'elementor_pro/forms/validation', function ( $record, $ajax_handler ) {
$fields = $record->get_field( [
'id' => 'b'
], ['cid' => 'a'
]);
if ( empty( $fields ) ) {
return;
}
$field = current( $fields );
if ( 1 !== strlen( $field['value'] ) < 13 ) {
$ajax_handler->add_error( $field['id'], 'Invalid Serial Code, Please enter the 13 Digit Code mentioned on your delivery letter' );
} else {
$output['result'] = get_post_meta( $field['cid'], $key = 'shp_tkn', $single = true );
}
if ($output == $field['id']){
$order = $field['cid'] ;
$order->update_status('completed');
} else {
$ajax_handler->add_error( $field['id'], 'Invalid Serial Code, Please try again' );
}
}, 10, 2 );
If anyone could tell me where I'm going wrong.
How do I make the gravity form name field only accept letters, numbers should give an error.
You need to use gform_field_validation validation filter to be able to do this kind of validation before the form submits.
In addition, we need to use preg_match function of PHP with a regex to ensure we are only taking Letters from Full Name input value.
Just add this code in your active theme functions.php file: (Code tested and working)
add_filter( 'gform_field_validation', function ( $result, $value, $form, $field ) {
if ( $field->type == 'name' ) {
// Input values
$fullName = rgar( $value, $field->id . '.3' );
if ( empty( $fullName )) {
$result['is_valid'] = false;
$result['message'] = empty( $field->errorMessage ) ? __( 'This field is required. Please enter a complete name.', 'gravityforms' ) : $field->errorMessage;
} else if (preg_match('/[A-Za-z].*[0-9]|[0-9].*[A-Za-z]/', $fullName)) { //check for letters only
$result['is_valid'] = false;
$result['message'] = empty( $field->errorMessage ) ? __( 'Full name must ony contains letters.', 'gravityforms' ) : $field->errorMessage;
} else {
$result['is_valid'] = true;
$result['message'] = '';
}
}
return $result; //return results
}, 10, 4 );
I would like to prevent (make these fields readonly, for example) users from changing their billing information on the WooCommerce checkout form.
I'm currently using this code snippet:
add_filter('woocommerce_billing_fields', 'mycustom_woocommerce_billing_fields', 10, 1 );
function mycustom_woocommerce_billing_fields($fields)
{
$fields['billing_first_name']['custom_attributes'] = array('readonly'=>'readonly');
$fields['billing_last_name']['custom_attributes'] = array('readonly'=>'readonly');
$fields['billing_email']['custom_attributes'] = array('readonly'=>'readonly');
$fields['billing_phone']['custom_attributes'] = array('readonly'=>'readonly');
return $fields;
}
But the problem is: If the user has not filled in any of these fields in the registration, he is unable to insert his data in the checkout form because these fields are not editable.
My question is:
If the fields are not empty, how to make them readonly (or disabled)
Someone who can help me with this?
The answer of 7uc1f3r certainly works getting the user data… But since WooCommerce 3, you can use WC_Checkout get_value() dedicated method as follow:
add_filter( 'woocommerce_billing_fields', 'filter_wc_billing_fields', 10, 1 );
function filter_wc_billing_fields( $fields ) {
// On checkout and if user is logged in
if ( is_checkout() && is_user_logged_in() ) {
// Define your key fields below
$keys_fields = ['billing_first_name', 'billing_last_name', 'billing_email', 'billing_phone'];
// Loop through your specific defined fields
foreach ( $keys_fields as $key ) {
// Check that a value exist for the current field
if( ( $value = WC()->checkout->get_value($key) ) && ! empty( $value ) ) {
// Make it readonly if a value exist
$fields[$key]['custom_attributes'] = ['readonly'=>'readonly'];
}
}
}
return $fields;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
If you want this code to be also active in My account > Addresses > edit…, you will just have to remove is_checkout() && from the first IF statement.
I believe this is what you are looking for, comment with explanation added in code
function mycustom_woocommerce_billing_fields( $fields ) {
// Get current user
$user = wp_get_current_user();
// User id
$user_id = $user->ID;
// User id is found
if ( $user_id > 0 ) {
// Fields
$read_only_fields = array ( 'billing_first_name', 'billing_last_name', 'billing_email', 'billing_phone' );
// Loop
foreach ( $fields as $key => $field ) {
if( in_array( $key, $read_only_fields ) ) {
// Get key value
$key_value = get_user_meta($user_id, $key, true);
if( strlen( $key_value ) > 0 ) {
$fields[$key]['custom_attributes'] = array(
'readonly'=>'readonly'
);
}
}
}
}
return $fields;
}
add_filter('woocommerce_billing_fields', 'mycustom_woocommerce_billing_fields', 10, 1 );
I´m working on a wordpress plugin with Metaboxes. The plugin got rejected because of the Sanitize of metabox fields.
My save_fields function
public function save_fields( $post_id ) {
if ( ! isset( $_POST['modalsettings_nonce'] ) )
return $post_id;
$nonce = $_POST['modalsettings_nonce'];
if ( !wp_verify_nonce( $nonce, 'modalsettings_data' ) )
return $post_id;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $post_id;
foreach ( $this->meta_fields as $meta_field ) {
$userInput = $_POST[ $meta_field['id'] ];
if ( isset( $userInput ) ) {
switch ( $meta_field['type'] ) {
case 'email':
$userInput = sanitize_email( $_POST[ $meta_field['id'] ] );
break;
case 'text':
$userInput = sanitize_text_field( $_POST[ $meta_field['id'] ] );
break;
}
update_post_meta( $post_id, $meta_field['id'], $userInput );
} else if ( $meta_field['type'] === 'checkbox' ) {
update_post_meta( $post_id, $meta_field['id'], '0' );
}
}
}
The comment from wordpress review team
Data Must be Sanitized, Escaped, and Validated
When you include POST/GET/REQUEST/FILE calls in your plugin, it's
important to sanitize, validate, and escape them. The goal here is to
prevent a user from accidentally sending trash data through the
system, as well as protecting them from potential security issues.
SANITIZE: Data that is input (either by a user or automatically) must
be sanitized as soon as possible. This lessens the possibility of XSS
vulnerabilities and MITM attacks where posted data is subverted.
VALIDATE: All data should be validated, no matter what. Even when you
sanitize, remember that you don’t want someone putting in ‘dog’ when
the only valid values are numbers.
ESCAPE: Data that is output must be escaped properly when it is
echo'd, so it can't hijack admin screens. There are many esc_*()
functions you can use to make sure you don't show people the wrong
data.
To help you with this, WordPress comes with a number of sanitization
and escaping functions. You can read about those here:
https://developer.wordpress.org/plugins/security/securing-input/
https://developer.wordpress.org/plugins/security/securing-output/
Remember: You must use the most appropriate functions for the context.
If you’re sanitizing email, use sanitize_email(), if you’re outputting
HTML, use esc_html(), and so on.
An easy mantra here is this:
Sanitize early Escape Late Always Validate
Clean everything, check everything, escape everything, and never trust
the users to always have input sane data. After all, users come from
all walks of life.
Example(s) from your plugin:
stylistic-modals/admin/metaboxes.php:202: $userInput = $_POST[
$meta_field['id'] ]; if ( isset( $userInput ) ) { switch (
$meta_field['type'] ) { case 'email': $userInput = sanitize_email(
$_POST[ $meta_field['id'] ] ); break; case 'text': $userInput =
sanitize_text_field( $_POST[ $meta_field['id'] ] ); break; }
update_post_meta( $post_id, $meta_field['id'], $userInput );
Because you save $userInput later down, you must sanitize it.
What can I do?
I have no more ideas what Wordpress want from me and when should I sanitize the fields...also if I search for examples I find just this way to sanitize $_POST arrays....
Do you have any idea?
Edit: Will this work?
public function save_fields( $post_id ) {
if ( ! isset( $_POST['modalsettings_nonce'] ) )
return $post_id;
$nonce = $_POST['modalsettings_nonce'];
if ( !wp_verify_nonce( $nonce, 'modalsettings_data' ) )
return $post_id;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $post_id;
foreach ( $this->meta_fields as $meta_field ) {
if ( isset( $_POST[ $meta_field['id'] ] ) ) {
$sanitizedUserInput = "";
$sanitizedMetaFieldID = "";
switch ( $meta_field['type'] ) {
case 'email':
$sanitizedUserInput = sanitize_email( $_POST[ $meta_field['id'] ] );
$sanitizedMetaFieldID = sanitize_email( $meta_field['id']);
break;
case 'text':
$sanitizedUserInput = sanitize_text_field( $_POST[ $meta_field['id'] ] );
$sanitizedMetaFieldID = sanitize_text_field( $meta_field['id']);
break;
default:
$sanitizedUserInput = sanitize_text_field( $_POST[ $meta_field['id'] ] );
$sanitizedMetaFieldID = sanitize_text_field( $meta_field['id']);
}
update_post_meta( $post_id, $sanitizedMetaFieldID, $sanitizedUserInput );
} else if ( $meta_field['type'] === 'checkbox' ) {
$sanitizedMetaFieldID = sanitize_text_field( $meta_field['id']);
update_post_meta( $post_id, $sanitizedMetaFieldID, '0' );
}
}
}
Well, you have this assigning $userInput = $_POST[ $meta_field['id'] ]; there before the if statement. Then you've a switch statement. Now, say, on some reasons, the php execution flow doesn't access to switch statement.
Next up, the php execution flow reaches here:
update_post_meta( $post_id, $meta_field['id'], $userInput );
That means the $userInput variable is NOT being then sanitized. This may be the reason. I hope this would help you.
Here is my function:
public function save_meta( $term_id = 0, $taxonomy = '' ) {
$meta = ! empty( $_POST['banner'] ) ? $_POST['banner'] : '';
if ( empty( $meta ) ) {
delete_term_meta( $term_id, 'banner' );
} else {
update_term_meta( $term_id, 'banner', $meta );
}
}
And When Travis review the code it tells me that
Processing form data without nonce verification.
| | (WordPress.CSRF.NonceVerification.NoNonceVerification)
I tried the following but is not working:
public function save_meta( $term_id = 0, $taxonomy = '' ) {
$meta = ! empty( $_POST['banner'] ) && wp_verify_nonce( sanitize_key( $_POST['banner'] ) ? $_POST['banner'] : '';
if ( empty( $meta ) ) {
delete_term_meta( $term_id, 'banner' );
} else {
update_term_meta( $term_id, 'banner', $meta );
}
}
What is wrong with my code?
The nonce is a hash of the user id, the session token, the current time and a tag generated by the function wp_create_nonce(). This hash is used to validate that the request is not conterfeit. In your case a suitable tag would be 'update-banner_' . $term_id. Your HTTP request should return this nonce as a query or post parameter. For form submission this is usually done by using a hidden field in the form. WordPress provides the convenience function wp_nonce_field() to do this. Your request handler should then verify this nonce using the function wp_verify_nonce() or the convenience function check_admin_referer(). Please read the WordPress documentation for details on calling these functions.