Query Protected Content Status

I'd like to query in the loop whether or not a post is protected content. Then, if false, I'd like to show an "unlocked" icon.
Is there a hook I can query to determine this? Can you provide some documentation?
Thanks.

    Denitsa

    Hello Mike,
    I hope you are having a fantastic day!

    I think you might give the 'post_class' hook a try here. You can also try taking look at a solution posted to a similar thread found here for reference and ideas:
    https://premium.wpmudev.org/forums/topic/add-class-depending-if-content-is-protected#post-1080356

    You can check the API documentation for the Membership 2 by going to Membership 2 -> Help -> API Docs.

    I hope this helps! Tell me if this doesn't work for you, so I can call in one of our developers here to give a better idea.

    All the best,
    Denitsa

    Mike

    I've checked out post_class() but it doesn't seem to return a class that refers to whether or not it is a protected post. For instance, for one post it returns:
    class="post-6892 post type-post status-publish format-standard hentry category-chicago tag-dean-angelo tag-lori-lightfoot tag-sharon-fairley posttype-articles topics-budget-committee topics-committee-on-public-safety homepost-home-one"

    category, tag, posttype, topics and homepost are obviously not it (most of those are generated by our system). Is there something else I should be looking for?

    Denitsa

    Hello Mike,

    I've pinged our SLS (second level support) team for their feedback on this one, since they're our coding masters and can give us best idea regarding this.

    Please keep in mind that those guys work round the clock and they have to deal with lots of critical issues and other things. So it may take a little while for them to check this and post back.

    I appreciate your patience on this one!

    Have a nice day!

    Warm regards,
    Denitsa

    Mahlamusa

    Hello Mike,

    I hope you are doing great today and I am sorry for the delayed response from our end, things have always been busy.

    I see that my colleague Denitsa has given you some directions as to what to try, I hope that it has gone well. To answer your question about what hooks to use to achieve that, unfortunately there are no simple hooks but after searching and reading the forum and the code of the plugin I was able to come up with the following solution. You can paste the following code in your theme's functions.php file:

    Here is the code:

    add_filter( 'the_content', 'check_protected_and_add_icon' );
    function check_protected_and_add_icon( $content) {
        $post_id = get_the_ID();
        $memberships = MS_Model_Membership::get_memberships();
        $available_for = array();
    
        foreach ( $memberships as $membership ) {
            $rule = $membership->get_rule( MS_Rule_Post::RULE_ID );
            if ( true === $rule->has_access( $post_id ) ) {
                $available_for[$membership->id] = $membership->name;
            }
        }
    
    	//icons as images or you can use a font icon
    	$icon_locked 	= '<img src="http://yourwebsite.com/assets/lock.png" />';
    	$icon_un_locked = '<img src="http://yourwebsite.com/assets/lock-open.png" />';
    
    	//if protected display locked icon, if not protected display unlokced icon
    	if ( !empty( $available_for ) && $available_for != "" ){
    		return $icon_locked . $content;
    	}else{
    		return $icon_un_locked . $content;
    	}
    }

    You may paste the code as it is in your theme's functions.php or create a new .php file and paste the code in to the file, at the top of the file add the PHP opening tag and the add the above code below the PHP tag as follows:

    <?php
    //the rest of the code

    Please remember to change 'http://yourwebsite.com/assets/' with the actual url to the location of your icons and make sure you are referencing the correct file names for your icons. You will then use CSS to style the images, or you can simply use the icons used by your theme if it uses Bootstrap or Font Awesome

    I hope that helps. Please let us know if you have any questions or concerns with regards to this. Please enjoy your day further.

    Cheers,
    Mahlamusa

    Mahlamusa

    Hi Mike,

    Sorry I forgot to mention that if you choose not to use the code in your theme's functions.php file as this may be overwritten by future updates, you my alternatively create a new file like 'icons-for-protected-content.php' add the PHP opening tag and the rest of the code above as follows:

    <?php
    //all the code pasted above goes here

    Save the file and upload it to your website on the folder:
    /wp-content/mu-plugins/
    If the folder 'mu-plugins' does not exist, you should just create it. So after that you will have the file in the location:

    /wp-content/mu-plugins/icons-for-protected-content.php

    That way, your code will be safe when WordPress or plugins and themes are updated.

    Cheers,
    Mahlamusa

    Mahlamusa

    Hi Mike.

    I hope you are doing great today and I am glad I could help. But Unfortunately, I would not know what you can hook to if because I do not know how your theme is designed and what WordPress functions you use on your theme.

    If you are using the built in Wordpress Loop, it should be easier for you to apply a filter on the content, but if you are building a custom loop, you may want to try to use the function 'check_protected_and_add_icon( $content)' directly in the code of your template files. I think the following may be helpful to you.

    1. Modify the function above so that instead of appending the icon to the '$content' it just returns the icon itself. Place the newly modified function into your theme's functions.php, it should look as follows:

    function check_protected_and_add_icon() {
        $post_id = get_the_ID();
    	//the rest of the code as it is	
    
    	//then right at the end, return the markup of the icon
    	$icon_locked 	= '<img src="http://yourwebsite.com/assets/lock.png" />';
    	$icon_un_locked = '<img src="http://yourwebsite.com/assets/lock-open.png" />';
    	if ( !empty( $available_for ) && $available_for != "" ){
    	 	return $icon_locked;
    	}else{
    	 	return $icon_un_locked;
    	}
    }

    2. Modify any of your theme's template files (should be those displaying single posts or pages) so that it calls the function and displays the icon anywhere you choose on the page. If you want this to apply on Posts then you should add the post to 'single-post.php' or 'single-{custom-post-type}.php, so if you want it on custom post types you can add it on 'single-product.php' if you have a products post type, otherwise 'single,php' will do the job just fine if your theme does not have specific templates.

    Add the code anywhere in your markup where you want to show the icon:

    <?php echo check_protected_and_add_icon();?>
    And that should display the icon for you, for example: you can place it before the post title like so:

    <h1><?php echo check_protected_and_add_icon();?> <?php the_title(); ?></h1>

    Now that should do it for single post pages, you should be able to apply it on the archives as well but you should have a fair understanding of how the theme works. In some themes that use template parts, you can apply it to archives just by modifying the single-{post-type}.php file, in some you will have to modify the archives templates one by one, please check your theme before doing such.

    Note: I have recommended (it it is always recommended) to use filters instead of instead of modifying your theme, especially if you will be receiving updates for your theme. But if its a custom theme that you control then you can build it as you want without.

    I hope that helps, please feel free to let us know if you have any trouble with regards to this. I hope you enjoy the rest of your day.

    Cheers,
    Mahlamusa

    Mike

    Mahlamusa-

    Thanks. I got most of it, I was missing "echo" from the function call in the loop. However, the function does not seem to be working properly. It does return a value for locked, but not unlocked, when I disable protection for an article. I even tried creating a new article, that has never had protection set, and it still returns a lock. Here is what I have placed in functions.php:

    // Lock and unlocked icon for articles
    function check_protected_and_add_icon() {
       $post_id = get_the_ID();
       $memberships = MS_Model_Membership::get_memberships();
       $available_for = array();
    
    // check to see if protected
       foreach ( $memberships as $membership ) {
           $rule = $membership->get_rule( MS_Rule_Post::RULE_ID );
           if ( true === $rule->has_access( $post_id ) ) {
               $available_for[$membership->id] = $membership->name;
           }
       }
    
    	//icons as images or you can use a font icon
    	$icon_locked 	= '<i class="fa fa-lock" aria-hidden="true"></i>';
    	$icon_un_locked = '<i class="fa fa-unlock" aria-hidden="true"></i>';
    
    	//if protected display locked icon, if not protected display unlokced icon
    	if ( !empty( $available_for ) && $available_for != '' ){
    		return $icon_locked;
    	}else{
    		return $icon_un_locked;
    	}
    }

    Any ideas?

    Mahlamusa

    Hi Mike,

    I hope you are doing great today. I am so sorry that the code is not working as it should. Can you please check the following:

    MS_Rule_Post::RULE_ID
    This line is only intended for posts, and if you are protecting using other rules then you should rewrite the code to loop through all the protection rules that you use, here are the ones you should try:

    MS_Rule_Post::RULE_ID //for posts
    MS_Rule_Page::RULE_ID //for pages
    MS_Rule_CptItem::RULE_ID //for custom post types

    Also check the value that you are returning by manually reading the line of code that holds the value. I have checked the Font Awesome reference, the following line seems correct.

    <i class="fa fa-unlock" aria-hidden="true"></i>

    Can you also try to

    echo implode(",",$available_for);

    To see the list of available memberships protecting that particular page . Also try changing the check:

    if ( !empty( $available_for ) && $available_for != '' ){

    into this:

    if (is_array( $available_for ) ){

    And see what happens. Can you also please share the pages you are working on, one that should be locked and one that should be unlocked. I want to check if anything gets displayed at all.

    I hope this helps, please let me know if you need any more help.

    Cheers,
    Mahlamusa

    Mike

    Mahlamusa-

    Tried each other MS_Rule calls for Page, Post and, Custom Post. When I switched to Page, everything showed unlocked (while there remained a mix of locked/unlocked statuses).

    Could not figure out where to place
    echo implode(",",$available_for);
    Put it in the function as
    return implode(",",$available_for);
    and also put it in the loop as
    <?php echo implode(",",$available_for); ?>
    but no effect.

    Tried the new if statement you provided, but that showed no change.

    Here is the page where it is called. Scroll to the section below "Latest Clout.Wiki Entries"

    http://bigtime.thedailyline.net/subscriber-home/

    The code for the loop is below. Thanks for your help!

    <?php if (have_posts()) : ?>
          <?php
      $c = 0;
      $color_id = 'grey';
      ?>
          <div id="ajax">
            <?php while (have_posts()) : the_post(); ?>
            <?php
             $c++; // increment the counter
             if( $c % 2 != 0) {
              $color_id = 'grey';
            } else {
              $color_id = 'white'; }
              ?>
            <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
              <div id="<?php echo $color_id ?>">
                <div class="container">
                  <div class="row">
                    <div class="col-lg-8 col-lg-offset-2">
                      <section class="post-meta">
                        <header>
    					<div style="text-transform: capitalize; margin-bottom: -15px;color: #666; font-weight: bold; font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 1.5em;"><?php foreach((get_the_category()) as $category) { echo $category->category_nicename . ' '; } ?></div>
    
                          <h1 class="post-title"><a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>">
                            <em style="color:#cbc800;"><?php echo check_protected_and_add_icon(); ?></em>
                            <?php the_title(); ?>
                            </a></h1>
                        </header>
    
                         <h3>
                        <ba>By
                          <?php if ( function_exists( 'coauthors_posts_links' ) ) {
        coauthors_posts_links();
    } else {
        the_author_posts_link();
    } ?>
                        </ba>
                        <bd>
                          <time class="post-date">&nbsp;-
                           <?php the_time( get_option( 'date_format' ) ); ?>
                          </time>
                        </bd>
                      </h3>
                      </section>
                      <!-- end of .post-meta -->
                      <section class="post-entry">
                          <!--?php if ( has_post_thumbnail()) : ?-->
                            <!--a href="<!--?php the_permalink(); ?>" title="<!--?php the_title_attribute(); ?>" >
                            <!--?php the_post_thumbnail(); ?>
                            </a>
                            <!--?php endif; ?-->
                        <?php the_excerpt(); ?>
                        <?php custom_link_pages(array(
                        'before' => '<nav class="pagination"><ul>' . __(''),
                        'after' => '</ul></nav>',
                                'next_or_number' => 'next_and_number', # activate parameter overloading
                                'nextpagelink' => __('&rarr;'),
                                'previouspagelink' => __('&larr;'),
                                'pagelink' => '%',
                                'echo' => 1 )
                                ); ?>
                      </section>
                      <!-- end of .post-entry --> 
    
                    </div>
                  </div>
                  <!-- /row -->
                </div>
                <!-- /container -->
              </div>
            </article>
            <!-- end of #post-<?php the_ID(); ?> -->
    
            <?php endwhile; ?>
          </div>
    Mahlamusa

    Hello Mike

    I hope you are doing great today. I am sorry that this is not working as it should on your side.

    I have noticed that you are using the function inside an archive page. I only suspect that the get_the_ID might be getting the id of the archive itself, or not getting the ID of the current post in the loop. Can you try to add the function pass the Id directly to the function instead of getting it from inside the function. Please try:

    function check_protected_and_add_icon( $post_id ) {
             //$post_id = get_the_ID();
             //the rest of the code
             if ( !empty( $available_for ) && $available_for != "" ){
    		return "(Memberships for this page: ".implode(",",$available_for) . ")" . $icon_locked;
    	}else{
    		return "(Memberships for this page: ".implode(",",$available_for) . ")" . $icon_un_locked;
    	}
    }

    Then in your loop you can call:

    <?php echo check_protected_and_add_icon( get_the_ID ); ?>

    This part:
    "(Memberships for this page: ".implode(",",$available_for) . ")" .
    In the function above is just for debugging so you will see what are the membership's available for that page. You should remove it once you have tested and seen what you are missing. For protected pages, it should return the list of memberships protecting that page, otherwise no memberships should be listed if the page/post is not protected.

    Please try that and let me know the result. I hope this helps.

    Cheers,
    Mahlamusa

    Mike

    Mahlamusa-

    Thanks again for keeping at this. It is much appreciated.

    I've added in the new code, and the debugging is working, but I'm still getting nothing but locked icons.

    http://bigtime.thedailyline.net/subscriber-home/

    I also tried changing this line in the function:

    $rule = $membership->get_rule( MS_Rule_Post::RULE_ID );

    To MS_Rule_Page and MS_Rule_CptItem. For Page, it does not return any memberships available and everything is unlocked. CptItem returns the same results as Post.

    Thoughts?

    Mahlamusa

    Hello Mike,

    I see on the linked page that most of the posts listed have the locked icon and have a list of the memberships that are protecting those pages. In that case it means the pages are protected and that is why the closed padlock is showing.

    If the page or post is not protected then it should not display any memberships and should display the open padlock. Please let me know if I am missing something, the way I see it is working fine for protected posts as it is listing the membership levels protecting that page or post and then shows the locked icon.

    See the screenshot below:

    It seems all the pages/posts listed in the linked page are protected and hence displaying the locked icon. Can you please show me a page/post in the list that is not protected but displaying the locked icon? If there is such page/post please send me the link and a screenshot.

    Cheers,
    Mahlamusa