Skip to main content
added 1006 characters in body
Source Link
Stephen Harris
  • 32.6k
  • 6
  • 84
  • 118

This was too much to put asMany of the comments below refer to code used for debugging, which for clarity I've removed.

I should have spotted this soon - you are adding only one row into the postmeta table, and that row has the key _my_meta. Before inserting the array int the table, WordPress serializes the array. When you retrieve the meta, you are retrieving a commentserialized array which you would then need to unserialize.

However, I shall removedon't think this later or replaceis what you want, (nor is it withadvisable). It would be better to save each of the values in the array as a solutionseparate key-value pair in the database (this would be more effecient, and allowing querying of specific key-values etc).

@Cristian, couldTo do that you tryneed to loop through the followingreceived data array and add each key-value individually: (I have relaced your code with appropriate comments)

function my_meta_save($post_id) {
     
// verify this is not an auto save routine. 
   if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id;

   //VerifyPerform nonce
  checks & ifpermissions (!wp_verify_nonce($_POST['my_meta_noncename'],__FILE__))
       for wp_die('Noncepages checkand failure'posts);

    if//Sanitize ($_POST['post_type']the ==input 'page'){ 

//Declare a white list of 'keys' with their ifdefaults (!current_user_can('edit_page',or $post_id)null) 
 //- i.e. this code will not add wp_die('Permissionany checkother failure');keys:
$whitelist = array(
  } 
  'title'=>null,
    $current_data'img01-title'=>null,
 = get_post_meta($post_id, '_my_meta', TRUE'img01-url'=>null
);  
    $new_data =//It $_POST['_my_meta'];
would probably make sense echoto 'currentdo data:'
this before sanitzing.  
 echo '<pre>';
  $new_data = var_dumpshortcode_atts($current_data$whitelist,$new_data);
   
  echo '</pre>';
 /Now add/update or echoremove 'sentkey-values data:';appropriately
    echo '<pre>';
 foreach ($whitelist as var_dump($new_data$key=>$value);{
    echo '<pre>';

    //my_meta_clean($new_data); Ignore this while debugging
    ifIf ($current_data)the 
 key has a value, {
update it. If it doesn't already exist it will var_dump('Currentadd data');it
        if (!is_null($new_data$whiltelist[$key])) 
 $ret =delete_post_meta($post_id,'_my_meta');
        else $ret =  update_post_meta($post_id,'_my_meta'$key,$new_data$value);
    }
    elseif (!is_null($new_data))else
    {
        $ret = add_post_metadelete_post_meta($post_id,'_my_meta',$new_data,TRUE$key);
    }else{
         wp_die('no data recieved');
    }
    //No need to return, this wp_die('success:'.$ret);
is an action not returna $post_id;filter
 }

Not tested ##Remarks##

  1. I've added an auto-save check so that data is updated when the post/page auto saves
  2. You've checked permissions if the post is a page - you should do this for posts too.
  3. I've made use of shortcode_atts which will remove any keys that you haven't declared in $whitelist. It will assign default values to keys that are missing/don't have a value.
  4. update_post_meta will add a new key if it doesn't exist

This was too much to put as a comment, I shall remove this later or replace it with a solution.

@Cristian, could you try the following:

function my_meta_save($post_id) {
    // verify this is not an auto save routine. 
   if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id;

   //Verify nonce
    if (!wp_verify_nonce($_POST['my_meta_noncename'],__FILE__))
        wp_die('Nonce check failure');

    if ($_POST['post_type'] == 'page'){
        if (!current_user_can('edit_page', $post_id)) 
        wp_die('Permission check failure');
    } 
 
    $current_data = get_post_meta($post_id, '_my_meta', TRUE);  
    $new_data = $_POST['_my_meta'];
    echo 'current data:'
    echo '<pre>';
    var_dump($current_data);
    echo '</pre>';
    echo 'sent data:';
    echo '<pre>';
    var_dump($new_data);
    echo '<pre>';

    //my_meta_clean($new_data); Ignore this while debugging
    if ($current_data) 
     {
         var_dump('Current data');
        if (is_null($new_data)) $ret =delete_post_meta($post_id,'_my_meta');
        else $ret = update_post_meta($post_id,'_my_meta',$new_data);
    }
    elseif (!is_null($new_data))
    {
        $ret = add_post_meta($post_id,'_my_meta',$new_data,TRUE);
    }else{
         wp_die('no data recieved');
    }
         wp_die('success:'.$ret);
    return $post_id;
}

Not tested

Many of the comments below refer to code used for debugging, which for clarity I've removed.

I should have spotted this soon - you are adding only one row into the postmeta table, and that row has the key _my_meta. Before inserting the array int the table, WordPress serializes the array. When you retrieve the meta, you are retrieving a serialized array which you would then need to unserialize.

However, I don't think this is what you want, (nor is it advisable). It would be better to save each of the values in the array as a separate key-value pair in the database (this would be more effecient, and allowing querying of specific key-values etc).

To do that you need to loop through the received data array and add each key-value individually: (I have relaced your code with appropriate comments)

function my_meta_save($post_id) {
 
// verify this is not an auto save routine. 
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id;

//Perform nonce checks & permissions (for pages and posts)

//Sanitize the input  

//Declare a white list of 'keys' with their defaults (or null)
//- i.e. this code will not add any other keys:
$whitelist = array(
    'title'=>null,
    'img01-title'=>null,
    'img01-url'=>null
);
   //It would probably make sense to do this before sanitzing.  
    $new_data = shortcode_atts($whitelist,$new_data);
 
   //Now add/update or remove key-values appropriately
   foreach ($whitelist as $key=>$value){
        //If the key has a value, update it. If it doesn't already exist it will add it
        if(!is_null($whiltelist[$key])) 
              update_post_meta($post_id,$key,$value);
        else
              delete_post_meta($post_id,$key);
    }

    //No need to return, this is an action not a filter
 }

##Remarks##

  1. I've added an auto-save check so that data is updated when the post/page auto saves
  2. You've checked permissions if the post is a page - you should do this for posts too.
  3. I've made use of shortcode_atts which will remove any keys that you haven't declared in $whitelist. It will assign default values to keys that are missing/don't have a value.
  4. update_post_meta will add a new key if it doesn't exist
added 113 characters in body
Source Link
Stephen Harris
  • 32.6k
  • 6
  • 84
  • 118

This was too much to put as a comment, I shall remove this later or replace it with a solution.

@Cristian, could you try the following:

function my_meta_save($post_id) {
    // verify this is not an auto save routine. 
   if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id;

   //Verify nonce
   if (!wp_verify_nonce($_POST['my_meta_noncename'],__FILE__))
        wp_die('Nonce check failure');

    if ($_POST['post_type'] == 'page'){
        if (!current_user_can('edit_page', $post_id)) 
        wp_die('Permission check failure');
    } 

    $current_data = get_post_meta($post_id, '_my_meta', TRUE);  
    $new_data = $_POST['_my_meta'];
    echo 'current data:'
    echo '<pre>';
    var_dump('<pre>'.$current_data.'</pre>'.);
    echo '</pre>';
    $new_dataecho ='sent $_POST['_my_meta'];data:';
    echo '<pre>';
    var_dump('<pre>'.$new_data.'</pre>'.);
    echo '<pre>';

    //my_meta_clean($new_data); Ignore this while debugging
    if ($current_data) 
    {
         var_dump('Current data');
        if (is_null($new_data)) $ret =delete_post_meta($post_id,'_my_meta');
        else $ret = update_post_meta($post_id,'_my_meta',$new_data);
    }
    elseif (!is_null($new_data))
    {
        $ret = add_post_meta($post_id,'_my_meta',$new_data,TRUE);
    }else{
         wp_die('no data recieved');
    }
         wp_die('success:'.$ret);
    return $post_id;
}

Not tested

This was too much to put as a comment, I shall remove this later or replace it with a solution.

@Cristian, could you try the following:

function my_meta_save($post_id) {
    // verify this is not an auto save routine. 
   if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id;

   //Verify nonce
   if (!wp_verify_nonce($_POST['my_meta_noncename'],__FILE__))
        wp_die('Nonce check failure');

    if ($_POST['post_type'] == 'page'){
        if (!current_user_can('edit_page', $post_id)) 
        wp_die('Permission check failure');
    } 

    $current_data = get_post_meta($post_id, '_my_meta', TRUE);  
    var_dump('<pre>'.$current_data.'</pre>'.);

    $new_data = $_POST['_my_meta'];
    var_dump('<pre>'.$new_data.'</pre>'.);

    //my_meta_clean($new_data); Ignore this while debugging
    if ($current_data) 
    {
         var_dump('Current data');
        if (is_null($new_data)) $ret =delete_post_meta($post_id,'_my_meta');
        else $ret = update_post_meta($post_id,'_my_meta',$new_data);
    }
    elseif (!is_null($new_data))
    {
        $ret = add_post_meta($post_id,'_my_meta',$new_data,TRUE);
    }else{
         wp_die('no data recieved');
    }
         wp_die('success:'.$ret);
    return $post_id;
}

Not tested

This was too much to put as a comment, I shall remove this later or replace it with a solution.

@Cristian, could you try the following:

function my_meta_save($post_id) {
    // verify this is not an auto save routine. 
   if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id;

   //Verify nonce
   if (!wp_verify_nonce($_POST['my_meta_noncename'],__FILE__))
        wp_die('Nonce check failure');

    if ($_POST['post_type'] == 'page'){
        if (!current_user_can('edit_page', $post_id)) 
        wp_die('Permission check failure');
    } 

    $current_data = get_post_meta($post_id, '_my_meta', TRUE);  
    $new_data = $_POST['_my_meta'];
    echo 'current data:'
    echo '<pre>';
    var_dump($current_data);
    echo '</pre>';
    echo 'sent data:';
    echo '<pre>';
    var_dump($new_data);
    echo '<pre>';

    //my_meta_clean($new_data); Ignore this while debugging
    if ($current_data) 
    {
         var_dump('Current data');
        if (is_null($new_data)) $ret =delete_post_meta($post_id,'_my_meta');
        else $ret = update_post_meta($post_id,'_my_meta',$new_data);
    }
    elseif (!is_null($new_data))
    {
        $ret = add_post_meta($post_id,'_my_meta',$new_data,TRUE);
    }else{
         wp_die('no data recieved');
    }
         wp_die('success:'.$ret);
    return $post_id;
}

Not tested

Source Link
Stephen Harris
  • 32.6k
  • 6
  • 84
  • 118

This was too much to put as a comment, I shall remove this later or replace it with a solution.

@Cristian, could you try the following:

function my_meta_save($post_id) {
    // verify this is not an auto save routine. 
   if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id;

   //Verify nonce
   if (!wp_verify_nonce($_POST['my_meta_noncename'],__FILE__))
        wp_die('Nonce check failure');

    if ($_POST['post_type'] == 'page'){
        if (!current_user_can('edit_page', $post_id)) 
        wp_die('Permission check failure');
    } 

    $current_data = get_post_meta($post_id, '_my_meta', TRUE);  
    var_dump('<pre>'.$current_data.'</pre>'.);

    $new_data = $_POST['_my_meta'];
    var_dump('<pre>'.$new_data.'</pre>'.);

    //my_meta_clean($new_data); Ignore this while debugging
    if ($current_data) 
    {
         var_dump('Current data');
        if (is_null($new_data)) $ret =delete_post_meta($post_id,'_my_meta');
        else $ret = update_post_meta($post_id,'_my_meta',$new_data);
    }
    elseif (!is_null($new_data))
    {
        $ret = add_post_meta($post_id,'_my_meta',$new_data,TRUE);
    }else{
         wp_die('no data recieved');
    }
         wp_die('success:'.$ret);
    return $post_id;
}

Not tested