Customization wanted to display posts from Pro Sites only

I would like a function for Recent Global Posts plugin or Recent Global Posts Widget plugin where I can use it to check Pro Sites status and display only posts from pro sites.

  • Lindeni Mahlalela

    Hello Mathias,

    I hope you are doing great today. Thank you for contacting us and for your patience as we were looking into these.

    I have checked the code for the plugins and found that the best option will be to create a custom mu plugin with which we can hook to the 'network_posts_where' filter as follows:

    add_filter( 'network_posts_where', 'callback_function', 99, 2 );

    This allows us to modify the query before it is executed. In this case we need to hook a callback function that will get all bogs, filter out all pro sites and then modify the WHERE clause of the query to exclude the filtered blogs. Here is a sample code that can be used to achieve this:

    add_filter( 'network_posts_where', 'exclude_non_pro_sites_blog_posts', 99, 2 );
    
    function exclude_non_pro_sites_blog_posts( $where, Network_Query $query ) {
    	global $psts;
    	$exclude_these = array();
    	if ( function_exists( 'get_sites' ) ) {
    		$blogs = get_sites( array( 'network_id' => 1 ) ); //Get all blogs of 'network_id' => 1 or array(1,2,3)
    
    		foreach ( $blogs as $blog ) {
    			if ( $psts->is_pro_site ( $blog->blog_id ) )
    				$exclude_these[] = $blog->blog_id; //add blog to exclude list
    		}
    	}
    
    	return !empty( $query->query_vars['blogs_not_in'] ) && !empty( $exclude_these )
    		? $where . sprintf( ' AND %s.BLOG_ID NOT IN (%s) ', $query->network_posts, $exclude_these )
    		: $where;
    }

    What this will do is get a list of non Pro Site blogs and modify the query so that these blogs are not queried because they don't have a Pro Site status.

    You may add the above code to your theme's functions.php or create a new PHP file, paste the code with the opening tag as follows:

    <?php
    //paste the above code

    then save and upload the file to 'wp-content/mu-plugins' folder. Alternatively download the attached zip file and install it as a plugin via "Plugins > Add New" then go to installed plugins and network activate it, it will be shown as "Show Posts From Pro Sites", you may also extract it and upload the PHP file to 'wp-content/mu-plugins' folder and it will start working right away.

    I did not test the code but it should work as it is but feel free to modify it as required. Please this and let us know if you run into any problems. We will be happy to help in anyway possible.

    Have a nice day.
    Mahlamusa

  • Lindeni Mahlalela

    Hello Mathias

    I hope you are doing great today. I am sorry for the confusion here, I don't know how I missed your comment, I am sorry for all the inconvenience that this confusion might have caused for your. Thank you so much for the feedback and for your patience while we were looking into this.

    If you intend to display the avatar of the post author then you can use WordPress's 'get_avatar()' function which is used as follows:

    echo get_avatar( $id_or_email, $size, $default, $alt, $args );

    The only required parameter is the '$id_or_email' which you can supply with the user ID of the post author or the email address of the author. Since you are getting the post_author field in the posts query then you already have the $id so you can just call the avatar as follows:

    echo get_avatar( $post->post_author )

    So from the code you supplied you need to change this line:

    $blogPost->avatar = get_wp_user_avatar($blogPost->post_author);

    Into this:

    $blogPost->avatar = get_avatar($blogPost->post_author, '16' );

    Where '$blogPost->post_author' is the user ID of the post author and 16 is the size of the avatar, in this case it will be 16x16. After that in the function 'ak_display_latest_posts_footer', you have to add the '$blogPost->avatar' value to the '$posts_str' string so it can be shown in the list. Please note that the get_avatar() function will return an HTML image tag like this:

    <img src="//avatar-url-here" alt="" width="16" height="16" />

    So you have to just echo or concatenate the string to your '$posts_str' string.

    As a suggestion, I recommend you take advantage of get_permalink() function to get the pretty url of each post instead of using the guid which may. So in your code you should add the following just under the get_avatar() line mentioned above:

    $blogPost->permalink = get_permalink( $blogPost->ID );

    And for security, I recommend you escape all output before it is rendered in html, you can achieve this using the esc_url() function to output a safe permalink. You can use this in the '$posts_str' string like this:

    <a href="'. esc_url( $post->permalink ) .'" target="_blank">&nbsp;</a>

    In the Javascript you have I also suggest you wrap it around a document ready event listener so that the javascript can only be executed once the DOM is ready. You can do this like this:

    <script type="text/javascript">
    	jQuery(document).ready(function(e) {
    		jQuery("#newsList").append('<?php echo $posts_str; ?>');
    	});
    </script>

    Once all these changes are done, you should see the posts like this:

    I ended up rewriting some parts of your plugin a little and if you are interested in the changes I have made, you can check the attached .zip file. You can upload and install it as a plugin or extract and upload the .php file to 'wp-content/mu-plugins' so you can use it as an MU plugin.

    Please review these suggestions, test and let us know how it goes. Please feel free to let us know if we have missed something or if you have any other questions or concerns.

    Have a nice day.
    Mahlamusa

  • Mathias

    Hello Mahlamusa

    Thank you so much. I tried to edit my existing plugin, but I still couldn't get any avatar to display. I also tried to use your plugin, but it doesn't output anything, so the #newsList div is just empty.

    If I put a standard div in the 'append', like this:
    <script type="text/javascript">
    jQuery(document).ready(function(e) {
    jQuery("#newsList").append('<div>Test</div>');
    });
    </script>

    Then i get the div showing, so I guess it's a problem with the PHP code, as it won't display.

  • Lindeni Mahlalela

    Hello Mathias

    I hope you are doing great today.

    The issue with the .append() might be caused by the fact that the avatar image comes with single quotes for the parameters like src='url' and the append also uses single quotes. In my setup I solved this by using the 'preg_replace' to replace single quotes with double quotes in the avatar tag to make the whole $posts_str use double quotes so it won't have issues when quoted with single quotes in the append().

    To make things simple for both of us and to avoid any back and forth that may cause us a lot of time, would you mind giving access to your FTP so that I can have a closer look? I will check on your site and update the code and report to you what I have done.

    You may send FTP login details via our secure contact form, make the subject "Attn: Lindeni Mahalalela" then in the Message box include:

    - FTP login details (ftp host, port, username and password)
    - WordPress login details (login url, username and password)
    - Link back to this thread for reference

    Once I have this I will check your code and see what I can do. I am looking forward to your response.

    Have a nice day.
    Mahlamusa

  • Lindeni Mahlalela

    Hello Mathias

    Thank you for sending the requested information. I have looked at your code and noticed that there is still a big difference between your code and the one I have rewritten.

    I decided to upload my version of the code into the mu-plugins folder of your website and it seems to working properly.

    To avoid php errors, I have renamed your file from:

    footer_latest_posts.php

    To:

    footer_latest_posts.php.backup

    To avoid execution of this code because the code I uploaded also uses the same names for the PHP functions as that of yours. I uploaded the new file as:

    global-posts-widget.php

    To your 'mu-plugins' folder. I checked by attempting to add a new Text widget in the Footer section and this is how how it looks:

    I haven't saved this as you may want to have a look first to see how it looks. Now the code is the and working already, but there is only one final step to take. You need to add a new text widget or add an html element to your theme's footer. It should be as follows:

    <div id="newsList"></div>

    Once you have this, the code should display the avatars like in the screenshot above.

    I hope this helps. Please let me know if you need any further assistance.

    Have a nice day.
    Mahlamusa

  • Lindeni Mahlalela

    Hello Mathias

    Thanks for your feedback. Please note that the theme has a lot of conditional logic it uses to display content, so if you place the code in the footer then you should place it where it will be not affected by most of the conditions.

    I have placed the following code inside the <footer></footer> tag in the footer.php, just at the top to make the posts appear above the dark footer background:

    <div class="container <?php echo $footer_classes; ?>">
    	<div class="container_inner">
    		<h2 class="post-title clearfix">Latest News</h2>
    		<p>&nbsp;</p>
    		<div id="newsList"></div>
    	</div>
    </div>

    And this is how it looks:

    I hope this is what you are looking for. You are welcome to edit the code as you wish to make it work the way you want it to work.

    Have a nice day.
    Mahlamusa

  • Lindeni Mahlalela

    Hello Mathias

    Thanks for the feedback. This must have been a small typing mistake, the test10.bloggerspoint.dk uses the theme 'bloggerspointblog' not 'bloggerspoint' theme. I have removed the code from the bloggerspoint to the bloggerspointblog.

    I have changed the footer.php file and moved the newsList div outside the

    <div id="social-bottom">

    Because it was breaking the layout of the page for some reason.

    You are right, it was not working on the test blog, this is because I made I small mistake in the code, I was querying the

    {$wpdb->prefix}pro_sites

    Instead of

    {$wpdb->base_prefix}pro_sites

    I have fixed this and it is now displayed properly. The issue was that the table could not be found as the pro_sites table is only created for the main site and not all blogs, as a result the base_prefix must be used to make sure the query selects the table with the prefix for the main site.

    Now the code should work on all your blogs but it seems you will obviously have to edit the style of the newsList as somehow it looks a little broken. I hope that won't be a big deal for you.

    I hope this is helpful. Thank you for your patience and cooperation, please let us know if you are having any further issues.

    Have a nice day.
    Mahlamusa

  • Lindeni Mahlalela

    Hello Mathias

    I am happy to hear that it works. I have modified the first function so that instead of looping through the posts in this manner:

    foreach($post_latest as $posts => $post){}

    You can take the first post like so:

    $post = $post_latest[0];
    $avatar = preg_replace("/\'/", '"', $post->avatar);
    $posts_str .="post str here";

    I have done this already, but you can double check to see if it is indeed the latest post being displayed. If it is not then you can use the SORT ORDER in the query to make sure the latest post is the first in the list.

    I hope this helps.

    Have a nice day.
    Mahlamusa

  • Lindeni Mahlalela

    Hello Mathias

    I hope you are doing great today. I have checked 3 websites (test8, livefrasjaelland, lifecontent, ablondegirlsworld) and they all display the same post (LINE ENGGROB: GOODIEBOX AUGUST 2017) which means it is not the latest post on the current blog only that is displayed, the post is taken from the network, however it is true that this was not the latest post because there are newer posts than that.

    The problem seems to be that the code get's the latest post from each bog and then returns the last post it got, this is not right since the post from the last blog processed will not always be the latest post in the whole network but the latest only on that blog. I have then modified the code so that its sorts the posts again to get the only latest post in the network.

    I have introduced the following function:

    function ak_get_latest_post(){
    	$all_posts = ak_get_network_posts();
    	$latest_post = $all_posts[0]; //assume the first post is the latest then compare with others	
    
    	foreach ( $all_posts as $post ) {
    		if ( strtotime( $post->post_date ) > strtotime( $latest_post->post_date ) ) {
    			$latest_post = $post;
    		}
    	}
    	return $latest_post;
    }

    And then modified the line:

    $post_latest = ak_get_network_posts();

    To:

    $post_latest = ak_get_latest_post();

    The latter function will get all posts using the function ak_get_network_posts() and then filter out the latest post. I have uploaded the code back to your website and it seems to be working just fine. By the time of this writing, the latest post was posted on on 2017-10-27 20:46:56, which seems correct.

    I hope this helps, please check and let us know if there is anything else we can help with.

    Have a nice day.
    Mahlamusa