Different content for user level in WP - php

okay so I'm using the following code to show different content to users with different levels in WordPress
<?php global $user_ID; if( $user_ID ) : ?>
<?php if( current_user_can('level_10') ) : ?>
Admin
<?php else : ?>
FREE
<?php endif; ?>
<?php endif; ?>
How can I get different content to show for users with level 10, level 9, level 8, level 7 ect...
Thanks in advance

there are many ways to do level based filtering - and it depends on what you want to do exactly, but basically you just need simple conditionals ( if - else or if - then or switch statements ) again - depends on context.
if( current_user_can( 'level_10' ) ){
echo 'A - content for user level 10';
} elseif( current_user_can( 'level_8' ) ) {
echo 'B - content for user level 8 and above';
} elseif( current_user_can( 'level_6' ) ) {
echo 'C - content for user level 6 and above';
} // ok for wordpress < 3.0
/*
* Please read my note below regarding user levels to roles conversion
*/
if( current_user_can( 'manage_options' ) ){
echo 'A - content for user level Admin';
} elseif( current_user_can( 'publish_pages' ) ) {
echo 'B - content for user level Editor and above';
} elseif( current_user_can( 'publish_posts' ) ) {
echo 'C - content for user level Author and above';
} // ok for wordpress > 3.0
which will output totally different content for each user , but also means that user level 10 will NOT SEE the content of level 6.. ( unless you drop the else.. )
// when Admin logged
A - content for user level Admin
// when level editor and above logged
B - content for user level Editor and above
// when level author and above logged
C - content for user level Author and above
or
if( current_user_can( 'publish_posts' ) ){ // Author
echo 'A - content for Author and above';
if( current_user_can( 'publish_pages' ) ){ // Editor
echo 'B - Additional content for Editor and above';
if( current_user_can( 'manage_options' ) ){ // Administrator
echo 'C - Additional content for administrator ';
}
}
}
which will ADD output based on user levels - so user 10 see user 6 content PLUS user 8 content PLUS user 10 content
Put in plain human language example one will show content for level 10 OR content for level 8 OR .. while example 2 will show content for level 10 AND content for level 8 AND ..
Like said before - there are many many ways to use it , but it all depends on context .
Note : Since wp 3.0 the user_level system was deprecated . you will need to filter by Capabilities using the user level to role Conversion system ..
if( current_user_can( 'administrator' ) ){} // only if administrator
if( current_user_can( 'editor' ) ){} // only if editor
if( current_user_can( 'author' ) ){} // only if author
if( current_user_can( 'contributor' ) ){} // only if contributor
if( current_user_can( 'subscriber' ) ){} // only if subscriber

Related

Display header based on user role and page (Wordpress)

