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.

My function does exactly what I want it to do: I'm trying to add/update meta fields in another post type when an "events" post is saved. Except the post needs to be updated twice for the information to update on the front end. What am I doing wrong?

  function bam_create_next_show_meta($post_id) {
        if(get_post_type() == 'tribe_events') {
            $meta = get_post_meta($post_id, $_artistMeta->$post_id, TRUE);
            $artists = unserialize($meta['_artistMeta'][0]);

            if($meta) {
                $event_link = get_permalink();
                $eventVenue = tribe_get_venue();
                if($eventVenue) {
                    $eventVenueSplit = explode (' ', $eventVenue, 3);
                    if($eventVenueSplit[0] == 'Centro' && $eventVenueSplit[1] == 'Cultural') {
                        $eventVenue = ' en C.C. '.$eventVenueSplit[2];
                    } elseif($eventVenueSplit[0] == 'Biblioteca') {
                        $eventVenue = ' en Bibl. '.$eventVenueSplit[1].' '.$eventVenueSplit[2];
                    } else {
                        $eventVenue = ' en '.$eventVenue;
                    }
                } else {
                    $eventVenue = '';
                }

                $eventStartDate = tribe_get_start_date($postID,false,'j');
                $eventStartMonth = tribe_get_start_date($postID,false,'M');

                $event_sort = tribe_get_start_date($postID,false,'Y-m-d');

                $es_eventStartMonth = strftime('%b', strtotime($eventStartMonth));

                $event_title = 'Proxima fecha: <span class="c1 me">'.$eventStartDate.' de '.$es_eventStartMonth.$eventVenue.'</span>';

                foreach ($artists['artistName'] as $artist) {
                    if($myid == $artist)
                        continue;
                    $output[] = $artist;
                    $myid = $artist;
                }

                global $post;

                $artistas = get_posts(array('post_type'=> 'artistas','post__in' => $output, 'posts_per_page' => -1));

                foreach($artistas as $artista) {
                    setup_postdata($post);

                    $artistID = $artista->ID;

                    $artist_event_id = get_post_meta($artistID, 'artistEventId', true);
                    $artist_event_link = get_post_meta($artistID, 'artistEventLink', true);
                    $artist_event_title = get_post_meta($artistID, 'artistEventTitle', true);
                    $artist_event_sort = get_post_meta($artistID, 'artistEventSort', true);

                    if(strtotime($artist_event_sort) >= $date_sort || $post_id == $artist_event_id) {
                        update_post_meta($artistID, 'artistEventId', $post_id, $artist_event_id);
                        update_post_meta($artistID, 'artistEventLink', $event_link, $artist_event_link);
                        update_post_meta($artistID, 'artistEventTitle', $event_title, $artist_event_title);
                        update_post_meta($artistID, 'artistEventSort', $event_sort, $artist_event_sort);                    
                    }
                }
            }
        }
    }

    add_action( 'save_post', 'bam_create_next_show_meta');
share|improve this question

1 Answer 1

up vote 1 down vote accepted

You're doing several things wrong, and they're all silly, avoidable, basic logic mistakes.

Firstly, you're not checking if this is an autosave. Autosaves do not save the custom fields, only the original core wordpress fields, like content, so an autosave will giv eyou unset/blank values.

Add this to the top of your save function:

if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
    return;

Next, you're calling get_post_type with no arguments. Normally this is okay if you're in the post loop, but you're not, so your not getting the post type of the saved post ( you might ). Add the post id as the parameter, e.g.:

if(get_post_type($post_id) == 'tribe_events') {

Immediatley afterwards on the following line:

$meta = get_post_meta($post_id, $_artistMeta->$post_id, TRUE);

I see no definition or declaration of the variable $_artistMeta, I can only assume it is a global value, but there is not even a global $_artistMeta;. $_artistMeta is not defined in this scope and you should fix this immediatley if not for readability but for resilience/robustness. If $_artistMeta is a global variable, define it as such, if not, assign the variable a value so it isn't null.

Further down we see the same mistake made as earlier:

$event_link = get_permalink();

should be

$event_link = get_permalink($post_id);

If we then scroll down we see:

$eventStartDate = tribe_get_start_date($postID,false,'j');
$eventStartMonth = tribe_get_start_date($postID,false,'M');

$event_sort = tribe_get_start_date($postID,false,'Y-m-d');

$postID is undefined here, I assume you're referring to the post being saved, so change it to:

$eventStartDate = tribe_get_start_date($post_id,false,'j');
$eventStartMonth = tribe_get_start_date($post_id,false,'M');

$event_sort = tribe_get_start_date($post_id,false,'Y-m-d');

Finally, you start a query to grab posts of type artistas, but:

  • You don't check if any posts are actually found you just assume and start a loop anyway if(!empty($artistas)){
  • You don't reset the post data afterwards using wp_reset_postdata meaning any code executed afterwards is not using the correct $post object and will be broken. Always clean up after yourself when doing queries
  • You're passing $post to the setup_postdata call, but this is incorrect. You want to stup the $artista post, not the saved post, passing $post makes no sense.

I get the impression you've either not read your code or attempted to debug it, or your PHP language skills aren't sufficient and you don't fully understand what the code actually does.

I recommend:

  • Read up on the WP_Query class and use that when you want to do post loops and grab any posts. It's cleaner than get_posts(), and has an easier to recognise syntax. This page has a lot of examples
  • Read your PHP error log for warnings and turn on WP_DEBUG. It's an invaluable tool for development.
  • Read the wordpress codex first for examples. They have warnings and extra steps that are very important for making things work that tutorials and articles sometimes miss out.
  • Comment your code and re-read it back
  • Read this short page on what PHP variable scope is
share|improve this answer
    
Tom thanks so much for your super, super, thorough answer. This is not copy and paste! I'm writing this code myself but it's one of the first times I'm writing a function of this complexity... I'm much more of a front-end developer, but relying on the community to teach, correct, and scold me! So again, really appreciate your time in checking my code. Thank you! –  j-man86 Apr 19 '12 at 15:30
    
Ah apologies if I offended, I'm glad things are working for you now =] –  Tom J Nowell Apr 19 '12 at 15:51
    
How do I turn on WP_DEBUG and PHP error log? –  j-man86 Apr 19 '12 at 16:00
    
The PHP error log is error.log or whichever is defined in your php.ini, for WP_DEBUG it's a definition in your wp-config.php –  Tom J Nowell Apr 19 '12 at 16:00

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.