Passing Custom Field Data as Array to be Saved (Resulting Custom Field Array is inconsistent)

I’ve been staring at this for hours, and it’s clear I’m missing something, but I don’t know what it can be…

I have custom meta box for adding downloads to a particular post or page. All the data is save into one custom field key as an array. For each “download” we enter 3 pieces of info: resource name (input=text), resource link(input=text), and resource type (select list of like pdf,zip file, video, etc).

Read More

The problem is when I save the data, it gets rearranged somehow, the order the data gets saved in and the resulting custom field array after the save is not consistent. And while saving, if I watch my log, data seems to be inserted randomly into the array for this custom field key.

Here’s the function which saves the data: http://pastebin.com/TY6LFuiL

The specific section is question starts just below this comment:
// If passed along is an array, we should remove all previous data

Here’s the bit that outputs the options: http://pastebin.com/EGF4dibZ – This is where things are getting messed up because, the order the data is saved and the order of the data in the resulting array for the custom field key is not consistent.

For example, if I save the options as:

input 1(text): Resource Name 1 - wsm-content-downloads[]

input 2(text): http://link.com/1.pdf - wsm-content-downloads[]

input 3(select): PDF - wsm-content-downloads[]

The array looks like this BEFORE being saved:

Array
(
    [0] => Resource Name 1
    [1] => http://link.com/1.pdf
    [2] => PDF
)

Then the function that saves the data, goes through and for each value of this array, saves it as custom field data for the same key (wsm-content-downloads) – which results in an array after saving:

Array
(
    [0] => http://link.com/1.pdf
    [1] => Resource Name 1
    [2] => PDF
)

Here’s a more detailed log:

http://pastebin.com/cdDsN5Sk

(had to code sample that last link because of limit on links)

I print out the custom field data as an array after each save/update in the loop. You can see how the data is saved is not consistent at all… sometimes the value being saved/updated goes at the beginning of the resulting custom field data array, sometimes at the end and sometimes even shoved right in the middle…

I need the custom field data array for this key (wsm-content-downloads) to be identical to the array I pass to the save function after all is said and done, but for some reason, it’s not coming out like that…

And perhaps the worst part is, this code works perfectly on my local server – on my live server it’s doing this…

Thanks in advance…

Cheers,
Bryan

Related posts

Leave a Reply

1 comment

  1. Definite solution: Seeing as wp’s core get_post_custom function returns multiple data fields saved as a single key in a random order, I resolved the issue by writing a function to replace it – which has some added flexibility:

      /*---------------------------------------------------------------
      Function: Retrieve post meta field for a post based on ID 
      Usage: [admin/meta_box/downloads.php] = to replace core wp get_post_custom function
      Params: $id = post id, $key = meta key, $order = ASC|DESC, 
        $return = meta_value|meta_key|post_id|meta_id, $single = true|false
      @return = result will be array unless $single = true, which will return the last result only
    ----------------------------------------------------------------*/
    function noconflict_get_post_custom($id,$key,$single=false,$column='meta_value',$order='ASC'){
        global $wpdb;
        $data = $wpdb->get_results("
        SELECT * FROM $wpdb->postmeta WHERE post_id = $id
        AND meta_key LIKE '$key'
        ORDER by meta_id $order
        ");
    
        if( !empty( $data ) ) {
            $metadata = array();
            foreach( $data as $result_object ) {
                $metadata[] = $result_object->$column;
            }
            if ($single)
                return $metadata[0];
            else
                return $metadata;
        }
    }