WordPress.org

Ready to get started?Download WordPress

Forums

Passing Custom Field Data as Array to be Saved (Resulting Array is Inconsistent) (5 posts)

  1. FueledPub
    Member
    Posted 2 years ago #

    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).

    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, when I pass it to my save function:

    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

    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

  2. esmi
    Forum Moderator
    Posted 2 years ago #

    Save each piece of download data as a separate custom field.

  3. FueledPub
    Member
    Posted 2 years ago #

    Esmi,

    Thanks for the suggestion, but that's not really what I'm looking to do... I need the data saved as an array in single meta key. It's not really efficient for me to save each piece of data as a separate custom field.

    Thanks though...

    Bryan

  4. FueledPub
    Member
    Posted 2 years ago #

    So the solution is to simply define names for the keys. For example instead of:

    <input style=\"width:25%;\" name=\"wsm-content-downloads[]\" onblur=\"if (this.value == '') { this.value='Download/Resource Name...';} \" onfocus=\" if (this.value == 'Download/Resource Name...') { this.value = ''; }\" value=\"Download/Resource Name...\" />

    Using this:

    <input style=\"width:25%;\" name=\"wsm-content-downloads['name']\" onblur=\"if (this.value == '') { this.value='Download/Resource Name...';} \" onfocus=\" if (this.value == 'Download/Resource Name...') { this.value = ''; }\" value=\"Download/Resource Name...\" />

    The thing that still stumps me is I don't understand why this even matters.

    I'm assuming the wp function add_post_meta does not save the data as a serialized array but instead creates new rows for every record in the array I pass to the save function...

    Then, when wp function get_post_custom grabs the custom field data is returns an array of the values of rows where meta key is _______...

    And apparently it doesn't return them in the same order they were added to the database, which seems weird to me. And it's even weirder that by simply adding a name for the key that it resolves the issue.

    ...and yet even weirder that the original code works perfectly on my local (MAMP) - same WP version - same all around and doesn't work on my live site...

    So many questions :D

    Bryan

  5. FueledPub
    Member
    Posted 2 years ago #

    Let me retract that last post... In fact, that does absolutely nothing to resolve the issue.

    The problem is the wp function get_post_custom returns data randomly, not by meta_id as you might expect... Once I realized this, I wrote a quick function to replace it and add more flexibility...

    /*---------------------------------------------------------------
      Function: Retrieve post meta field for a post based on ID
      Usage: [admin/meta_box/downoads.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;
    	}
    }

    This works perfectly...

Topic Closed

This topic has been closed to new replies.

About this Topic