I want a pop up message to appear when a user without a certain postal code tries to look at a certain category.
I have gotten as far as to redirect the user if there postal code is not in the allowed array.
I would just like it to state "You cannot access this category" and without any redirect.
function my_restrict_access() {
if ( is_product_category() ) {
$category = get_queried_object();
if ( $category ) {
$category_id = $category->term_id;
$allowed_category_id = array(3078, 3385);
if ( in_array($category_id, $allowed_category_id) ) {
if ( !is_user_logged_in() ) {
wp_redirect( '/' );
exit;
} else {
global $woocommerce;
$customer = new WC_Customer();
$customer_postcode = $woocommerce->customer->get_billing_postcode();
// uncomment line below for debug purposes, this will show you the postcode on the current page
//echo $customer_postcode;
$allowed_post_code = array(3610, 3626, 3650);
if ( !in_array($customer_postcode, $allowed_post_code) ) {
wp_redirect( '/' );
exit;
}
}
}
}
}
}
add_action( 'template_redirect', 'my_restrict_access');
You better need to use wp filter the_content to change front content...
add_action( 'the_content', 'restrict_user_to_certain_shop_category' );
function restrict_user_to_certain_shop_category( $content ){
global $woocommerce;
// list of all allowed woo product categories
$allowed_categories = array( 3078, 3385 );
// allowed user whose postcodes are following
$allowed_post_codes = array( 3610, 3626, 3650 );
// check if current viweing page is product archive page
if ( is_product_category() ) {
$current_category = get_queried_object();
// extract archive category id
$current_category_id = $current_category->term_id;
// check if current category is in allowed array list
if ( in_array( $current_category_id, $allowed_categories ) ) {
// check if user is not logged in
if ( ! is_user_logged_in() ) {
// message to show when user is not logged in and viewing allowed product category
$content = 'You cannot access this category';
}
// user is logged in and viewing allowed product category
else {
$customer = new WC_Customer();
$customer_postcode = $woocommerce->customer->get_billing_postcode();
// check if user is from allowed postarea
if ( !in_array( $customer_postcode, $allowed_post_codes ) ) {
// message to show when user is logged in and viewing allowed product category + from allowed postarea
$content = 'You cannot access this category';
}
}
}
}
return $content;
}
Related
I'm not a big programmer, but this week get in touch with Openai. It's my first experience with AI. I tried to create code that works as a Wordpress plugin to meet a need.
I make a lot of posts and each post I have to mark the same category. Then I thought that there should be a plugin to mark the category so that when I need to post again, the category would already have its checkbox checked, so I wouldn't need to scroll the selection box of the categories and mark the same category.
Openai generated this code, it didn't work, from what I noticed the cookie is not being created.
Plugin Name: Category Marker
Description: Checks the checkbox of the previously marked category when making a post
Version: 0.1
Author:
*/
//This is the first function
function catemarcada_create_cookie() {
global $post;
if ( isset( $post ) && 'post-new.php' == basename( $_SERVER['SCRIPT_FILENAME'] ) ) {
// Create cookie when making a post
if ( isset( $post->ID ) ) {
$categoryID = get_post_meta($post->ID, '_category_id', true);
setcookie( 'catemarcada', $categoryID, time() + (86400 * 30), "/"); // 86400 = 1 day
}
}
}
add_action( 'wp_loaded', 'catemarcada_create_cookie' );
//This is the second function
function catemarcada_get_cookie() {
global $post;
if ( isset( $post ) && 'post-new.php' == basename( $_SERVER['SCRIPT_FILENAME'] ) ) {
// Get cookie when accessing the post-new.php file
if ( isset( $_COOKIE['catemarcada'] ) ) {
$categoryfound = $_COOKIE['catemarcada'];
}
}
}
add_action( 'wp_loaded', 'catemarcada_get_cookie' );
//This is the third function
function catemarcada_check_category() {
global $post;
if ( isset( $post ) && 'post-new.php' == basename( $_SERVER['SCRIPT_FILENAME'] ) ) {
// Compare the value of the cookie with the category IDs in the WordPress database
$categories = get_categories();
foreach ( $categories as $category ) {
if ( $categoryfound == $category->cat_ID ) {
// Check the checkbox field of the category in the WordPress database
echo '<input type="checkbox" name="'.$category->cat_ID.'" checked="checked" />';
}
}
}
}
add_action( 'wp_loaded', 'catemarcada_check_category' );
// Redirect to post-new.php
add_action('post_updated', 'redirect_post_new', 10, 3);
function redirect_post_new( $post_id, $post, $update ){
if( $update ){
wp_redirect( admin_url( 'post-new.php' ) );
exit();
}
}
This is the description of the plugin I asked to be generated:
Write PHP code that works as a Wordpress plugin. The plugin will only work when I access the “post-new.php” file.
First function:
When making a post, the plug-in will create a cookie with the name “catemarcada”.
This cookie will store the selected category ID during text posting. The cookie must expire within 360 days.
Second function:
When accessing the “post-new.php” file, check if the cookie named “catemarcada” already exists. If it exists, do not create it again.
And every time I access the “post-new.php” file, the plug-in will look up the ID that was recorded in the cookie named “catemarcada” and record the ID in a variable called “categoryfound”.
Third function:
The plug-in should compare the ID that is in the variable called “categoryfound” with the IDs of the categories in the Wordpress database.
If the ID that is in the variable called “categoryfound” is the same as the ID of any of the categories in the Wordpress database, check the checkbox field of the category in the Wordpress database in question.
When making a post, redirect to the post-new.php file.
I try to send a customized email template when a customer has a ticket (custom product type) in cart.
I have the following:
function bc_customer_completed_order_template($template, $template_name, $template_path)
{
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$product = wc_get_product( $cart_item['product_id'] );
$type = get_class($product);
if ( $type == 'WC_Product_Tickets' && 'customer-completed-order.php' === basename($template) ) {
$template = trailingslashit(plugin_dir_path( __FILE__ )) . 'templates/customer-completed-order.php';
}
}
return $template;
}
add_filter('woocommerce_locate_template', 'bc_customer_completed_order_template', 10, 3);
The conditionals are working (on cart and checkout page for example), but when the order is placed, the new template is not used.
Anybody?
Your email template will look like this:
Code snippets:
// Suppose orders don't have ticket products.
$has_tickets = false;
// Loop order items.
foreach ( $order->get_items() as $item_id => $item ) {
// Get product object from order item.
$_product = $item->get_product();
// Check if the product object is valid and the class is `WC_Product_Tickets`
if ( $_product && 'WC_Product_Tickets' === get_class( $_product ) ) {
// Change the flag.
$has_tickets = true;
// Break the loop as we alreay have true flag.
break;
}
}
// Check if order have tickets items.
if ( $has_tickets ) {
// Load custom email template.
wc_get_template( 'templates/custom-customer-completed-order.php' );
// Return as we don't need the below code.
return;
}
It turned out, although the above solution is correct in its idea, in reality one cannot load a template and make use of the $order without extending the woocommerce email class.
Therefore i loaded the function inside the email template itself and made an if - else statement so for situation A the layout is different then for situation b.
Like so:
$has_tickets = false;
// Loop order items.
foreach ( $order->get_items() as $item_id => $item ) {
// Get product object from order item.
$_product = $item->get_product();
// Check if the product object is valid and the class is `WC_Product_Tickets`
if ( $_product && 'WC_Product_Tickets' === get_class( $_product ) ) {
// Change the flag.
$has_tickets = true;
// Break the loop as we alreay have true flag.
break;
}
}
// Check if order have tickets items.
if ( $has_tickets ) {
do_action( 'woocommerce_email_header', $email_heading, $email ); ?>
//custom email layout here//
}
else{
//Regular email template here
}
I'm using this simple code to add a 'buy now' button on a single product page.
add_action( 'woocommerce_after_add_to_cart_button', 'add_content_after_addtocart' );
function add_content_after_addtocart() {
// get the current post/product ID
$current_product_id = get_the_ID();
// get the product based on the ID
$product = wc_get_product( $current_product_id );
// get the "Checkout Page" URL
$checkout_url = WC()->cart->get_checkout_url();
// run only on simple products
if( $product->is_type( 'simple' ) ) {
echo 'Buy Now';
}
}
This code effectively redirects to the checkout page and add the product to the cart, but I want to add two little features to it:
After clicking on the button, I want it to clear the cart before taking the action.
After adding the product to the cart, I want it to redirect users to '/checkout' page. Right now it sends users on 'checkout/?add-to-cart=3122', which means that any refresh on the checkout page adds 1 product on the cart automatically.
Any advice?
Instead of using the add-to-cart param in your url, which will cause the product to be added (but also perform other actions in WooCommerce), you can use a custom url for your button and the template_redirect action hook
That way you get rid of the built-in functionality in WooCommerce and you can perform your own custom actions based on the GET parameters
So you get:
// Add new/extra button
function action_woocommerce_after_add_to_cart_button() {
global $product;
// Is a WC product
if ( is_a( $product, 'WC_Product' ) ) {
// Run only on simple products
if ( $product->is_type( 'simple' ) ) {
// Get product ID
$product_id = $product->get_id();
// Get permalink
$permalink = $product->get_permalink();
// Output url
echo ''. __ ( 'Buy Now', 'woocommerce' ) . '';
}
}
}
add_action( 'woocommerce_after_add_to_cart_button', 'action_woocommerce_after_add_to_cart_button', 10 );
// Redirect
function action_template_redirect() {
// Determines whether the current request is for an administrative interface page
if ( is_admin() ) return;
// Returns true when viewing a single product
if ( ! is_product() ) return;
// Get params
if ( isset( $_GET['product_id'] ) && isset( $_GET['redirect_checkout'] ) ) {
// Get param 1
$product_id = $_GET['product_id'];
// Get param 2
$boolean = $_GET['redirect_checkout'];
// WC Cart
if ( WC()->cart ) {
// 1. Empty cart
WC()->cart->empty_cart();
// 2. Add to cart
WC()->cart->add_to_cart( $product_id );
// 3. Redirect
// When true
if ( $boolean ) {
// Gets the url to the checkout page
$checkout_url = wc_get_checkout_url();
// Performs a safe (local) redirect
wp_safe_redirect( $checkout_url );
exit;
}
}
}
}
add_action( 'template_redirect', 'action_template_redirect' );
Here is code for clear cart before add item
add_filter( 'woocommerce_add_to_cart_validation', 'ji_remove_cart_item_before_add_to_cart', 20, 3 );
function ji_remove_cart_item_before_add_to_cart( $passed, $product_id, $quantity ) {
if( ! WC()->cart->is_empty() )
WC()->cart->empty_cart();
return $passed;}
After adding the product to the cart, I want it to redirect users to '/checkout' page. Right now it sends users on 'checkout/?add-to-cart=3122', which means that any refresh on the checkout page adds 1 product on the cart automatically.
add_filter( 'woocommerce_add_to_cart_redirect', 'ji_redirect_checkout_after_add_to_cart' );
function ji_redirect_checkout_after_add_to_cart() {
return wc_get_checkout_url();
}
I am trying to check if a user meta data is empty or not. If empty, redirect the user to a page, else redirect to the default page.
But my following codes is only redirecting to the default page.
add_filter('woocommerce_login_redirect', 'ac_my_acct_login_redirect');
function ac_my_acct_login_redirect($redirect_to) {
$user_id = get_current_user_id();
$father = get_user_meta( $user_id, 'fath_name', true );
$update_pro = esc_url(get_permalink('123')); // the page I want for redirection if metadata is empty
$my_acct = esc_url(get_permalink( wc_get_page_id( 'myaccount' ) )); // default woocommerce my account page
if(empty($father)){
$redirect_to = $update_pro;
}
else {
$redirect_to = $my_acct;
}
return $redirect_to;
}
meta key = fath_name (even it has value, still the redirection is not working as intended). Any advice?
Your code contains some mistakes
get_current_user_id() is not necessary, as $user is passed to the callback function
get_permalink() expects an int (123), not a string ("123")
Make sure the page ID actually exists
So you get:
function filter_woocommerce_login_redirect( $redirect, $user ) {
// Get user meta
$value = get_user_meta( $user->ID, 'fath_name', true );
// Empty
if ( empty( $value ) ) {
$redirect = get_permalink( 123 );
} else {
// Get the "My account" url
$redirect = get_permalink( wc_get_page_id( 'myaccount' ) );
}
return $redirect;
}
add_filter( 'woocommerce_login_redirect', 'filter_woocommerce_login_redirect', 10, 2 );
I am using the Yoast SEO plugin in WordPress and wanted to know if there was a way to make it only visible to one specific user in the db or in the functions.php file? Not a role, an actual user.
I tried an universal solution to simply add "plugin-name" and disable it, but failed.
But, to show WPSEO only to a specific user (ID equals 2), the following works:
add_action( 'plugins_loaded', 'seo_so_25654837' );
function seo_so_25654837()
{
if ( '2' == get_current_user_id() )
return;
remove_action( 'plugins_loaded', 'wpseo_admin_init', 15 );
}
Don't add the code to functions.php, use it as a normal plugin.
The following is also needed to remove the SEO menu from the admin bar:
add_action( 'wp_before_admin_bar_render', 'bar_so_25654837' );
function bar_so_25654837()
{
if ( '2' == get_current_user_id() )
return;
global $wp_admin_bar;
$nodes = $wp_admin_bar->get_nodes();
foreach( $nodes as $node )
{
if( !$node->parent )
{
if( 'wpseo-menu' === $node->id )
$wp_admin_bar->remove_menu( $node->id );
}
}
}
You can hook to pre_current_active_plugins to remove elements from the table before it is displayed. Using get_current_user_id() within the function will let you selectively hide a plugin.
function hide_plugins_by_user( $all_plugins=false ) {
global $wp_list_table;
// if the current user ID is not 1, hide it.
if ( 1 != get_current_user_id() ){
// the active plugins from the table
$plugins = $wp_list_table->items;
// loop through them
foreach ( $plugins as $key => $val ) {
// use the dir + filename of the plugin to hide
if ( $key == 'plugindir/plugin.php' ) {
unset( $wp_list_table->items[$key] );
}
}
}
}
add_action( 'pre_current_active_plugins', 'hide_plugins_by_user' );
This code is working fine (Credits goes to Hislop):
// Returns true if user has specific role
function check_user_role( $role, $user_id = null ) {
if ( is_numeric( $user_id ) )
$user = get_userdata( $user_id );
else
$user = wp_get_current_user();
if ( empty( $user ) )
return false;
return in_array( $role, (array) $user->roles );
}
// Disable WordPress SEO meta box for all roles other than administrator and seo
function wpse_init(){
if( !(check_user_role('seo') || check_user_role('administrator')) ){
// Remove page analysis columns from post lists, also SEO status on post editor
add_filter('wpseo_use_page_analysis', '__return_false');
// Remove Yoast meta boxes
add_action('add_meta_boxes', 'disable_seo_metabox', 100000);
}
}
add_action('init', 'wpse_init');
function disable_seo_metabox(){
remove_meta_box('wpseo_meta', 'post', 'normal');
remove_meta_box('wpseo_meta', 'page', 'normal');
}
Just place it in the functions.php file.
To disable the Yoast for all the users and enable it for just for few or specific, just add the following piece of code to your function.php file.
function remove_wpseo(){
/* if you want to keep it enabled for user with id 2 */
if ( '2' == get_current_user_id() ) {
return;
}
global $wpseo_front;
if(defined($wpseo_front)){
remove_action('wp_head',array($wpseo_front,'head'),1);
}
else {
$wp_thing = WPSEO_Frontend::get_instance();
remove_action('wp_head',array($wp_thing,'head'),1);
}
}
add_action('template_redirect','remove_wpseo');
Reference: https://makersbyte.com/disable-yoast-seo-plugin-specific-page/