What are the best practices to restrict access to my website except for two pages - wordpress

I'm building a website on Wordpress with Bedrock/Timber/ACF.
This site is restricted for a big major part of it.
There is 4-5 pages available for anonymous users (home, contact, login & legal/privacy policy pages).
I'm currently managed it with Timber routing with like:
Routes::map('/blog/page/:num/', function ($params) {
if (!is_user_logged_in()) {
wp_redirect(home_url().'/login');
exit();
}
$user = wp_get_current_user();
if ($user->roles[0]=="subscriber") {
$post_type="publish";
} else {
$post_type="any";
}
$query = 'order=ASC&orderby=title&paged='.$params['num'].'&post_status='.$post_type;
Routes::load('list-blog.php', $params, $query, 200);
});
However I don't know if it's the good way to do it because I can't use wordpress template hierarchy, on the admin side everytimes I want to create a new page I have to create the road...
So my solution is not flexible and hard to maintain...
Do you have some advices?
EDIT:
I almost removed all my routes by using wordpress template hierarchy. But I still have routes link to the login page because I don't want to have mysite.com/wp/login but mysite.com/login.

I would use array_key_exists instead of checking for the first var because there a situation that the subscriber role is second.
If you are using ACF you could try to add a checkbox field to your pages and query for the variable of the field.
https://www.advancedcustomfields.com/resources/query-posts-custom-fields/
Routes::map('/blog/page/:num/', function ($params) {
if (!is_user_logged_in()) {
wp_redirect(home_url().'/login');
exit();
}
$user = wp_get_current_user();
$post_type = array_key_exists("subscriber", $user->roles) ? "publish" : "any";
$query = 'order=ASC&orderby=title&paged='.$params['num'].'&post_status='.$post_type;
Routes::load('list-blog.php', $params, $query, 200);
});

Related

Wordpress: How to allow some comment-actions (delete, edit...) only to specific roles?

Is it possible to customize Wordpress via action, hook or anything, that
only users of role "administrator" or "editor" may trash, spam or edit comments from the backend?
only users of role "administrator" or "editor" may trash, spam or edit comments from mail that will be generated on new comments?
I did not find anything on codex.wordpress.org as well as I did not find a proper plugin. :-/
Thanks!
I would advice using a plugin such as User Role Editor for this, but hey - heres a working code example :):
In the the class WP_Role you'll find a property named ‘edit_comment’ which is mapped to the ‘edit_posts’ thus isn't handled as a separate capability. we can however modify the behaviour by applying a filter to the selected user role we want to restrict editing comments on by using the map_meta_cap function.
Example for:
Only users "administrator" or "editor" may trash, spam or edit comments from the backend:
<?php
// Restrict editing capability of comments using `map_meta_cap`
function restrict_comment_editing( $caps, $cap, $user_id, $args ) {
if ( 'edit_comment' == $cap ) {
// Allowed roles
$allowed_roles = ['editor', 'administrator'];
// Checks for multiple users roles
$user = wp_get_current_user();
$is_allowed = array_diff($allowed_roles, (array)$user->roles);
// Remove editing capabilities on the back-end if the role isn't allowed
if(count($allowed_roles) == count($is_allowed))
$caps[] = 'moderate_comments';
}
}
return $caps;
}
add_filter( 'map_meta_cap', 'restrict_comment_editing', 10, 4 );
// Hide comment editing options on the back-end*
add_action('init', function() {
// Allowed roles
$allowed_roles = ['editor', 'administrator'];
// Checks for multiple users roles
$user = wp_get_current_user();
$is_allowed = array_diff($allowed_roles, (array)$user->roles);
if(count($allowed_roles) == count($is_allowed)) {
add_filter('bulk_actions-edit-comments', 'remove_bulk_comments_actions');
add_filter('comment_row_actions', 'remove_comment_row_actions');
}
});
function remove_bulk_comments_actions($actions) {
unset($actions['unapprove']);
unset($actions['approve']);
unset($actions['spam']);
unset($actions['trash']);
return $actions;
}
function remove_comment_row_actions($actions) {
unset($actions['approve']);
unset($actions['unapprove']);
unset($actions['quickedit']);
unset($actions['edit']);
unset($actions['spam']);
unset($actions['trash']);
return $actions;
}
?>
Code goes into your functions.php file
Thanks to #Kradyy I came around to map_meta_cap and remove_cap.
With the following in the functions.php, the links are removed in the comments section of the dashboard as well as in the email sent to the author (except for admins and editors):
global $wp_roles;
$allowed_roles = ['editor', 'administrator'];
foreach (array_keys($wp_roles->roles) as $role){
if (!in_array($role, $allowed_roles)) {
$wp_roles->remove_cap( $role, 'moderate_comments' );
}
}

