I am trying to give access of the specific page just for my subscriber user role, if someone else with other then subscriber role or non role user want to access to this page redirect them to a custom login page, I tried with below snippet but I think something is wrong with it, can you please help me to fix this
Example : Restrict access to specific pages
add_action( 'template_redirect', function() {
// Get global post
global $post;
// Prevent access to page with ID 1052
$page_id = 1052;
if ( is_page() && ( $post->post_parent == $page_id || is_page( $page_id ) ) ) {
// Set redirect to true by default
$redirect = true;
// If logged in do not redirect
// You can/should place additional checks here based on user roles or user meta
if ( current_user_can( 'subscriber' ) || !is_user_logged_in()) {
$redirect = false;
}
// Redirect people without access to login page
if ( $redirect ) {
wp_redirect( get_site_url().'/custom-url-login' ); exit;
}
}
} );
You could refactor your code like this:
add_action( 'template_redirect', 'checking_current_user' );
function checking_current_user()
{
global $post;
global $current_user;
$page_id = 1052;
if (
( $post->post_parent == $page_id || is_page( $page_id ) )
&&
( !in_array('subscriber', $current_user->roles) )
)
{
wp_safe_redirect( site_url('/custom-url-login') );
exit;
}
}
This answer has been tested and works fine!
Wouldn't this do what you asked for?
// If user role 'subscriber' & logged in do not redirect
// You can/should place additional checks here based on user roles or user meta
if ( current_user_can( 'subscriber' ) && is_user_logged_in()) {
$redirect = false;
}
WordPress Admin Dashboard > Appearance > Theme File Editor > Theme Functions functions.php
Edit code by adding to the bottom:
// Allow subscribers to see Private posts and pages
$subRole = get_role( 'subscriber' );
$subRole->add_cap( 'read_private_pages' );
$subRole->add_cap( 'read_private_posts' );
Then change your chosen Pages / Posts from Public to Private visibility:
Pages > All Pages > Page > Quick Edit > Private (check box)
You can do a redirection, replace siteurl at the bottom of functions.php using:
// Redirect to page on login
function loginRedirect( $redirect_to, $request_redirect_to, $user ) {
if ( is_a( $user, 'WP_User' ) && $user->has_cap( 'edit_posts' ) === false ) {
return get_bloginfo( 'siteurl' );
}
return $redirect_to; }
add_filter( 'login_redirect', 'loginRedirect', 10, 3 );
or URL redirection to the "page only for subscribers" e.g:
https://WordPress.com/wp-login.php?user_id=3&redirect_to=https%3A%2F%2Fwordpress.com%2Fabout%2F#top
First of all you must need to check user is logged-in or not, If user is not logged-in then you need to redirect user to login page, After to login you need to apply code code then it will work fine.
add_action( 'template_redirect', 'check_current_user' );
function check_current_user(){
global $post, $current_user;
$page_id = 1052;
if ( is_page() && ( $post->post_parent == $page_id || is_page( $page_id ) ) ) {
if ( is_user_logged_in() ) {
/*==Now check user is subscriber==*/
$current_user = wp_get_current_user();
$role = $current_user->roles;
$currentRole = $role[0];
if($currentRole == "subscriber"){
$redirect = false;
}else{
$redirect = true;
}
}else{
wp_safe_redirect( site_url('/custom-url-login') );
}
}
}
So I have found the way to remove all of that in Posts (for non admins) with the following line:
/**
* Remove the 'all', 'publish', 'future', 'sticky', 'draft', 'pending', 'trash'
* views for non-admins
*/
add_filter( 'views_edit-post', function( $views )
{
if( current_user_can( 'manage_options' ) )
return $views;
$remove_views = [ 'all','publish','future','sticky','draft','pending','trash' ];
foreach( (array) $remove_views as $view )
{
if( isset( $views[$view] ) )
unset( $views[$view] );
}
return $views;
} );
Now I want to remove all of those in Comments as well.
I can't find the answer.
Any help would be appreciated.
As said in the comments, just add another add_filter with "views_edit-comments".
To always show only own comments to a non-admin user, use the follow code:
add_action( 'current_screen', 'wp_66446729_filter_comments', 10, 2 );
function wp_66446729_filter_comments( $screen )
{
if ( current_user_can('administrator') )
return;
add_action( 'pre_get_comments', 'wp_66446729_list_own_comments_only', 10, 1 );
}
function wp_66446729_list_own_comments_only( $clauses )
{
$user_id = get_current_user_id();
if ($user_id) {
$clauses->query_vars['user_id'] = $user_id;
}
}
please help! I'm trying to define Payment Gateway by changing order details from admin.
As a default option I want to use 'bacs' payment gateway. Customer make order and then I want to change order and turn payment method to custom 'payment2' gateway.
For this, I've made metabox with checkbox which should turn on/off 'payment2' method and unset default 'bacs'. Checkbox working properly.
But, I can't get it to work. First of all, I can't get post meta with checkbox value. Check code below please:
function show_payment2_payment_gateway( $available_gateways ) {
$use_payment2 = get_post_meta( $post->ID, 'use_payment2', true );
if($use_payment2 == "yes") {
unset( $available_gateways['bacs'] );
}
else {
unset( $available_gateways['payment2'] );
}
return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'show_payment2_payment_gateway', 10, 1 );
UPD
This is my code for backend checkbox. As I said it's working well and save meta value as 'yes'
//
//Adding Meta container admin shop_order pages
//
add_action( 'add_meta_boxes', 'mv_add_meta_boxes' );
if ( ! function_exists( 'mv_add_meta_boxes' ) )
{
function mv_add_meta_boxes()
{
global $woocommerce, $order, $post;
add_meta_box( 'mv_other_fields', __('PAYMENT2','woocommerce'), 'mv_add_other_fields_for_packaging', 'shop_order', 'side', 'core' );
}
}
//
//adding Meta field in the meta container admin shop_order pages
//
if ( ! function_exists( 'mv_save_wc_order_other_fields' ) )
{
function mv_add_other_fields_for_packaging()
{
global $woocommerce, $order, $post;
$meta_field_data = get_post_meta( $post->ID, 'use_payment2', true );
$meta_field_data_checked = $meta_field_data["use_payment2"][0];
if($meta_field_data == "yes") $meta_field_data_checked = 'checked="checked"';
echo '
<label for="use_epay">TURN PAYMENT2 ON?</label>
<input type="hidden" name="mv_other_meta_field_nonce" value="' . wp_create_nonce() . '">
<input type="checkbox" name="use_payment2" value="yes" '.$meta_field_data_checked.'>';
}
}
//
//Save the data of the Meta field
//
add_action( 'save_post', 'mv_save_wc_order_other_fields', 10, 1 );
if ( ! function_exists( 'mv_save_wc_order_other_fields' ) )
{
function mv_save_wc_order_other_fields( $post_id ) {
// We need to verify this with the proper authorization (security stuff).
// Check if our nonce is set.
if ( ! isset( $_POST[ 'mv_other_meta_field_nonce' ] ) ) {
return $post_id;
}
$nonce = $_REQUEST[ 'mv_other_meta_field_nonce' ];
//Verify that the nonce is valid.
if ( ! wp_verify_nonce( $nonce ) ) {
return $post_id;
}
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
// Check the user's permissions.
if ( 'page' == $_POST[ 'post_type' ] ) {
if ( ! current_user_can( 'edit_page', $post_id ) ) {
return $post_id;
}
} else {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return $post_id;
}
}
// --- Its safe for us to save the data ! --- //
// Sanitize user input and update the meta field in the database.
update_post_meta( $post_id, 'use_payment2', $_POST[ 'use_payment2' ] );
}
}
UPD
This is working code for Back-End (custom checkbox metabox). It save checkbox value and change payment method in order details:
//
//Adding Meta container admin shop_order pages
//
add_action( 'add_meta_boxes', 'mv_add_meta_boxes' );
if ( ! function_exists( 'mv_add_meta_boxes' ) )
{
function mv_add_meta_boxes()
{
global $woocommerce, $order, $post;
add_meta_box( 'mv_other_fields', __('PAYMENT2','woocommerce'), 'mv_add_other_fields_for_packaging', 'shop_order', 'side', 'core' );
}
}
//
//adding Meta field in the meta container admin shop_order pages
//
if ( ! function_exists( 'mv_save_wc_order_other_fields' ) )
{
function mv_add_other_fields_for_packaging()
{
global $woocommerce, $order, $post;
$meta_field_data = get_post_meta( $post->ID, 'use_payment2', true );
echo '<label for="use_payment2">USE PAYMENT2?</label>
<input type="hidden" name="mv_other_meta_field_nonce" value="' . wp_create_nonce() . '">';
if($meta_field_data == "yes") {
$meta_field_data_checked = 'checked="checked"';
echo'<input type="checkbox" name="use_payment2" value="yes" '.$meta_field_data_checked.'>';
}
else {
echo'<input type="checkbox" name="use_payment2" value="yes">';
}
}
}
//Save the data of the Meta field
add_action( 'save_post', 'mv_save_wc_order_other_fields', 10, 1 );
if ( ! function_exists( 'mv_save_wc_order_other_fields' ) )
{
function mv_save_wc_order_other_fields( $post_id ) {
// We need to verify this with the proper authorization (security stuff).
// Check if our nonce is set.
if ( ! isset( $_POST[ 'mv_other_meta_field_nonce' ] ) ) {
return $post_id;
}
$nonce = $_REQUEST[ 'mv_other_meta_field_nonce' ];
//Verify that the nonce is valid.
if ( ! wp_verify_nonce( $nonce ) ) {
return $post_id;
}
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
// Check the user's permissions.
if ( 'page' == $_POST[ 'post_type' ] ) {
if ( ! current_user_can( 'edit_page', $post_id ) ) {
return $post_id;
}
} else {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return $post_id;
}
}
// --- Its safe for us to save the data ! --- //
// Sanitize user input and update the meta field in the database.
$use_payment2 = sanitize_text_field($_POST[ 'use_payment2' ]);
update_post_meta( $post_id, 'use_payment2', $use_payment2 );
if($_POST[ 'use_payment2' ] == 'yes') {
update_post_meta( $post_id, '_payment_method', 'payment2' );
}
elseif (get_post_meta( $post_id, '_payment_method', true ) != 'bacs') {
update_post_meta( $post_id, '_payment_method', 'bacs' );
}
}
}
But, how I can use checkbox state on my front-end? I still can't get checkbox value using this code:
function show_payment2_payment_gateway( $available_gateways ) {
global $woocommerce, $order, $post;
$payment_method = get_post_meta( $post_id, 'use_payment2', true );
if(isset($payment_method) == 'yes') {
unset( $available_gateways['bacs'] );
}
else {
unset( $available_gateways['payment2'] );
}
return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'show_payment2_payment_gateway', 10, 1 );
Now, it's always showing Payment2 option even if checkbox is checked or unchecked.
Update 2 related to your comments (and your question update)
The hook your are using is a front end hook (not admin), so it will not work.
To achieve what want, you need to replace some code inside the function that is going to save your custom checkbox value when you update the order in backend (Admin) edit order pages.
So your code will be now like this:
add_action( 'save_post', 'mv_save_wc_order_other_fields', 10, 1 );
if ( ! function_exists( 'mv_save_wc_order_other_fields' ) )
{
function mv_save_wc_order_other_fields( $post_id ) {
// We need to verify this with the proper authorization (security stuff).
// Check if our nonce is set.
if ( ! isset( $_POST[ 'mv_other_meta_field_nonce' ] ) )
return $post_id;
// Passing the value to a variable
$nonce = $_REQUEST[ 'mv_other_meta_field_nonce' ];
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $post_id;
// Check the user's permissions.
if ( 'page' == $_POST[ 'post_type' ] ) {
if ( ! current_user_can( 'edit_page', $post_id ) )
return $post_id;
} else {
if ( ! current_user_can( 'edit_post', $post_id ) )
return $post_id;
}
// --- Its safe for us to save the data ! --- //
// Sanitize user input and update the meta field in the database.
$use_payment2 = sanitize_text_field($_POST[ 'use_payment2' ]);
update_post_meta( $post_id, 'use_payment2', $use_payment2 );
// Updating securely the data with your conditions
if($use_payment2 == 'yes')
update_post_meta( $post_id, '_payment_method', 'payment2' );
else
update_post_meta( $post_id, '_payment_method', 'bacs' );
}
}
This should work as you expect now…
Code goes in function.php file of your active child theme (or theme). Or also in any plugin php files.
As this code comme from one of my answers, you are not obliged to keep the same functions beginning names with "mv_" that was related to the username of the question. You can change it to "dan_" for example…
Reference: WooCommerce : Add custom Metabox to admin order page
The function that lists default payment gateways in WooCommerce is core_gateways(). This function is hooked to a filter called woocommerce_payment_gateways. So, the first step is to remove that filter and add our own. I will work only in the functions.php file within the theme folder (remember? Never modify core files). To do so, we’ll use the remove_filter() and the add_filter() functions:
remove_filter( 'woocommerce_payment_gateways', 'core_gateways' );
add_filter( 'woocommerce_payment_gateways', 'my_core_gateways' );
Now that we have removed the filter, you can see that in the add_filter() function we have a callback named my_core_gateways. This callback is the name of a function that will replace the default core_gateways() function. This function is the one that list WooCommerce default payment gateways. I will change the content of that function and replace the call to the WC_Gateway_BACS class. This class is the bank transfer default class. Here is the code of that new function:
/**
* core_gateways function modified.
*
* #access public
* #param mixed $methods
* #return void
*/
function my_core_gateways( $methods ) {
$methods[] = 'WC_Gateway_BACS_custom';
$methods[] = 'WC_Gateway_Cheque';
$methods[] = 'WC_Gateway_COD';
$methods[] = 'WC_Gateway_Mijireh';
$methods[] = 'WC_Gateway_Paypal';
return $methods;
}
As you can see the only change I made is that I replaced WC_Gateway_BACS by WC_Gateway_BACS_custom.
Are you still with me huh? Well, to summarize, I need to remove the filter that calls the default payment gateways, and use a custom function. In this custom function, I replace the call to the BACS class, and now i need to create this new BACS class. To do so, use that code:
class WC_Gateway_BACS_custom extends WC_Gateway_BACS {
/**
* Process the payment and return the result
*
* #access public
* #param int $order_id
* #return array
*/
function process_payment( $order_id ) {
global $woocommerce;
$order = new WC_Order( $order_id );
// Mark as processing (that's what we want to change!)
$order->update_status('processing', __( 'Awaiting BACS payment', 'woocommerce' ));
// Reduce stock levels
$order->reduce_order_stock();
// Remove cart
$woocommerce->cart->empty_cart();
// Return thankyou redirect
return array(
'result' => 'success',
'redirect' => add_query_arg('key', $order->order_key, add_query_arg('order', $order->id, get_permalink(woocommerce_get_page_id('thanks'))))
);
}
}
In this snippet, I only changed the default status from “on-hold” to “processing”…. and boom the magic appears! Now each order paid using the BACS payment gateway will be marked as processing, not as on hold.
After few days of headache I found easy way how to show defined payment gateway only when I send link to customer.
Now customer can make order with default 'bacs' method, and Admin can check it before payment. Then admin change order status to Waiting for payment and link sends to customer. When customer opens link, my custom payment gateway becomes active.
I decided to use woocommerce endpoints to check if it 'order-pay' page. I used code below:
function show_payment2_payment_gateway( $available_gateways ) {
global $woocommerce, $order, $post;
if (is_wc_endpoint_url( 'order-pay' )) {
unset( $available_gateways['bacs'] );
}
else {
unset( $available_gateways['payment2'] );
}
return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'show_payment2_payment_gateway', 10, 1 );
Now it works exactly as I wanted before. I hope this will be useful. Thanks to #LoicTheAztec for help!
In Wordpress, I added some fields in the users dashboard. I made them required but I'd like to display a message if they are empty.
Here is an example (just one field) of what I did :
function my_admin_notice() { ?>
<div class="error">
<p><?php _e( 'Error!', 'user_street' ); ?></p>
</div>
<?php
}
function save_extra_user_profile_fields( $user_id ) {
if ( !current_user_can( 'edit_user', $user_id ) ) {
return false;
}
if (!empty($_POST['user_street'])) {
update_user_meta( $user_id, 'user_street', $_POST['user_street'] );
}
else {
add_action('admin_notices', 'my_admin_notice');
return false;
}
}
add_action( 'personal_options_update', 'save_extra_user_profile_fields' );
add_action( 'edit_user_profile_update', 'save_extra_user_profile_fields' );
Unfortunately, nothing happens.
I also tried with add_settings_error but I had the same problem.
Can someone give me a hand or just explain to me what I am doing wrong? It would be much appreciated! Thank you very much!
Looks like it's too late to add the admin_notice. An alternative is to use the action hook load-$page (that runs at the very beginning of a page load) and check if the user meta is empty. If so, trigger the notice.
add_action( 'load-profile.php', 'notice_so_23373245' );
add_action( 'load-user-edit.php', 'notice_so_23373245' );
function notice_so_23373245()
{
// Check to see if page is user-edit or profile
$user = isset( $_GET['user_id'] ) ? $_GET['user_id'] : get_current_user_id();
if( empty( get_user_meta( $user, 'user_street' ) ) )
add_action('admin_notices', 'my_admin_notice');
}
I am designing my website on wordpres. And I want to bolck subscribers completely from backend. I managed little little with some plugins. But the problem is that when they post something they get their display name beside their post and when they click on their display name they got redirected to their profile page on the backend. Please help me how to redirect subscriber to custom profile page when they click on their dispaly name and completely block them from beckend.
There is a great plugin by Christopher Davies (chrisguitarguy) which does what you are asking:
<?php
/*
Plugin Name: No Dashboard
Description: Don't allow subscribers to access to the wp-dashboard
Author: Christopher Davis
Plugin URI: https://gist.github.com/chrisguitarguy/1877504
*/
register_activation_hook( __FILE__, 'wpse43054_activation' );
function wpse43054_activation()
{
$role = get_role( 'subscriber' );
if( $role ) $role->remove_cap( 'read' );
}
register_deactivation_hook( __FILE__, 'wpse43054_deactivation' );
function wpse43054_deactivation()
{
$role = get_role( 'subscriber' );
if( $role ) $role->add_cap( 'read' );
}
add_action( 'init', 'wpse43054_maybe_redirect' );
function wpse43054_maybe_redirect()
{
if( is_admin() && ! current_user_can( 'read' ) )
{
wp_redirect( home_url(), 302 );
exit();
}
}
add_filter( 'get_user_metadata', 'wpse43054_hijack_admin_bar', 10, 3 );
function wpse43054_hijack_admin_bar( $null, $user_id, $key )
{
if( 'show_admin_bar_front' != $key ) return null;
if( ! current_user_can( 'read' ) ) return 0;
return null;
}