Add custom metadata to forum topics for sorting purposes
-
[Updates] Well, it worked for a good while, and just when I was good and ready to launch, things went haywire again. I appreciate all who have helped me find my bearings thus far. Hopefully this journey will have a happy ending (without any plot twists )
Hello all,
I’ll try to break down what I’m trying to accomplish as clearly as possible.
1. I want to add custom metadata to forum posts, which I will use to sort form posts into “categories” (using custom loops that will only display posts that contain certain metadata). I’ve been looking at Rate Forum Posts (http://is.gd/oyinad) and I’m struggling to decipher how the author managed to so easily add custom metadata to the bp_bb_meta table. It’s pretty slick stuff. If somebody could point me to the basic idea I’d be very grateful.
2. The user will generate the custom metadata when he or she wants to create a new form post. I will have to customize the forum’s ‘New Topic’ form, to accept the metadata, and insert it into the bp_bb_meta table hen the user submits the form. The metadata consists of a fixed set of values that will be presented as options for the user to choose from via check-boxes and radio buttons. The form must be validated to ensure that the user selected at least one checkbox, and one of the two radio buttons. Again, I’m trying to figure out the basics of modifying the form, as well as form validation.
So here’s what I need my customized installation of BuddyPress to be able to do:
1. User logs in, goes to the forum and types up a new post (standard stuff)
2. User must select at least one of three options from a check list, AND one of two radio buttons. If the user fails to do this, the new post will fail, with an error message, and the user will have to select the required options
3. The form will submit the data to the appropriate tables, including the custom metadata that the user selected
4. The post will be called by the appropriate loop, which will only output posts that contain the required metadataSo, that’s the basic plan. I’m now trying to figure out how to code it. I’ll post my findings here for all to benefit, but I’d really appreciate and hints, tips or pointers. Maybe I’m going about it the wrong way.
Thanks for your time and consideration.
-
Any suggestions would be helpful. I could particularly use a jump-start on adding data to a table, via a form. I’ll post any finds here.
Okay here’s what I’ve come up with so far. It doesn’t do anything (neither works, nor breaks the website) so I’m definitely doing something wrong. Could somebody point it out?
In functions.php
1. cg_newmeta: take the metadata and add it to the bp_bb_meta table. Code taken from BP Rate Forum Post
2. cg_postcatagory: retrieve the metadata from the user input via a custom forum.phpCode snippet from functions.php
`
function cg_newmeta( $id, $postcat ) {
if ( !$id || !$postcat )
return false;
global $wpdb, $bbdb;do_action( ‘bbpress_init’ );
$catagory = $wpdb->get_row( $wpdb->prepare( “SELECT meta_id, meta_value FROM {$bbdb->meta} WHERE object_type = ‘bb_cgcat’ AND meta_key = ‘cg_catagory’ AND object_id = {$id}” ) );
$wpdb->query( $wpdb->prepare( “REPLACE INTO {$bbdb->meta} ( meta_id, object_type, object_id, meta_key, meta_value ) VALUES (%d, %s, %d, %s, %d )”, $rating->meta_id, ‘bb_cgcat’, $id, ‘cg_catagory’, $postcat ) );
}function cg_postcatagory()
{
$post_id = $_POST;
$postmeta = $_POST;
cg_newmeta( $post_id, $postmeta );
}add_filter (‘bp_after_group_forum_post_new’, ‘cg_postcatagory’);
`
Code snipped from forum.php (relevant bit towards the end)
forum.php
`
`Okay, I got it semi-working.
1. The function, cg_newmeta, inserts a new record into bp_bb_meta table
2. It gets it’s data from the function, postcatagory.
3. cg_postcatagory() SHOULD get its data from the new topic form (forum.php). However, I haven’t figured out how to do that yet.Basically if I set the variables in cg_postcatagory(), then cg_newmeta() adds them to the bp_bb_meta table. If I try to get it from the New Topic form (in forum.php) via POST, then what happens is that bp_bb_meta gets updated with a record that has object_id set to 0, and meta_value is empty. So that means it’s not getting the relevant info from the New Topic form via POST, right?
Here’s the code so far:
functions.php
`
function cg_newmeta($getid, $getcat) {
global $wpdb, $bbdb;
$id = $getid;
$postcat = $getcat;do_action( ‘bbpress_init’ );
$wpdb->query( $wpdb->prepare( “INSERT INTO $bbdb->meta ( meta_id, object_type, object_id, meta_key, meta_value ) VALUES (%d, %s, %d, %s, %s )”, $catagory->meta_id, ‘bb_cgcat’, $id, ‘cg_catagory’, $postcat ) );
}function cg_postcatagory()
{
$post_id = $_POST;
$postmeta = $_POST;
cg_newmeta( $post_id, $postmeta );
}add_filter(‘bp_after_group_forum_post_new’, ‘cg_postcatagory’);
`
form.php is customized with“
Any ideas why cg_postcatagory() isn’t getting any info from the form?
Struggling to figure out a way to get a topic’s post_id. I have to approaches I’m considering.
1. Return the latest post’s id (somehow) and then increment it +1 for the object id (to match the new post)
2. Find a way to get the newest post id…Since the post_id is autoincrement, something tells me it’s not meant to be accessed directly. Is there a round-about way of getting it?
Bleh, so frustrating. I know the answer is in front of me somewhere. I’m just not l337 enough to see it yet.
The ‘bp_after_group_forum_post_new’ hook is used to add data to the template, rather than to process the data. So instead of manually editing the forum.php template, you would do something like:
`cg_add_post_metacat_html() {
echo ”;
}
add_action( ‘bp_after_group_forum_post_new’, ‘cg_add_post_metacat_html’ );`To process the post data, you would do something like:
`function cg_postcatagory( $post_id = false ) {
if ( empty( $post_id ) || empty( $_POST ) )
return false;$post_id = (int) $post_id;
$postmeta = $_POST;$cg_newmeta = ( cg_newmeta( $post_id, $postmeta ) ) ? true : false;
return $cg_newmeta;
}
add_action( ‘bp_forums_new_post’, ‘cg_postcatagory’ );`You’ll also need to adjust your newmeta function to something like:
`function cg_newmeta( $id, $postcat ) {
global $catagory, $wpdb, $bbdb;do_action( ‘bbpress_init’ );
$wpdb->query( $wpdb->prepare( “INSERT INTO $bbdb->meta ( meta_id, object_type, object_id, meta_key, meta_value ) VALUES (%d, %s, %d, %s, %s )”, $catagory->meta_id, ‘bb_cgcat’, $id, ‘cg_catagory’, $postcat ) );
}`And just as I thought I was drowning, Brandon Allen’s hand reaches into the dark waters of PHP/MySQL/BuddyPress and pulls me out. Thanks bro! This is exactly what I was looking for.
I’m gong to thoroughly review this and compare it against where I was stuck. This has been a great trial by fire for me, as a developer and a budding WordPress modder. I pray for many more of these experiences.
Thanks again for the assistance Back to coding I go!
Haha! No worries. Post back if you get stuck.
bbPress also has built-in functions for adding meta:
`bb_get_postmeta( $id, $key );
bb_update_postmeta( $id, $key, $value );`
You can find these functions in:
bb-includes/functions.bb-meta.phpMake sure bbPress is run first with:
`do_action( ‘bbpress_init’ );`r-a-y! Thanks for sharing the knowledge! It didn’t occur to me to look into bbPress’s functions. I’ll definitely look into it. I’m trying to figure out how to pass an array of meta, so that each post can individually have several user-selected meta associated with it. I have a feeling I’ll find my answers in functions.bb-meta.php
my tweaks, to get it accepting arrays. Sound code?
`function cg_newmeta( $id, $postcat) {
global $catagory, $wpdb, $bbdb;
do_action( ‘bbpress_init’ );
foreach ($postcat as $value)
{
$wpdb->query( $wpdb->prepare( “INSERT INTO $bbdb->meta ( meta_id, object_type, object_id, meta_key, meta_value ) VALUES (%d, %s, %d, %s, %s )”, $catagory->meta_id, ‘bb_cgcat’, $id, ‘cg_catagory’, $value ) );
}
}`
Looks okay. I would change:
`foreach ($postcat as $value)`
to
`foreach ((array)$postcat as $value)`
just in case something happens and $postcat isn’t an array.Have you tried r-a-y’s suggestion for using the `bb_get_postmeta()` and `bb_update_postmeta()` functions rather than a direct query?
Thanks for the tip! I’m going to have to figure out how to validate the form input to ensure that it’s an array (and that the check-boxes have been selected). That’s next on my to-do list after I’ve set up some custom loops to display posts based on the metadata I’ve created (will post the code when I’m done, so all can critique, and benefit)
Yes, I have tried r-a-y’s suggestion, and it worked like a charm (Thanks again r-a-y!) However, using bb_update_postmeta() wouldn’t allow me to assign an object_type, as far as I could tell, by passing it as an argument. I’m not even sure if a custom object_type is necessary, but I figured it couldn’t hurt, and could prove useful later on… I’d love to tinker more with this function, but I have deadlines to meet so I’ll push on ahead and review this later, once I’ve got more time. For now, it gets the job done
EDIT: Function, r-a-y style!
`function cg_newmeta( $id, $postcat) {
do_action (‘bbpress_init’);
bb_update_postmeta($id, ‘cg_catagory’, $postcat);
}`I’ve decided that I wanted to add “meta data” as topic tags, instead, so I could use the bp_has_forum_topics() so I filter posts easily. I’ve modified the functions you guys helped me make, using bb_add_topic_tags() however no new tags are added. I want the user to be able to add their own tags via the text area box, in addition to selecting from a set of tags via check-boxes. Here’s what I came up with:
`function cg_postcatagory( $post_id = false ) {
if ( empty( $post_id ) || empty( $_POST ) )
return false;$post_id = (int) $post_id;
$postmeta = $_POST;$cg_newmeta = ( cg_newmeta( $post_id, $postmeta ) ) ? true : false;
return $cg_newmeta;
}
add_action( ‘bp_forums_new_post’, ‘cg_postcatagory’ );function cg_newmeta( $id, $postcat) {
do_action (‘bbpress_init’);
bb_add_topic_tags($id, $postcat);
}`I have a feeling that there’s a conflict between the form.php new topic form’s text-area input, and the check-boxes input that I’ve added…
Confidence +1
Okay got it working it was so simple (thanks to you guys for drop kicking me into the right direction.) Next up, creating a custom forum loop that will retrieve the necessary tag from POST and display all topics that contain that tag.
`function cg_postcatagory( $post_id = false ) {
if ( empty( $post_id ) || empty( $_POST ) )
return false;$post_id = (int) $post_id;
$postmeta = $_POST;bb_add_topic_tags($post_id, $postmeta);
}
add_action( ‘bp_forums_new_post’, ‘cg_postcatagory’ );`Suddenly bb_add_topic_tags() stopped working.
How I isolated the problem: In function cg_postcatagory( $post_id = false ), I subbed out bb_add_topic_tags() with echo $postmeta (in a foreach loop) and upon posting a new post, it displayed the categories that I wanted saved to the database. So I know that bb_add_topic_tags() is getting the categories, but it just isn’t doing anything with them.
I’m going to install an older version of wp on my test server to see if the upgrade is what borked it. Because that’s the only thing I can think of at this point.
This function is literally the backbone of my site, and I was all set to launch too. If anybody could help me out I’d appreciate it.
Confidence -100
Panic +10Alright solved again. Turns out there was a mistake in my code. Here’s the breakdown:
Old Code:
`function cg_postcatagory( $post_id = false )
{
if ( empty( $post_id ) || empty( $_POST ) )
return false;$post_id = (int) $post_id;
$postmeta = $_POST;$cg_newmeta = ( cg_newmeta( $post_id, $postmeta ) ) ? true : false;
return $cg_newmeta;
}
add_action( ‘bp_forums_new_post’, ‘cg_postcatagory’ );`Initially I wanted the post to store custom metadata, but that turned out to be a pain in the neck to use, and unnecessarily complicated. So, I decided to store tags instead. The problem, I discovered, was that the function was using the post_id to store the tags, which apparently isn’t how it’s supposed to work. What I should have one was instead topic_id instead, since that’s what tags are attached to (according to the bb_terms_relationships table).
So I modified my function accordingly and ended up with
`function cg_postcatagory( $topic_id = false )
{
if ( empty( $topic_id ) || empty( $_POST ) )
return false;$topic_id = (int) $topic_id;
$postmeta = $_POST;$cg_newmeta = ( cg_newmeta( $topic_id, $postmeta ) ) ? true : false;
return $cg_newmeta;
}
add_action( ‘bp_forums_new_topic’, ‘cg_postcatagory’ );`And it worked, testing it on the latest stable WordPress (3.2.1) and BuddyPress (1.2.9) and so far so good. If the code is solid, I hope somebody benefits from this. if It isn’t, I hope somebody can point out the holes in it, so I can plug them up.
Will set the status of this thread to Resolved (permanently this time, I hope)
Menelik, thanks so much for writing out your work and your thought process so clearly. I needed to add custom metadata to a topic, and I was able to get it working in under an hour following your example. I really appreciate it!
- The topic ‘Add custom metadata to forum topics for sorting purposes’ is closed to new replies.