Wordpress - Erase "Roles" on Profile Page - wordpress

I'm new at Wordpress plugin creation and still trying to get the concept of action hook or filter hook.
I've created a custom role for "moderator". What I want for this role:
- in charge of users with specific role, e.g. subscribers.
- able to change users password.
- NOT able to change other users roles.
the problem is this: to be able to change other users password the moderators will need to have access to user profile page. But, on the user profile page, the moderators can change the other user role. I'm able to hide it by changing the wp-admin/user-edit.php but I think it's better done by plugin. So, how to hide / modify the "roles" selection with a plugin?
Thanks for the help.
To make it more clear, I'm attaching a picture for it.

There are no hooks to remove that. It has to be solved with CSS and/or jQuery.
Here, both CSS and jQuery do almost the same, you can choose one or another, or use both.
The current_user_can has to be adjusted to your roles/capabilities setup.
Note that the hook admin_head can have a suffix, so it'll only run in that specific /wp-admin/WP-PAGE.php address.
add_action( 'admin_head-user-edit.php', 'so_13598192_remove_roles_dropbox' );
function so_13598192_remove_roles_dropbox()
{
// Admins can edit that, exit without printing scripts
if ( current_user_can( 'administrator' ) )
return;
?>
<style>
label[for=role], #role
{
display:none;
}
</style>
<script>
jQuery(document).ready(function($)
{
$('label[for=role]').parent().parent().remove();
});
</script>
<?php
}

Related

WordPress: adding or enabling user/customer registration? And making content only visible when logged in?

I currently have a very basic WordPress site with a few pages.
There are no user accounts, only my own admin account.
What I'm looking for:
A possibility for visitors to sign up i.e. register their own customer account. I don't need detailed account information, just an email address and perhaps a name and/or company name.
Restrict certain content to logged in visitors only. Preferably when someone is not logged in I would want the page to show 'this information is only accessible for customers - log in or sign up here'. And if someone is logged in, show the actual content.
Caveat: I'm dealing with a Woocommerce site and one of the things I'd like to restrict to logged in users only is the Shop page. But as I understood this is not a normal page with regular content in Wordpress. I guess its content is generated or controlled through the Woocommerce plugin. So is there a way to pull this off?
I'd assume this is a very common pattern in WordPress and this is probably very simple. But being a total WordPress newbie with zero experience, I wouldn't know how/where to start.
User Registration
Those are default WordPress behaviors. Enabling registration can be done via the admin control panel.
Settings → General → Membership, ✓ Anyone can register
Once this is done, users can registered # http://localhost/www/wordpress/wp-login.php?action=register
Conditional Tags
Conditional Tags can be used in your Template Files to alter the display of content depending on the conditions that the current page matches. They tell WordPress what code to display under specific conditions. Conditional Tags usually work with PHP if/else Conditional Statements.
Source # https://developer.wordpress.org/themes/basics/conditional-tags/
Restricting content to logged in user can be done via the is_user_logged_in() function.
Determines whether the current visitor is a logged in user.
For more information on this and similar theme functions, check out the Conditional Tags article in the Theme Developer Handbook.
Source # https://developer.wordpress.org/reference/functions/is_user_logged_in/
Use Case Scenario
<?php
if ( is_user_logged_in() ) {
// ... logged-in user content
} else {
// ... non-logged-in user content
};
WooCommerce Conditional Tags
You can use is_shop() to determine if the current page is a shop page.
Returns true when on the product archive page (shop).
Source # https://docs.woocommerce.com/document/conditional-tags/#section-4
Usually the shop page is built around the archive-product.php page template. the following should englobe the content from the archive-product.php page template. You don't have to specify is_shop as we're building the conditional statement on the archive-product.php page template.
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
};
/**
* Basic logged-in restricted `archive-product.php` page template example.
*/
get_header();
if ( is_user_logged_in() ) {
// ... logged-in user content
} else {
// ... non-logged-in user content
};
get_footer();
Template hierarchy
As you're new to WordPress you should try to understand the basics in term of template hierarchy. You should refer to https://developer.wordpress.org/themes/basics/template-hierarchy/. WooCommerce works the same.

