WordPress: BuddyPress: Allow only one email domain to register - wordpress

In the BuddyPress, I want to allow register and log in using only one email domain. For instance, xxx#myemaildomain.com restore all will be disallowed.
I have checked in the BuddyPress source and found that BuddyPress is using bp_core_validate_user_signup( $user_name, $user_email ) for sign up that has a filter
return apply_filters( 'bp_core_validate_user_signup', $result );
So I have tried to use the filter to modify the user_email filed as in the code below. But it is not working.
function wf_validate_email_domain($result)
{
$email = $result[ 'user_email' ];
// make sure we've got a valid email
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
// split on # and return last value of array (the domain)
$domain = array_pop(explode('#', $email));
if ($domain != 'mydomain.com') {
$result[ 'user_email' ] = '';
}
}
return $result;
}
add_filter('bp_core_validate_user_signup', 'wf_validate_email_domain', 9999);
Question:
How can I validate email so it allows to register and login only from
one specific email domain?

The $result should contain an errors field, according to the documentation:
https://www.buddyboss.com/resources/reference/functions/bp_core_validate_user_signup/
Therefore, you should add an error instead of setting the mail address to an empty string like so:
function wf_validate_email_domain($result)
{
$allowed_domain = 'apolloblake.com';
$email = $result[ 'user_email' ];
// make sure we've got a valid email
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
// split on # and return last value of array (the domain)
$domain = array_pop(explode('#', $email));
if ($domain != $allowed_domain) {
$result[ 'errors' ]->add( 'user_email',
"You may only register with mail addresses on #${allowed_domain}." );
}
}
return $result;
}
You may have to make this message multilingual, but that depends on your WP setup.

Related

Woo-commerce: allow checkout only if the customer is living in a certain city

I am making a woocommerce website for my supermarket which delivers only to one city(Ras Tanura).
Since it is a supermarket store, I replaced Shipping with Delivery. I'm trying to restrict checking out to allow only customers how live in Ras Tanura to choose a payment method. I don't want people to pay for something that can't be delivered to them. Here is what I tried.
add_filter( 'default_checkout_billing_country', 'change_default_checkout_country' );
add_filter( 'default_checkout_shipping_country', 'change_default_checkout_country' );
function change_default_checkout_country() {
return 'SA'; // country code
}
// default checkout state
add_filter( 'default_checkout_billing_state', 'change_default_checkout_state' );
add_filter( 'default_checkout_shipping_state', 'change_default_checkout_state' );
function change_default_checkout_state() {
return 'RT'; // state code
}
// Setting one state only
add_filter( 'woocommerce_states', 'custom_woocommerce_state', 10, 1 );
function custom_woocommerce_state( $states ) {
// Returning a unique state
return array('SA' => array('RT' => 'Ras Tanura'));
}
// Only one country at checkout
add_filter( 'woocommerce_checkout_fields', 'custom_checkout_fields', 10, 1 );
function custom_checkout_fields( $fields ) {
$fields['billing']['billing_city']['type'] = 'select';
$fields['billing']['billing_city']['options'] = array('Ras Tanura' => 'Ras Tanura');
$fields['shipping']['shipping_city']['type'] = 'select';
$fields['shipping']['shipping_city']['options'] = array('Ras Tanura' => 'Ras Tanura');
return $fields;
}
I have added this code to my functions.php under oceanWP theme.
This code does half of the job. It sure sets the default city to Ras Tanura and it can't be changed by customers, but I tried to order from another city and it accepted my order the only thing that this code has done is writing that the order is coming from Ras Tanura even though it wasn't.
how can I make my website knows the location of the user and prevent or accept checkout based on that?
(accepts if the person is in Ras Tanura and prevents if he lives elsewhere)
Note that I have already set the selling location under woocommerce> setting> general to sell to specific countries and I have chosen this country to SA.
Note: this method make use of third party api "https://ip-api.com/" to
request customer data based on ip address, which allow limited request
(as per website documentation it allow 45 HTTP requests per minute
from an IP address.)
Woocommerce provide geolocate customer setting by default,I have make use of some part of Woocommerce Geolocate code to fix issue.
What below code do : It will locate customer based on ip address and if customer is not belongs to specific location(country and city), it will not allow the customer to go to checkout page, redirect customer to cart error page.
Kindly note that in general setting of woocommerce "Default customer location" is set to Geolocate.
Keep your code as it is , and additionally put below code in your functions.php file,
/*
* This function is used to retrieve location data based on ip address,
* note that each service/api has different response format
*/
function geolocate_customer() {
$ip_address = WC_Geolocation::get_external_ip_address();
$geoipdata = get_transient('geoip_' . $ip_address);
if (false === $geoipdata) {
// you can add more service key : service name, value : service-endpoint
$geoip_services = array(
'ip-api.com' => 'http://ip-api.com/json/%s',
);
$geoip_services_keys = array_keys($geoip_services);
shuffle($geoip_services_keys);
foreach ($geoip_services_keys as $service_name) {
$service_endpoint = $geoip_services[$service_name];
$response = wp_safe_remote_get(sprintf($service_endpoint, $ip_address), array('timeout' => 2));
if (!is_wp_error($response) && $response['body']) {
switch ($service_name) {
case 'ipinfo.io':
$geoipdata = json_decode($response['body']);
//this flag is used for error
$flag = ($geoipdata->error) ? true : false;
break;
case 'ip-api.com':
$geoipdata = json_decode($response['body']);
//this flag is used for error, each api may have different response format
$flag = ($geoipdata->status == 'success') ? false : true;
break;
default:
$geoipdata = '';
break;
}
if ($geoipdata && !$flag) {
break;
}
}
}
// This will store geolocation data so that frequent call to api can be reduced.
set_transient('geoip_' . $ip_address, $geoipdata, WEEK_IN_SECONDS);
}
return $geoipdata;
}
Note : replace 'PUT CITY NAME HERE' with city name you got in $geoipdata variable in below function.
/*
* This function is attached to 'woocommerce_before_checkout_form_cart_notices' hook,
* It will check country,city criteria and if criteria is not matched it will add error
* notice so checkout page is loaded with error message(load cart-errors.php template)
*
*/
function add_cart_notice() {
$geoipdata = geolocate_customer();
if (!empty($geoipdata)) {
if ($geoipdata->city != 'PUT CITY NAME HERE' && $geoipdata->countryCode != 'SA') {
wc_add_notice(__('Add your message here', 'woocommerce'), 'error');
add_action('woocommerce_cart_has_errors', 'print_notices');
}
}
}
add_action('woocommerce_before_checkout_form_cart_notices','add_cart_notice');
/*
* This function is used to show error message on cart page.
*/
function print_notices(){
wc_print_notice('Add your message here', 'error');
}
For testing purpose, you can put below code in functions.php file to get city and other details based on ip address.City name can be accessed using $geoipdata->city. This will output data on website.
$geoipdata = geolocate_customer();
var_dump($geoipdata);

