Preventing editing of pages with certain IDs - wordpress

I have created this plugin to prevent certain posts being deleted.
This plugin removes the TRASH option from the page list.
register_activation_hook( __FILE__, 'prevent_page_delete_activate' );
function prevent_page_delete_activate() {
add_action('admin_menu', 'prevent_page_delete');
}
add_filter ('user_has_cap', 'prevent_default_theme_deletion', 10, 3);
function prevent_default_theme_deletion($allcaps, $caps, $args) {
$ids = [2000,2333,4444];
// trash will ve removed for this page IDs
$numElementos = count($ids);
for ($i=0; $i < $numElementos; $i++) {
$post_id = $ids[$i];
if ( isset( $args[0] ) && isset( $args[2] ) && $args[2] == $post_id && $args[0] == 'delete_post' ) {
$allcaps[ $caps[0] ] = false;
}
}
return $allcaps;
}
What would be the equivalent to remove the EDIT link from certain page ids?

As per your last comment, there is a few thing to consider:
Visually hiding any hints to edit/delete ... etc.
Removing any default link styling.
Preventing direct access.
Preventing database update.
You can intercept the post edit via the pre_post_update action hook which fires immediately before an existing post is updated in the database..
We can use post_row_actions which filters the array of row action links on the Posts list table to prevent edits actions.
Finally we use the admin_head-{$hook_suffix} hook to remove any visual style and prevent the direct access through URL.
Everything is wrapped up in a single class to make it easier.
<?php
if ( ! class_exists( 'wpso70412723' ) ) {
class wpso70412723 {
public $protected_posts_IDs = [ //Define the protected posts IDs
2000,
2333,
4444,
];
public function __construct() {
add_action( 'pre_post_update', array( $this, 'wpso_70412723_prevent_database_update_on_specific_post_edit' ), 10, 2 );
add_filter( 'post_row_actions', array( $this, 'wpso_70412723_remove_edit_related_actions_from_post_action_row' ), 10, 2 );
add_action( 'admin_head-edit.php', array( $this, 'wpso_70412723_prevent_link_style_and_click_ability_from_post_title' ));
add_action( 'admin_head-post.php', array( $this, 'wpso_70412723_prevent_direct_access_to_a_specific_post_through_URL' ));
} //public function __construct() {
/**
* Prevent specific posts edits actions.
* Any post modifications (edit, delete, etc.) will be prevented.
*
* #param Integer $post_ID
* #param Array $data
*/
public function wpso_70412723_prevent_database_update_on_specific_post_edit($post_ID, $data) {
if (in_array($post_ID, $this->protected_posts_IDs))
wp_die('You are not allowed to edit this post.', 'Something went wrong...', [
'back_link' => true
]);
} //public function wpso_70412723_prevent_database_update_on_specific_post_edit() {
/**
* Filters-out edit related actions from the array of row action links on the Posts list table.
*
* #param String $actions An array of row action links.
* #param Object (WP_Post) The post object.
*/
public function wpso_70412723_remove_edit_related_actions_from_post_action_row($actions, $post) {
if (in_array($post->ID, $this->protected_posts_IDs)) {
unset( $actions['edit'] );
unset( $actions['inline hide-if-no-js'] );
unset( $actions['trash'] );
};
return $actions;
} //public function wpso_70412723_prevent_database_update_on_specific_post_edit() {
/**
* Prevent link style and click ability from the post title.
* Fires in head section for a specific admin page.
* In our case, the admin posts listing edit page.
*
* #see https://developer.wordpress.org/reference/hooks/admin_head-hook_suffix/
*/
public function wpso_70412723_prevent_link_style_and_click_ability_from_post_title() {
if ( 'edit' !== get_current_screen()->base )
return;
global $wp_query;
$posts = $wp_query->posts;
foreach ($posts as $post) {
if (in_array($post->ID, $this->protected_posts_IDs)) {
echo '<style type="text/css">
#the-list .post-' . $post->ID . ' strong a {
pointer-events: none;
color: initial;
text-decoration: none;
}
</style>';
};
};
} //public function wpso_70412723_prevent_link_style_and_click_ability_from_post_title() {
/**
* Prevent direct access to a specific post through URL.
* Fires in head section for a specific admin page.
* In our case, the admin posts listing edit page.
*
* #see https://developer.wordpress.org/reference/hooks/admin_head-hook_suffix/
*/
public function wpso_70412723_prevent_direct_access_to_a_specific_post_through_URL() {
if ( 'post' !== get_current_screen()->base )
return;
if (in_array(get_the_ID(), $this->protected_posts_IDs)) {
wp_die('You are not allowed to edit this post.', 'Something went wrong...', [
'back_link' => true
]);
};
} //public function wpso_70412723_prevent_direct_access_to_a_specific_post_through_URL() {
}; //class wpso70412723 {
new wpso70412723();
}; //if ( ! class_exists( 'wpso70412723' ) ) {
By the way, deleting a post is considered an edit.
You don't need your prevent_default_theme_deletion() function.
You could be tempted to use the edit_post action hook tho this wouldn't work because:
edit_post: Fires once an existing post has been updated.
The "once" statement is why we need to use pre_post_update.
pre_post_update: Fires immediately before an existing post is updated in the database.

