WordPress SEO plugin only visible to specific user - wordpress

I am using the Yoast SEO plugin in WordPress and wanted to know if there was a way to make it only visible to one specific user in the db or in the functions.php file? Not a role, an actual user.

I tried an universal solution to simply add "plugin-name" and disable it, but failed.
But, to show WPSEO only to a specific user (ID equals 2), the following works:
add_action( 'plugins_loaded', 'seo_so_25654837' );
function seo_so_25654837()
{
if ( '2' == get_current_user_id() )
return;
remove_action( 'plugins_loaded', 'wpseo_admin_init', 15 );
}
Don't add the code to functions.php, use it as a normal plugin.
The following is also needed to remove the SEO menu from the admin bar:
add_action( 'wp_before_admin_bar_render', 'bar_so_25654837' );
function bar_so_25654837()
{
if ( '2' == get_current_user_id() )
return;
global $wp_admin_bar;
$nodes = $wp_admin_bar->get_nodes();
foreach( $nodes as $node )
{
if( !$node->parent )
{
if( 'wpseo-menu' === $node->id )
$wp_admin_bar->remove_menu( $node->id );
}
}
}

You can hook to pre_current_active_plugins to remove elements from the table before it is displayed. Using get_current_user_id() within the function will let you selectively hide a plugin.
function hide_plugins_by_user( $all_plugins=false ) {
global $wp_list_table;
// if the current user ID is not 1, hide it.
if ( 1 != get_current_user_id() ){
// the active plugins from the table
$plugins = $wp_list_table->items;
// loop through them
foreach ( $plugins as $key => $val ) {
// use the dir + filename of the plugin to hide
if ( $key == 'plugindir/plugin.php' ) {
unset( $wp_list_table->items[$key] );
}
}
}
}
add_action( 'pre_current_active_plugins', 'hide_plugins_by_user' );

This code is working fine (Credits goes to Hislop):
// Returns true if user has specific role
function check_user_role( $role, $user_id = null ) {
if ( is_numeric( $user_id ) )
$user = get_userdata( $user_id );
else
$user = wp_get_current_user();
if ( empty( $user ) )
return false;
return in_array( $role, (array) $user->roles );
}
// Disable WordPress SEO meta box for all roles other than administrator and seo
function wpse_init(){
if( !(check_user_role('seo') || check_user_role('administrator')) ){
// Remove page analysis columns from post lists, also SEO status on post editor
add_filter('wpseo_use_page_analysis', '__return_false');
// Remove Yoast meta boxes
add_action('add_meta_boxes', 'disable_seo_metabox', 100000);
}
}
add_action('init', 'wpse_init');
function disable_seo_metabox(){
remove_meta_box('wpseo_meta', 'post', 'normal');
remove_meta_box('wpseo_meta', 'page', 'normal');
}
Just place it in the functions.php file.

To disable the Yoast for all the users and enable it for just for few or specific, just add the following piece of code to your function.php file.
function remove_wpseo(){
/* if you want to keep it enabled for user with id 2 */
if ( '2' == get_current_user_id() ) {
return;
}
global $wpseo_front;
if(defined($wpseo_front)){
remove_action('wp_head',array($wpseo_front,'head'),1);
}
else {
$wp_thing = WPSEO_Frontend::get_instance();
remove_action('wp_head',array($wp_thing,'head'),1);
}
}
add_action('template_redirect','remove_wpseo');
Reference: https://makersbyte.com/disable-yoast-seo-plugin-specific-page/

Related

How to hide a tag from a download page of Easy Digital Downloads

I created a function to redirect all the products with the tag 'ABC' to a different page (for logged-out users only).
is_singular('download') && has_term(array('ABC'), 'download_tag')
The problem is that logged-in users can still access the page and see the 'ABC' tag in the tags list.
What's the function that I can add to the functions.php file that will only hide the ABC tag specifically?
Thank you
You can hook into get_object_terms to filter terms before they are displayed. Here's an example:
function custom_hide_terms( $terms, $object_ids, $taxonomies, $args )
{
if ( !is_admin() ) {
// note that we are filtering by the term slug, not the term name,
// so be careful with "ABC" versus "abc"
$exclude = array( 'ABC' );
// Loop through terms and remove ABC
if ( $terms ) {
foreach ( $terms as $key => $term ) {
if (is_object($term) && in_array( $term->slug, $exclude ) ) {
unset( $terms[$key] );
}
}
}
}
return $terms;
}
add_filter( 'get_object_terms', 'custom_hide_terms', 10, 4 );

woocommerce conditional email template if product type in order

