Post visibility based on buddypress profile

I am running several custom post types on a website and I have been using a code which hides custom posts from users unless they are logged in and the author of the post. Which is through the code below.

add_filter( 'the_content', 'protect_posts_from_non_author' );

function protect_posts_from_non_author( $content ){
global $post;
$user_id = get_current_user_id();

if( ! isset( $post->post_author ) || $user_id == $post->post_author || !($post->post_type == "post" || $post->post_type =="Singer" || $post->post_type =="Dancer" )) return $content;

return "Sorry, you are not allowed to see this post content";
}

function exclude_category( $query ) {

$user_id = get_current_user_id();

if ( !is_admin() && $query->is_post_type_archive('Singer') ){
$query->set('author', $user_id );
}
if ( !is_admin() && $query->is_post_type_archive('Dancer') ){
$query->set('author', $user_id );
}
}
add_action( 'pre_get_posts', 'exclude_category' );

I have a third custom post type called 'events' which is used to display details of upcoming events for the users that are logged in to see. The event custom post type has a custom field in it to display which profession the event is applicable to, i.e singer, dancer, actor.

As part of my website I'm using buddypress and specifically the extended profile that has a field where users can select their profession type in a checkbox.

Is there any way to adapt the above code to include an option only to show the events custom posts to the users who are logged in based on the profession(s) they have selected in the buddypress extended profile checkbox