I have created multiple different headers as templates with Elementor.
I would like to display all of the different headers based on user role (Logged in/Logged out) and page.
I'm looking for a code snippet that I could easily customize to assign all of the different headers for different scenarios.
Could someone please create an example code snippet that would:
Display header A for Logged Out users on the entire
website, EXCEPT pages X and Y.
Display header B for Logged In users on the entire
website, EXCEPT pages X and Y.
Display header C for Logged Out users only on pages X and
Y.
Display header D for Logged In users only on pages X and
Y.
This way, people can easily copy the code and customize it to fit their needs.
EDIT
There's 2 places where I can create templates.
1st one is added by Elementor and is found in Admin > Templates > Saved Templates. Here I can create either section or page templates (Screenshot).
2nd one is added by my theme, OceanWP, and is found in Admin > Theme Panel > My Library. Here I can create only 1 type of template. The templates created here can later be assigned as custom headers or footers to individual pages or the entire website.
Are the templates created in these 2 places considered to be template parts? Is there a difference where I choose to create the header templates?
Here's a list of the header templates I have created:
Template title
Post ID
A
Main Header (Logged Out)
5448
B
Main Header (Logged In)
6714
C
Checkout Header (Logged Out)
6724
D
Checkout Header (Logged In)
3960
Here's the page I want to have a different header than the entire website:
Page title
Post ID
Slug
X
Checkout
18
checkout
Something like this should work:
<?php
if (! is_user_logged_in() && ! is_page(array( 'page-x-slug', 'page-y-slug' ))){
// display header A
}
if (is_user_logged_in() && ! is_page(array( 'page-x-slug', 'page-y-slug' ))){
// display header B
}
if (! is_user_logged_in() && is_page(array( 'page-x-slug', 'page-y-slug' ))){
// display header C
}
if (is_user_logged_in() && is_page(array( 'page-x-slug', 'page-y-slug' ))){
// display header D
}
?>
The following offer the same result as the previous answer but is minified and has less repetitiveness.
<?php
if ( is_page( [ 'page-x', 'page-y' ] ) )
if ( is_user_logged_in() )
get_header( 'B' ); //... header-B.php
else
get_header( 'A' ); //... header-A.php
else
if ( is_user_logged_in() )
get_header( 'D' ); //... header-D.php
else
get_header( 'C' ); //... header-C.php
?>
Following your comments
I'm guessing that what you refer as...
section templates
...are in fact templates part. Instead of using get_header( string $name ); you would then use get_template_part( string $slug, string $name = null );.
$slug and $name can be anything that you chose.
Source # https://developer.wordpress.org/reference/functions/get_template_part/
For example, section-A.php would be get_template_part( 'section', 'A' );.
<?php
//...
if ( is_user_logged_in() )
get_template_part( 'section', 'B' ); //... section-B.php
else
get_template_part( 'section', 'A' ); //... section-A.php
?>
In regards to specifying pages and templates. is_page() can take IDs, slugs or titles.
is_page( int|string|int[]|string[] $page = '' )
Parameter
Description
$page
(int|string|int[]|string[]) (Optional) Page ID, title, slug, or array of such to check against. Default value: ''
Source # https://developer.wordpress.org/reference/functions/is_page/
But you could also use other is_ function like is_search() or is_archives(), is_404()... etc.
Here is a complete list # https://codex.wordpress.org/Conditional_Tags
If you want to add multiple conditional statement you can just add elseif statements in-between.
<?php
if ( is_page( [ 'page-x', 'page-y' ] ) )
//...
elseif ( is_search() || is_archive() )
//...
else
//...
?>
If you want to get a better understanding of PHP operators, which are how conditional statements are built, take a look # https://www.w3schools.com/php/php_operators.asp

Wordpress - Show admin bar only to the post author

I want to show the admin bar on my single.php page ONLY when the actual author of the post is on the page.
I took this article as a reference and was able to make the admin bar visible on single.php pages only, but I also want to add a condition to hide it to non-author viewers.
https://second-cup-of-coffee.com/hiding-the-wordpress-admin-bar-on-certain-pages/
And this is the code I tried on my functions.php:
function my_theme_hide_admin_bar($bool) {
$logged_in_user = wp_get_current_user();
$logged_in_user_id = $logged_in_user->ID;
if ( ! is_single() && $logged_in_user_id !== get_the_author_meta('ID') ) :
return false;
else :
return $bool;
endif;
}
add_filter('show_admin_bar', 'my_theme_hide_admin_bar');
However, the admin bar still shows when I view a post from another author.
You've got to compare the two ID's, the one from the post author and the one from the current user. We also want to make sure that the user is an actual author for redundancy.
Function
Description
get_post_field( 'post_author' )
Retrieve data from a post field based on Post ID.
get_current_user_id()
Get the current user’s ID.
current_user_can( 'author' )
Returns whether the current user has the specified capability.
<?php
add_filter( 'show_admin_bar', function( $show ) {
if( is_single() && current_user_can( 'author' ) && get_post_field( 'post_author' ) == get_current_user_id() ) {
return $show;
} else {
return;
};
} ); ?>
EDIT:
While checking against particular roles in place of a capability is supported in part, this practice is discouraged as it may produce unreliable results.
Source # https://developer.wordpress.org/reference/functions/current_user_can/#description
Having that in mind using current_user_can( 'author' ) isn't considered best practice. Instead an actual capability handle should be used. You can refer to the Roles and Capabilities page for a complete list of users and capabilities.
I decided to use the export capability, but you can use anything from Capability vs. Role Table.
<?php
add_filter( 'show_admin_bar', function( $show ) {
if( is_single() && current_user_can( 'export' ) && get_post_field( 'post_author' ) == get_current_user_id() ) {
return $show;
} else {
return;
};
} ); ?>
Special thanks to #Xhynk in the comments for the tips and the optimization.