I try to send a customized email template when a customer has a ticket (custom product type) in cart.
I have the following:
function bc_customer_completed_order_template($template, $template_name, $template_path)
{
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$product = wc_get_product( $cart_item['product_id'] );
$type = get_class($product);
if ( $type == 'WC_Product_Tickets' && 'customer-completed-order.php' === basename($template) ) {
$template = trailingslashit(plugin_dir_path( __FILE__ )) . 'templates/customer-completed-order.php';
}
}
return $template;
}
add_filter('woocommerce_locate_template', 'bc_customer_completed_order_template', 10, 3);
The conditionals are working (on cart and checkout page for example), but when the order is placed, the new template is not used.
Anybody?
Your email template will look like this:
Code snippets:
// Suppose orders don't have ticket products.
$has_tickets = false;
// Loop order items.
foreach ( $order->get_items() as $item_id => $item ) {
// Get product object from order item.
$_product = $item->get_product();
// Check if the product object is valid and the class is `WC_Product_Tickets`
if ( $_product && 'WC_Product_Tickets' === get_class( $_product ) ) {
// Change the flag.
$has_tickets = true;
// Break the loop as we alreay have true flag.
break;
}
}
// Check if order have tickets items.
if ( $has_tickets ) {
// Load custom email template.
wc_get_template( 'templates/custom-customer-completed-order.php' );
// Return as we don't need the below code.
return;
}
It turned out, although the above solution is correct in its idea, in reality one cannot load a template and make use of the $order without extending the woocommerce email class.
Therefore i loaded the function inside the email template itself and made an if - else statement so for situation A the layout is different then for situation b.
Like so:
$has_tickets = false;
// Loop order items.
foreach ( $order->get_items() as $item_id => $item ) {
// Get product object from order item.
$_product = $item->get_product();
// Check if the product object is valid and the class is `WC_Product_Tickets`
if ( $_product && 'WC_Product_Tickets' === get_class( $_product ) ) {
// Change the flag.
$has_tickets = true;
// Break the loop as we alreay have true flag.
break;
}
}
// Check if order have tickets items.
if ( $has_tickets ) {
do_action( 'woocommerce_email_header', $email_heading, $email ); ?>
//custom email layout here//
}
else{
//Regular email template here
}

Detect a screen option change in WordPress Admin

In WordPress code, how can I detect a screen option change? Ie, in the below image I want to hook when one of the column screen options changes. Is there a specific hook for this?
My usecase:
I need to add a screen option to the 'All Posts' page. If the user has unchecked my screen option then the All Posts table should not display posts that have a certain category. I have pretty much all my code for this usecase working (see below) apart from being able to hook/detect when 'My Custom Screen Option' is changed (ticked on or off). If I can do that I can then update the users meta with this decision.
function add_custom_columns( $columns ) {
$columns['display_xyz'] = __( 'XYZ Posts' );
return $columns;
}
add_filter( 'manage_posts_columns', 'add_custom_columns' );
function set_sortable_columns( $columns ) {
$columns['display_xyz'] = 'display_xyz';
return $columns;
}
add_filter( 'manage_edit-post_sortable_columns', 'set_sortable_columns' );
function sort_all_posts( $query ) {
global $current_screen;
// If on 'All Posts' page.
if ( isset( $current_screen ) && is_admin() && $current_screen->id === 'edit-post' && $query->query_vars['post_type'] === 'post' ) {
$show_xyz_posts = get_user_meta( get_current_user_id(), 'display_xyz' );
if ( ! $show_xyz_posts ) {
// Edit $query to not retrieve posts that have a specific category 'xyz'
}
}
}
add_filter( 'parse_query', 'sort_all_posts' );
// How to detect change of my custom screen option so I can hook the below option??
function on_change_screen_option($option, $value) {
if ( $option === 'display_xyz' ) {
update_user_meta( get_current_user_id(), 'display_xyz', $value );
}
}
add_action( '???', 'on_change_screen_option' );

Setting Cookie for Custom URL Parameter - wordpress/woocommerce

