Bug: Post needs to be updated twice when adding action for save_post hook

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