function test_repeating_post_types_filter()
 {
     $this->assertContains('post', repeating_post_types());
     add_filter('hm_post_repeat_post_types', function ($post_types) {
         $post_types[] = 'page';
         return $post_types;
     });
     $this->assertContains('page', repeating_post_types());
 }
/**
 * Create the next repeat post when the last one is published.
 *
 * When a repeat post (or the original) is published we copy and schedule a new post
 * to publish on the correct interval. That way the next repeat post is always ready to go.
 * This is hooked into publish_post so that the repeat post is only created when the original
 * is published.
 *
 * @param int $post_id The ID of the post.
 */
function create_next_repeat_post($post_id)
{
    if (!in_array(get_post_type($post_id), repeating_post_types())) {
        return false;
    }
    if ('publish' !== get_post_status($post_id)) {
        return false;
    }
    $original_post_id = get_repeating_post($post_id);
    // Bail if we're not publishing a repeat(ing) post
    if (!$original_post_id) {
        return false;
    }
    $original_post = get_post($original_post_id, ARRAY_A);
    // If there is already a repeat post scheduled don't create another one
    if (get_next_scheduled_repeat_post($original_post['ID'])) {
        return false;
    }
    // Bail if the saved schedule doesn't exist
    $repeating_schedule = get_repeating_schedule($original_post['ID']);
    if (!$repeating_schedule) {
        return false;
    }
    // Bail if the original post isn't already published
    if ('publish' !== $original_post['post_status']) {
        return false;
    }
    $next_post = $original_post;
    // Create the repeat post as a copy of the original, but ignore some fields
    unset($next_post['ID']);
    unset($next_post['guid']);
    unset($next_post['post_date_gmt']);
    unset($next_post['post_modified']);
    unset($next_post['post_modified_gmt']);
    // We set the post_parent to the original post_id, so they're related
    $next_post['post_parent'] = $original_post['ID'];
    // Set the next post to publish in the future
    $next_post['post_status'] = 'future';
    // Use the date of the current post being saved as the base
    $next_post['post_date'] = date('Y-m-d H:i:s', strtotime(get_post_field('post_date', $post_id) . ' + ' . $repeating_schedule['interval']));
    // Make sure the next post will be in the future
    if (strtotime($next_post['post_date']) <= time()) {
        return false;
    }
    // All checks done, get that post scheduled!
    $next_post_id = wp_insert_post(wp_slash($next_post), true);
    if (is_wp_error($next_post_id)) {
        return false;
    }
    // Mirror any post_meta
    $post_meta = get_post_meta($original_post['ID']);
    if ($post_meta) {
        // Ignore some internal meta fields
        unset($post_meta['_edit_lock']);
        unset($post_meta['_edit_last']);
        // Don't copy the post repeat meta as only the original post should have that
        unset($post_meta['hm-post-repeat']);
        foreach ($post_meta as $key => $values) {
            foreach ($values as $value) {
                add_post_meta($next_post_id, $key, maybe_unserialize($value));
            }
        }
    }
    // Mirror any term relationships
    $taxonomies = get_object_taxonomies($original_post['post_type']);
    foreach ($taxonomies as $taxonomy) {
        wp_set_object_terms($next_post_id, wp_list_pluck(wp_get_object_terms($original_post['ID'], $taxonomy), 'slug'), $taxonomy);
    }
    return $next_post_id;
}