I've created a shortcode that always me to use a URL parameter to dynamically swap the featured product on the home page which works well:
// Shortcode to display specific product page via URL - ?myppid=46
// =============================================================================
function ppid_from_query( $atts ) {
$atts = shortcode_atts( array(
'default' => 46
), $atts, 'myppid' );
$pp_id = $atts['default'];
if ( isset( $_REQUEST['ppid'] ) && $_REQUEST['ppid'] != '' ) {
$pp_id = intval( $_REQUEST['ppid'] );
}
return do_shortcode( "[product_page id='".$pp_id."']" );
}
add_shortcode( 'myppid', 'ppid_from_query' );
The challenge I'm having, is that if the user goes to any other page on my site and returns, the URL parameter is gone, and the default product shows up.
I've tried several methods for passing the parameter, but have not succeeded... Even if I had, it would have worked for that session only. In other words, if user leaves site and comes back to primary domain without ?ppid=X, then they won't see that product. So to that end, I've tried setting a cookie per this thread I found (granted it's a bit dated): https://wordpress.stackexchange.com/questions/188749/i-am-looking-to-append-url-parameter-to-all-urls
So in my header, I have:
<script>
if(!isset($_SESSION['ppid']) and $_GET['ppid']){
$cookie_expire = time()+60*60*24*30;
$_SESSION['ppid'] = $_GET['ppid'];
setcookie('ppid', $_SESSION['ppid'], $cookie_expire, '/', '.'.$_SERVER['HTTP_HOST']);
</script>
and in functions:
function wprdcv_param_redirect(){
if(isset($_COOKIE['ppid']) and !$_GET['ppid']){
$location = esc_url(add_query_arg('ppid', $_COOKIE['ppid']));
wp_redirect($location);
}
}
add_action('template_redirect', 'wprdcv_param_redirect');
Still no luck. What am I doing wrong?
The PHP code is processed by the web server and not by the browser. You don't have to set the cookie between the <script> tags. Instead, run it via the Wordpress init hook.
Based on #MattMelton's comment I added the checkout page exclusion in the wprdcv_param_redirect function.
You can optimize your functions like this:
add_shortcode( 'myppid', 'ppid_from_query' );
function ppid_from_query( $atts ) {
$atts = shortcode_atts( array(
'default' => 46
), $atts, 'myppid' );
$pp_id = $atts['default'];
if ( isset( $_REQUEST['ppid'] ) && $_REQUEST['ppid'] != '' ) {
$pp_id = intval( $_REQUEST['ppid'] );
}
return do_shortcode( "[product_page id='".$pp_id."']" );
}
// set the cookie based on the url parameter "ppid"
add_action( 'init', 'set_cookie_based_on_url_parameter_ppid' );
function set_cookie_based_on_url_parameter_ppid() {
if ( ! isset($_SESSION['ppid'] ) && $_GET['ppid'] ) {
$cookie_expire = time()+60*60*24*30;
$_SESSION['ppid'] = $_GET['ppid'];
setcookie('ppid', $_SESSION['ppid'], $cookie_expire, '/', '.'.$_SERVER['HTTP_HOST']);
}
}
add_action('template_redirect', 'wprdcv_param_redirect');
function wprdcv_param_redirect(){
// if it's the checkout page, don't redirect
if ( is_checkout() ) {
return;
}
/*
// if it is the order confirmation page in checkout, please do not redirect
if ( is_checkout() && is_wc_endpoint_url( 'order-received' ) ) {
return;
}
*/
if ( isset($_COOKIE['ppid']) && ! $_GET['ppid'] ) {
$location = esc_url( add_query_arg('ppid', $_COOKIE['ppid']) );
wp_redirect($location);
}
}
The code has been tested and works for me. Add it to your active theme's functions.php.

wordpress show only media user has uploaded in wp_editor

I'm creating a wordpress site where the registered user has the ability to create his own post via wp_editor() on the frontend, but just one post.
Now I want to restrict the user to be able to only see his uploaded media. I use the following script in the functions.php, which works in the backend. So if a user goes to the media section in the backend he will only see his uploaded media.
But if the user goes to "insert media" pop-up on the frontend wp_editor he can still see the uploaded media from all the users.
function restricted_media_view( $wp_query ) {
if ( strpos( $_SERVER[ 'REQUEST_URI' ], '/wp-admin/upload.php' ) !== false
|| strpos( $_SERVER[ 'REQUEST_URI' ], '/wp-admin/edit.php' ) !== false ) {
if ( !current_user_can( 'level_5' ) ) {
global $current_user;
$wp_query->set( 'author', $current_user->id );
}
}
}
add_filter('parse_query', 'restricted_media_view' );
Do you have any idea hot to solve this annoyance? Thank you!
You might try this plugin: http://wordpress.org/extend/plugins/view-own-posts-media-only/
Alternatively try this:
add_action('pre_get_posts','ml_restrict_media_library');
function ml_restrict_media_library( $wp_query_obj ) {
global $current_user, $pagenow;
if( !is_a( $current_user, 'WP_User') )
return;
if( 'admin-ajax.php' != $pagenow || $_REQUEST['action'] != 'query-attachments' )
return;
if( !current_user_can('manage_media_library') )
$wp_query_obj->set('author', $current_user->ID );
return;
}
Source: http://wpsnipp.com/index.php/functions-php/restricting-users-to-view-only-media-library-items-they-upload/#comment-810649773
alternatively since WordPress 3.7
add_filter( 'ajax_query_attachments_args', "user_restrict_media_library" );
function user_restrict_media_library( $query ) {
global $current_user;
$query['author'] = $current_user->ID ;
return $query;
}
I use API/Filter Reference/ajax query attachments args for WP 4.3.1 and works
add_filter( 'ajax_query_attachments_args', 'show_current_user_attachments', 10, 1 );
function show_current_user_attachments( $query = array() ) {
$user_id = get_current_user_id();
if( $user_id ) {
$query['author'] = $user_id;
}
return $query;
}
just add on functions.php
or check this link WP Codex

Resources