WordPress plugin boilerplate AJAX functionality

I “resolved” it in the following way:

In src -> App -> Frontend -> FrontRequestHandler.php i added the handler function that will insert the Custom Post.

<?php
/**
 * Class Enqueue
 *
 * @package DemoPlugin\App\Frontend
 * @since 1.0.0
 */
class FrontRequestHandler extends Base {

    /**
     * Initialize the class.
     *
     * @since 1.0.0
     */
    public function init() {
        /**
         * This frontend class is only being instantiated in the frontend as requested in the Bootstrap class
         *
         * @see Requester::isFrontend()
         * @see Bootstrap::__construct
         *
         * Add plugin code here
         */
    }

    /**
     * Insert post with data from frontend
     *
     * @since 1.0.0
     */
    public function insert_post() {

    // Prevent processing requests from external sources
    check_ajax_referer( 'fetch_fr_ajax_nonce', 'nonce' );

    if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'fetch_fr_ajax_nonce' ) ) {
        wp_send_json_error( 'Invalid nonce' );
    }

    echo "inserting Demo Plugin Post" . "\n";

    $page_slug = 'custom-post'; // Slug of the Post
    $new_page = array(
        'post_type'     => PostTypes::POST_TYPE['id'],              // Post Type Slug eg: 'page', 'post'
        'post_title'    => sanitize_text_field($_POST['title']),    // Title of the Content
        'post_content'  => 'Test Page Content', // Content
        'post_status'   => 'pending',           // Post Status
        'post_name'     => $page_slug       // Slug of the Post
    );

    if (!get_page_by_path( $page_slug, OBJECT, 'page')) { // Check If Page Doesn't Exits
        $new_page_id = wp_insert_post($new_page);
    }

    echo "Demo Plugin Post Inserted successfully" . "\n";

    wp_die();
    }
    
}

In src -> App -> General -> PostTypes.php :

In the init function i added the action called on wp_loaded hook (other hooks proved to not work the same).

public function init() {
        /**
         * This general class is always being instantiated as requested in the Bootstrap class
         *
         * @see Bootstrap::__construct
         *
         * Add plugin code here
         */
        add_action( 'wp_loaded', [$this, 'frontAjaxRequest'] );
    }

Then below in the same PostTypes.php file i would have the callback function which contains the ajax action hooks (wp_ajax_nopriv & wp_ajax for both logged and non logged users) :

/**
     * Add actions for the frontend ajax request
     *
     * @since 1.0.0
     */
    function frontAjaxRequest() {
        $frontRequestHandler = new FrontRequestHandler();

        add_action("wp_ajax_nopriv_insert_post", [ $frontRequestHandler, 'insert_post']);
        add_action("wp_ajax_insert_post", [ $frontRequestHandler, 'insert_post']);  
    }

The game changer seems to be the hook wp_loaded – now the ajax handler works for all users. Also placing the frontAjaxRequest in the init() function of the PostTypes.php also had some impact. I tried placing this function in other Classes/Files and it didn’t work. The previous init hook was working only for the non-logged users.

I am not sure this is the best way to do it, but it works, the code logic is separated.