Redirect Custom Admin Role - Wordpress - wordpress

I've defined a custom role in Woocommerce. This user ONLY needs access to urls to edit shop_orders and inspect individual shop orders. Like:
/wp-admin/edit.php?post_type=shop_order
/wp-admin/post.php?post=124&action=edit
/wp-admin/post-new.php?post_type=shop_order
If they go anywhere else I want to redirect them to:
/wp-admin/edit.php?post_type=shop_order
In effect they should only see orders, modify orders, and create orders. I've added all the right permissions for this, and modified the menus drastically so they can't see 'products', 'my profile', etc. However, if they accessed some links directly they would still load (the 'dashboard' for one and 'my settings'). Removing them from dashboard != removing access to them.
I'm trying to harden my security a bit by redirecting on everything except a few whitelisted routes with wildcards. Any thoughts on how to approach? Thanks.

This sounds like something you may be able to do with this filter:
https://codex.wordpress.org/Plugin_API/Filter_Reference/user_has_cap
My understanding of it is that when wordpress queries whether or not the user has the capability to do something on the site e.g. edit_posts, then you can apply further logic (in your example, checking whether or not their role is the custom role you defined) to decide to restrict or enhance that capability if you wish. In your case, if the user didn't meet your criteria (they are not requesting a pre-defined page), you could redirect.
Quick proof of concept (I think):
function only_let_user100_see( $allcaps, $cap, $args ) {
if($args[0] === 'edit_posts' && is_admin()) {
if(get_current_user_id() !== 100) {
echo "No way";
exit;
}
} else {
return $allcaps;
}
}
add_filter( 'user_has_cap', 'only_let_user100_see', 10, 3 );

Related

Appending parameter to URL to solve issue with Page Caching and Tax Toggles

I have a WooCommerce website which uses a plugin called "Booster for WooCommerce" primarily for their "Tax Display" module. This plugin enables us to have a button in the header which allows the customer to switch between inc and exc VAT. The default setting is including tax.
The problem I'm encountering now is when I enable page caching in W3 Total Cache, the plugin is caching the first visit to a shop or product page along with the prices and then the next person to visit that page sees pricing based on the first user's tax toggle setting, not their own.
I can think of a few solutions to this in varying complexity but after noticing that the booster plugin sets a session variable via:
WC()->session->set('wcj_toggle_tax_display',( 'incl' === $current_value ? 'excl' : 'incl' ));
I'm wondering if there's a simple fix where I could simply hook in just before page load and if that session variable is set to excl, then set a URL parameter such as "?vat=false". Which I'm assuming would then cache as it's own unique URL and solve the problem.
I'm just not sure which hook would work for appending the parameter to the URL and my searches are getting me nowhere.
I've scoured over various solutions to this issue for days now, so a simple fix like this would be a godsend, I'm just not 100% sure how possible it is.
Any help on this would be greatly appreciated!
Thanks,
Jack
So far, the following code seems to have solved this problem but I'm still testing further with W3 Total Cache.
// Add URL parameter vat=false if tax toggle set to excl
function custom_redirect_append_url_params() {
if (is_woocommerce()) {
$toggle_status = wcj_session_get( 'wcj_toggle_tax_display' );
if (empty($toggle_status)) $toggle_status = 'incl'; //default value = incl
//if vat isn't set as a query var && toggle status is set to excl then redirect
if(!isset($_GET['vat']) && $toggle_status === 'excl') {
//do your redirect here with wp_redirect()
wp_redirect( add_query_arg( 'vat', 'false', $_SERVER['REQUEST_URI'] ));
exit; //prevent wordpress continuing to load templates
}
elseif($_GET['vat'] === 'false' && $toggle_status === 'incl') {
wp_redirect( add_query_arg( 'vat', 'true', $_SERVER['REQUEST_URI'] ));
exit; //prevent wordpress continuing to load templates
}
}
}
add_action('template_redirect','custom_redirect_append_url_params');

WordPress - Storing URL in transient is not constant

I need to store current URL in transient, so I can access it for later use (when I need to link back to that page from search page).
Code:
if(!is_page_template('search.php')) {
set_transient( 'last_url', $current_url, 60*60 );
}
So this code should save current url of current page, until we are on search page.
However, once I click on the search page, 'last_url' will become domain.tld/search. I have no idea why is that happening when I explicitly have the rule if(!is_page_template('search.php'))
However, my temporary solution is to check if there is also word search in URL, and if there isn't then create transient, like:
if(!is_page_template('search.php')) {
if(stripos($current_url, 'search') === false) {
set_transient( 'shop_last_url', $current_url, 60*60 );
}
}
While this solution works, its the bad one since search page have different slug - for example if there are several languages...
I have also tried to use cookies and sessions without any luck.
If your theme doesn't uses default WordPress queries ($wp_query) then the functions such as is_page_template,get_page_template_slug would not work properly.
You can see it in corresponding Core code here.
So, for your current case you can use global template variable instead.
if (basename($GLOBALS["template"])=='search.php'){
set_transient( 'last_url', $current_url, 60*60 );
}
or
if (basename(get_page_template())=='search.php'){
set_transient( 'last_url', $current_url, 60*60 );
}