Can't set the default value of some fields in checkout page

I want to put user's previous data at the checkout page fields by default in my website which based on woocommerce. I cant set value for first name, last name and phone fields, although I can set value for other fields. How can I solve this problem?
Looking at the WC_Checkout class (/includes/class-wc-checkout.php), it contains a get_value method that is responsible for the default methods in the form.
This method has a filter woocommerce_checkout_get_value that you can use to override the default value that is loaded for each field.
Here's an example that overrides both the first name (both billing and shipping) and the last name:
add_filter('woocommerce_checkout_get_value', function( $value, $input ) {
// first check if user is logged in
if ( is_user_logged_in() ) {
$current_user = wp_get_current_user();
switch ($input) {
case 'billing_first_name':
case 'shipping_first_name':
$value = 'Jack'; // fixed default
break;
case 'billing_last_name':
case 'shipping_last_name':
$value = $current_user->user_lastname; // use lastname from user profile
break;
default:
// don't change if we don't have substituting data
break;
}
}
return $value;
},10 ,2 );
In the same method there's also a filter default_checkout_{form_field} that would let you check existing values first (the former is a short-circuit that prevents the normal default from loading), ex:
add_filter('default_checkout_billing_first_name', 'woocommerce_override_default_checkout_values', 10, 2 );
add_filter('default_checkout_billing_last_name', 'woocommerce_override_default_checkout_values', 10, 2 );
add_filter('default_checkout_shipping_first_name', 'woocommerce_override_default_checkout_values', 10, 2 );
add_filter('default_checkout_shipping_last_name', 'woocommerce_override_default_checkout_values', 10, 2 );
function woocommerce_override_default_checkout_values( $value, $input ) {
// first check if user is logged in
if ( is_user_logged_in() ) {
// only load if value is empty
if (empty($value)) {
// read your own
$value = '...';
}
}
return $value;
}

Prevent Specific Email Registration Wordpress.org