i.e if the custom field in the event custom post type is set to 'singer' it only shows the post to users who have selected the 'singer' checkbox in the buddypress profile. and hide the remaining event post types

  • Kasia Swiderska

    Hello Adam,

    So you want now to remove part that shows events posts only for authors of those posts and change it so the users with the same profession will only be able to see posts for them? So all users will be able to see posts depending on whats in the custom field of that post?
    Please let me know if we are on the same page with that and I will see if we can prepare some code for you.

    kind regards,
    Kasia

  • Adam

    The website has 4 different post types in it and still needs to use the code above, I just needed to add to the code to filter the next set of custom post types.

    the native post type which is used for the blog on the website which is viewable to everyone who visits the site irrespective of whether or not they are logged in.

    custom post type A which is only visible to the author of the post when they are logged in, and uses the code above
    custom post type B which is only visible to the author of the post when they are logged in, and uses the code above

    I now need to add custom post type C which will only be visible to logged in users if it's custom field entry matches the entry in the users profile

    The buddypress profile has a checkbox field in it for profession which the user can select their profession which at the moment is
    Singer
    Dancer
    Actor
    Model

    The custom field in the custom post type C has the same four values as options in the buddypress profile so the idea being if the custom field entry and profile entry match the post is shown if not it's hidden.

    Hopefully the way I have explained it makes sense.

  • Panos

    Hi Adam ,

    You can use buddypress' function bp_get_member_profile_data:
    bp_get_member_profile_data( 'field=Profession' )

    I have created a custom mu-plugin which creates a CPT reports and has these 4 meta values in a meta box (Allowed Professions). In function protect_posts_per_profession you can see how this is handled :slight_smile:

    Please download attached file, unzip it and upload it to your wp-content/mu-plugins folder (you can create it if it doesn't exist). Then create new Report, add some text and test the output when changing the Professions for report and user.

    Hope this helps!

    Kind regards,
    Panos

  • Panos

    Hi Adam!

    This was mostly intended as an example to demonstrate the use of bp function:
    bp_get_member_profile_data( 'field=Profession' )

    I have attached another version which should be fixing the warning message.

    As for the filtering, you need to make sure that in Users > Profile Fields you have created a field "Profession" with the 4 options Actor, Dancer, Singer and Model as you mentioned. If they are spelled differently it might not work.

    In case you still have issues could you please enable support access so we can have a look in the BP settings?

    Thanks!
    Panos

  • Adam

    This is where I've got to, I took the bit that seemed to be the filtering part and put it in the existing plugin for filtering. I know get an error,
    Fatal error: Cannot use isset() on the result of an expression (you can use "null !== expression" instead)

    This is the code as it stands that I'm using, where am I going wrong?

    <?php
    /**
    * Plugin Name: Hide posts from non author
    * Description: Filters posts shown on BuddyPress profiles
    * Version: 1.0.0
    * License: GPLv2
    */

    add_filter( 'the_content', 'protect_posts_from_non_author' );

    function protect_posts_from_non_author( $content ){
    global $post;
    $user_id = get_current_user_id();
    //if( ! isset( $post->post_author ) || $user_id == $post->post_author || !( $post->post_type == "post" ) ) return $content;

    if( ! isset( $post->post_author ) || $user_id == $post->post_author || !($post->post_type == "post" || $post->post_type =="photoshoot" || $post->post_type =="model_download" )) return $content;

    return "Sorry, you are not allowed to see this post content";
    }

    if( !isset( $post->post_type == "casting Calls") || !(function_exists( 'bp_member_profile_data' ))) return $content;

    $error_msg = 'Sorry, you are not allowed to see this post content';

    if( ! is_user_logged_in() ) return $error_msg;

    $allowed_professions = get_post_meta( $post->ID, 'Shooting_Level', true );

    $user_professions = explode( ',', bp_get_member_profile_data( 'field=Modelling Levels' ) );

    $allowed_to_view = false;
    foreach( $user_professions as $user_profession ){

    if( in_array( strtolower( trim( $user_profession ) ), $allowed_professions ) ) $allowed_to_view = true;

    }

    if( $allowed_to_view ) return $content;

    return $error_msg;

    function exclude_category( $query ) {

    $user_id = get_current_user_id();

    if ( !is_admin() && $query->is_post_type_archive('photoshoot') ){
    $query->set('author', $user_id );
    }
    if ( !is_admin() && $query->is_post_type_archive('model_download') ){
    $query->set('author', $user_id );
    }
    }
    add_action( 'pre_get_posts', 'exclude_category' );

  • Panos

    Hi Adam ,

    I notice there are some differences in the post types and bp field values and can't be sure where the issue occurs.

    Could you provide ftp and admin access so I can have a closer look on settings and code? You can send that privately through our contact form: https://premium.wpmudev.org/contact/

    Select "I have a different question?" for your topic - this and the subject line ensure that it gets assigned to me.

    Send in:Subject: "Attn: Panos Lyrakis"

    - Admin login:
    Admin username
    Admin password
    Login url

    - FTP credentials
    host
    username
    password
    (and port if required)

    - link back to this thread for reference: https://premium.wpmudev.org/forums/topic/post-visibility-based-on-buddypress-profile

    Also please mention in which file you have added your custom code (eg on your theme's functions.php, a custom plugin or a mu-plugin).

    Thanks!
    Panos

  • Panos

    Hi Adam ,

    Apologies for delay here! Thanks for sending your info :slight_smile:

    I would like to note that these kind or requests exceed the purpose of our support as they require some custom coding. You can post a job at our Jobs board where you can hire a skilled professional for this job. Keep in mind that developers on our jobs section are not employed by WPMUDEV.

    However, since I enjoy some codding, I have gone forward and made some modifications on the "Hide_non_author.php" file. It adds a metabox at the "casting_calls" posts, which informs (doesn't provide checkboxes only displays the professions allowed ) which professions will be able to view this post based on post authors "Modelling Levels". In front end it should allow to view content if user viewing post has required "Modelling Levels" set.

    I am posting the code here just in case it might help other members:

    if( !class_exists( 'WPMUDEV_bp_cpt' ) ){
    
        class WPMUDEV_bp_cpt{  
    
            private static $_instance = null;
            public static $post_type = null;
    
             public static function get_instance() {
                if ( is_null( self::$_instance ) ) {
                    self::$_instance = new WPMUDEV_bp_cpt();
                }
    
                return self::$_instance;
            }
    
    		private function __construct() {
    
                self::$post_type = apply_filters( 'bb_cpt_post_type', 'casting_calls' );
    
                add_action( 'init', array( $this, 'meta_boxes' ), 1 );
    
                add_filter( 'the_content', array( $this, 'protect_posts_per_profession' ) );
    
            }
    
    		public function meta_boxes(){
    
                add_action( 'add_meta_boxes_' . WPMUDEV_bp_cpt::$post_type, array( $this, 'casting_calls_meta_boxes' ) );
    
            }
    
            public function casting_calls_meta_boxes( $post ){
    
                 add_meta_box(
                    'casting_calls-professions',
                    __( 'Allowed Professions', 'some-text-domain' ),
                    array( $this, 'casting_calls_professions' ),
                    $post->post_type,
                    'side',
                    'core'
                );
    
            }
    
    		public function casting_calls_professions( $post ){
    
                wp_nonce_field( 'report_meta_box_nonce', 'r_meta_box_nonce' );
    
    			$args = array(
    				'field'   => 'Modelling Levels',
    				'user_id' => $post->post_author
    			);
    			$user_professions = explode( ',', bp_get_member_profile_data( $args ) );
    
                ?>
    			<div class="wpmudev-casting_calls-professions">
    				<strong><?php _e( 'This casting call will be visible to: ', 'some-text-domain' ); ?></strong>
    				<?php
    				$oust = '';
    				foreach( $user_professions as $user_profession ){
    					ob_start();
    					?>
    					<div class="casting_call_wrap">
    						<span class="casting_call"><i class="dashicons dashicons-yes"></i> <span><?php _e( $user_profession ); ?></span></span>
    					</div>
    					<?php
    					$out .= ob_get_clean();
    				}
    
    				echo $out;
    				?>
    			</div>
                <?php
            }
    
    		public function protect_posts_per_profession( $content ){
    
                global $post;
    
                if( !isset( $post->post_type ) || $post->post_type != WPMUDEV_bp_cpt::$post_type || ! function_exists( 'bp_member_profile_data' ) ) return $content;
    
                $error_msg = 'Sorry, you are not allowed to see this post content';
    
                if( ! is_user_logged_in() ) return $error_msg;
    
    			$args = array(
    				'field'   => 'Modelling Levels',
    				'user_id' => $post->post_author
    			);
    			$allowed_professions = explode( ',', bp_get_member_profile_data( $args ) );
    			$allowed_professions = array_map('trim',$allowed_professions);
    			$allowed_professions = array_map('strtolower',$allowed_professions);
    
                $user_professions = explode( ',', bp_get_member_profile_data( 'field=Modelling Levels' ) );
    
                $allowed_to_view = false;
                foreach( $user_professions as $user_profession ){
    
                    if( in_array( strtolower( trim( $user_profession ) ), $allowed_professions ) ) $allowed_to_view = true;
    
                }
    
                if( $allowed_to_view ) return $content;
    
                return $error_msg;
            }
    
    	}
    
    	function WPMUDEV_bp_cpt_init(){
    		$GLOBALS['WPMUDEV_bp_cpt'] = WPMUDEV_bp_cpt::get_instance();
    	}
    
    	add_action( 'plugins_loaded', 'WPMUDEV_bp_cpt_init' );
    
    }

    Hope this helps and please feel free to ask if you need some tweaking on the code :slight_smile:

    Thanks!
    Panos

  • Adam

    Thanks for your help, the code works brilliantly. The only problem with it I've run into and this may not even be possible to do, If a user sets up their profile and ticks more than one checkbox, then they cannot see any posts that are checked with just one checkbox.

    For example if the users checks they are a singer and actor and the casting only checks actor they can't see the post, the only posts they can see are the ones that check both actor and singer.

    I've attached a graphic representation of what I'm talking about if it makes it clearer

    No worries if it's not something that can be done.

  • Panos

    Hi Adam ,

    I think it's possible to do that. I tried connecting with ftp credentials you have previously sent and can't connect.

    Could you please check or send new ones? You can send them as a reply to your previous email message, or you can send a new one and in subject add "Attn: Panos Lyrakis" so it gets assigned to me.

    You can also send me the file and I can modify it on my test site and resend it to you. In this case you can simply compress it (.zip) and attach it here in your reply.

    Cheers!
    Panos

  • Nithin

    Hi Adam,

    Hope you are doing good today. :slight_smile:

    I checked your FTP credentials, and they are working fine, thank you for sending the info. However, the dashboard login you provided doesn't work, since the support access is enabled it should be more than enough at the moment. I'm pinging Panos, and will ask to give a look at this, and keep you posted asap. Have a nice day. :slight_smile:

    Kind Regards,
    Nithin