Related

Wordpress - Add submit button to admin toolar

I have my own function fsww_i_add_funds_request_daily that I wrote to perform the addition of a profit by a user based on the role of the user. This function was created / added for one plugin that I use. I am not sending any parameters to the function. I need to call this function using the submit button which will be on the admin toolbar. The function should be implemented in the plugin as it is necessary to use its "library" (maybe I spoke badly, I'm still a beginner in WP). How and where I need these functions implement?
Function
function fsww_i_add_funds_request_daily() {
require_once(dirname(__FILE__) . '/Wallet.php');
global $wpdb;
$query = $wpdb->get_results("SELECT user_id FROM {$wpdb->prefix}fswcwallet ORDER BY user_id ASC");
if($query) {
foreach($query as $user)
{
$user_id = $user->user_id;
$dailyProvision = 0;
if($user_id != 0)
{
$balance = fsww_price(Wallet::get_balance($user_id));
$last_deposit = fswcw_format_date(Wallet::get_last_deposit($user_id));
$status = Wallet::get_status($user_id);
$username = get_user_by('id', $user_id);
}
}
}
}
function fb_add_admin_bar_profit() {
global $wp_admin_bar;
$current_object = get_queried_object();
$wp_admin_bar->add_menu(
array( 'id' => 'addprofit',
'title' => __('Add profit'),
'href' => ?????)
);
}
add_action( 'admin_bar_menu', 'fb_add_admin_bar_profit');
Could you please help me with this?
Create plugin Custom Plugin and add the below code to that plugin. and in you admin bar custom button add URL like this home_url( '/?funds_request_daily=true' ) and check this query string funds_request_daily params on init hook.
<?php
/**
* Plugin Name: Custom Plugin
* Plugin URI: https://example.com/plugins/the-basics/
* Description: Handle the basics with this plugin.
* Version: 1.0.0
* Author: Cleemas
* Author URI: https://author.example.com/
* License: GPL v2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: my-custom-plugin
* Domain Path: /languages
*/
function fsww_i_add_funds_request_daily() {
if( isset( $_GET['funds_request_daily'] ) && $_GET['funds_request_daily'] == 'true' ){
require_once(dirname(__FILE__) . '/Wallet.php');
global $wpdb;
$query = $wpdb->get_results("SELECT user_id FROM {$wpdb->prefix}fswcwallet ORDER BY user_id ASC");
if( $query ) {
foreach( $query as $user ) {
$user_id = $user->user_id;
$dailyProvision = 0;
if($user_id != 0) {
$balance = fsww_price(Wallet::get_balance($user_id));
$last_deposit = fswcw_format_date(Wallet::get_last_deposit($user_id));
$status = Wallet::get_status($user_id);
$username = get_user_by('id', $user_id);
}
}
}
}
}
add_action( 'init', 'fsww_i_add_funds_request_daily', 10, 1 );
function fb_add_admin_bar_profit() {
global $wp_admin_bar;
$current_object = get_queried_object();
$wp_admin_bar->add_menu(
array(
'id' => 'addprofit',
'title' => __('Add profit'),
'href' => home_url( '/?funds_request_daily=true' )
)
);
}
add_action( 'admin_bar_menu', 'fb_add_admin_bar_profit');
?>

Custom product type with variation, variation name not show in cart/checkout

I created a CUSTOM product type variation, everything works good in backend and front end, the only problem is, in the shopping cart / Checkout details, the variable product name not showing, also after purchase item the stock is not reducing, 1 item available for the variable, after purchase, keep the 1 item available instead of out of stock.
This is the code used.
* Step 1. Add a custom product type "term" to other hardcoded ones
*/
add_filter( 'product_type_selector', 'misha_ticket_product_type' );
function misha_ticket_product_type( $product_types ){
$product_types[ 'ticket' ] = 'Ticket';
return $product_types;
}
/**
* Step 2. Each product type has a PHP class WC_Product_{type}
*/
add_action( 'init', 'misha_create_ticket_product_class' );
add_filter( 'woocommerce_product_class', 'misha_load_ticket_product_class',10,2);
function misha_create_ticket_product_class(){
class WC_Product_Ticket extends WC_Product_Variable {
public function __construct( $product ) {
$this->product_type = 'ticket';
$this->supports[] = 'ajax_add_to_cart';
parent::__construct( $product );
}
public function get_type() {
return 'ticket'; // so you can use $product = wc_get_product(); $product->get_type()
}
}
}
add_filter('woocommerce_product_data_tabs','ticket_showtabs',10,1);
function ticket_showtabs($tabs) {
array_push($tabs['attribute']['class'], 'show_if_variable', 'show_if_ticket');
array_push($tabs['variations']['class'], 'show_if_ticket');
return $tabs;
}
function producttype_custom_js() {
if ( 'product' != get_post_type() ) :
return;
endif;
?><script type='text/javascript'>
jQuery("body").bind("DOMNodeInserted", function() {
jQuery(this).find('.enable_variation').addClass('show_if_ticket').show();
});
</script><?php
}
add_action( 'admin_footer', 'producttype_custom_js' ,99);
function misha_load_ticket_product_class( $php_classname, $product_type ) {
if ( $product_type == 'ticket' ) {
$php_classname = 'WC_Product_Ticket';
}
return $php_classname;
}
add_filter( 'woocommerce_data_stores', function( $stores ){
$stores['product-ticket'] = 'WC_Product_Variable_Data_Store_CPT';
return $stores;
} );
add_action( 'woocommerce_ticket_add_to_cart', 'woocommerce_variable_add_to_cart' );
//**************************************END*********************************//```
I ran into the exact same problem, and it occurs because woocommerce_add_to_cart_handler expects get_type to return 'variable' in order to trigger the add_to_cart_handler_variable method.
function misha_custom_add_to_cart_handler( $handler, $adding_to_cart ){
if( $handler == 'ticket' ){
$handler = 'variable';
}
return $handler;
}
add_filter( 'woocommerce_add_to_cart_handler', 'misha_custom_add_to_cart_handler', 10, 2 );
You would need something like the above as per discussion here How to add a custom WooCommerce product type that extends WC_Product_Variable to the cart

Create Post with Meta Field – WP REST API

I have just started with REST API and using it for creating posts from frontend. I managed to publish post with Title, Excerpt, Content.
I want to add a Custom Meta Field value aswell, any example or help is much appreciated.
This is my Ajax Code, all other fields working fine except meta value is not being added in post
jQuery( document ).ready( function ( $ ) {
$( '#post-submission-form' ).on( 'submit', function(e) {
e.preventDefault();
var title = $( '#post-submission-title' ).val();
var excerpt = $( '#post-submission-excerpt' ).val();
var content = $( '#post-submission-content' ).val();
var status = 'draft';
var data = {
title: title,
excerpt: excerpt,
content: content,
status: status,
meta: {
'video_url_url' : 'abc',
}
};
$.ajax({
method: "POST",
url: POST_SUBMITTER.root + 'wp/v2/posts',
data: data,
beforeSend: function ( xhr ) {
xhr.setRequestHeader( 'X-WP-Nonce', POST_SUBMITTER.nonce );
},
success : function( response ) {
console.log( response );
alert( POST_SUBMITTER.success );
},
fail : function( response ) {
console.log( response );
alert( POST_SUBMITTER.failure );
}
});
});
} );
Add this to your functions.php :
/**
* Add the meta fields to REST API responses for posts read and write
* Read and write a post meta fields in post responses
*/
function mg_register_meta_api() {
//Meta Fields that should be added to the API
$meta_fields = array(
'video_url_url',
'another_meta_key'
);
//Iterate through all fields and add register each of them to the API
foreach ($meta_fields as $field) {
register_rest_field( 'ring',
$field,
array(
'get_callback' => array( $this, 'mg_fw_get_meta'),
'update_callback' => array( $this, 'mg_fw_update_meta'),
'schema' => null,
)
);
}
}
add_action( 'rest_api_init', 'mg_register_meta_api' );
/**
* Handler for getting custom field data.
*
* #since 0.1.0
*
* #param array $object The object from the response
* #param string $field_name Name of field
*
* #return mixed
*/
function mg_get_meta( $object, $field_name ) {
return get_post_meta( $object[ 'id' ], $field_name );
}
/**
* Handler for updating custom field data.
*
* #since 0.1.0
* #link http://manual.unyson.io/en/latest/helpers/php.html#database
* #param mixed $value The value of the field
* #param object $object The object from the response
* #param string $field_name Name of field
*
* #return bool|int
*/
function mg_update_meta( $value, $object, $field_name ) {
if ( ! $value || ! is_string( $value ) ) {
return;
}
return update_post_meta( $object->ID, $field_name, maybe_serialize( strip_tags( $value ) ) );
}
Now you should be able to read and write for meta 'video_url_url' using the api.
I was playing around with this today and came up with the following solution that works well and adds multiple fields.
Hope this helps anyone who may be stuck on this.
add_action( 'rest_api_init', 'foo_register_meta_api' );
function foo_register_meta_api() {
// Meta Fields to add to the API
$meta_fields = array(
'field_1',
'foo_bar',
'foobar',
'another_field'
);
// Loop all fields and register each of them to the API
foreach ($meta_fields as $field) {
register_rest_field( 'my-post-type',
$field,
array(
'get_callback' => function ($params) use ($field) {
return \get_post_meta($params['id'], $field);
},
'update_callback' => function ($value, $object, $fieldName){
return \update_post_meta($object->ID, $fieldName, $value);
},
'schema' => null
)
);
}
}
I am trying to save phy_marks in post type candidates. What I've got is creating the post but not saving phy_marks.
My JSON data:
{ "title": "Why not working finally","content": "Test", "status": "publish" ,"post_type": "candidates", "meta": {
"phy_marks": 66 } }
My Code:
add_action( 'rest_api_init', 'foo_register_meta_api' );
function foo_register_meta_api() {
// Meta Fields to add to the API
$meta_fields = array(
'phy_marks'
);
// Loop all fields and register each of them to the API
foreach ($meta_fields as $field) {
register_rest_field( 'candidates',
$field,
array(
'get_callback' => function ($params) use ($field) {
return \get_post_meta($params['id'], $field);
},
'update_callback' => function ($value, $object, $fieldName){
return \update_post_meta($object->ID, $fieldName, $value);
},
'schema' => null
)
);
}
}

How to allow Laravel and WordPress to share logins?

I'm a Laravel developer. I develop one ecommerce plugin with Laravel and I just want to combine WordPress with Laravel. So I need to share or make common login session between Laravel and WordPress.
How could I implement this? And are there special plugins available for this? Or could I use laravel-Auth?
The right way of doing it is to Have a Laravel (or Wordpress) as an Auth server
And create like an SSO plugin.
I was doing the same with NodeBB Forum login from Laravel.
Steps that I suggest:
Look at this package Laravel OAuth Server
Create or find any SSO plugin for wordpress
So you have all users in laravel (Registration and etc)
and if they want to login to Wordpress they login to Laravel App and give permission to login to wordpress.
Think of it Like you add Facebook Login to your site
Reading more for wordpress SSO
But to play with session and cookies it can be security issues.
Hope Helped.
Enabling Single-Sign-On in WordPress took me 18+ hours of struggle but might take you only a few minutes:
I experimented with all sorts of things: Laravel Passport (OAuth2), OpenID Connect, etc.
But the only solution I could get to work was to have the WordPress login page redirect to an auth-protected Laravel route that generates a JWT (JSON Web Token) and redirects back to a special callback URL on WordPress that either creates a new user or logs in an existing user.
It works well.
class JwtController extends Controller {
/**
* Inspired by https://github.com/WebDevStudios/aad-first-party-sso-wordpress/tree/master/lib/php-jwt
*
* #param Request $request
* #return ResponseInterface
*/
public function redirectWithToken(Request $request) {
$key = config('jwt.key');
$wpJwtUrl = $request->input('callback');
$redirectUrlAfterLogin = $request->input('redirect_to'); //Get the original intended destination and append as URL param to /jwt.
$tokenArray = $this->getToken(auth()->user(), $redirectUrlAfterLogin);
$jwt = \Firebase\JWT\JWT::encode($tokenArray, $key);
$wpJwtUrlWithTokenAsParam = $wpJwtUrl . '?token=' . $jwt;
return redirect()->away($wpJwtUrlWithTokenAsParam);
}
/**
*
* #param \App\User $user
* #param string $redirectUrlAfterLogin
* #return array
*/
public function getToken($user, $redirectUrlAfterLogin) {
$now = \Carbon\Carbon::now();
$aud = config('jwt.audience'); //root URL of the WordPress site
$firstName = StrT::getFirstNameFromFullName($user->name);
$expirationMins = config('jwt.expirationMins');
$token = [
"iss" => url("/"),
"aud" => $aud, //"audience" https://tools.ietf.org/html/rfc7519#section-4.1.3
"iat" => $now->timestamp, //"issued at" https://tools.ietf.org/html/rfc7519#section-4.1.6
"exp" => $now->addMinutes($expirationMins)->timestamp, //"expiration" https://tools.ietf.org/html/rfc7519#section-4.1.4
"attributes" => [
'emailAddress' => $user->email,
'firstName' => $firstName,
'lastName' => StrT::getLastNameFromFullName($user->name),
'nickname' => $firstName,
'displayName' => $user->name,
'redirectUrlAfterLogin' => $redirectUrlAfterLogin//In plugin: use redirectUrlAfterLogin from attributes after login.
]
];
return $token;
}
}
Install this WordPress plugin, but don't activate it until you're finished with everything else: https://wordpress.org/plugins/wp-force-login/
Install this WordPress plugin: https://as.wordpress.org/plugins/jwt-authenticator/
And then edit its auth.php to be this:
// register the callback
add_action('rest_api_init', function () {
register_rest_route('jwt-auth/v1', 'callback', [
'methods' => 'GET',
'callback' => 'ja_login'
], true);
});
require_once('JWT.php');
function ja_login() {
//get all attributes
$options = get_option('ja_settings');
$token_name = $options['token_name'];
$secret_key = $options['secret_key'];
$iss = $options['iss'];
$aud = $options['aud'];
// decode the token
$token = $_GET[$token_name];
$key = $secret_key;
$JWT = new JWT;
$json = $JWT->decode($token, $key);
$jwt = json_decode($json, true);
// use unix time for comparision
$exp = is_int($jwt['exp']) ? $jwt['exp'] : strtotime($jwt['exp']);
$nbf = $jwt['nbf'] ?? null;
$now = strtotime("now");
// if authentication successful
if (($jwt['iss'] == $iss) && ($jwt['aud'] == $aud) && ($exp > $now) && ($now > $nbf)) {
return getUserFromValidToken($options, $jwt);
} else {
return 'Login failed. Please let us know exactly what happened, and we will help you out right away.';
}
}
/**
*
* #param array $options
* #param array $jwt
* #return string
*/
function getUserFromValidToken($options, $jwt) {
$attributesKey = $options['attributes'];
$mail = $options['mail'];
$givenname = $options['first_name'];
$surname = $options['last_name'];
$nickname = $options['nickname'];
$displayname = $options['displayname'];
$default_role = $options['default_role'];
$attributes = $jwt[$attributesKey];
$redirectUrlAfterLogin = $attributes['redirectUrlAfterLogin'] ?? get_site_url();
$_SESSION['attributes'] = $attributes;
$_SESSION['jwt'] = $jwt;
// find or create user
$user = ja_find_or_create_user($attributes[$mail], $attributes[$mail], $attributes[$givenname], $attributes[$surname], $attributes[$nickname], $attributes[$displayname], $default_role);
// login user
if ($user) {
wp_clear_auth_cookie();
wp_set_current_user($user->ID, $user->user_login);
wp_set_auth_cookie($user->ID);
do_action('wp_login', $user->user_login);
wp_safe_redirect($redirectUrlAfterLogin);
exit();
} else {
return 'getUserFromValidToken failed!';
}
}
/**
*
* #param string $username
* #param string $emailAddress
* #param string $firstName
* #param string $lastName
* #param string $nickname
* #param string $displayName
* #param string $defaultRole
* #return mixed
*/
function ja_find_or_create_user($username, $emailAddress, $firstName, $lastName, $nickname, $displayName, $defaultRole) {
// if user exists, return user
if (username_exists($username)) {
return get_user_by('login', $username);
} elseif (email_exists($emailAddress)) {
return get_user_by('email', $emailAddress);
} else {// create user
$length = 16;
$include_standard_special_chars = false;
$random_password = wp_generate_password($length, $include_standard_special_chars);
// create user
$user_id = wp_create_user($username, $random_password, $emailAddress);
// update user metadata and return user id
$userData = [
'ID' => $user_id,
'first_name' => $firstName,
'last_name' => $lastName,
'nickname' => $nickname,
'display_name' => $displayName,
'role' => $defaultRole
];
return wp_update_user($userData);//(If successful, returns the user_id, otherwise returns a WP_Error object.)
}
}
/**
* Get login message link HTML for adding to the login form
* #return string
*/
function getLoginMessage() {
$options = get_option('ja_settings');
$redirect_to = $_GET['redirect_to'] ?? null;
$login_url = $options['login_url'] . '?callback=' . urlencode(site_url('/wp-json/jwt-auth/v1/callback'));
if($redirect_to){
$login_url .= '&redirect_to=' . urlencode($redirect_to);
}
$login_message = $options['login_message'];
return "<a id='jwt_link' href='{$login_url}'>{$login_message}</a>";
}
add_filter('login_message', 'getLoginMessage');
add_action( 'load-profile.php', function() {//https://wordpress.stackexchange.com/a/195370/51462 Redirect from profile.php to the dashboard since there is no reason for WordPress users to see or manage their profile since their main account is on the other site.
if( ! current_user_can( 'manage_options' ) ){
$redirectUrl = get_site_url();//admin_url()
exit( wp_safe_redirect( $redirectUrl ) );
}
} );
function show_admin_bar_conditionally(){//remove the WordPress admin toolbar https://premium.wpmudev.org/blog/remove-the-wordpress-admin-toolbar/
return current_user_can( 'manage_options' );
}
add_filter('show_admin_bar', 'show_admin_bar_conditionally');//can use 'show_admin_bar_conditionally' or '__return_false' for never.
//------------------------------------------------------------------
//for https://wordpress.org/support/topic/rest-api-26/#post-9915078
//and https://github.com/kevinvess/wp-force-login/issues/35
//and https://wordpress.org/support/topic/rest-api-26/page/2/#post-10000740
//and https://wordpress.org/support/topic/jwt-authentication/#post-10698307
add_filter( 'rest_authentication_errors', '__return_true' );
This belongs in functions.php of your theme in WordPress:
// https://codex.wordpress.org/Customizing_the_Login_Form
function my_custom_login_page() { ?>
<style type="text/css">
#loginform, #login #nav{display: none;}
#jwt_link{font-weight: bold; font-size: 20px;}
</style>
<script>
document.addEventListener("DOMContentLoaded", function(event) {
document.getElementById('jwt_link').click();//immediately upon load of login page, click the JWT link automatically
});
</script>
<?php }
add_action( 'login_enqueue_scripts', 'my_custom_login_page' );

Woocommerce Checkout not Working with No CAPTCHA reCAPTCHA for WooCommerce Plugin

when i active 'No CAPTCHA reCAPTCHA for WooCommerce' plugin, so on checkout page of WooCommerce when customer checked the 'Create an account?' check-box and than Place Order, it does not work. the page just scroll on to the top and nothing action.
any idea?
Reagrds
Faizan
The plugin is just written to protect the Woocommerce Registration and Login, not the Checkout Process.
In order to protect the Checkout Process, I tweaked registration.php like this
class WC_Ncr_Registration_Captcha extends WC_Ncr_No_Captcha_Recaptcha {
/** Initialize actions and filters */
public static function initialize() {
// initialize if login is activated
if ( isset( self::$plugin_options['captcha_wc_registration'] ) || self::$plugin_options['captcha_wc_registration'] == 'yes' ) {
// adds the captcha to the registration form
add_action( 'register_form', array( __CLASS__, 'display_captcha' ) );
}
//added the following lines to the plugin
add_action('woocommerce_after_checkout_billing_form', array( __CLASS__, 'display_captcha' ));
add_action('woocommerce_checkout_process', array(
__CLASS__,
'validate_captcha_wc_checkout'
), 10, 3 );
//added the previous lines to the plugin
}
/**
* Verify the captcha answer
*
* #param $validation_errors
* #param $username
* #param $email
*
* #return WP_Error
*/
public static function validate_captcha_wc_registration( $validation_errors, $username, $email ) {
if ( ! isset( $_POST['g-recaptcha-response'] ) || ! self::captcha_wc_verification() ) {
$validation_errors = new WP_Error( 'failed_verification', self::$error_message );
}
return $validation_errors;
}
//added the following lines to the plugin
public static function validate_captcha_wc_checkout( $validation_errors, $username, $email ) {
if ( ! isset( $_POST['g-recaptcha-response'] ) || ! self::captcha_wc_verification() ) {
wc_add_notice(__( 'Please verify you are not a robot.' ), 'error' );
}
}
//added the previous lines to the plugin
}
Add to functions.php
function my_woocommerce_before_checkout_process() {
remove_filter( 'woocommerce_registration_errors', array('WC_Ncr_Registration_Captcha', 'validate_captcha_wc_registration'), 10 );
}
add_action('woocommerce_before_checkout_process', 'my_woocommerce_before_checkout_process');

Resources