Validation error on custom fields woo-commerce checkout [duplicate] - validation

I would like add my own regular expression for validating the phone number. In my class-wc-validation.php I have changed the regular expression to my requirement.
public static function is_phone( $phone ) {
//if ( strlen( trim( preg_replace( '/[\s\#0-9_\-\+\(\)]/', '', $phone ) ) ) > 0 )
if ( strlen( trim( preg_replace( '/^[6789]\d{9}$/', '', $phone ) ) ) > 0 )
return false;
return true;
}
But the validation is not happening. What am I missing?

Was facing the same issue and followed what others had said here, but Woocommerce only sets the errors on validation after woocommerce_checkout_process hook.
But, in the latest Woocommerce 3.0 (not sure if this is in the 2.x version), we can use the woocommerce_after_checkout_validation hook and then look into the $data param if you are using the standard checkout fields or use $_POST if you have custom fields that aren't added in the standard Woocommerce way. An example of the code is:
public function validate($data,$errors) {
// Do your data processing here and in case of an
// error add it to the errors array like:
$errors->add( 'validation', __( 'Please input that correctly.' ));
}
add_action('woocommerce_after_checkout_validation', 'validate',10,2);
Hope that helps!

I have not seen your code that hooks these up to the woocommerce checkout flow.
please check their documentation on
woocommerce_checkout_process and woocommerce_checkout_order_processed
But in your case, I highly suggest that you hook it up on woocommerce_checkout_process
so put these codes below on your functions.php on your theme, or you create your own woocommerce plugins, and put it in the bootstrap code.
add_action('woocommerce_checkout_process', 'is_phone');
function is_phone() {
$phone_number = $_POST['---your-phone-field-name---'];
// your function's body above, and if error, call this wc_add_notice
wc_add_notice( __( 'Your phone number is wrong.' ), 'error' );
}

You should not edit plugin files, because if you update plugin all the
customization will be lost, rather you can use hook to achieve your
goal. You can use using woocommerce_checkout_process hook to do
this.
Here is the code:
add_action('woocommerce_checkout_process', 'wh_phoneValidateCheckoutFields');
function wh_phoneValidateCheckoutFields() {
$billing_phone = filter_input(INPUT_POST, 'billing_phone');
if (strlen(trim(preg_replace('/^[6789]\d{9}$/', '', $billing_phone))) > 0) {
wc_add_notice(__('Invalid <strong>Phone Number</strong>, please check your input.'), 'error');
}
}
Code goes in functions.php file of your active child theme (or theme). Or also in any plugin PHP files.
Please Note: By default WooCommerce use billing_phone field to take phone number, but if you have customized it then you can replace billing_phone with your field name.
Hope this helps!

