0

I'm using s2member and I added a new registration field to my registration form. s2member stores all custom registration fields in an array under the meta key wp_s2member_custom_fields. An example array (private data is x'd out) looks like this:

a:15:{s:14:"street_address";s:19:"xx xxxxxxxx xxxxxxx";s:4:"city";s:15:"xxxxxxxxxxx xxxx";s:12:"can_province";s:2:"NS";s:7:"country";s:2:"CA";s:10:"postalcode";s:7:"xxx xxx";s:5:"phone";s:12:"xxx-xxx-xxxx";s:17:"weaving_interests";a:10:{i:0;s:6:"iw_gen";i:1;s:6:"iw_bas";i:2;s:6:"iw_bla";i:3;s:7:"iw_fash";i:4;s:5:"iw_FA";i:5;s:7:"iw_felt";i:6;s:6:"iw_lin";i:7;s:9:"iw_design";i:8;s:6:"iw_rug";i:9;s:6:"iw_sao";}s:14:"spin_interests";a:2:{i:0;s:7:"is_wool";i:1;s:7:"is_misc";}s:12:"is_misc_desc";s:110:"alpaca, bamboo, seacell...  pretty much any fibre - primarily animals based - as long as it's soft and pretty!";s:13:"dye_interests";a:2:{i:0;s:7:"id_chem";i:1;s:6:"id_nat";}s:8:"ew_count";s:1:"6";s:8:"ew_about";s:202:"36" eight shaft jack loom
45" four shaft jack loom
25" 16 shaft table loom
15" four shaft table loom
tapestry loom
1 1/2 inkle looms (the second one is under construction)
20ish" rigid heddle loom";s:7:"ec_spin";s:1:"3";s:8:"es_about";s:392:"- Ashford traveller which I love - it's my primary wheel
- a homemade wheel which is a little heavy and a tiny bit clunky, but spins nice yarn - it's at my cottage
- a small antique wheel that I use mostly for display and have never used (I haven't gotten around to putting a drive band on it yet)
- I also have a few drop spindles, including one I made this summer from a rock and a stick";s:8:"eo_about";s:80:"I love my drum carder for blending colours and making very cool rovings to spin!";}

I attempted to add my new field loomsong_del to this array.

a:16:{ ....;s:12:"loomsong_del";s:5:"email";} //desired result
a:2:{i:0;a:15:{ ....}s:12:"loomsong_del";s:5:"email";} //actual result

To correct the situation I tried this:

    $s2_custom=get_user_meta($u->ID, 'wp_s2member_custom_fields');
    $real = $s2_custom[0];
    $real['loomsong_del']='email';
    update_user_meta($u->ID,  'wp_s2member_custom_fields',$real);

which resulted in this:

a:2:{i:0; a:16:{ ....;s:12:"loomsong_del";s:5:"email";} s:12:"loomsong_del";s:5:"email";} 
//should be a:16:{ ....;s:12:"loomsong_del";s:5:"email";} only

How can I fix it?

2
  • Please always link to plugins you're using... Commented Aug 31, 2012 at 16:33
  • @kaiser: I've added the link to s2member, but in this case I think it likely that the particular plugin is immaterial. Commented Aug 31, 2012 at 16:35

1 Answer 1

2

This code is your problem:

$s2_custom=get_user_meta($u->ID, 'wp_s2member_custom_fields');
$real = $s2_custom[0];
$real['loomsong_del']='email';
update_user_meta($u->ID,  'wp_s2member_custom_fields',$real);

get_user_meta returns an array of the meta values. Since in this case there's only a single value with the array, you need to pass the single parameter to it.

Try this:

$s2_custom=get_user_meta($u->ID, 'wp_s2member_custom_fields', true);
$s2_custom['loomsong_del']='email';
update_user_meta($u->ID,  'wp_s2member_custom_fields',$s2_custom);

This won't fix your already broken data in the DB, BTW. You'll need to fix that by hand or by code to read the broken array and rebuild the correct one.

Edit: To clarify what I'm talking about...

Meta data can be stored independently as separate rows in the Database, and all the meta functions assume that's what you're doing, even when you're not.

So if I call add_user_meta(1, 'foo', 'value1'); and add_user_meta(1, 'foo', 'value2');, then I actually have two rows in the database there.

If I were to then call get_user_meta(1, 'foo'); then the code actually returns an array with value1 and value2 in it. It makes those separate rows into an array for me.

Now, if I actually only have 1 entry, then I don't necessarily need it wrapped in an array. In which case I can call get_user_meta(1, 'foo', true); to only return the first result, one row, by itself, no array wrapping. That hidden array wrapping is what got you the first time, because it sent back an array within an array that you didn't expect.

Undoing the problem basically means going through and reading out the meta, finding the actual data you want in the array of arrays, then modifying it properly and updating it back into the database.

3
  • I think there is a misunderstanding. The code you mark as incorrect was to fix the initial change I had made which produced a:2:{i:0;a:15:{ ....}s:12:"loomsong_del";s:5:"email";}. Strangely, my initial change was made using code very similar to what you suggest: ` $s2_custom=get_user_meta($u->ID, 'wp_s2member_custom_fields'); $old=$s2_custom; if(!array_key_exists('loomsong_del', $s2_custom)){ $s2_custom['loomsong_del']='email'; update_user_meta($u->ID, 'wp_s2member_custom_fields', $s2_custom); }` Commented Aug 31, 2012 at 17:26
  • 1
    I actually changed my answer after re-reading, however fixing your data isn't that easy. And I can see why your initial code produced that result, since you didn't include true for the $single parameter to the get_user_meta call. Commented Aug 31, 2012 at 17:28
  • ah! I thought I didn't need $single since the data was already an array. But I guess I ended up with array(0=>$mydataarr). Commented Aug 31, 2012 at 18:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.