How Can I Add a Category Field to the BP Activity Plus Form

Hello,

After searching the forums I haven't been able to find how to alter a form defined by the BP Activity Plus plugin.

I would like to add a Category field without having to hack the plugin.

For example;
I create a plugin that will hook into that form and add a field that will be positioned based on its weight. Similar to Drupal.
Is this possible in WordPress and which Hook Filter should I use.

Thank you,
V.

  • Victor

    Thank you Hoang for your quick response.

    I found this code that explains how to add a jquery dropdown box;
    http://www.html-form-guide.com/jquery/drop-down-list-jquery.html

    The problem is that I don't know where to place the following jquery code inside the already existing plugin files

    -------------------
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>

    <title>List Sample 1</title>
    <style>
    body{ font-family : Arial, Helvetica, sans-serif; font-size : 1em;}
    h1 {font-size : 18pt; color : #000066;}
    h2 {font-size : 14pt; color : #000066;}
    a:hover{text-decoration : none;}
    </style>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
    <script type="text/javascript">
    /*function to load a list*/
    function loadlist(selobj,url,nameattr)
    {
    $(selobj).empty();
    $.getJSON(url,{},function(data)
    {
    $.each(data, function(i,obj)
    {
    $(selobj).append($('<option></option>').val(obj[nameattr]).html(obj[nameattr]));
    });
    });
    }

    $(function()
    {
    loadlist($('select#country').get(0), 'get-list.php?getlist=country','country');
    });
    </script>
    </head>

    ------------------------

    Any help on where you I place this functions inside the plugin is appreciated.

    Thank you
    V.

    P.S. Here is a working example outside the plugin files;
    http://dev.areyoupop.com/tests/jquery_category/list-1.html

  • Hoang Ngo

    Hi @Victor,

    I hope you are well today.

    For append the code inside the plugin core code, it seem complicate and duplicate.

    I have write another function, which will help you to add the dropdown inside the form.

    add_action( 'wp_footer', 'append_dropdown_activity_plus' );
    function append_dropdown_activity_plus() {
    	?>
    	<script type="text/javascript">
    		jQuery(document).ready(function ($) {
    			var data = [
    				{
    					key  : 'key1',
    					text: 'value1'
    				},
    				{
    					key  : 'key2',
    					text: 'value2'
    				},
    				{
    					key  : 'key3',
    					text: 'value3'
    				},
    			];
    			var dropdown = $('<select/>').attr('id', 'bpp_ex_custom_dropdown');
    			$.each(data, function (i, v) {
    				dropdown.append($('<option/>').text(v.text).val(v.key));
    			})
    			console.log(dropdown);
    			setTimeout(function(){
    				dropdown.insertBefore('#bpfb_cancel_action');
    			},2000)
    		})
    	</script>
    <?php
    }

    The variable data is an array will be convert as select options. The text is what the options will display, and key is the value of it.

    Please give it a try and let us update.

    Best Regards,
    Hoang

  • Victor

    Hoang,

    Thank you for the code. I finally found some time to work on this and created a new plugin using the code above. Please, see below;

    -----------------------

    <?php
    /**
    * Plugin Name: BuddyPress Activity Plus Category
    * Plugin URI: http://www.website.com
    * Description: This plugin adds a dropdown field with the category
    * Version: The Plugin's Version Number, e.g.: 1.0
    * Author: Website
    * Author URI: http://www.website.com
    * License: A "Slug" license name e.g. GPL2
    */

    add_action( 'wp_footer', 'append_dropdown_activity_plus' );

    function append_dropdown_activity_plus() {

    echo "here";

    ?>
    <script type="text/javascript">
    jQuery(document).ready(function ($) {
    alert("here");
    var data = [
    {
    key : 'key1',
    text: 'value1'
    },
    {
    key : 'key2',
    text: 'value2'
    },
    {
    key : 'key3',
    text: 'value3'
    },
    ];
    var dropdown = $('<select/>').attr('id', 'bpp_ex_custom_dropdown');
    $.each(data, function (i, v) {
    dropdown.append($('<option/>').text(v.text).val(v.key));
    })
    console.log(dropdown);
    setTimeout(function(){
    dropdown.insertBefore('#bpfb_cancel_action');
    },2000)
    })
    </script>
    <?php
    }

    -----------------------------

    But unfortunately it is not adding the dropdown element to the form.
    Could you let me know how can I debug this better? Any links to a jquery debugging tutorial?

    Thank you

    Victor

  • Patrick

    Hey there @Saurabh Shukla

    Thanks for the assist on this one! Much appreciated. :slight_smile:

    @Victor

    It would appear Saurabh is correct, the BuddyPress Like plugin is throwing a js error.

    It might even be a good idea to add your plugin script in noConflict mode to eliminate any risk that it conflicts with other stuff on your site. Here's the amended code that works just fine on my test site:

    <script type="text/javascript">
    jQuery.noConflict()
    jQuery(document).ready(function () {
    (function($){
    
    alert("here");
    var data = [
    {
    key : 'key1',
    text: 'value1'
    },
    {
    key : 'key2',
    text: 'value2'
    },
    {
    key : 'key3',
    text: 'value3'
    },
    ];
    var dropdown = $('<select/>').attr('id', 'bpp_ex_custom_dropdown');
    $.each(data, function (i, v) {
    dropdown.append($('<option/>').text(v.text).val(v.key));
    })
    console.log(dropdown);
    setTimeout(function(){
    dropdown.insertBefore('#bpfb_cancel_action');
    },2000)
    })(jQuery);
    });
    </script>
  • Victor

    Thank you everybody who has helped on this little project of mine.

    I was wondering what is the hook function I can use to add and call to save the category chosen in the select dropdown box, in the database.

    Do I also do this by calling jquery when the user clicks on "post" button or is there an array inside a hook function that I can call (similar to drupal)?

    Any other ideas or links about where and or how can I accomplish this will be great

    Thank you

    V.

  • Victor

    Sorry to ask again but I realized you actually use hooked into the buddypress functionality using with the plugin code instead of hacking the buddypress core functions as I understood in your previous post ..

    - "The hook for handler the activity is "bp_actions", you can check how it run at line 247 file buddypress/bp-activity/bp-activity-actions.php." -

    I would like to know how did you do this without hacking budypress core files.

    Thank you

    V.

  • Hoang Ngo

    Hi @Victor,

    I hope you are well today.

    Sorry for the confusion, after I review the buddypress code again, I found this action "bp_activity_posted_update", which will be fire after an user posted new activity. Here is an example of usage:

    add_action( 'bp_activity_posted_update', 'after_activity_posted_55123', 10, 3 );
    function after_activity_posted_55123( $content, $user_id, $activity_id ) {
    //$content is the activity content
    //$user_id is the user who posted the activity
    //$activity_id is the new activity
    }

    If you have any issues please don't hesitate to let us know so we can assist.
    Best regards,
    Hoang

  • Victor

    Hoang,

    Thank you for the response.
    But, I'm pretty much trying to replicate what the activity plus plugin has been able to do with links, images and video.

    Notice that activity plus plugin doesn't hack the buddypress core hook into the already existing "post" functionality of buddypress core.

    So, my questions is; how did the activity plus plugin;
    1. Attaches the buttons; link, video and image to the posting area of bbpress and
    2. How does the activity plus plugin saves the; link. image or video when the user clicks on the "post" button?

    Could you point me to the part of the code, inside the activity plus plugin, where this happens?
    I don't want to hack bbpress core and I know it is possible because this "activity plus" plugin attaches to the text only post dialog box.

    Thank you

    V.

  • Hoang Ngo

    Hi @Victor,

    I hope you are well today.

    But, I'm pretty much trying to replicate what the activity plus plugin has been able to do with links, images and video.

    Notice that activity plus plugin doesn't hack the buddypress core hook into the already existing "post" functionality of buddypress core.

    The concept of activity plus is different from yours achievement I think, they post new activity, and yours is categorize the activity.

    We don't hack the core file too, as using the action, that's mean we can create another separate plugin for adding functions and make it work with the current plugin.

    1. Attaches the buttons; link, video and image to the posting area of bbpress and

    They use javascript for add new element to the activity form. You can check the code at buddypress-activity-plus/js/bpfb_interface.js

    And the way is same like us, we use javascript too and we place the code separate. No hack there, right ?

    2. How does the activity plus plugin saves the; link. image or video when the user clicks on the "post" button?

    They using ajax. Example, when you added a link, and click add link, an ajax will called and doing the function. You can check about that in file buddypress-activity-plus/lib/class_bpfb_binder.php

    From here, you will notice many functions for the preview action, and the function handler importing activity to database is "ajax_update_activity_contents"

    About the action "bp_activity_posted_update", for testing how it work, please create new plugin, and add this code

    add_action( 'bp_activity_posted_update', 'after_activity_posted_55123', 10, 3 );
    function after_activity_posted_55123( $content, $user_id, $activity_id ) {
    wp_email('YOUR EMAIL','DEBUG','Content:'.$content.PHP_EOL.'User:'.$user_id);
    }

    This will send an email to you when new activity posted, we added new function to the activity but we don't modify the core code :slight_smile:.

    If you have any issues please don't hesitate to let us know so we can assist

    Best regards,
    Hoang

  • Victor

    Hoang,

    Thank you for the example code and quick reply.
    I have created this plugin and activated it in my dev site. dev.areyoupop.com

    Unfortunately, it is not working since I haven't received any emails yet. Note: I have changed my email address to a fake one but in my plugin I'm using the right email address.

    --------------------------------

    <?php
    /**
    * Plugin Name: BuddyPress Activity Plus Email
    * Plugin URI: http://www.areyoupop.com
    * Description: This plugin adds a dropdown field with the category
    * Version: The Plugin's Version Number, e.g.: 1.0
    * Author: AreYouPop
    * Author URI: http://www.areyoupop.com
    * License: A "Slug" license name e.g. GPL2
    */

    add_action( 'bp_activity_posted_update', 'after_activity_posted_55123', 10, 3 );

    function after_activity_posted_55123( $content, $user_id, $activity_id )
    {
    wp_email('myemail@yahoo.com', 'DEBUG', 'Content:' . $content . PHP_EOL . 'User:' . $user_id);
    }
    ?>

    ' ------------------

    Any ideas ? Do I have to remove the DEBUG or is that the subject line of the email?

    Thank you,

    Victor

    P.S. So my understanding now is that it is possible to extend a form by using actions and hooking into the post function.

  • Victor

    Hoang,

    Thank you for your reply.
    I read the link and it makes sense to use action hooks to safe the $content variable after it has been codec.

    So far this is what I understand;
    1. Using jquery I can add a text field category to the update activity form
    2. Using a codec function I can add the category to the $content
    3. Using an action hook named "bp_activity_post_update" I can hook into the update action of the activity form post

    Here is a kind of close to code;

    // if the category was entered in the post variable then codec
    if (@$_POST['data']['bpfb_category'])
    {
    $bpfb_code = $codec->create_category_tag($_POST['data']['bpfb_category']);
    }

    //
    $bpfb_code = apply_filters('bpfb_code_before_save', $bpfb_code);

    // All done creating tags. Now, save the code
    $gid = (int)@$_POST['group_id'];

    if ($bpfb_code)
    {
    $content = @$_POST['content'] . "\n" . $bpfb_code;

    $content = apply_filters('bp_activity_post_update_content', $content);

    $aid = $gid ?

    groups_post_update(array('content' => $content, 'group_id' => $gid))

    :

    bp_activity_post_update(array('content' => $content))
    }

    // --------------------------------------------

    Am I on the right path?
    Also, is there any tutorial on how to debug the variable $content so I can see what's going on? I've tried print_r($content) but it doesn't show anything in firebug or screen

    Thank you

    V.

  • Hoang Ngo

    Hi @Victor,

    I hope you are well today.

    So firstly, please update the first code I posted to this

    add_action( 'wp_footer', 'append_dropdown_activity_plus' );
    function append_dropdown_activity_plus() {
    	?>
    	<script type="text/javascript">
    		jQuery(document).ready(function ($) {
    			var data = [
    				{
    					key  : 'key1',
    					text: 'value1'
    				},
    				{
    					key  : 'key2',
    					text: 'value2'
    				},
    				{
    					key  : 'key3',
    					text: 'value3'
    				},
    			];
    			var dropdown = $('<select/>').attr({
    'id': 'bpp_ex_custom_dropdown',
    'name':'bpp_ex_custom_dropdown'
    });
    			$.each(data, function (i, v) {
    				dropdown.append($('<option/>').text(v.text).val(v.key));
    			})
    			setTimeout(function(){
    				dropdown.insertBefore('#bpfb_cancel_action');
    			},2000)
    		})
    	</script>
    <?php
    }

    So later, you can get the categories by
    $_POST['bpp_ex_custom_dropdown']
    So instead of this

    if (@$_POST['data']['bpfb_category'])
    {
    $bpfb_code = $codec->create_category_tag($_POST['data']['bpfb_category']);
    }

    You can use this

    if (@$_POST['bpp_ex_custom_dropdown'])
    {
    $bpfb_code = $codec->create_category_tag($_POST['bpp_ex_custom_dropdown']);
    }

    Also, is there any tutorial on how to debug the variable $content so I can see what's going on? I've tried print_r($content) but it doesn't show anything in firebug or screen

    Hmm, can you post your script here, using our code tag, include your action hook too, so I can know which stage it is fire, and I can point you in right direction :slight_smile:

    If you have any issues please don't hesitate to let us know so we can assist

    Best Regards,
    Hoang

  • Victor

    Hoang,

    I have added a codec category function and a ajax_update_activity_category
    That I don't really understand how is it going to send the category value to the input into database by calling a content call

    header('Content-type: application/json');

    Is there a tutorial on making these calls?

    Here is the existing code so far

    <?php
    /**
     * Plugin Name: BuddyPress Activity Plus Category
     * Plugin URI: http://www.areyoupop.com
     * Description: This plugin adds a dropdown field with the category
     * Version: The Plugin's Version Number, e.g.: 1.0
     * Author: AreYouPop
     * Author URI: http://www.areyoupop.com
     * License: A "Slug" license name e.g. GPL2
     */
    
    add_action( 'wp_footer', 'append_dropdown_activity_plus' );
    
    function append_dropdown_activity_plus() {
    
    	?>
    	<script type="text/javascript">
    		jQuery.noConflict()
    
    		jQuery(document).ready(function () {
    		(function($){
    
    			var data = [
    				{
    					key  : 'key1',
    					text: 'value1'
    				},
    				{
    					key  : 'key2',
    					text: 'value2'
    				},
    				{
    					key  : 'key3',
    					text: 'value3'
    				},
    			];
    
    			var dropdown = $('<select/>').attr({'id': 'bpp_ex_custom_dropdown', 'name':'bpp_ex_custom_dropdown'});
    
    			$.each(data, function (i, v) {
    				dropdown.append($('<option/>').text(v.text).val(v.key));
    			})
    
    			console.log(dropdown);
    
    			setTimeout(function(){
    				dropdown.insertBefore('#bpfb_cancel_action');
    			},2000)
    		})(jQuery);
    		})
    	</script>
    <?php
    }
    
    // -- NEW -----------------------------
    
    function ajax_update_activity_category () {
    
    		$bpfb_code = '';
    		$activity = '';
    
    		$aid = 0;
    
    		// Create an object codec
    		$codec = new BpfbCodec;
    
    		//
    		if (@$_POST['bpp_ex_custom_dropdown']) {
    
    			$bpfb_code = $codec->codec_category($_POST['bpp_ex_custom_dropdown']);
    
    		}
    
    		//
    		$bpfb_code = apply_filters('bpfb_code_before_save', $bpfb_code);
    
    		// All done creating tags. Now, save the code
    
    		$gid = (int)@$_POST['group_id'];
    
    		if ($bpfb_code) {
    
    			$content = @$_POST['content'] . "\n" . $bpfb_code;
    
    			$content = apply_filters('bp_activity_post_update_content', $content);
    
    			/*
    			echo "<pre>";
    			print_r($content);
    			echo "<pre />";
    			exit();
    			*/
    
    			$aid = $gid ?
    
    				groups_post_update(array('content' => $content, 'group_id' => $gid))
    
    				:
    
    				bp_activity_post_update(array('content' => $content))
    
    			;
    
    			global $blog_id;
    
    			bp_activity_update_meta($aid, 'bpfb_blog_id', $blog_id);
    
    		}
    
    		if ($aid) {
    
    			ob_start();
    
    			if ( bp_has_activities ( 'include=' . $aid ) ) {
    
    				while ( bp_activities() ) {
    
    					bp_the_activity();
    
    					if (function_exists('bp_locate_template'))
    						bp_locate_template( array( 'activity/entry.php' ), true );
    
    					else
    						locate_template( array( 'activity/entry.php' ), true );
    
    				}
    
    			}
    
    			$activity = ob_get_clean();
    
    		}
    
    		header('Content-type: application/json');
    
    		echo json_encode(array(
    
    			'code' => $bpfb_code,
    
    			'id' => $aid,
    
    			'activity' => $activity,
    
    		));
    
    		exit();
    
    	}
    
    	// function to codec the category
    	function codec_category($category) {
    
    		if (!$category) return '';
    
    		return "[bpfb_category category='{$category}']{$category}[/bpfb_category]";
    
    	}
    
    ?>

    Thank you for any help

    V.

  • Hoang Ngo

    Hi @Victor

    Sorry if I made you confusion. Actually what we need is the $activity_id, not the content.

    The logic will be simple, when user post an activity, we will catch the activity_id and the category(By the action I posted above). After that, you can use your $codec function to create category if not exist and and assign the activity to the category.

    That I don't really understand how is it going to send the category value to the input into database by calling a content call

    The header('Content-type: application/json'); is for telling browser the file output is JSON type, not normal html type. This is not using for import category.

    But this process will require a solid PHP/Wordpress skill, and you can always hire some good one for help at our job board here https://premium.wpmudev.org/wordpress-development/

    For practice, I think the simplest plan you can get now is catch the category and activity id, and then save the category in table _activity_meta

    Here is an example

    add_action( 'bp_activity_posted_update', 'after_activity_posted_55123', 10, 3 );
    function after_activity_posted_55123( $content, $user_id, $activity_id ) {
    //get the category from POST
    $category = isset($_POST['bpp_ex_custom_dropdown'])?$_POST['bpp_ex_custom_dropdown']:null;
    if(!is_null($category)){
    //update the category to activity meta
    bp_activity_update_meta($activity_id,'activity_category',$category);
    }
    }

    If you have any issues please don't hesitate to let us know so we can assist

    Best regards,
    Hoang

  • Victor

    Hoang,

    K. So I removed the overkill code and now I only have to functions and two actions; one for adding the category in the form and another function that gets triggered when the activity is posted.

    Here it is;

    add_action( 'wp_footer', 'append_dropdown_activity_plus' );
    add_action( 'bp_activity_posted_update', 'after_activity_posted_55123', 10, 3 );
    
    function after_activity_posted_55123( $content, $user_id, $activity_id )
    {
    	//get the category from POST
    	$category = isset($_POST['bpp_ex_custom_dropdown'])?$_POST['bpp_ex_custom_dropdown']:null;
    
    	if(!is_null($category)){
    		//update the category to activity meta
    		echo $category;
    		// bp_activity_update_meta($activity_id, 'activity_category', $category);
    	}
    }
    
    function append_dropdown_activity_plus() {
    
    	?>
    	<script type="text/javascript">
    		jQuery.noConflict()
    
    		jQuery(document).ready(function () {
    		(function($){
    
    			var data = [
    				{
    					key  : 'key1',
    					text: 'value1'
    				},
    				{
    					key  : 'key2',
    					text: 'value2'
    				},
    				{
    					key  : 'key3',
    					text: 'value3'
    				},
    			];
    
    			var dropdown = $('<select/>').attr({'id': 'bpp_ex_custom_dropdown', 'name':'bpp_ex_custom_dropdown'});
    
    			$.each(data, function (i, v) {
    				dropdown.append($('<option/>').text(v.text).val(v.key));
    			})
    
    			console.log(dropdown);
    
    			setTimeout(function(){
    				dropdown.insertBefore('#bpfb_cancel_action');
    			},2000)
    		})(jQuery);
    		})
    	</script>
    <?php
    }

    But I can't see the category value been posted in the the console view of firebug.

    Do you know if there a a debugging tool I can use to see if it has been passed?

    Thank you

    V.

  • Hoang Ngo

    Hi @Victor,

    I hope you are well today and I'm sorry about the delay.

    Please update this to the javascript, this will catch the ajax request, and inject our parameter(category) to it. So now, the firebug will display the category in return :smiley:

    jQuery(document).ajaxSend(function (event, jqxhr, settings) {
    			//parse settings
    			var new_sets = settings.data.split('&');
    			var actions = ['post_update','bpfb_update_activity_contents'];
    			jQuery.each(new_sets, function (i, v) {
    				var data = v.split('=');
    				if (data[0] == 'action') {
    					if (jQuery.inArray(data[1], actions) > -1) {
    						//append new data
    						settings.data+='&bpp_ex_custom_dropdown='+jQuery('#bpp_ex_custom_dropdown').val();
    					}
    				}
    			})
    		});

    So finally, the whole code will be like this

    add_action( 'wp_footer', 'append_dropdown_activity_plus' );
    add_action( 'bp_activity_posted_update', 'after_activity_posted_55123', 10, 3 );
    
    function after_activity_posted_55123( $content, $user_id, $activity_id )
    {
    	//get the category from POST
    	$category = isset($_POST['bpp_ex_custom_dropdown'])?$_POST['bpp_ex_custom_dropdown']:null;
    
    	if(!is_null($category)){
    		//update the category to activity meta
    		echo $category;
    		// bp_activity_update_meta($activity_id, 'activity_category', $category);
    	}
    }
    
    function append_dropdown_activity_plus() {
    
    	?>
    	<script type="text/javascript">
    		jQuery(document).ready(function () {
    			(function($){
    
    				var data = [
    					{
    						key  : 'key1',
    						text: 'value1'
    					},
    					{
    						key  : 'key2',
    						text: 'value2'
    					},
    					{
    						key  : 'key3',
    						text: 'value3'
    					},
    				];
    
    				var dropdown = $('<select/>').attr({'id': 'bpp_ex_custom_dropdown', 'name':'bpp_ex_custom_dropdown'});
    
    				$.each(data, function (i, v) {
    					dropdown.append($('<option/>').text(v.text).val(v.key));
    				})
    
    				setTimeout(function(){
    					dropdown.insertBefore('#bpfb_cancel_action');
    				},2000)
    			})(jQuery);
    		});
    		jQuery(document).ajaxSend(function (event, jqxhr, settings) {
    			//parse settings
    			var new_sets = settings.data.split('&');
    			var actions = ['post_update','bpfb_update_activity_contents'];
    			jQuery.each(new_sets, function (i, v) {
    				var data = v.split('=');
    				if (data[0] == 'action') {
    					if (jQuery.inArray(data[1], actions) > -1) {
    						//append new data
    						settings.data+='&bpp_ex_custom_dropdown='+jQuery('#bpp_ex_custom_dropdown').val();
    					}
    				}
    			})
    		});
    	</script>
    <?php
    }

    Please give it a try and let us update.

    Best regards,
    Hoang

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.