Give access to only two (/home, /inbox) page for a particular user with specific role in wordpress

I want to give only two page (/home, /inbox) access to my user with role "Vendor", if user tries to access other pages than it will automatically redirect to "/inbox" page, I put the below code to achieve the functionality but after adding this to function.php, site again n again redirect and finally dies with message "Page isn't properly redirected". please suggest what is wrong with my tried code or any other solution.
function vendor_redirect() {
global $post;
if(current_user_can('Vendor') && !in_array($post->slug,array("home","inbox"))) {
wp_safe_redirect('/inbox');
}
}
add_action('template_redirect', 'vendor_redirect');
The main issue the way I tried to get the page slug, the correct way to get the slug is "$post->post_name". also I put exit after wp_safe_redirect as well because codex suggest that:
function vendor_redirect() {
global $post;
if(current_user_can('Vendor') && !in_array($post->post_name,array("home","inbox"))) {
wp_safe_redirect(get_permalink(get_page_by_path( 'inbox' )));
exit;
}
}
add_action('template_redirect', 'vendor_redirect');

Wordpress, filter pages in Admin edit screen

Is it possible to 'filter' which pages are shown in the 'edit' screen for pages ( http://cl.ly/6nLC ) in Wordpress? I have looked in the action / hook section of Wordpress for plugin developers but I could not find any.
What I am trying to accomplish is is that certain users can edit certain pages (and child pages) and other persons cannot edit those pages but might be able to edit other pages.
I have allready written a plugin which makes it possible to put different users in differtent groups, which now just needs to have different rights, which user is member of which group is stored in the user_meta table.
However if there is 'any' filter hook / method for this, can someone point this out, I think I will be able to go further from there.
Kind regards.
You can use a posts_where filter to add a condition to the SQL query to filter out some pages. A load-{filename} action can be used to ensure the filter is only applied when managing pages.
add_action('load-edit.php', 'my_load_edit_php_action');
function my_load_edit_php_action() {
if ($_GET['post_type'] !== 'page') return;
add_filter('posts_where', 'my_posts_where_filter');
}
function my_posts_where_filter($sql) {
if (current_user_can('your_capability')) {
global $wpdb;
$sql = " AND $wpdb->posts.ID NOT IN (1,2,3)" . $sql;
}
return $sql;
}

How to redirect user to a specific page after they login if they belong to a certain role?

We have certain users in our member list that have a role "vendor" attached to them. All such members are to be redirected to a certain page upon login. How can this be accomplished?
There is more than one way to skin this cat...
This is my preferred Drupal 7 method:
function hook_user_login(&$edit, $account) {
$edit['redirect'] = 'node/123';
}
For Drupal 7
Action --> admin/config/system/actions - Redirect to URL
then enable your trigger module
Trigger --> /admin/structure/trigger/node
if your are trying to login redirect just follow this(select user tab in the page)
go to --> admin/structure/trigger/user
then
Trigger: After a user has logged in
choose an action -->Redirect to URL and assign.
Then clear the cache.
It will work for you!
You can define actions and triggers in Drupal:
Action(admin/settings/actions)
- Redirect to a specific page
Trigger (admin/build/trigger/user)
- After user has logged in
Try this.
EDIT (see comments):
Create a small module to check on a user's login process what role he has and then redirect if neccesary.
drupal_goto => redirect-function in drupal
hook_user =>triggers on user operations
And for the user's roles:
GLOBAL $user;
$roles = $user->roles;
$vendor = in_array('vendor', $roles);
$vendor then holds a true/false value will decide to redirect or not.
If you don't know how to do this, just post here and I'll write the module for you. But this would be a good practice for writing future drupa modules for you perhaps. :)
There are 2 ways in DRUPAL 7
1) Using action and trigger
see this http://drupal.org/node/298506
2)if using custom module
function YOURMODULE_user_login(&$edit, $account) {
if (!isset($_POST['form_id']) || $_POST['form_id'] != 'user_pass_reset' || variable_get('login_destination_immediate_redirect', FALSE)) {
if(in_array('THE-ROLE-WANTED-TO-REDIRECT',$account->roles)):
drupal_goto('PATH');
else: drupal_goto('user/'.$account->uid);
endif;
}
}
You can use Rules
Events: User has logged in.
Condition: User has role
Actions: Page redirect
There are modules that do this (besides Trigger+Actions), such as LoginDestination: http://drupal.org/project/login_destination. This Drupal forum post has a bit more info about it as well.
following condition for hook_user
if($op =='login') drupal_goto("your path");
This can be achieved by using a combination of content access and login toboggan modules. You'll be able to restrict pages and prompt user to login to access them.
First set the conditions in form preprocess (for example I want to redirect only users that logged in using the form at node page)
function YOURMODULE_form_user_login_alter(&$form, &$form_state, $form_id)
{
$pathArguments = explode('/', current_path());
if (count($pathArguments) == 2 && $pathArguments[0] === 'node' && is_numeric($pathArguments[1])) {
$form_state['nodepath'] = current_path();
}
}
than define redirect:
function YOURMODULE_user_login(&$edit, $account)
{
if (isset($edit['nodepath']) && !empty($edit['nodepath'])) {
drupal_goto($edit['nodepath']);
}
}

Resources