So I'm looking for a way to prevent a specific email from registering an account on my website. It's a wordpress.org site.
I tried the Ban Hammer plugin, but it won't work.
I'm not looking for Comments, but for the site proper. Like a code I can put in functions.php or someplace and when this specific email is used to try and register an account on my site, to get an error.
Not an entire email domain, for example, #gmail.com. But a specific email, for example, stack#gmail.com.
Anyone knows how to do that?
EDIT: I found this tutorial here: http://www.davidtiong.com/block-spam-registrations-on-wordpress/
I tried adding this in Functions.php file right above the last ?> at the very bottom of the file:
function dtwd_blocked_emails($user_email) {
$dtwd_blocked_list = array("slojehupri#thrma.com", );
$user_email_split = explode('#', $user_email); $user_email_domain = $user_email_split[1];
if (in_array($user_email_domain, $dtwd_blocked_list)) {
//Return 1, for detection
return 1;
} else {
//Return 0 for no detection
return 0;
}
}
And I also added this in register.php of my theme:
elseif ( dtwd_blocked_emails( $user_email ) == 1) {
$errors->add( 'blocked_email', __( '<strong>ERROR</strong>: This email is not allowed.' ) );
}
And I added the same code in login.php of my theme.
And then I tried registering an account with this email (which should be blocked now): slojehupri#thrma.com
The site allowed me to register, and it allowed me to login. The email should've been blocked now and return an error when I try to register and/or login with it.
I'm not really sure how that function is supposed to work (it's not even hooked into anything...). I haven't tested this, but it sounds as simple as validating the email when the registration_errors filter hook is run. From the Codex:
The registration_errors filter hook filters the errors encountered when a new user is being registered. If any errors are present in $errors, this will abort the user's registration.
This sounds exactly like what you want to do (abort registration if the user email is in your blacklist). Again, this hasn't been tested, but I'd try something like the following in functions.php:
function so_32767928_blacklisted_user( $errors, $sanitized_user_login, $user_email ) {
// One or more blacklisted emails to validate against
$blacklist = array( 'slojehupri#thrma.com', );
// If the user trying to register is in the blacklist, add an error message
if ( in_array( $user_email, $blacklist ) ) {
$errors->add( 'blacklist_error', '<strong>ERROR</strong>: This email is not allowed to register on this site.' );
}
// Always return $errors, even if there are none
return $errors;
}
add_filter( 'registration_errors', 'so_32767928_blacklisted_user', 10, 3 );

Catchable fatal error: Object of class WP_User could not be converted to string in /directory/ on line 139

I'm currently trying to get the username of whomever submitted a form, to be stored in a database along with the value they submitted.
This is line 139 from my function:
$retval = $newdb->query("SELECT * FROM $table WHERE user = '$hf_username' ");
add_action("init", "ref_access");
function ref_access() {
global $error;
if ( is_user_logged_in() ) {
global $quanid;
global $newdb;
$hf_username = wp_get_current_user();
$inputValue = isset($_POST['$quanid']);
$newdb = new wpdb( 'user', 'password', 'db', 'localhost' );
$retval = $newdb->query("SELECT * FROM $table WHERE user = '$hf_username' ");
if( mysqli_num_rows($retval) > 0)
{
$newdb->query("UPDATE table SET user = '$hf_username' "); //If user exists, update
}
else
{
global $table;
global $newdb;
$newdb->insert(
$table,
array(
'ItemID' => $quanid,
'Price' => $inputValue,
'user' => $hf_username
)
);
}
} else {
$error = "Error: You must be logged in to submit prices";
return;
}
}
wp_get_current_user returns a WP_User object, not the username as a string. The username is stored in the user_login property of the WP_User object.
$hf_user = wp_get_current_user();
$hf_username = $hf_user->user_login;
That said, there are a couple of things that seem a bit off with your code:
You seem to be mixing the WordPress database functions with the built in mysqli_ functions. $newdb->query will already return the number of selected rows, there is no need to call mysqli_num_rows and it will not work the way you expect it.
You're declaring a new instance of wpdb instead of using the existing database object via global $wpdb. This is not necessary if you're accessing the same database that WordPress is installed on.

Wordpress additional login rules

I made a plugin that requires the user to validate their email address. It creates "activation_key" meta key with random string for the user and sets it to '' once the user validates. So far so good. But now I need to hook into login and check that activation_key == ''.
This is what I thought should be, but it doesn't get to here.
add_filter( 'authenticate', 'check_if_activated', 10, 3 );
function check_if_activated($user, $username, $password)
{
// check if user has activated their email
return $user;
}
Wordpress already adds filters to authenticate, so you have to register your lower.
add_filter( 'authenticate', 'check_if_activated', 50);
function check_if_activated($user)
{
// If we have an error, no need to check the activation key
// (Wrong credentials, for instance)
if (is_wp_error($user))
{
return $user;
}
// Checks the meta and returns an error if needed
$validation_key = get_user_meta($user->ID, 'activation_key', true);
return empty($validation_key) ? $user : new WP_Error('your_plugin_error_code', 'your error message');
}

Resources