Block subscribers completely from beckend on wordpress - php

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;
}

Related

WordPress how to give access to a page only for subscribers

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') );
}
}
}

Add custom my account menu item based on user role in WooCommerce 3+

I am using WordPress and WooCommerce and I have followed this article https://rudrastyh.com/woocommerce/my-account-menu.html to add new menu items in WooCommerce my account menus.
This is my working code.
function getUserRolesByUserId( $id ) {
if ( !is_user_logged_in() ) { return false; }
$oUser = get_user_by( 'id', $id );
$aUser = get_object_vars( $oUser );
$sRoles = $aUser['roles'];
return $sRoles;
}
function createMenuBasedonUserRole($userId)
{
$userRoleIds = getUserRolesByUserId(get_current_user_id());
$urlMenuData = [];
if(!empty($userRoleIds) && in_array('mindesk_var_account',$userRoleIds)) {
$urlMenuData = [
'pageName' => "Clients",
"pageLink" => "clients"
];
} else if(!empty($userRoleIds) && in_array('mindesk_owner_account',$userRoleIds)) {
$urlMenuData = [
'pageName' => "Children",
"pageLink" => "children"
];
}
return $urlMenuData;
}
/*
* Step 1. Add Link (Tab) to My Account menu
*/
add_filter ( 'woocommerce_account_menu_items', 'mindesk_clients_children_link', 40 );
function mindesk_clients_children_link( $menu_links ){
$urlData = createMenuBasedonUserRole(get_current_user_id());
if(!empty($urlData)){
$menu_links = array_slice( $menu_links, 0, 5, true ) + array( $urlData['pageLink'] => $urlData['pageName'] ) + array_slice( $menu_links, 5, NULL, true );
}
return $menu_links;
}
/*
* Step 2. Register Permalink Endpoint
*/
add_action( 'init', 'mindesk_add_menu_endpoint' );
function mindesk_add_menu_endpoint() {
add_rewrite_endpoint( 'clients', EP_PAGES );
add_rewrite_endpoint( 'children', EP_PAGES );
}
/*
* Step 3. Content for the new page in My Account, woocommerce_account_{ENDPOINT NAME}_endpoint
*/
add_action( 'woocommerce_account_clients_endpoint', 'mindesk_clients_my_account_endpoint_content' );
function mindesk_clients_my_account_endpoint_content() {
require_once(get_template_directory() . '/myaccount/clients.php') ;
}
add_action( 'woocommerce_account_children_endpoint', 'mindesk_children_my_account_endpoint_content' );
function mindesk_children_my_account_endpoint_content() {
require_once(get_template_directory() . '/myaccount/children.php') ;
}
/* Step 4
*/
// Go to Settings > Permalinks and just push "Save Changes" button.
And this is my how my new menu called as "Clients" showing.
As you can see above, I have added new menu and executing the page and based on user role mindesk_var_account I need to show clients and mindesk_owner_account I need to show children.
I have created these 2 php pages at /wp-content/themes/twentytwentyone/myaccount and its working fine.
However, I want to use wp_die or something if user with another role try to access one of the page which they are not allowed to.
So for example if logged in user has mindesk_var_account role then if they try to go to http://localhost/wordpress/my-account/clients/ then i need to use wp_die() to not execute it.
I tried to use wp_die inside these new 2 pages but then menus and other things executed. I just want something like this.
I tried to use following code...
add_action( 'template_redirect', 'my_account_redirect' );
function my_account_redirect() {
if( is_page( 'my-account' ) ) {
wp_die('fg');
}
}
But then its checking for all my-account pages .. and I want it to be checked only for inner pages like client or children.
Can someone guide me how can I achieve this what should I do from here on.
Thanks
There are still some little mistakes in your code, some missing things and since WooCommerce 3 there are some related changes within step 2 for My account endpoints. Some things can be simplified too.
To avoid non allowed user roles to access to some prohibited section(s) or endpoint(s) you can use a custom function hooked in template_redirect hook that will redirect user to an allowed section.
Here is the complete code:
// Custom function that get My account menu item data based on user roles
function get_menu_item_by_user_role() {
$user_roles = wp_get_current_user()->roles;
if ( ! empty($user_roles) ) {
$menu_item = [];
// if ( in_array('mindesk_var_account', $user_roles) ) {
if ( in_array( 'mindesk_var_account', $user_roles ) ) {
$menu_item = [ 'clients' => __( "Clients", "woocommerce" ) ];
}
elseif( in_array( 'mindesk_owner_account', $user_roles ) ) {
$menu_item = [ 'children' => __( "Children", "woocommerce" ) ];
}
}
return $menu_item;
}
// Step 1 - Add Link (Tab) to My Account menu
add_filter ( 'woocommerce_account_menu_items', 'add_mindesk_custom_menu_items', 40 );
function add_mindesk_custom_menu_items( $menu_items ){
$new_item = get_menu_item_by_user_role();
if ( ! empty($new_item) ) {
$menu_items = array_slice( $menu_items, 0, 5, true ) + $new_item + array_slice( $menu_items, 5, null, true );
}
return $menu_items;
}
// Step 2 - Enable endpoint (and endpoint permalink) - Since WooCommerce 3
add_filter( 'woocommerce_get_query_vars', 'add_mindesk_menu_item_endpoint' );
function add_mindesk_menu_item_endpoint( $query_vars ) {
$query_vars['clients'] = 'clients';
$query_vars['children'] = 'children';
return $query_vars;
}
// Step 3. Content for the new page in My Account, woocommerce_account_{ENDPOINT NAME}_endpoint
add_action( 'woocommerce_account_clients_endpoint', 'add_mindesk_account_clients_endpoint_content' );
function add_mindesk_account_clients_endpoint_content() {
require_once(get_template_directory() . '/myaccount/clients.php') ;
}
add_action( 'woocommerce_account_children_endpoint', 'add_mindesk_account_children_endpoint_content' );
function add_mindesk_account_children_endpoint_content() {
require_once(get_template_directory() . '/myaccount/children.php') ;
}
// Step 4. Endpoint page title
add_filter( 'woocommerce_endpoint_clients_title', 'set_mindesk_account_clients_endpoint_title', 10, 2 );
function set_mindesk_account_clients_endpoint_title( $title, $endpoint ) {
$title = __("Clients", "woocommerce" );
return $title;
}
add_filter( 'woocommerce_endpoint_children_title', 'set_mindesk_account_children_endpoint_title', 10, 2 );
function set_mindesk_account_children_endpoint_title( $title, $endpoint ) {
$title = __( "Children", "woocommerce" );
return $title;
}
// Step 5. Redirect if not allowed user role
add_action( 'template_redirect', 'redirect_mindesk_account_dashboard' );
function redirect_mindesk_account_dashboard() {
if ( is_account_page() ) {
global $wp;
$item_key = array_keys(get_menu_item_by_user_role());
$page_url = get_permalink( get_option('woocommerce_myaccount_page_id') );
if ( empty($item_key) && ( isset($wp->query_vars['children']) || isset($wp->query_vars['clients']) ) ) {
wp_safe_redirect( get_permalink($page_id) );
exit();
}
elseif ( 'clients' == reset($item_key) && isset($wp->query_vars['children']) ) {
wp_safe_redirect( get_permalink($page_id) . 'clients/' );
exit();
}
elseif ( 'children' == reset($item_key) && isset($wp->query_vars['clients']) ) {
wp_safe_redirect( get_permalink($page_id) . 'children/' );
exit();
}
}
}
// Step 6. FLush rewrite rules:
// Go to Settings > Permalinks and click on "Save Changes".
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
related: WooCommerce My Account custom endpoint menu item

