Helping you Build Your Own Social Network!

Faster, better and easier!

tutorial help on adding post_type to activity stream

(25 posts) (2 voices)
  • Started 1 year ago by shawn
  • Latest reply from Brajesh Singh

Tags:

No tags yet.


  1. @Brajesh
    I've been working on custom post_types for some time now and have everything working just about perfect. Now I want to add my custom post_type to the bp activity stream. I do not plan on creating a component for this particular post_type, but simply want the data added to the stream.

    After reading all the bp code, I finally figured out why and where bp decides to put data from the blog into the stream.

    It's in bp-blogs.php file around line 359 with the function bp_blogs_record_post

    In trying to figure out why my custom post_types would not show up, it is due to the following in line 373

    if ( $post->post_type != 'post' )
    		return false;

    By commenting out those lines I am now able to get my custom post_type to also show up in the activity stream.

    http://deardaddy.org/activity/
    first link in stream 'april 5th 2010' is a post_type sermon

    However:
    It ends up saying user x posted a blog post instead of user x posted a 'post_type' post. Obviously it does that because the logic is not there.

    request:
    Could you write-up a quick tutorial on how to put a conditional statement in place of 'return false' something like:

    if ( $post->post_type = 'post_type(x)' )
    	return info about new post_type here
    else;

    if ( $post->post_type != 'post' )
    continue;`

    also:
    My custom post type has a custom field 'video embed' that I would like to show in the activity stream just like you are doing for the photo plugin.

    example:
    http://deardaddy.org/sermons/

    I get the custom field inserted into my template via code:

    <?php $video = shawn_embed('width=200&height=150'); ?>
    <?php
      if (!empty($video)){ ?>
     <div class="video <?php echo $GLOBALS['single_align']; ?>">
     <?php echo $video; ?>
      </div><!-- /.image -->
     <?php } ?>

    Basically I want the activity stream to show that video above when displaying the particular post_type 'sermons'.

    I have spent an entire day trying to figure out how to write the if/else function for displaying the post_type in the activity stream and to have it show my custom field above. I have had no luck so far, and there is no documentation anywhere about how to do this.

    I believe this would become a very popular tutorial, as when people really start using post_types and bp together, the question will be asked many times. There will be many scenario's where a user creates a post_type, but never needs a full bp component but just wants to display the information in the activity stream.

    Could you please do a quick writeup on how to do this?
    Would be much appreciated and a great learning experience for everyone.

    Posted 1 year ago #
  2. hi Shawn
    Sure, I am going to post it within an hour. Sorry for missing your earlier posts(on the same topic).
    Thank you and @mercime for getting those topic resolved :)

    Posted 1 year ago #
  3. Hi Shawn
    Here we go.
    The basics of activity:-
    BuddyPress provides a few functions to manipulate the items in activity stream. The main functions of our interest are

    bp_activity_add($arg);//to add/update an item to activity
     bp_activity_new_comment( $args);//add a child activity to existing activity
     bp_activity_delete($arg);//generic function for deleting activity items

    There are some more generalized functions for deleting activity by item/component etc.

    Now Our Item of interest here is

    bp_activity_add($arg);

    Where $arg can be an array or query string consisting of the following(taken from the bp-activity.php)

    'id' => false, // Pass an existing activity ID to update an existing entry.
    
    		'action' => '', // The activity action - e.g. "Jon Doe posted an update"
    		'content' => '', // Optional: The content of the activity item e.g. "BuddyPress is awesome guys!"
    
    		'component' => false, // The name/ID of the component e.g. groups, profile, mycomponent
    		'type' => false, // The activity type e.g. activity_update, profile_updated
    		'primary_link' => '', // Optional: The primary URL for this item in RSS feeds (defaults to activity permalink)
    
    		'user_id' => $bp->loggedin_user->id, // Optional: The user to record the activity for, can be false if this activity is not for a user.
    		'item_id' => false, // Optional: The ID of the specific item being recorded, e.g. a blog_id
    		'secondary_item_id' => false, // Optional: A second ID used to further filter e.g. a comment_id
    		'recorded_time' => gmdate( "Y-m-d H:i:s" ), // The GMT time that this activity was recorded
    		'hide_sitewide' => false // Should this be hidden on the sitewide activity stream?

    You will mostly find yourself using the "action","content","user_id","component","item_id" and "type"

    here "action" is what you see i the activity stream like "xyz posted an update to alpha beta", and "type" is the actual thing you will use to separate your activity from other activity. For example, I use the type="new_media_update" for media comments.

    Ok, That's enough for you(And I guess, you might already be knowing all these stuffs:) )

    Now coming to the current situation, since bp does not want to record activity for publishing papges, you see the line

    if ( $post->post_type != 'post' )
    		return false;

    I hope, It will be changed in bp 1.3 since that's going to be fully featured for wp 3.0

    For now, we will add our own actions to handle posting to activity stream than editing the core files.
    So, let us decide what we want.
    Since you want to show the custom video in the stream, let us build our code

    function bp_record_custom_post( $post_id, $post, $user_id = false ) {
    	global $bp, $wpdb;
    //do not record post/page just record sermons or other custom post types
    $custom_post_types=array("sermons"=>__("Sermons"),"othertype"=>__("label for other type"),"some_other_type"=>"Label for some other type");//please edit it to all the custom post ttypes you want
    	$post_id = (int)$post_id;
    	$blog_id = (int)$wpdb->blogid;
    
    	if ( !$user_id )
    		$user_id = (int)$post->post_author;
    
    	/* This is to stop infinite loops with Donncha's sitewide tags plugin */
    	if ( (int)$bp->site_options['tags_blog_id'] == (int)$blog_id )
    		return false;
    
    	/* Don't record this if it's not a post */
    	if ( !array_key_exists($post->post_type,$custom_post_types ))//do not record if it is not the custom post type we want to record
    		return false;
    
    	if ( 'publish' == $post->post_status && '' == $post->post_password ) {
    		//you may remove the line below
    		bp_blogs_update_blogmeta( $recorded_post->blog_id, 'last_activity', gmdate( "Y-m-d H:i:s" ) );
    
    		if ( (int)get_blog_option( $blog_id, 'blog_public' ) || !bp_core_is_multisite() ) {
    			/* Record this in activity streams */
    			$post_permalink = get_permalink( $post_id );
    
    			//what you want to say in the activity strea, like xyz posted to the sermon
    			$activity_action = sprintf( __( '%s wrote a new %s: %s', 'buddypress' ), bp_core_get_userlink( (int)$post->post_author ),$custom_post_types[$post->post_type], '<a href="' . $post_permalink . '">' . $post->post_title . '</a>' );
    
    			//what content you want to show, I assume you want video,so I am calling your function for video
    			  $video = shawn_embed('width=200&height=150');//you will need to specify post id here in the function to fetch the video link from custom field
    			 if (!empty($video)){
    			$activity_content ="<div class=\"video\"".  $GLOBALS['single_align']."\">".$video."</div>";
    			 }
    			else
    				$activity_content = $post->post_content;
    
    			bp_record_custom_post_activity( array(
    				'user_id' => (int)$post->post_author,
    				'action' => apply_filters( 'bp_blogs_activity_new_post_action', $activity_action, &$post, $post_permalink ),
    				'content' => apply_filters( 'bp_blogs_activity_new_post_content', $activity_content, &$post, $post_permalink ),
    				'primary_link' => apply_filters( 'bp_blogs_activity_new_post_primary_link', $post_permalink, $post_id ),
    				'type' => 'new_blog_post',
    				'item_id' => $blog_id,
    				'secondary_item_id' => $post_id,
    				'recorded_time' => $post->post_date_gmt
    			));
    		}
    	} else
    		bp_blogs_remove_post( $post_id, $blog_id );
    
    	bp_blogs_update_blogmeta( $blog_id, 'last_activity', gmdate( "Y-m-d H:i:s" ) );//remove this if you don't want blog to be updated in the blogs dir
    
    	do_action( 'bp_blogs_new_blog_post', $post_id, $post, $user_id );//you may want to remove this
    }
    add_action( 'save_post', 'bp_record_custom_post', 20, 2 );//hook to post save
    
    /*since we do not want bp tp create excerpt of our content, let us create our own recording function*/
    function bp_record_custom_post_activity( $args = '' ) {
    	global $bp;
    
    	if ( !function_exists( 'bp_activity_add' ) )
    		return false;
    
    	/* Because blog, comment, and blog post code execution happens before anything else
    	   we may need to manually instantiate the activity component globals */
    	if ( !$bp->activity && function_exists('bp_activity_setup_globals') )
    		bp_activity_setup_globals();
    
    	$defaults = array(
    		'user_id' => $bp->loggedin_user->id,
    		'action' => '',
    		'content' => '',
    		'primary_link' => '',
    		'component' => $bp->blogs->id,
    		'type' => false,
    		'item_id' => false,
    		'secondary_item_id' => false,
    		'recorded_time' => gmdate( "Y-m-d H:i:s" ),
    		'hide_sitewide' => false
    	);
    
    	$r = wp_parse_args( $args, $defaults );
    	extract( $r, EXTR_SKIP );
    
    	if ( !empty( $content ) )
    		$content = apply_filters( 'bp_blogs_record_custom_post_activity_content', $content  );
    
    	/* Check for an existing entry and update if one exists. */
    	$id = bp_activity_get_activity_id( array(
    		'user_id' => $user_id,
    		'component' => $component,
    		'type' => $type,
    		'item_id' => $item_id,
    		'secondary_item_id' => $secondary_item_id
    	) );
    
    	return bp_activity_add( array( 'id' => $id, 'user_id' => $user_id, 'action' => $action, 'content' => $content, 'primary_link' => $primary_link, 'component' => $component, 'type' => $type, 'item_id' => $item_id, 'secondary_item_id' => $secondary_item_id, 'recorded_time' => $recorded_time, 'hide_sitewide' => $hide_sitewide ) );
    }

    This will do what you want to do, just make sure you have edited the first function "

    bp_record_custom_post properly
    I hope it helps a little bit, though I will be creating a post(as per your advise) and posting it back later this week :)

    Let me know if you find difficulties

    P.s: I may be away for couple of hours now.

    Posted 1 year ago #
  4. Thank you very much.
    I've only glanced at the code as I have to leave for a bit, but I will play with it tonight for sure.

    I have to thank you again. This article is very clear and concise. I look forward to playing with it in a few hours.

    Have a wonderful evening.

    Posted 1 year ago #
  5. I may be missing something. What I did was to copy the code above and add it into a file called bp-custom.php which I placed in my plugins directory.

    The only change I needed to make was to change the post_type to 'sermons' lowercase s. I did not add other post types to the array because the other types do not contain video, they contain audio etc. Hence I did not want to make the call to a video file that would not be there.

    I did then go back into the bp-blogs.php and remove the code that I commented out which says only post type 'post'. That way the core files are untouched.

    Then I created a new sermon, yet it does not show up in the activity stream as expected. The post shows up as it should in the blog.

    I've read the code a few times now, and do not see anything obvious that would be missing that would cause bp to not pick up the new 'sermons' post_type.

    also:
    my $video function is nothing more than a function to do a preg_replace on an embed code custom field to remove and replace the height and width parameters. It does contain a function to grab the post_id, so that is covered

    function shawn_embed($args) {
    
    	//Defaults
    	$key = 'sermon_video_embed_code';
    	$width = null;
    	$height = null;
    	$class = 'video';
    	$id = null;	
    
    	if ( !is_array($args) )
    		parse_str( $args, $args );
    
    	extract($args);
    
      if(empty($id))
        {
        global $post;
        $id = $post->ID;
        } 
    
    $custom_field = get_post_meta($id, $key, true);
    
    if ($custom_field) :

    ....etc

    I'll keep on this for another hour or so, then I have to drive dad home. I should be back online working on this later tonight.

    thanks

    p.s.
    you have a pm, as I have to leave for a bit

    Posted 1 year ago #
  6. OK, I got it to actually show when I post a sermon. However it's not showing the video. My best guess is because $video is not passing the post_id outside of the loop. Also my attempts to actually get bp_record_custom_post to also include the $content from the post itself is not working properly. I was trying to style it just like my blog post, video on left, $content on right side. Later I may apply a few css tricks to make video sermon posts really stand out in the activity stream.

    I sent you a pm with access to my functions, maybe you can see why it's not passing the id. From what I can see it should be doing it properly.

    I've tried to do a print_r of $video, but it's rather difficult as the output changes depending upon where/when it's called. I would love to find out how to call the value of a variable function like this when it's tied to an action. That is new territory for me.

    I'll keep searching the php docs for a while to see if I can figure it out. If I do I will post back.

    Normally I would simply post my $video function in the forums here, but I'd rather not do that at the moment.

    This is a really great step though! making progress.

    Posted 1 year ago #
  7. Shawn
    Let me do that. I guess It is because of the way shawn_embed is called. I will check it on your server and fix there :)

    Posted 1 year ago #
  8. Yes, I believe it has to be shawn_embed, as the post is being added to the stream, just no video shows up. I do have shawn_embed returning the post_id if it is 'null' or not hardcoded. Of course you can see that in the above snippet. My best guess is that for some reason the id is not being passed in this scenario, because it is outside of the loop?

    Maybe I need to start by simply calling the custom field itself instead of wrapping it in shawn_embed? The only problem with that though, is that at some point I would still have to dynamically change the width/height of the video. Otherwise we would end up with a huge video showing up in the activity stream. That is what I like about my little function so much. I can change the size of the video dynamically in the template with only one simple change. Saves a ton of time with theme changes.

    I'm sure a big part of my problem is the bp_custom does not call the loop like I am used to working with. Actually I don't yet understand how it knows the post_id to insert. Still trying to grasp the bp logic.

    Posted 1 year ago #
  9. Well I screwed around on this most of the day but had no luck. Will just wait until the experts have a chance to chime in.. :) time for sleep

    Posted 1 year ago #
  10. Well I kept trying for the past few days, but man I would never have guessed it would be this hard to add to the activity stream. I suppose the one benefit is that I am finally starting to understand how bp really works. In some ways it's quite different than 'normal' wp operation, but similar in others. The 'scary' part for me, is the codebase looks so different in 1.3 than the 1.2 series. Almost wondering if I should just study 1.3 more and pretty much ignore 1.2 in my learning process.

    Posted 1 year ago #
  11. Hi Shawn
    tried to contact you over skype 2 days ago, but could not. It seems to me , the problem is with the order when the custom field is saved and the post is published. If post is published before saving custom field(which happens because of auto revision mode turned on in wp), we will never be able to get the custom field data on save_post action. I am looking for some other action to hook it.

    Yes bp 1.3 will be quiet different from 1.2 but once you get the understanding of 1.2, 1.3 will not be difficult to grasp.

    Posted 1 year ago #
  12. I would never have even thought about the save order of custom fields. Great catch there! I'll do some searching to see if anyone has written about that before. I do know that I had a function on one of my wp sites that turned off auto revision, but that still would not change the save order.

    Posted 1 year ago #
  13. Turning revision should definitely help.
    try putting this line in wp-config.php for testing

    define('WP_POST_REVISIONS', FALSE);

    btw I had edited calls to shawn_embed in custom activity and also a small change in shawn_embed, please make sure to have them in your file(I had passed post_id to shawn_embed)

    Let me know if that makes it work or not.

    Posted 1 year ago #
  14. I added the post revisions to wp config, added sermon. Same results. Sermon shows up but no video.

    I did not make any changes to the shawn_embed function in either file. Your changes are still there.

    Posted 1 year ago #
  15. hi Shawn
    I will take a look at my own dev system with custom field in more details and find some workaround and fix it on your site too.

    Sorry for a little delayed response.

    Thanks
    brajesh

    Posted 1 year ago #
  16. Brajesh, you have new pm.
    (should add a blinking pm button to the template so a user knows when they have mail, would be nice addition)

    Posted 1 year ago #
  17. Hi Shawn
    Just tested post meta with custom post type, It works at save_post action. It's time to check shawn_embed again.

    Well, It seems to me that save_post is fired after saving meta. I will wait for you to come online, will be available on IRC, just drop a message when you come online.

    Posted 1 year ago #
  18. i'm back if you want to test again, all the login information is the same if you still have it. I don't use irc, but do have skype

    Posted 1 year ago #
  19. hi Shawn
    Sure, I will be interested in testing the things again, but not now. It's 11:13 Am and I need to get some sleep. So if you don't mind, I will test it in the evening today or what ever time you will be online tomorrow.

    Posted 1 year ago #
  20. sleep well my friend. It's 11pm here so going to bed myself.

    Posted 1 year ago #
  21. Curious if you were able to track down why the embed code was not working.

    Posted 1 year ago #
  22. hi Shawn
    I will be on skype after 10 AM PST, will let you know in details then.

    Posted 1 year ago #
  23. sounds good, I'm online and should be for a while

    Posted 1 year ago #
  24. hi Shawn
    first of all sorry for not being able to catch you yesterday.

    But the good thing is, I tried on sermons today and got the reason. the reason is you are using embed code and try to post it in the activity which bp does not allow(filters out).

    what I did, I posted some custom text instead of the video embed code in the video meta box and was surprised to see the content of video meta box appeared in the activity.
    Please check your site activity for the same.
    So now what we need is a way to stop bp filtering out the embed code. I am working on your site still, will post back in half an hour again.

    Posted 1 year ago #
  25. ok, fixed problem. Now it is showing video in activity. Please make sure to check bp-custom.php, as I have edited it.
    Also, In the process of testing, I created a few test posts in sermon, please delete them.

    Posted 1 year ago #

Reply

You must log in to post.