Get and use the user group name in Woocommerce

I am only using Wordpress with Woocommerce. Is there a way to get user group name based on logged in user's info?
I have group of users called 'Group1' and assigned 2 users to it - user1, user12
I have the second group of users called 'Group2' and assigned 2 users to it - user2 and user23.
Now I need to check from which user group is the logged in user (all users have the same role - Customers).
Here is the sample of the code of what I am trying to do:
$user_logged = wp_get_current_user();
$user_group_name = // how to get user_logged's group name ?
if ($user_group_name == 'Group1') // do 1st
if ($user_group_name == 'Group2') // do 2nd
Names of the groups will be not changed so I will put them as strings into the code. However I need to get dynamically after user loggs in the name of the group he is assigned to.
How can I do it ?
Any help is appreciated.
You almost made it. Based on documentation, wp_get_current_user() return WP_User object that has properties roles (the roles the user is part of).
$roles = wp_get_current_user()->roles;
if (in_array("Group1", $roles)) {
// do 1st
}
if (in_array("Group2", $roles)) {
// do 2nd
}
Hope it helps
If you mean that you want to know what the role of an online user is?
Finally, you should use the following code.
$get = wp_get_current_user();
if ( in_array( 'administrator', $get->roles ) )
// do 1st
if ( in_array( 'editor', $get->roles ) )
// do 2st
if ( in_array( 'group1', $get->roles ) )
// do 3st
if ( in_array( 'groupN', $get->roles ) )
// do N st
You can use easily and directly current_user_can() WordPress dedicated function with a specific user role (or a user capability) like:
if ( current_user_can( 'Group1' ) ) {
// do 1st
} elseif ( current_user_can( 'Group2' ) ) {
// do 2st
}
WordPress and Woocommerce don't provide any Usergroup functionality by default. What related plugin are you using for those Usergroups.
You need to search in the database table wp_usermeta to see if 'Group1' or 'Group2' are assigned to users and give us the meta_key used for it.
Use wp_get_current_user()->roles to retrieve the groups the user is a member of.
$roles = wp_get_current_user()->roles;
if (in_array('group1',$roles)) {
echo 'Do something here for group 1';
}

Redirect Loop when logged out only

I wrote a function that runs with the 'wp' hook and redirects if certain conditions are met (using Advanced Custom Fields), but it only works if I am logged in. When logged out, it spits out a too many redirects error
function swa_wc_product_redirect_to_post(){
if ( is_product() ) :
if ( get_field( 'redirect_to_post' ) == 1 ) :
$redirect_post_url = get_permalink( get_field( 'redirect_post_id' ) ) ;
wp_redirect( $redirect_post_url , 301 );
endif;
endif;
}
add_action('wp','swa_wc_product_redirect_to_post');
any ideas as to why it loops when logged out only? Perhaps I am missing something simple.
Wow - need a break on this project ;-)
Turns out that the post it was trying to redirect to was set to private - hence the loop.

Detect dashboard of WooCommerce "my account" pages