How To Disable (or Remove) “All Comments, Published, and Trash” in WP Dashboard for non admins

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;
}
}

Unable to Override WooCommerce Checkout Fields

I've created a custom WooCommerce checkout field with Woothemes Checkout Field Editor labeled "po_number". I would like the PO Number checkout field to only display for the user role "distributor".
So far I've been unsuccessful in overriding the checkout fields. I'm using Wordpress 4.5.1 / Woocommerce 2.5.5. Here's the code I've placed in my child theme's functions.php. I've also tested to make sure it is not a theme conflict.
Any help is greatly appreciated.
This is my code:
function custom_override_checkout_fields( $fields ) {
if ( ! current_user_can( 'distributor' ) && isset( $fields['billing']['po_number'] ) ) {
unset($fields['billing']['po_number']);
}
return $fields;
}
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
The current_user_can() function is related to capabilities of the user roles, but not to detect the user roles themselves. For that reason is not working in your code.
You need to set a conditional function for this purpose (user roles):
function is_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;
}
if ( in_array( $role, (array) $user->roles ) == 1) {
return true;
} else {
return false;
}
}
Then in your code you can use that function:
function custom_override_checkout_fields( $fields ) {
if ( !is_user_role( 'distributor' ) && isset( $fields['billing']['po_number'] ) ) {
unset($fields['billing']['po_number']);
}
return $fields;
}
add_filter( 'woocommerce_checkout_fields', 'custom_override_checkout_fields' );
This should work in your code.

Wordpress Single User Session

I'm using the Current version of Wordpress (4.2.4) and woocommerce (2.3.6).
Problem: Don't let users share their login details to the site.
Old Solution: The Answer to this question has been working until now.
What i need: Can anyone see what's wrong with this code & why it wouldn't work with the new Wordpress update (4.2.4).
Or offer up another solution.
Code from answer by #manoj-dhiman:
how can I prevent multiple login from same user id from different browsers in wordpress?
if( !class_exists( 'WPSingleUserLoggin' ) ) {
class WPSingleUserLoggin
{
private $session_id;
function __construct()
{
if ( ! session_id() )
session_start();
$this->session_id = session_id();
add_action( 'init', array( $this, 'init' ) );
add_action( 'wp_login', array( $this, 'wp_login' ), 10, 2 );
}
function init()
{
if( ! is_user_logged_in() )
return;
$stored_sess_id = get_user_meta( get_current_user_id(), '_wp_single_user_hash', true );
if( $stored_sess_id != $this->session_id )
{
wp_logout();
wp_redirect( wp_login_url() );
exit;
}
}
function wp_login( $user_login, $user )
{
update_user_meta( $user->ID, '_wp_single_user_hash', $this->session_id );
return;
}
}
new WPSingleUserLoggin();
}

Categories