Word Press: How to add custom validation to Advanced Custom Fields - wordpress

I'm trying to use this plug in: Advanced Custom Fields and add my own validation for specific fields.
I tried to follow this post:
https://www.advancedcustomfields.com/resources/acf-validate_value/
But what file do I change in my word press folder to allow it to work?
I'm trying to validate a Pin # that matches 1234.
I have recently tried to put it in the acf plugin folder for validation.php.
I tried it in here:
In
function acf_validate_value( $value, $field, $input ) {
// vars
$valid = true;
$message = sprintf( __( '%s value is required', 'acf' ), $field['label'] );
// valid
if ( $field['required'] ) {
// valid is set to false if the value is empty, but allow 0 as a valid value
if ( empty( $value ) && ! is_numeric( $value ) ) {
$valid = false;
}
}
/**
* Filters whether the value is valid.
*
* #date 28/09/13
* #since 5.0.0
*
* #param bool $valid The valid status. Return a string to display a custom error message.
* #param mixed $value The value.
* #param array $field The field array.
* #param string $input The input element's name attribute.
*/
$valid = apply_filters( "acf/validate_value/type={$field['type']}", $valid, $value, $field, $input );
$valid = apply_filters( "acf/validate_value/name={$field['_name']}", $valid, $value, $field, $input );
$valid = apply_filters( "acf/validate_value/key={$field['key']}", $valid, $value, $field, $input );
$valid = apply_filters( 'acf/validate_value', $valid, $value, $field, $input );
$valid = add_filter('acf/validate_value/name=registration_pin', 'my_acf_validate_value', 10, 4);
// allow $valid to be a custom error message
if ( ! empty( $valid ) && is_string( $valid ) ) {
$message = $valid;
$valid = false;
}
if ( ! $valid ) {
acf_add_validation_error( $input, $message );
return false;
}
// return
return true;
}
function my_acf_validation_registation_pin($valid, $value, $field, $input_name ){
// Bail early if value is already invalid.
if( $valid !== true ) {
return $valid;
}
console.log('validate registration pin: test ->' + new Date());
}

Yeah your code wont work. The add_filter will be hit too late.
If you are simply trying to get an acf field to validate the submitted value against a defined set value.
Best way to do this is to add this to your functions.php, see comments in my code below...
<?php
// add validate value filter for all acf fields with the field name `registration_pin`
// you can use `acf/validate_value/key=` to target a specific acf field by key if you have multiple fields with the same name `registration_pin` in different field groups
add_filter('acf/validate_value/name=registration_pin', 'acf_validate_reg_pin', 10, 4);
// function used by the above `add_filter`
function acf_validate_reg_pin($valid, $value, $field, $input_name) {
// define our registration pin to validate submitted value against
$reg_pin = '1234';
// if submitted value is empty or false
// remove this condition if you want the form to still validate if the field value is empty/false
if(!$value) {
// field returns invalid and show this error message
return __('Please enter registration pin.');
}
// if submitted value is a string and is not equal to our defined registration pin
if(is_string($value) && $value !== $reg_pin) {
// field returns invalid and show this error message
return __('Incorrect registration pin.');
}
// return field as valid, if none of the above conditions are true
return $valid;
}
This might make it a bit clearer for you about how to handle validation on specific acf fields. You should use this add_filter in your functions.php so the filter is hit.
You can use require_once(__DIR__ . '/folder/example.php'); in your functions.php, if you want to keep things tidy in your functions. You can load php files, lib classes, etc... everything required here runs first in the wordpress admin and your theme.

Related

WooCommerce - register second user in woocommerce_created_customer hook