Hide Wordpress Categories from Users by Role

I want to be able to hide certain Wordpress Post Categories from Users dependent on their Role.
I've tried the code here:
Wordpress: Hide specific categories from User Role on the Add New page
I think its deprecated, and would really appreciate some help
add_filter('list_terms_exclusions', 'yoursite_list_terms_exclusions', 10, 2);
function yoursite_list_terms_exclusions( $exclusions, $args ) {
global $pagenow;
if (in_array($pagenow,array('post.php','post-new.php')) && !current_user_can('see_special_cats')) {
$exclusions = " {$exclusions} AND t.slug NOT IN ('slug-one','slug-two')";
}
return $exclusions;
}
With this code nothing happens. I've tried 10+ different plugins and am really getting desperate. Thanks in advance.
add_filter('list_terms_exclusions', 'yoursite_list_terms_exclusions', 10, 2);
function yoursite_list_terms_exclusions( $exclusions, $args ) {
global $pagenow;
if (in_array($pagenow,array('post.php','post-new.php')) &&
!current_user_can('see_special_cats')) {
$exclusions = " {$exclusions} AND t.slug NOT IN ('slug-one','slug-two')";
}
return $exclusions;
}
This code presumes that you've used a plugin like the Members plugin to create a capability called 'see_special_cats' and that you've assigned it to every role that you want to have access to the categories except of course 'Contributors'.
Since you found the plugin you may not need this, but maybe it will help someone else.
add_filter('list_terms_exclusions', 'yoursite_list_terms_exclusions', 10, 2);
function yoursite_list_terms_exclusions( $exclusions, $args ) {
$current_user = wp_get_current_user();
// Change 'see_special_cats' to capability user must have to be able see category or categories
if ( $current_user->has_cap('see_special_cats') ) {
$capCheck = 1;
} else {
$capCheck = 0;
}
global $pagenow;
if (in_array($pagenow,array('post.php','post-new.php')) && !$capCheck) {
// Change category-slug-one and two to desired categories to hide. Additional categories may be added
// by separating with a comma. Delete ", 'category-slug-two'" to only hide one category
$exclusions = " {$exclusions} AND t.slug NOT IN ('category-slug-one', 'category-slug-two')";
}
return $exclusions;
}
This code works without using current_user_can(). Paste this code in your functions.php file. If you want to hide a category from everyone except for the Administrator role, as set up by the default hierarchical structure, change 'see_special_cats' to 'create_users'. Change category-slug-one and category-slug-two to the category slugs that you want hidden. There is no additional plugin required (I'm not sure where 'see_special_cats' comes from).

How to add verified badge in front of author name across wordpress blog

Good Day,
I have been trying to add verification badge to WordPress users but I no success. I tried using administrator to do the testing by checking if user has role administrator and trying to enter code here update_user_meta (display_name) but I wasn't able to add icons to the display name.
I have as well tried creating a custom field in user profile called verify_user (text field) .... In which I entered the value "verified" and saved ... I have been searching for hooks to use but haven't seen one. I'm not sure which hook/filter to use here
Please is there any solution to adding this verification icon to author's display name in which when the word "verified" is entered into the custom field created in user profile or any other approach available (e.g if user has specific role). I don't mind if the little structure I wrote above would be changed.
Thanks
I was able to get a solution which worked exactly as i wanted. For anyone who might have same task to tackle;
function add_verification_bagdge_to_authors($display_name) {
global $authordata;
if (!is_object($authordata))
return $display_name;
$icon_roles = array(
'administrator',
'verified_author',
);
$found_role = false;
foreach ($authordata->roles as $role) {
if (in_array(strtolower($role), $icon_roles)) {
$found_role = true;
break;
}
}
if (!$found_role)
return $display_name;
$result = sprintf('%s <i title="%s" class="fa fa-check-circle"></i>',
$display_name,
__('This is a Verified Author', 'text-domain-here')
);
return $result;
}
add_filter( 'the_author', 'add_verification_bagdge_to_authors' );
The way i was able to tackle this was to create a user role called Verified Author (using add_role() function from Wordpress Codex ), which will be the role assigned to verified author across the website. All Users with Admin Role are automatically Verified while user role has to be switched from either contributor/Author role to Verified Author.
The above code was able to do 98% of the task but when a verified author / administrator comments, their display name doesn't show the verified badge. I was able to use the below code to fix that (combining the code with a shortcode).
function my_comment_author( $author = '' ) {
// Get the comment ID from WP_Query
$comment = get_comment( $comment_ID );
if ( ! empty($comment->comment_author) ) {
if (!empty($comment->user_id)){
$user=get_userdata($comment->user_id);
$author=$user->display_name.' '. do_shortcode('[this_is_verified-sc]'); // This is where i used the shortcode
} else {
$author = $comment->comment_author;
}
} else {
$author = $comment->comment_author;
}
return $author;
}
add_filter('get_comment_author', 'my_comment_author', 10, 1);
Shortcode to return the Verified Badge if user is admin or verified author
function add_verification_bagdge_to_authors_sc($display_name) {
global $authordata;
if (!is_object($authordata))
return $display_name;
$icon_roles = array(
'administrator',
'verified_author',
);
$found_role = false;
foreach ($authordata->roles as $role) {
if (in_array(strtolower($role), $icon_roles)) {
$found_role = true;
break;
}
}
if (!$found_role)
return $display_name;
$result = sprintf('%s <i title="%s" class="fa fa-check-circle"></i>', $display_name, __('This is a Verified Author', 'text-domain-here') );
return $result;
}
add_shortcode( 'this_is_verified-sc', 'add_verification_bagdge_to_authors_sc' );
Please Note: Not all Magazine theme are properly coded / have a hard coded Block and module elements, so the verified badge might not work on their block / module element. I experienced this during the whole website design process, so we had to change up theme and the only modification i had to make to the new theme was to remove the html escape added to their block/module code, so that the icon can be rendered. i.e. in their module/block code they had something like this esc_html( the_author() ) and i removed the esc_html to have just the_author() an it all worked.
Its not really a straight forward solution but that is how i was able to tackle the task without using a plugin. Just add the codes to your functions.php file and that's it. I hope it helps someone.
Thanks to Kero for pointing me in the right direction, providing the code i was able to work with and manipulate

How to hide media uploads by other users in the Media manager

i am using wordpress multisite and wan to hide medea which others have uploaded. Like if X User of that site have uploaded any media in the wordpress, Y User should not be able to see or access this from there login. Please help
You could try something like this.
/**
* Allow access to own content only
*/
function my_authored_content($query) {
//get current user info to see if they are allowed to access ANY posts and pages
$current_user = wp_get_current_user();
// set current user to $is_user
$is_user = $current_user->user_login;
//if is admin or 'is_user' does not equal #username
if (!current_user_can('manage_options')){
//if in the admin panel
if($query->is_admin) {
global $user_ID;
$query->set('author', $user_ID);
}
return $query;
}
return $query;
}
add_filter('pre_get_posts', 'my_authored_content');
This will only let admin and the author see the content.
You can either add it to the main functions file or turn it into a plugin.
To create it as a plugin:
Create a new file
add the code from here: http://pastebin.com/rfMLM0BU
save it as my-authored-content.php
upload it to your plugins directory.
Hope this helps you! :-)
For me works this:
function mymo_parse_query_useronly( $wp_query ) {
if(isset($wp_query->query_vars['post_type']) && $wp_query->query_vars['post_type'] == 'attachment'){
if ( !current_user_can( 'level_5' ) ) {
$wp_query->set( 'author', get_current_user_id() );
}
}
}
add_filter('parse_query', 'mymo_parse_query_useronly' );
I use this for uploaded profile picture for the user profile in front end