WordPress functions.php - Admin html injection and submitting forms

I created a new navigation item on the left for my WP Admin:
add_action( 'admin_menu', 'addManagementMenuItem' );
function addManagementMenuItem(){
add_menu_page('Issue Management', 'Issue Management', 'manage_options', 'issue_management_slug', 'issue_management_building_function','',3);
}
function issue_management_building_function(){
if(!current_user_can('manage_options')){
}
else {
?>
...
...
So where I have the ellipsis ... is where my HTML begins and I write out some information to the page with various php echo statements to print some data out.
What I would like to do is now give the user the ability to enter in a filter and press submit. This would issue a POST to another page which would receive the post data, run some stuff, and spit out something else to the screen. I was just thinking this would take the user away from the WP-ADMIN area entirely (what I want to do is keep the user all within the right pane so it looks like it's natively happening on WordPress under my new admin area)
Something feels wrong about this approach above where I'm putting tons of html into functions.php - what is the way to create pages for a custom admin section where I can do things like post forms and go to multiple pages?
I was thinking the best solution would be to put an iframe in my injected HTML in functions.php, and then the pages can talk to themselves just like normal behind the scenes in WP-admin.
Could anyone point me in the right direction?
thanks!
Considering the user input/_POST features you'd like to add to this, you may want to consider building this functionality out as your own plugin. I've always kept custom functionality limited to non-user interaction in the functions.php file, but anything further would probably be better fit as it's own plugin.
For example, what if you created a plugin directory named nullhypothesis:
add_action( 'admin_menu', 'addManagementMenuItem' );
function addManagementMenuItem(){
add_menu_page('Issue Management', 'Issue Management', 'manage_options', 'nullhypothesis/file_to_do_your_bidding.php', 'issue_management_building_function','',3);
}
It's that fourth parameter that in the documentation mentions that you should include the menu_slug, but it doesn't necessarily need to only be a function - it can also be a file you define.
Then, in your file_to_do_your_bidding.php file (within your plugin), you can add whatever _POST functionality you'd need it to. It could also exist as the 'admin' page that the administrator/whoever interacts with.
Was that what you were looking for?

Admin hierarchy

Can any user in Wordpress with full admin privileges (ALL capabilities turned on) be hidden from other users with admin privileges (with comparatively lesser capabilities turned on) in the ‘Users’ area (list_users)?
I want to create a sort of hierarchy of administrator roles and users, where the user with the top admin role with ALL capabilities should be hidden from other users with lesser admin roles and capabilities – in the ‘Users’ area.
How can I achieve / implement this?
Thanx.
To entirely hide the user will be very hard and would require a lot of hooking and filtering, even if the super admin is only passively active (no post editing, publishing, etc.)
If you just want to hide the user from the backend users list the pre_user_query hook will probably be helpful:
https://developer.wordpress.org/reference/hooks/pre_user_query/
Alternative solution: Do not make the other users admins. Create a custom role with custom capabilities. An admin is intended to do/see everything on a wordpress site except for a multisite installation, where the network admin is even stronger.
The code below seems to work for users list ONLY:
add_action('pre_user_query','yoursite_pre_user_query');
function yoursite_pre_user_query($user_search) {
global $current_user;
$username = $current_user->user_login;
if ($username == 'DESIRED USERNAME GOES HERE') {
}
else {
global $wpdb;
$user_search->query_where = str_replace('WHERE 1=1',
"WHERE 1=1 AND {$wpdb->users}.user_login != 'DESIRED USERNAME GOES HERE'",$user_search->query_where);
}
}
function hide_user_count(){
?>
<style>
.wp-admin.users-php span.count {display: none;}
</style>
<?php
}
add_action('admin_head','hide_user_count');
[Disclaimer: Code not mine, source forgotten.]

Wordpress roles don't upgrade unless refresh users page in admin panel

Hello so I'm using Ultimate Member plugin with S2member pro plugin and ultimate members has their own roles called community roles. Also S2member has their own roles called s2member_level1 i'm trying to combine those 2 that whenever s2member_level1role has some user ultimate member community role also would change to premium for example. i'm using this code to achieve that.
global $ultimatemember;
$user_id = get_current_user_id();
if( current_user_is(s2member_level1) ) {
update_user_meta($user_id, 'role', 'premium');
} elseif ( current_user_is(s2member_level0) ){
update_user_meta($user_id, 'role', 'member');
} else {
}
It works like if some person has s2member_level1 role than it would update ultimate member role to premium and if S2member_level0 that means member is without membership or its already expired than it would change also ultimate member role back to memberwhich is subscriber for wordpress role.
Problem:
It works only if i refresh wordpress admin panel user section than everything updates if i don't refresh that and user s2member role changed it does not react user can still access to only premium users section but when i refresh or access users wordpress admin panel section all roles that should update without this action updates.
Why this happens and how to fix it?
For people like me solution:
global $ultimatemember;
$user_id = get_current_user_id();
if( current_user_is(s2member_level1) ) {
update_user_meta($user_id, 'role', 'premium');
delete_option( "um_cache_userdata_{$user_id}" );
} elseif ( current_user_is(s2member_level0) ){
update_user_meta($user_id, 'role', 'member');
delete_option( "um_cache_userdata_{$user_id}" );
} else {
}
I have added delete_option( "um_cache_userdata_{$user_id}" );
You may ask whats this, well plugin ultimate member has very stupid caching system that if you want use some custom things it does not include their cache cleaning so whenever u go to users its one of the places where ultimate member cleans cache when page is loaded, better include this code to all custom codes that u will do in future because it wont work simply because of cache problem...
I don't undestand why they need to cache user data, anyway i got the same problem wit advanced custom field.
I use ACF to display and manage custom user field on user profile page.
But every changes on this page will not be visible on their modal info page because there is their cache.
I have deleted all old cache then i turned off:
Ultimate Member -> Settings -> Advanced -> Stop caching user’s profile data
Then they get data every time from usermeta with key submitted.

How to disable page's title in wp-admin from being edited?

I have a wp-network installed with users that can create pages in each site.
Each of those pages get a place in the primary menu, and only one user have permission to create all this menu.
I want to create a user only to be able to edit the content of the pages, but not the title.
How can I disable the title of the page to be edited from the admin menu for a specific user, or (far better) for a capability?
I thought only a possibility, that's editing admin css to hide the title textbox, but I have two problems:
I don't like to css-hide things.
I don't know where is the admin css.
I know php, but don't know how to add a css hide to an element for a capability.
You should definitely use CSS to hide the div#titlediv. You'll want the title to show in the markup so the form submission, validation, etc continues to operate smoothly.
Some elements you'll need to know to implement this solution:
current_user_can() is a boolean function that tests if the current logged in user has a capability or role.
You can add style in line via the admin_head action, or using wp_enqueue_style if you'd like to store it in a separate CSS file.
Here is a code snippet that will do the job, place it where you find fit, functions.php in your theme works. I'd put it inside a network activated plugin if you're using different themes in your network:
<?php
add_action('admin_head', 'maybe_modify_admin_css');
function maybe_modify_admin_css() {
if (current_user_can('specific_capability')) {
?>
<style>
div#titlediv {
display: none;
}
</style>
<?php
}
}
?>
I resolved the problem, just if someone comes here using a search engine, I post the solution.
Doing some research, I found the part of the code where the title textbox gets inserted, and I found a function to know if a user has a certain capability.
The file where the title textbox gets added is /wp-admin/edit-form-advanced.php. This is the line before the textbox
if ( post_type_supports($post_type, 'title') )
I changed it to this
if ( post_type_supports($post_type, 'title') and current_user_can('edit_title') )
That way, the textbox is only added when the user has the capability called "edit_title"
When this IF block ends few lines after, I added:
else echo "<h2>".esc_attr( htmlspecialchars( $post->post_title ) )."</h2>";
To see the page title but not to edit it, when the user hasn't got "edit_title" capability.
Then I had already installed a plugin to edit user capabilities and roles, wich help me to create a new capability (edit_title) and assign it to the role I want.

Resources