I'm coming across an issue when trying to register a second user account once someone registers as a customer via WooCommerce. I have added the following woocommerce_created_customer hook:
add_action('woocommerce_created_customer', function($customer_id)
{
if(isset($_POST['second_user_first_name']) && isset($_POST['second_user_last_name']))
{
$createSecondUserId = wp_create_user(strtolower($_POST['second_user_first_name'].'-'.$_POST['second_user_last_name']).'-'.$customer_id, wp_generate_password(), 'test#test.com');
if(is_wp_error($createSecondUserId))
{
$errors = $createSecondUserId->errors;
print_r($errors);
die();
}
}
});
However I get the following error when submitting a new WooCommerce registration:
Array ( [existing_user_login] => Array ( [0] => Sorry, that username already exists! ) )
It's strange as I'm setting a random username within the wp_create_user function, so the usernames should not clash. Has anyone got any ideas?
You can use username_exists() to determines that the given username exists.
add_action( 'woocommerce_created_customer', function($customer_id){
if( isset( $_POST['second_user_first_name'] ) && isset( $_POST['second_user_last_name'] ) ) {
if( !username_exists( strtolower( $_POST['second_user_first_name'].'-'.$_POST['second_user_last_name'] ).'-'.$customer_id ) ){
$createSecondUserId = wp_create_user( strtolower( $_POST['second_user_first_name'].'-'.$_POST['second_user_last_name'] ).'-'.$customer_id, wp_generate_password(), 'test#test.com' );
if(is_wp_error($createSecondUserId)){
$errors = $createSecondUserId->errors;
print_r($errors);
die();
}
}
}
});
If the username already exists you can create a new one by adding a progressive numeric suffix. In this way you will be sure that the username of the second account will always be unique.
Note that if you run multiple tests with your current code you need to
make sure you remove the user with the email address test#test.com
otherwise you will get an error: [existing_user_email] => Sorry, that email address is already used!.
add_action('woocommerce_created_customer', function( $customer_id ) {
if ( isset($_POST['second_user_first_name']) && isset($_POST['second_user_last_name']) ) {
// create the username based on the form data
$username = strtolower( $_POST['second_user_first_name'] . '-' . $_POST['second_user_last_name'] ) . '-' . $customer_id;
// if the username already exists it creates a unique one
if ( username_exists($username) ) {
$i = 0;
while ( username_exists($username) ) {
$username = $username . '-' . ++$i;
}
}
// create the second user
$createSecondUserId = wp_create_user( $username, wp_generate_password(), 'test#test.com' );
}
});
The code has been tested and works. Add it to your active theme's functions.php.

Redirect user based on custom metadata, wordpress/woocommerce

I have added some custom metadata to wordpress per user and would like to redirect each user after login based on this custom metadata.
For instance i have a page called foo and another called bar. User one has a custom key (acCustomerName) in the metadata stating foo. And the other user has bar in his.
Depending on whats inside that field I would like to redirect the first user to http://example.tld/foo and the other to http://example.tld/bar.
I am able to retrieve this information perfectly fine and echo it out directly to test the function but are not able to retrieve that information inside the sencond function named forward_user and would like to know why.
Right now the user is redirected only to http://example.tld only. So it seems like the function does not get the $kundtyp string.
function kundtyp($Uuser) {
$key = 'acCustomerName';
$single = true;
return get_user_meta( $Uuser, $key, $single );
}
function forward_user( $redirect, $user ) {
$kundtyp = kundtyp($user);
$redirect_page_id = url_to_postid( $redirect );
$checkout_page_id = wc_get_page_id( 'checkout' );
if( $redirect_page_id == $checkout_page_id ) {
return $redirect;
}
return site_url( kundtyp( get_current_user_id() ) );
}
add_filter( 'woocommerce_login_redirect', 'forward_user', 1100, 2 );
Here is the updated code, you have to pass the ID of the user object to get_user_meta data function. You were passing the WP_User object to your function. I don't think you can use function get_current_user_id() because the global wp_user object has not been set yet. I checked it and it always returns 0 as the value. This would explain why they provide the $user variable in the filter.
function kundtyp($Uuser) {
$key = 'acCustomerName';
$single = true;
return get_user_meta( $Uuser->ID, $key, $single );
}
function forward_user( $redirect, $user ) {
$kundtyp = kundtyp($user);
$redirect_page_id = url_to_postid( $redirect );
$checkout_page_id = wc_get_page_id( 'checkout' );
if( $redirect_page_id == $checkout_page_id ) {
return $redirect;
}
return site_url( kundtyp( $user ) );
}
add_filter( 'woocommerce_login_redirect', 'forward_user', 1100, 2 );

Gravity Forms: Require minimum/maximum characters in input field

