Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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?

share|improve this question
    
Please always link to plugins you're using... –  kaiser Aug 31 '12 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. –  dnagirl Aug 31 '12 at 16:35

1 Answer 1

up vote 1 down vote accepted

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.

share|improve this answer
    
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); }` –  dnagirl Aug 31 '12 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. –  Otto Aug 31 '12 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). –  dnagirl Aug 31 '12 at 18:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.