Need to store additional information about a Membership subscription

I just got Membership up and working and booyaa! It's working just like I hoped it would. However, I need to store a few extra fields of information about each subscription. I would store them as user_metadata, but they need to be on a subscription by subscription basis, not per user.

I have a separate table to store everything, but I'm not sure of the best method to link it to the subscription. I'm going to tie it to the rel_id column of the wp_[blogid]_m_membership_relationships table, so it has to be after the subscription is successfully signed up.

I could:
1. Create my record before and try and hook it all in somewhere when paypal calls back to Membership to activate the subscription. I would have to send something to paypal and back.

2. I could just send the extra fields to paypal and then create the record as paypal calls back and activates the subscription.

3. Create the record and tie it to the subscription record before it goes to paypal if the subscription record is created after step #1. (It doesn't look like it is)

Is there a proper way to customize the screens or paypal links to send extra data to be returned? Is there a way to customize the activation process when paypal calls the notify_url?

I'm sure I could hack this any number of ways, but I'd like to modify Membership as little as possible. So far I can't even find where the code for do_action('membership_payment_processed' .... is. Any suggests on the best way to do this would be great. Even just where the do_action hooks are processed.

I also tried doing a ping. First I don't think I will get the information I need and second my test ping didn't work. I found this in the apache logs:

[Sun Jul 10 02:03:37 2011] [error] [client 173.0.82.126] PHP Fatal error: Call to undefined function apply_filter() in /home/highfive/public_html/wp-content/plugins/membership/membershipincludes/classes/class.ping.php on line 326

Thanks

  • highfive

    Ok, in addition to fixing the ping, I need some more variables, including the userid which is supposed to be available, but always comes across blank in the ping. I fixed that and added 2 more. I need the IDs of certain records so I can look stuff up properly in the database and not just their descriptions.

    Is there any chance that the changes I've made to class.ping.php can be made part of the plugin in the future? I don't really know what I am doing for sure, so please if there is a better way to do what I've changed please let me know.

    Also, if someone could figure out how to get the rel_id of the relationship that just changed (or at least was just added) that would be awesome.

    I've attached my modified file. The differences seem pretty minor.

  • highfive

    The 2.1 Beta fixed the missing userid and added useremail. So that's definitely a step in the right direction, thank you. I fixed the userid pingconstant the same way you did, so at least I got that right.

    2.1 didn't fix the fatal error in the 'default' case I mentioned above and I still need the blog_id and site_id (networkid). Since I can't attach source files I'll just note my small changes here. If there is any chance they can make it into 2.1 that would be great, assuming I haven't done something wrong.

    LINE 28:

    var $pingconstants = array('%blogname%' => '',
    '%blogurl%' => '',
    '%blogid%' => '',
    '%username%' => '',
    '%usernicename%' => '',
    '%useremail%'	=>	'',
    '%userid%'		=>	'',
    '%networkname%' => '',
    '%networkurl%' => '',
    '%networkid%' => '',
    '%subscriptionname%' => '',
    '%levelname%' => '',
    '%timestamp%' => ''
    );

    LINE 273: (I left out the unchanged cases for brevity)

    global $current_blog;
    foreach($pingdata as $key => $value) {
       switch($key) {
    ...
          case '%networkid%': $pingdata[$key] = $current_blog->site_id;
                                         break;
          case '%blogid%':	     $pingdata[$key] = $current_blog->blog_id;
                                         break;
          default:                    $pingdata[$key] = apply_filters( 'membership_pingfield_' . $key, '' );
                                         break;
       }
    }
  • highfive

    So my plan is to put some script code into my sign-up page that will hijack the paypal forms and add some extra fields to each subscription option. Then when they click to go to paypal, I will first AJAX up the extra information I've gathered and tie it to the user_id, blog_id and site_id.

    Once the paypal process completes I have a ping setup that sends me those three items, allowing me to lookup the newly created membership relationship record. I can also look up my extra information in the database and populate the rel_id onto my extra information.

    End result, I have a jQuery datatables plugin table that creates a Member Wall. By creating a join between my table and the wp_[blogid]_m_membership_relationship table, I can show which active members have been signed up the longest what type of member they are and a bunch of other information I've gathered during the sign up process.

    If I can the IDs passed in the ping like my code above instead of just names and my script to work, I should be able to avoid any custom changes to Membership. I suppose I could look up the blog by blog name and reverse the blog_id out of the table name, but that would be really really ugly. :slight_smile:

  • highfive

    For posterity:

    I used jQuery to add some fields to the actual paypal form generated by Membership and put an id attribute on the forms.

    jQuery("DIV.priceforms form").each(function (index, domEle) {
    	domEle.id = 'payform'+index;
    	var cTable = jQuery('#copytable').clone();
    	cTable.attr('id','paytable'+index);
    	cTable.prependTo(domEle);
    });

    Then I hijacked the submit of the form to first ajax my fields up and continue or halt the submit based on the results of my ajax:

    jQuery("DIV.priceforms form").submit(function() {
    	return ajaxExtraFields(this);
    });
    
    var submitTheForm = false;
    function ajaxExtraFields(payform)
    {
    	submitTheForm = false;
    	var options = {
    		success:	doAjaxResponse,
    		url:		'<?php bloginfo('stylesheet_directory');?>/handle-extra-sub-fields-ajax.php',
    		async:   	false,
    		cache:   	false
    	};
    
       	jQuery("#"+payform.id).ajaxSubmit(options);
    	return submitTheForm;
    }
    
    function doAjaxResponse(data)
    {
    	if (data == 'success')
    	{
      		submitTheForm = true;
     	}
     	else
     	{
      		submitTheForm = false;
      	}
    }

    I'm sure I could generalize this into some kind of subscription_user_meta table, but for now I just have hard-coded fields. This is the first jQuery stuff I've done so there may be better ways to do some of it.

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.