is it possible to limit the characters in an input field for every form we have?
I need an input field with exact 5 numbers (zip field).
I found this solution:
(full code here: https://gravitywiz.com/require-minimum-character-limit-gravity-forms/)
new GW_Minimum_Characters( array(
'form_id' => 524,
'field_id' => 1,
'min_chars' => 4,
'max_chars' => 5,
'min_validation_message' => __( 'Oops! You need to enter at least %s characters.' ),
'max_validation_message' => __( 'Oops! You can only enter %s characters.')
)
);
The problem is, that we have dozens of forms and couldn't build a function for all of them ;)
So we couldn't use the "form_id" and the "field_id".
Maybe there is a way to use a parameter name for the input field?
I had a similar issue where I needed to have minimum no. of characters for text fields and textarea. This setting had to be used in different forms and multiple fields therefore I could not add filters with pre-defined form ids and field ids.
What I did is that I created a new setting which was visible when editing a field and then I validated the submission. You can use the code below:
add_action( 'gform_field_standard_settings', 'minimum_field_setting', 10 );
add_action( 'gform_editor_js', 'editor_script' );
add_filter( 'gform_tooltips', 'add_encryption_tooltips' );
add_filter( 'gform_validation', 'general_validation' );
/**
* Adds the Minimum Characters Field to Form Fields
*
* #param integer $position
*/
function minimum_field_setting( $position ) {
//Position: Underneath Description TextArea
if ( $position == 75 ) {
?>
<li class="minlen_setting field_setting">
<label for="field_minlen" class="section_label">
<?php esc_html_e( 'Minimum Characters', 'gravityforms' ); ?>
<?php gform_tooltip( 'form_field_minlen' ) ?>
</label>
<input type="number"
id="field_minlen"
onblur="SetFieldProperty('minLength', this.value);"
value=""
/>
</li>
<?php
}
}
/**
* Adds Javascript to Gravity Forms in order to render the new setting field in their appropriate field types
*/
function editor_script() {
?>
<script type='text/javascript'>
//Append field setting only to text and textarea fields
jQuery.each(fieldSettings, function (index, value) {
if (index === 'textarea' || index === 'text') {
fieldSettings[index] += ", .minlen_setting";
}
});
//binding to the load field settings event to initialize the checkbox
jQuery(document).bind("gform_load_field_settings", function (event, field, form) {
if (field.type === 'textarea' || field.type === 'text') {
console.log(field);
if (typeof field.minLength !== "undefined") {
jQuery("#field_minlen").attr("value", field.minLength);
} else {
jQuery("#field_minlen").attr("value", '');
}
}
});
</script>
<?php
}
/**
* Add GF Tooltip for Minimum Length
*
* #param array $tooltips
*
* #return mixed
*/
function add_encryption_tooltips( $tooltips ) {
$tooltips['form_field_minlen'] = "<h6>Minimum Length</h6>Minimum number of characters for this field";
return $tooltips;
}
/**
* Validate Form Submission
*
* #param array $validation_result
*
* #return mixed
*/
function general_validation( $validation_result ) {
$form = $validation_result['form'];
foreach ( $form['fields'] as &$field ) {
if ( in_array( $field->type, [ 'text', 'textarea' ] ) && ! empty( $field->minLength ) ) {
$input_name = 'input_' . $field->id;
if ( isset( $_POST[ $input_name ] ) && $_POST[ $input_name ] != '' ) {
if ( strlen( $_POST[ $input_name ] ) < (int) $field->minLength ) {
$field->failed_validation = true;
$field->validation_message = 'Field must contain at least ' . $field->minLength . ' characters';
$validation_result['is_valid'] = false;
}
}
}
}
$validation_result['form'] = $form;
return $validation_result;
}
You can change the setting from Minimum Length to Exact Length and then update the validation accordingly.

after setup theme action creating issue with nonce in wordpress 4.3.1

I am using add_action( 'after_setup_theme', 'custom_login' ); hook in one of my website for auto redirect user to his dashboard page.
Here is my code :---
function custom_login($username, $password='') {
$creds = array();
$creds['user_login'] = $username;
$creds['user_password'] = $password;
$creds['remember'] = true;
$user = wp_signon( $creds, false );
if ( is_wp_error($user) ){
echo $user->get_error_message();
}
}
// run it before the headers and cookies are sent
add_action( 'after_setup_theme', 'custom_login' );
Its working fine on old version, But now I have upgrade wordpress version and its creating problem with nonce.
Are you sure you want to do this?
Everytime this error display on the screen when I do anything like update plugin, theme and permalinks.
When I comment this code then website working fine except auto redirect functionality.
Here is my website url :- https://www.linearrecruitment.co.uk/
Please help me where I do mistake.
That's a normal behaviour - nonce is a token used by Wordpress to check the validity of the form in order to prevent CSRF attacks.
A valid login form in Wordpress should have an hidden input field generated with wp_nonce_field:
wp_nonce_field('my_login_form');
Then in the login function the token is checked with the wp_verify_nonce function:
if (!isset($_POST['my_login_form']) || !wp_verify_nonce($_POST['_wpnonce'], 'my_login_form')) {
die('Invalid form');
}
What you're trying to do (auto login) is done wrong as add_action doesn't send any parameter for the after_setup_theme hook, so your username is probably empty. I don't know how this could possibly work before, maybe it managed to log in somehow with an empty username.
I suggest you to declare some globals vars for your username and password, as it seems to be static inputs:
global $username, $password;
$username = 'my_login';
$password = 'my_password';
And then on the beginning of your function import those globals with:
global $username, $password;
So what about the nonce?
On the last versions of Wordpress, the check_admin_referer have changed a bit, from:
function check_admin_referer( $action = -1, $query_arg = '_wpnonce' ) {
if ( -1 == $action )
_doing_it_wrong( __FUNCTION__, __( 'You should specify a nonce action to be verified by using the first parameter.' ), '3.2' );
$adminurl = strtolower(admin_url());
$referer = strtolower(wp_get_referer());
$result = isset($_REQUEST[$query_arg]) ? wp_verify_nonce($_REQUEST[$query_arg], $action) : false;
if ( !$result && !(-1 == $action && strpos($referer, $adminurl) === 0) ) {
wp_nonce_ays($action);
die();
}
do_action( 'check_admin_referer', $action, $result );
return $result;
}
To :
function check_admin_referer( $action = -1, $query_arg = '_wpnonce' ) {
if ( -1 == $action )
_doing_it_wrong( __FUNCTION__, __( 'You should specify a nonce action to be verified by using the first parameter.' ), '3.2' );
$adminurl = strtolower(admin_url());
$referer = strtolower(wp_get_referer());
$result = isset($_REQUEST[$query_arg]) ? wp_verify_nonce($_REQUEST[$query_arg], $action) : false;
do_action( 'check_admin_referer', $action, $result );
if ( ! $result && ! ( -1 == $action && strpos( $referer, $adminurl ) === 0 ) ) {
wp_nonce_ays( $action );
die();
}
return $result;
}
As you can see they moved the check_admin_referer hook - now we can change the value of $result before the wp_nonce_ays function (the one that display the message you try to get rid of) as been called.
That mean we could add the following hook in the theme functions.php in order to force the nonce validation:
add_action( 'check_admin_referer', array('custom_check_admin_referer' ) );
function custom_check_admin_referer() {
return 1;
}
That should work around your problem, but you must be aware that this could possibly be a security issue - you maybe want to do more test in that function before returning 1.

Multiple Content Filters Gravity View Plugin For Gravity Forms Plugin For WordPress

We are working with filters using the Gravity View plugin for Gravity Forms for WordPress. Not super good at filters yet, so hoping to get a little help with this if possible. We have a filter when added, that filters out certain content, based on the Gravity Form field ID. In the example below, we are filtering out the Gravity Form field with an ID of 18.
Example:
add_filter( 'gravityview/fields/custom/content_before', 'my_gv_custom_content_before', 10, 1 );
function my_gv_custom_content_before( $content ) {
$id = '18';
global $gravityview_view;
extract( $gravityview_view->field_data );
if( empty( $entry[ (string)$id ] ) ) {
return '';
}
return $content;
}
This works. Then taking it a step further, we are told we can add something to this filter to filter out multiple Gravity Form field ids using this something like this added to our example above. In this example, filtering Field 18 & 26:
if( ( false !== strpos( $content, '{MY_FIELD_NAME:18}') && empty( $entry['18'] ) ) || ( ( false !== strpos( $content, '{MY_FIELD_NAME:26}') && empty( $entry['26'] ) ) ) {
return '';
}
What would the two look like combined? For example, if we wanted to filter field id 18, 26 and perhaps a third field 34? Using the first part of the code example and then the second example, what would they look like combined? Could anyone provide an example?
Have been playing with this and not having much luck combining it all into one filter. Keep getting errors and I am sure we don't have something quite right. Thank you in advance.
Got it worked out, here is the code in case anyone needs it.
/** Modify the content returned from the Custom Content field */
add_filter( 'gravityview/fields/custom/content_before', 'my_gv_custom_content_before', 10, 1 );
/**
* Removes the custom content field's content in case a certain entry field is empty
*
* #param string $content Custom Content field content
* #return string
*/
function my_gv_custom_content_before( $content ) {
global $gravityview_view;
extract( $gravityview_view->field_data );
// field_id => merge_tag
$validation = array(
'18' => '{Custom Background:18}',
'26' => '{New YouTube Video Test:26}',
'28' => '{New Vimeo:28}'
);
foreach( $validation as $id => $merge ) {
if( false !== strpos( $content, $merge ) && empty( $entry[ (string)$id ] ) ) {
return '';
}
}
return $content;
}

Resources