I want to add a capability to one of the default roles in WordPress. The add_cap article advises people to do this sort of thing on theme activation because the setting is saved to the database:
NB: This setting is saved to the database, so it might be better to run this on theme/plugin activation
The function I intend to use is:
function add_theme_caps() {
$role = get_role( 'author' );
$role->add_cap( 'edit_others_posts' );
}
add_action( 'admin_init', 'add_theme_caps');
As you can see, I'm currently hooking to admin_init, which causes the function to be run each time the admin area is accessed. How can I run the function on theme activation only?
You can use after_switch_theme . It will affect only your theme, of course.
http://codex.wordpress.org/Plugin_API/Action_Reference/after_switch_theme
I feel you should try something like this
if ( is_admin() && isset($_GET['activated'] ) && $pagenow == "themes.php" ) {
$role = get_role( 'author' );
$role->add_cap( 'edit_others_posts' );
}
Related
Following the woocommerce documentation, I added an endpoit to my-account page in woocommerce.
I want to make this endpoint visible only to a specific user role, lets say shop_manager.
Is there a way to redirect to a 404 page users who try to access directly that endpoint?
Thanks in advance.
Assuming that you have already created a custom endpoint to my account section (see this related answer), you can redirect all non allowed user roles to a specific page using template_redirect hook in this simple way:
add_action( 'template_redirect', 'custom_endpoint_redirection' );
function custom_endpoint_redirection() {
$allowed_user_role = 'administrator';
$custom_endpoint = 'my-custom-endpoint';
if ( is_wc_endpoint_url($custom_endpoint) && ! current_user_can($allowed_user_role) ) {
$redirection_url = home_url( '/404/' );
wp_redirect( $redirection_url );
exit;
}
}
You need to specify your custom end point, your allowed user role and the url redirection.
Code goes in functions.php file of your active child theme (or active theme). It could works.
Related:
WooCommerce - Assign endpoints to multiple custom templates in my-account page
WooCommerce: Assigning an endpoint to a custom template in my account pages
WooCommerce: Adding custom template to customer account pages
Custom my account new menu item for a specific user role in Woocommerce
Just add the follows code snippet in your active theme's functions.php and this is only for administrator user role, you can change it as per you -
function add_custom_my_account_endpoint() {
add_rewrite_endpoint( 'shop_manager', EP_PAGES );
}
add_action( 'init', 'add_custom_my_account_endpoint' );
function add_custom_wc_menu_items( $items ) {
$user = wp_get_current_user();
if( $user && in_array( 'administrator', $user->roles ) ){
$items[ 'shop_manager' ] = __( 'Shop Manager', 'text-domain' );
}
return $items;
}
add_filter( 'woocommerce_account_menu_items', 'add_custom_wc_menu_items' );
function add_shop_manager_endpoint_content(){
$user = wp_get_current_user();
if( $user && !in_array( 'administrator', $user->roles ) ) return;
echo "Your content goes here";
}
add_action( 'woocommerce_account_shop_manager_endpoint', 'add_shop_manager_endpoint_content' );
After this just flush_rewrite_rules from Backend Settings > Permalinks. Thats it.
I'm currently using Foobox lightbox (free) plugin, and apparently the plugins' files are loaded on every page regardless of whether it's used or not. However I would like to change this, but I can't seem to find any handles to dequeue the scripts through.
It seems that the scripts are called by the code beneath, which to me at least, doesn't show any handles. I've tried using remove_action(...) to "counter" them as well as various inputs in wp_dequeue_script() to try and target the files directly - e.g. wp_dequeue_script('foobox.free.min.js')
class Foobox_Free extends Foo_Plugin_Base_v2_1 {
const JS = 'foobox.free.min.js';
const CSS = 'foobox.free.min.css';
const CSS_NOIE7 = 'foobox.noie7.min.css';
const FOOBOX_URL = 'http://fooplugins.com/plugins/foobox/?utm_source=fooboxfreeplugin&utm_medium=fooboxfreeprolink&utm_campaign=foobox_free_pro_tab';
const BECOME_AFFILIATE_URL = 'http://fooplugins.com/affiliate-program/';
private static $instance;
public static function get_instance() {
if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Foobox_Free ) ) {
self::$instance = new Foobox_Free();
}
return self::$instance;
}
/**
* Initialize the plugin by setting localization, filters, and administration functions.
*/
private function __construct() {
//init FooPluginBase
$this->init( FOOBOXFREE_FILE, FOOBOXFREE_SLUG, FOOBOX_BASE_VERSION, 'FooBox FREE' );
if (is_admin()) {
add_action('admin_head', array($this, 'admin_inline_content'));
add_action('foobox-free-settings_custom_type_render', array($this, 'custom_admin_settings_render'));
new FooBox_Free_Settings();
add_action( FOOBOX_ACTION_ADMIN_MENU_RENDER_GETTING_STARTED, array( $this, 'render_page_getting_started' ) );
add_action( FOOBOX_ACTION_ADMIN_MENU_RENDER_SETTINGS, array( $this, 'render_page_settings' ) );
add_action( 'admin_notices', array( $this, 'admin_notice_foogallery_lightboxes' ) );
add_action( 'wp_ajax_foobox_foogallery_lightboxes_ignore_notice', array( $this, 'admin_notice_foogallery_lightboxes_ignore' ) );
add_action( 'wp_ajax_foobox_foogallery_lightboxes_update', array( $this, 'admin_notice_foogallery_lightboxes_update' ) );
add_action( 'admin_print_scripts', array( $this, 'admin_notice_foogallery_lightboxes_inline_js' ), 999 );
add_filter( 'foobox-free-has_settings_page', '__return_false' );
} else {
// Render JS to the front-end pages
add_action('wp_enqueue_scripts', array($this, 'frontend_print_scripts'), 20);
add_action('foobox-free_inline_scripts', array($this, 'inline_dynamic_js'));
// Render CSS to the front-end pages
add_action('wp_enqueue_scripts', array($this, 'frontend_print_styles'));
if ( $this->is_option_checked('disable_others') ) {
add_action('wp_footer', array($this, 'disable_other_lightboxes'), 200);
}
}
}
How, if possible, do I dequeue these scripts (and styles) without editing the plugin file directly?
Edit
Below I've added the things I've tried doing to remove the scripts (all added to functions.php):
add_action( 'wp_enqueue_scripts', 'remove_foobox_scripts', 100 );
function remove_foobox_scripts() {
if ( !is_page('my-page') ) {
wp_deregister_script( 'foobox.free.min.js' );
wp_dequeue_script( 'foobox.free.min.js' );
}
}
Also tried the below, which is just a straight copy from the foobox file:
remove_action('wp_enqueue_scripts', array($this, 'frontend_print_scripts'), 20);
remove_action('foobox-free_inline_scripts', array($this, 'inline_dynamic_js'));
remove_action('wp_enqueue_scripts', array($this, 'frontend_print_styles'));
Also tried the below, where the array( part is removed:
remove_action('wp_enqueue_scripts','frontend_print_scripts', 20);
remove_action('foobox-free_inline_scripts', 'inline_dynamic_js');
remove_action('wp_enqueue_scripts', 'frontend_print_styles');
The problem with the way you are trying to do this stems from the order in which things happen in Wordpress.
You are relying on the conditional tags like is_page('my-page') to determine whether or not to load the plugin. These conditional tags do not become available until Wordpress has parsed the URL for the current query, and at this point all the plugins and your theme have already been loaded. Even if you parse the URL yourself instead of using the conditional tags you cannot be sure your code will run before the plugins are loaded.
The solution is to add your code as an mu-plugin. These are loaded before normal plugins so you can use an option (option name) filter here to alter the plugins you want to be loaded.
Option filters pass an array to your function containing the values which are set for that option, so in this case you want to hook option_active_plugins.
You can find the values to use for by running print_r(get_option('active_plugins')); or look through the plugins folder of your wordpress install.
The following example is specific to your question, but you could modify it to make a more comprehensive set of rules, adding and removing multiple plugins on different pages based on many conditions.
My function checks you are not in wp-admin and then has 2 conditions. The first disables a normally active plugin on the specified pages, the second enables a normally disabled plugin on the specified pages.
<?php
add_filter( 'option_active_plugins', 'add_or_remove_plugins' );
function add_or_remove_plugins( $plugins ) {
if (strpos( $_SERVER['REQUEST_URI'], '/wp-admin/' ) !== 0) { // Disable in admin pages or admin plugin settings stop working properly
if (strpos( $_SERVER['REQUEST_URI'], '/remove-plugin-here/' ) === 0) { // Conditonal tags still unavailable so you have to parse urls yourself
$k = array_search( 'foobox-image-lightbox/foobox-free.php', $plugins ); // This will stop an active plugin from loading
if( false !== $k ){
unset( $plugins[$k] );
}
}
if (strpos( $_SERVER['REQUEST_URI'], '/add-plugin-here/' ) === 0) {
$plugins[] = 'foobox-image-lightbox/foobox-free.php'; // This will load the plugin along with all the active plugins
}
}
return $plugins;
}
?>
To install just change the values to suit, paste into a file and upload into your mu-plugins folder
EDIT
Looks like your inline js is added to wp_head during the constructor of the Foobox_Free class. You could try adding this to your functions.php:
add_action( 'wp_head', 'remove_dynamic_js' );
function remove_dynamic_js(){
$foo = Foobox_Free::getInstance();
remove_action('wp_head', array($foo, 'inline_dynamic_js'));
}
or if that doesn't work then maybe this:
add_action( 'wp_head', 'remove_dynamic_js' );
function remove_dynamic_js(){
remove_action('wp_head', array('Foobox_Free', 'inline_dynamic_js'));
}
The action is added inside a private function, so I don't know if either of those will actually work. Give it a shot. If not my first answer will as it stops the plugin from loading at all on the specified pages.
UPDATE
Well, I was close... Here's the code to remove the scripts, as supplied by the plugin author.
$foobox = Foobox_Free::get_instance();
remove_action('foobox-free_inline_scripts', array($foobox, 'inline_dynamic_js'));
I need to detect when user goes to :
Plugins -> Installed Plugins and Appearance -> Themes
in wordpress admin.
Something like :
add_action("core_upgrade_preamble", "action_core_upgrade_preamble")
You have 2 options:
Option 1:
Use the callback $hook, first get the $hook of the page using this:
function load_custom_wp_admin_style($hook) {
var_dump($hook);
}
add_action( 'admin_init', 'load_custom_wp_admin_style' );
Check your page in the browser you should get the string name, then you can use:
function load_custom_wp_admin_style($hook) {
// Load only on my specific page
if($hook != 'page_hook_i_got') {
return;
}
//DO MY LOGIC
}
add_action( 'admin_init', 'load_custom_wp_admin_style' );
Option 2:
Use get_current_screen();
add_action( 'current_screen', 'this_screen' );
function this_screen() {
$current_screen = get_current_screen();
if( $current_screen ->id === "widgets" ) {
// Run some code, only on the admin widgets page
}
}
you will need to do a var_dump to find the id of the page, like in option 1, you can find more info here.
For my website I’m using the plugin Woocommerce Variations to Table Grid, but I would like to restrict this one only for some roles ‘Administrator’ and ‘wholesaler’. (my website is for wholesalers and ‘normal’ customer)
Anyway I was thinking to just desactivate the plugin by checking the user role so I tried the following solution : https://wordpress.stackexchange.com/questions/159085/deactivate-plugin-for-a-specific-user-group
Doesn’t work.
I’ve got a variable in my plugin called $vartable_disabled which is a boolean which “Disable globally” the plugin.
So I am thinking to do something in my functions.php like:
add_action('admin_init', 'my_option_change_plugins');
function my_option_change_plugins()
{
global $current_user;
if (!in_array('administrator' || 'wholesaler', $current_user->roles)) {
deactivate_plugins( // activate for variation-table
$vartable_disabled == 0
$vartable_position == 'under'
);
} else { // desactivate for those than can't use it
activate_plugins(
$vartable_disabled == 1
$vartable_position == 'side'
);
}
But for sure I’m doing something wrong, I tried plenty of different thing the whole day, impossible to figure it out.
Anyone can help?
Cheers 🙂
deactivate_plugins is need. base plugin name. But you are passing variables.
https://codex.wordpress.org/Function_Reference/deactivate_plugins
I found a partial solution with the function "update_option()"
add_action('admin_init', 'my_filter_the_plugins');
function my_filter_the_plugins()
{
global $current_user;
if (in_array('administrator', $current_user->roles)) {
update_option( 'vartable_disabled', 0 );
} else { // activate for those than can use it
update_option( 'vartable_disabled', 1 );
}
}
With that my plugin option switch to '1' (disabled).. but the thing is, it doesn't matter the role as it always go only for the first line..
I'm a bit lost, I don't understand why it works in one way but not the other.
My plugin fonction is:
if ( ((get_post_meta($product->id, 'disable_variations_table', true) == 1 || !empty($checkcat)) || $vartable_disabled == 1) && $vartable_shortcd != 1) {
// Enqueue variation scripts
wp_enqueue_script( 'wc-add-to-cart-variation' );
// Load the template
wc_get_template( 'single-product/add-to-cart/variable.php', array(
'available_variations' => $product->get_available_variations(),
'attributes' => $product->get_variation_attributes(),
'selected_attributes' => $product->get_variation_default_attributes()
) );
return;
}
I think there's a little misunderstanding of a point. A plugin can't be activated for an user and deactivated for another one (in the pure concept of Plugin Activation/Deactivation). It is globally activated or globally deactivated.
Said this, depending on the way that your plugin is programmed, its functions could be disabled to certain users or groups. Instead keeping trying the deactivation method you can, for example, find the parts where your plugin admits to be filtered and take advantage of that. If there is not filters, you can try:
$current_user = wp_get_current_user();
if ( !in_array( array( 'administrator' , 'wholesaler' ) , (array) $current_user->roles ) ) {
update_option( 'vartable_disabled' , 1 ); // Assuming 'vartable_disabled' parameter really disables the plugin for the current user
}
In addition, alike you can hide all the html related to that option (checkboxes, menu elements and others).
It finally didn't work as expected because to change an option you need kind of "administrator" rights, so for the other roles like "customer" it didn't change the option as expected.
Anyway, instead I worked with the plugin developer (thanks Spyros) and the solution has been to hook directly in the plugin (functionnality now added to the new plugin version ;))
The following code has been added:
// if the table is disabled for this product display the default select menus
$checkcat = array();
if (is_array($vartable_categories_exc) && is_array($pcids)) {
$checkcat = array_intersect($pcids, $vartable_categories_exc);
}
$checkrole = array();
if (is_array($vartable_roles_exc) && is_user_logged_in()) {
$user_info = get_userdata(get_current_user_id());
$checkrole = array_intersect($user_info->roles, $vartable_roles_exc);
}
if (!is_user_logged_in() && is_array($vartable_roles_exc) && in_array('guest', $vartable_roles_exc)) {
$checkrole['guest'] = 'guest';
}
if (
((get_post_meta($product->id, 'disable_variations_table', true) == 1 || !empty($checkcat)) || $vartable_disabled == 1 || !empty($checkrole))
&& get_post_meta($product->id, 'disable_variations_table', true) != 2
&& $vartable_shortcd != 1) {
// Enqueue variation scripts
wp_enqueue_script( 'wc-add-to-cart-variation' );
// Load the template
wc_get_template( 'single-product/add-to-cart/variable.php', array(
'available_variations' => $product->get_available_variations(),
'attributes' => $product->get_variation_attributes(),
'selected_attributes' => $product->get_variation_default_attributes()
) );
return;
}
Thanks everyone for your time/help.
I would like to do that only administrator(role) allow to login with wp-admin not any other role, other uses like(editor,author) are login from front end and it's working fine but i would like only administrator can login through wp-admin.
I have used ultimate member plug in for front end login.
Ultimate Plugin link
also i have used below code for access wp-admin only for administrator(role) but it's not working.
<?php
function restrict_admin(){
//if not administrator, kill WordPress execution and provide a message
if( !current_user_can('administrator') ) {
wp_die( __('You are not allowed to access this part of the site') );
}
}
add_action( 'admin_init', 'restrict_admin', 1 );
?>
Thank you guys for your help, I am answering my own question hope this will help others too.
I have referred this link https://developer.wordpress.org/reference/functions/wp_authenticate/
I have solved this with hook wp_authenticate
add_action( 'wp_authenticate' , 'check_custom_authentication' );
function check_custom_authentication ( $username ) {
$username;
$user = new WP_User($username);
$user_role_member=$user->roles[0];
if($user_role_member == 'author' || $user_role_member == 'editor'){
session_destroy();
wp_redirect( home_url() );
exit;
}
}
add_action( 'admin_init', 'redirect_none_admin' );
function redirect_none_admin(){
if(is_admin() && current_user_can(activate_plugins)){
//...
}else{
wp_redirect(home_url());
}
}
i tested this one and it worked i think it is simple and easy
you can find Roles and Capabilities here
If anyone will need the same here is code that allows only administrators, authors and editors to login using /wp-login.php
//------------- This website is read only - so only staff can log in -------------
add_filter( 'authenticate', 'myplugin_auth_signon', 30, 3 );
function myplugin_auth_signon( $user, $username, $password ) {
$user_role_member=$user->roles[0];
if(!in_array($user_role_member,array('administrator','author','editor'))){
wp_logout();
return new WP_Error( 'broke', __( "This website is read only for regular users", "your_wp_domain_name" ) );
exit;
}else{
return $user;
}
}
//------------- this website is read only - so staff can log in ------------------
You can add\remove roles in the array above array('administrator','author','editor')
Try this
add_action( 'admin_init', 'redirect_non_admin_users' );
/**
* Redirect non-admin users to home page
*
* This function is attached to the 'admin_init' action hook.
*/
function redirect_non_admin_users() {
if ( is_admin() !== false) {
wp_redirect( home_url() );
exit;
}
}