Custom plugin foreach wp_insert_post not working

The problem as I could see it from your code and the error logs, is that your plugin is calling wp_insert_post() too early, which is before functions like is_user_logged_in() is defined or before the file it’s defined is loaded, which by the time you call videos() or videoss() (which calls wp_insert_post()), that file has not yet been loaded and thus, PHP threw the fatal error which says “Call to undefined function is_user_logged_in()“.

My ~/error_log file (I don’t call is_user_logged_in function):

Yes maybe you didn’t, but then, wp_insert_post() called wp_transition_post_status() and if you examine the stack trace in the error log entry, what happened is:

  1. wp_transition_post_status() fired the transition_post_status hook.

  2. Then that hook called one of its registered callbacks, which is _transition_post_status().

  3. And finally, that function called _count_posts_cache_key() which is the one that called is_user_logged_in().

And in response to your comment: (* I formatted it for brevity)

The first $postarr array wp_insert_post is okay, but need more 26
posts in foreach loop. Why only the first? First post added, and see
the error screen.

The reason why the first one worked is because the post was already added to the database before the post status is transitioned, but the other (26) posts could not be created because after wp_transition_post_status() is called, PHP threw the above fatal error and therefore WordPress displayed the error screen.

So how can you solve the problem?

It’s basically simple: Use a hook like plugins_loaded, init or wp_loaded to run your videos() or videoss() function (you got two plugins in the question) and don’t simply call the function which would be the same as you calling wp_insert_post() directly from the root in the main plugin file.

So for example using the init hook, in mypluggg.php, call videos() like so:

add_action( 'init', 'mypluggg_create_posts' );
function mypluggg_create_posts() {
    videos();
}
// or yes, this would work as well..
//add_action( 'init', 'videos' );

However, note that init (and the other 2 hooks mentioned above) runs on each page load, so you might better off look for another approach to create the posts you wanted to create, e.g. you could use a cron job or WP-CLI, but that’s another story. 🙂

Additionally, if you want wp_insert_post() to return a WP_Error instance/object if the post creation/update didn’t succeed, then set the 2nd parameter to true like so: wp_insert_post( $postarr[ $key ], true ), or you could use $wp_error, but make sure that variable is defined. E.g.

$wp_error = true; // here, define it

foreach ( $videos as $key => $video ) {
    $postarr[ $key ] = array( ... );

    // pass $wp_error as the 2nd parameter
    $id = wp_insert_post( $postarr[ $key ], $wp_error );

    if ( is_wp_error( $id ) ) {
        error_log( 'Error creating post! Message: ' . $id->get_error_message() );
    }
}