How can I detect if the "myaccount/my-account.php" template is used on the Dashboard.
Currently I use:
<?php
global $wp;
if ( !isset($wp->query_vars['page']) ) {
?>
Back to my Account
<?php } ?>
<div class="myaccount_content">
<?php
do_action( 'woocommerce_account_content' );
?>
</div>
But that feels kind of hacky. Isn't there something like a is_myaccount_dashboard() function?
Update: Detecting specifically the My account "Dashboard" page
<?php
global $wp;
$request = explode( '/', $wp->request );
// If NOT in My account dashboard page
if( ! ( end($request) == 'my-account' && is_account_page() ) ){
?>
Back to my Account Dashboard
<?php
}
?>
<div class="myaccount_content">
<?php
do_action( 'woocommerce_account_content' );
?>
</div>
Tested and works.
Original answer:
Yes of course there is is_account_page() native WooCommerce conditional that returns true on the customer’s account pages.
Here is an example using is_account_page() and is_user_logged_in(). To get the my account link url you can use: get_permalink( get_option('woocommerce_myaccount_page_id') ).
if ( !is_account_page() ) { // User is NOT on my account pages
if ( is_user_logged_in() ) { // Logged in user
// Link to "My Account pages dashboard".
?>
<?php _e( 'My Account', 'woocommerce' ); ?>
<?php }
else { // User is NOT logged in
// Link to "Login / register page".
?>
<?php _e( 'Login / Register', 'woocommerce' ); ?>
<?php
}
}
?>
Reference:
Official WooCommerce Conditional Tags
Display My Account link in a template file
After that you can Override WooCommerce Templates via a Theme using my account templates to fine tune even more WooCommerce behaviors…
To detect the exact page you're in, within the My Account area, (to allow you to determine which template is being used), I don't think Woocommerce provides a way.
I think you'll have to get the current URL, with vanilla PHP, and compare it to the URL of the page that is set to be the Dashboard/My Account Home page.
e.g.
$current_url = (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$dashboard_url = get_permalink( get_option('woocommerce_myaccount_page_id'));
if($dashboard_url == $current_url){
// do your stuff here
}
Woocommerce's is_account_page() conditional function will return true for ALL the My Account sub pages, so can't be used to determine if you're specifically on the Dashboard page.
I had the same question (years later, lol). For people looking at the answer and wondering why it isn't helpful there are endpoint detecting functions available in woocommerce that do exactly what you're looking for. You can read the list of functions available here.
This is taken directly from the woocommerce docs. I am just copying it just incase the link is broken in the future
is_account_page() =>
Returns true on the customer’s account pages.
is_wc_endpoint_url() =>
Returns true when viewing any WooCommerce endpoint
is_wc_endpoint_url( 'order-pay' ) =>
When the endpoint page for order pay is being displayed.
is_wc_endpoint_url( 'order-received' ) =>
When the endpoint page for order received is being displayed.
is_wc_endpoint_url( 'view-order' ) =>
When the endpoint page for view order is being displayed.
is_wc_endpoint_url( 'edit-account' ) =>
When the endpoint page for edit account is being displayed.
is_wc_endpoint_url( 'edit-address' ) =>
When the endpoint page for edit address is being displayed.
is_wc_endpoint_url( 'lost-password' ) =>
When the endpoint page for lost password is being displayed.
is_wc_endpoint_url( 'customer-logout' ) =>
When the endpoint page for customer logout is being displayed.
is_wc_endpoint_url( 'add-payment-method' ) =>
When the endpoint page for add payment method is being displayed.
Actually I found out this condition that seems to work fine in order to detect the WC Dashboard page with native WC code only:
if (is_user_logged_in() && is_account_page() && !is_wc_endpoint_url()) {
echo 'WC Dashboard';
} else {
echo 'no WC Dashboard';
}
<?php if(is_page("account") && !is_wc_endpoint_url()) { ?>
Assuming your account page is at /account/, this will detect your dashboard.
If you were to only do is_page("account"), the conditional would trigger for all account pages. However, because the dashboard isn't considered a WC endpoint like 'view-order' or 'last-password' is, this simple check will do the job.
I also needed to identify the dashboard specifically and found this question but I didn't like any of the answers and WooCommerce still has no built-in tag to do this...
I have 2 issues with the answers, the first is using is_wc_endpoint_url() (not infallible) and the second is comparing URLs (personal taste I guess?)
is_wc_endpoint_url() can return false for endpoints which are
added by a theme or plugin so you can get a false negative. There's
a filter so you can add your own but you can't trust that a plugin
will do that.
Comparing URLs feels hacky to me. You can probably get
trustworthy results and it's pretty straightforward, so it's not
necessarily a bad way to do it. Although I would forgo hardcoding parts of the URL(s) or at least allow for translating.
Now if you think about it, WooCommerce itself knows without fail when to load dashboard.php so I just took that code and refactored it to simply identify the dashboard:
function is_dashboard(){
global $wp;
if( ! empty( $wp->query_vars ) ){
foreach ( $wp->query_vars as $key => $value ) {
// Ignore pagename param.
if ( 'pagename' === $key ) {
continue;
}
if ( has_action( 'woocommerce_account_' . $key . '_endpoint' ) ) {
return false;
}
}
}
return true;
}
For me, this is the most foolproof way to do it, although if done correctly, comparing URLs might be sufficient. You just can't trust is_wc_endpoint_url() for this issue.
Hope this helps anyone still looking for an is_dashboard() or is_account_page('dashboard')

Categories