In your question you're saying that validation rule is not working and I guess it's written in a wrong way. You can test it in online with regexp tools, e.g. Regex101 or others.
To answer more general on this topic, changing validation rules safely can be done this way:
Make a copy of class-wc-validation.php to your theme directory in your_theme_path/woocommerce/includes/class-wc-validation.php and make customization to the validation rules.
Then you should make a validation rule for the phone filed in checkout.js otherwise your field always will have green border despite it's invalid.
So my solution was to add custom regular expression validator to checkout.js about line 192:
if ( $parent.is( '.validate-phone' ) ) {
if ( $this.val() ) {
var pattern = new RegExp(/^([0-9\s\/\+\-\#\_\(\)]*)$/);
if ( ! pattern.test( $this.val() ) ) {
$parent.removeClass( 'woocommerce-validated' ).addClass( 'woocommerce-invalid woocommerce-invalid-phone' );
validated = false;
}
}
}
And include your customized .js file (in functions.php)
add_action( 'wp_enqueue_scripts', 'my_checkoutjs_enqueue_scripts', 100 );
function gv_checkoutjs_enqueue_scripts() {
if ( is_checkout() ) {
wp_deregister_script( 'wc-checkout' );
wp_enqueue_script( 'wc-checkout', get_template_directory_uri() . '/js/modified_checkout.js', array( 'jquery', 'woocommerce', 'wc-country-select', 'wc-address-i18n' ) );
}}
Hope this helps!

Related

WordPress ajax request not translated with Polylang

I've had problem with ajax requests that my requests translating __() functions didn't work.
Googled it from everywhere.
Everywhere was as an answer that url parameter in the following form ?lang=fi should be added for the requests.
It turned out that if you are using Polylang your ajax requests url must in format /fi. Note for the default language this shouldn't be defined at all.
Solved the problem with this change.
I hope this helps someone.
I know am late to the party but I couldn't find any answers anywhere that will solve this problem and Libla's answer it's just right.
Just a little context:
I have a multilingual Woocommerce website and all translations were working great except for the checkout "order review" that is loading with Ajax.
This part after Ajax is showing in the website language (the one you have set up in settings).
All of that is because the Ajax call ignores the "?lang=" parameter (probably just the Polylang plugin, I never checked with other translation plugins).
Instead, Ajax should contain the language parameter (like in the browser www.yourwebsite.com/fi).
To solve that, I've added a filter (in functions.php)
/** Fix ajax handler translation */
add_filter( 'woocommerce_get_script_data', 'ajax_handler_fix_translation' );
if ( ! function_exists( 'ajax_handler_fix_translation' ) ) {
function ajax_handler_fix_translation( $params ) {
/** Get the current language */
$locale = determine_locale();
/** Take just the first part of the $locale */
$lang = ( ! empty( $locale ) ) ? strstr( $locale, '_', true ) : '';
if ( empty( $lang ) ) {
/** If there is no $lang parameter, just return to standard */
return $params;
}
if ( isset( $params['wc_ajax_url'] ) ) {
$params['wc_ajax_url'] = '/'.$lang.$params['wc_ajax_url'];
}
return $params;
}
}

Joomla 3 reCaptcha validation

I have a simple custom form in Joomla 3.6 that I have added reCaptcha to successfully. However, I am struggling with validating this.
After a few web searches, I can up with the following code:
$joomla_captcha = JFactory::getConfig()->get('captcha');
if ( $joomla_captcha != '0') {
$jpost = JFactory::getApplication()->input->post;
$reCaptcha = $jpost->get("g-recaptcha-response");
$dispatcher = JEventDispatcher::getInstance();
$captcha_response = $dispatcher->trigger('onCheckAnswer', $reCaptcha);
}
if ( ! $captcha_response[0] ) {
die("Invalid Captcha");
}
However, the form is passing whether the captcha is done or not.
What changes do I need to make to pick up whether the captcha was passed or not?
The form is really basic and I am loathe to install yet another component just for this validation.
Okay, it appears I hit a brick wall in trying to find a "Joomla" way to do this that calls on inbuilt API methods.
Since I am only using Google reCaptcha, I found on Google's site that the "g-recaptcha-response" field is empty if the captcha challenge has not been completed and not empty if correctly completed.
So, for Google reCaptcha, I need to test the "g-recaptcha-response" field and my code example becomes:
$joomla_captcha = JFactory::getConfig()->get('captcha');
if ( $joomla_captcha != '0') {
$jpost = JFactory::getApplication()->input->post;
$reCaptcha = $jpost->get("g-recaptcha-response");
}
if ( isset( $reCaptcha ) && empty( $reCaptcha ) {
die("Invalid Captcha");
}
This is obviously limited to Google reCaptcha and would have been nice to query the Joomla API Layer instead to allow flexibility but good enough.
Edit
The following Joomla API calls will return "true" or "false" into $completed indicating whether the captcha passed or not
$config = JFactory::getConfig()->get('captcha');
$captcha = JCaptcha::getInstance($config);
$completed = $captcha->CheckAnswer();
if ($completed === false) {
die("Invalid Captcha");
}
Preferable to the earlier approach as will be able to work with other captcha plugins that may be added to Joomla.

Front-End Plug-In Page

Ok, so I've looked at many posts on here about similar topics, but every single one of them is a rewrite rule for an actual php file in the url such as cart.php rather than the pretty permalink /cart/.
Basically, all I'm trying to do here is have WordPress include a template whenever a specific url is visited. In this case, example.com/cart/. Since this code is for a plug-in, it's a url that does not exist, and I cannot create a page for it. I'm trying to use a rewrite rule, along with query vars, to display the correct template when the user visits /cart/. I think I'm pretty close, but I've tried it several different ways, and I know I'm probably missing something obvious. I keep getting a 404 error, and I'm pretty sure it's my rewrite rule that is the problem. Can you guys give me a hand with this one?
Code:
/* Rewrite Rules */
add_action('init', 'llc_product_rewrite_rule');
function llc_product_rewrite_rule() {
add_rewrite_rule( 'cart/', 'index.php?llc_page=cart', 'top' );
}
/* Query Vars */
add_filter( 'query_vars', 'llc_product_register_query_var' );
function llc_product_register_query_var( $vars ) {
$vars[] = 'llc_page';
return $vars;
}
/* Parse Request */
add_action('parse_request', 'llc_cart_template');
function llc_cart_template() {
if (get_query_var('llc_page') && (get_query_var('llc_page') == "cart")) {
include plugin_dir_path(__FILE__).'inc/cart.php';
exit();
}
return;
}
Thank you for all of your well thought out responses you guys, but unfortunately I don't have all day and had to go through trial and error hell to figure this one out.
So firstly, if you want to simply have example.com/cart/ load a specific page template, when the page does not exist (for example if you need your wordpress plug-in to generate the page), this is how you'll need to set up your code. To clarify what's different from the code in my question, it's the rewrite rule, and the way I included the template. I used template_include rather than parse_request.
/* Rewrite Rules */
add_action('init', 'llc_product_rewrite_rule');
function llc_product_rewrite_rule() {
add_rewrite_rule( 'cart/?$', 'index.php?llc_page=cart', 'top' );
}
/* Query Vars */
add_filter( 'query_vars', 'llc_product_register_query_var' );
function llc_product_register_query_var( $vars ) {
$vars[] = 'llc_page';
return $vars;
}
/* Template Include */
add_filter('template_include', 'llc_cart_template_include', 1, 1);
function llc_cart_template_include($template)
{
global $wp_query;
$llc_page_value = $wp_query->query_vars['llc_page'];
if ($llc_page_value && $llc_page_value == "cart") {
return plugin_dir_path(__FILE__).'inc/cart.php';
}
return $template;
}

Validate custom xprofile field on edit profile page in BuddyPress

OK so I’m struggling with this one for hours now and can’t get it to work, but it feels like there is a strait forward simple and elegant solution. All I want to do is to validate the value of a custom xprofile email field when a member is editing its info. Trying to mimic how xprofile_screen_edit_profile() works with returning error before saving, I tried to add_action/add_filter/do_action/apply_filter to xprofile_updated_profile, xprofile_screen_edit_profile, bp_actions, bp_screens, xprofile_data_value_before_save and more, but I failed every time probably because I don’t know how to properly use them. All I want to do is simple as:
function my_validate_email () {
if (!empty($field_id->value) && !is_email($field_id->value))
bp_core_add_message( __( 'That email address is invalid. Check the formatting and try again.', 'buddypress' ), 'error' );
//and redirect back to editing, same like for the required fields
}
add_action( 'bp_hook_here', 'my_validate_email' );
Please help with the correct way of doing this, possibly without using additional plugin
Thanks so much
Is this an additional email field ?
And not the user's email related to registration?
If it is not an additional email field, then use WP hooks.
If it is, take a look at bp-xprofile-classes, function save(), ~Line 1032
And do something like this (untested):
function my_validate_email ($this ) {
// figure out if $this is an array or object and adjust accordingly...
if ( $this['field_id'] == $the_id_of_your_email_field ) {
if (!empty($this['value']) && !is_email($this['value'])) {
$this['field_id'] = 0;
bp_core_add_message( __( 'That email address is invalid. Check the formatting and try again.', 'buddypress' ), 'error' );
}
}
return $this;
}
add_action( 'xprofile_data_before_save', 'my_validate_email', 1, 1 );

Wordpress media_sideload_image - Download http://placekitten.com/100/100?

media_sideload_image
WordPress have a function called media_sideload_image. It is used to upload an image and attach it to the media library.
I accepts image urls like this:
h**p://s.wordpress.org/style/images/wp-header-logo.png
Rewritten URLs
Some URLs on the web are rewritten, for example:
http://placekitten.com/100/100
Error message:
"Sorry, this file type is not permitted for security reasons."
The file type is a correct JPG-file but the file extension is missing.
Adding extra MIME types don't work, in my case
I tried this function but it does not help me, because it's the file extension that is not set.
add_filter('upload_mimes', 'add_custom_upload_mimes');
function add_custom_upload_mimes($existing_mimes){
$existing_mimes['jpeg'] = 'image/jpeg';
return $existing_mimes;
}
Question
How do I upload the URL h**p://placekitten.com/100/100 with media_sideload_image or alike to attach the image to the media library?
I read your question yesterday, when i need this solution.
I find a answer after 24 hours.
Here is Full solution
require_once(ABSPATH . 'wp-admin/includes/media.php');
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/image.php');
$image_url = "http://domain.com/blog/23092839823";
$image_tmp = download_url($image_url);
if( is_wp_error( $image_tmp ) ){
echo "<br> Image Download Fail:";
}else {
$image_size = filesize($image_tmp);
$image_name = basename($image_url) . ".jpg"; // .jpg optional
//Download complete now upload in your project
$file = array(
'name' => $image_name, // ex: wp-header-logo.png
'type' => 'image/jpg',
'tmp_name' => $image_tmp,
'error' => 0,
'size' => $image_size
);
//This image/file will show on media page...
$thumb_id = media_handle_sideload( $file, $post_id, $desc);
set_post_thumbnail($post_id, $thumb_id); //optional
echo "<br> Image Save ";
}
Digging into core, it looks like you need the unfiltered_upload capability in order to upload files without an extension:
if ( ( !$type || !$ext ) && !current_user_can( 'unfiltered_upload' ) )
return $upload_error_handler( $file, __( 'Sorry, this file type is not permitted for security reasons.' ));
According to the Roles and Capabilities documentation:
This capability is not available to any role by default (including Super Admins). The capability needs to be enabled by defining the following constant:
define( 'ALLOW_UNFILTERED_UPLOADS', true );
With this constant defined, all roles on a single site install will be given the unfiltered_upload capability, but only Super Admins will be given the capability on a Multisite install.
Today I have faced the same problem, and come up with a bit dirty yet successful method to work around. As it turns out, media_sideload_image only checks for the .jpg (or any image) extension in the url, so if you add it to the end of your link, it shoud work.
So you only need to add something to the end of the url that won't change the output, for example:
http://placekitten.com/100/100?name=image.jpg
I can't say it works all the time, but it works here (TESTED). :)

Resources