Modify User Roles in WordPress?

I have been working on a client's WordPress Website and last day my client want to hide navigation menu and pages from author/contributor categories.
I have searched and tried some of the plugin but didn't get the exact thing. Please let me know what should i use to hide some pages from user and from navigation.
Only Admin can see all the pages and other members should see only 1 section that is allowed to visible for them.
Thank You
use this plugin to manage All roll:
http://wordpress.org/plugins/user-role-editor/
Here is the Complete function for removing each Menu and submenu from wp-admin for another user:
function remove_menus() {
global $menu, $submenu;
$restricted = array(__('Dashboard'), __('Profile'), __('Users'), __('Tools'), __('Comments'), __('Settings'), __('Plugins')); //Here you can also define the name like Pages
end($menu);
while (prev($menu)) {
$value = explode(' ', $menu[key($menu)][0]);
if (in_array($value[0] != NULL ? $value[0] : "", $restricted)) {
unset($menu[key($menu)]);
}
}
unset($menu[5]); // this is just for example
unset($submenu['edit.php'][16]); // this is just for example
}
Now You have to put a conditon for other user i.e:
$thisusername = $current_user->user_login; // this is to get the current user login
if (($thisusername == "user123")) {
add_action('admin_menu', 'remove_menus');
}
Note: You can find many plugins but all of them are not in depth like this code.Well you can try this plugin to manage your user's roles.Capability Manager Plugin

Resources