Programmatically create new site with template

Hi guys,

I have a quick question for you. We are succesfully using the New Blog Templates plugin and it works just fine, but we need a way to automatically deploy a blog when a product is purchased using woocommerce.

I know how to hook into Woo's API to trigger an action when a new order comes in, and I know I can programatically deploy a new blog like this:

wpmu_create_user( $username, $password, $email )
wpmu_create_blog( $newdomain, $path, $title, $user_id , array( 'public' => 1 ), $current_site->id );

How can I define which template to apply to this new site?

Thanks!

  • Vaughan

    Hi Leni,

    Hope you're well?

    I haven't ever tried this, but perhaps you could use the nbt-api?

    For example:

    /**
     * Sample code
     *
     * This code will copy all posts, pages and menus in the source blog. It also updates
     * the dates of the posts and pages
     */
    include_once( WP_CONTENT_DIR . '/plugins/blogtemplates/nbt-api.php' );
    nbt_load_api();
    
    add_action( 'wpmu_new_blog', 'my_test_function', 99, 2 );
    function my_test_function( $new_blog_id, $new_user_id ) {
    	$args = array(
    			'to_copy' => array(
    				'posts'		=> true,
    				'pages'		=> true,
    				'menus'		=> true,
    			),
                'update_dates' => true
    		);
    	nbt_api_copy_contents_to_new_blog( 55, $new_blog_id, $new_user_id, $args );
    }

    Where 55 is the blog_id of the template site you want to use.

    The args that can be used are:

    * param Array $args Default values:
      		array(
    			'to_copy' => array(
    				'settings' 	=> false, => Copy settings?
    				'posts'		=> false, => Copy posts?
    				'pages'		=> false, => Copy pages?
    				'terms'		=> false, => Copy categories, tags...?
    				'users'		=> false, => Copy users?
    				'menus'		=> false, => Copy menus?
    				'files'		=> false  => Copy files?
    			),
    			'pages_ids'		=> array( 'all-pages' ), IDs of the pages you want to copy ([to_copy][pages] must be set to true)
    			'post_category' => array( 'all-categories' ), Categories of the posts you want to copy ([to_copy][posts] must be set to true)
    			'template_id'	=> 0, If you are saving templates in the NBT tables you can add here the template ID but is not needed. Will dissapear in following releases
    			'additional_tables' => array(), Tables you want to copy
                'block_posts_pages' => false, Block posts/pages for edition?
                'update_dates' => false Update the dates of the posts/pages copied?
    		)

    See the nbt-api.php file fore more info.

    /wp-content/plugins/blogtemplates/nbt-api.php

    Hope this helps

  • Leni Neto

    Hi Vaughan,

    I was able to get pretty much everything done except the nbt_api_copy_contents_to_new_blog is not working.

    I have a function that creates a new user and a new blog when an order is successful in woorcommerce. Up to the user an blog creation, it all works perfectly.

    The new user is created, password properly assigned, new blog is created, user can login to the newly created bog... its all good.

    When I plugin the function to apply the template to the new blog, I got an error message on woo's checkout page:

    SyntaxError: Unexpected token < in JSON at position 1

    On the logs, there absolutely nothing.

    The funny thing is, the user and blog are still being created just fine.

    Here is what I have in my code:

    // Load the ntp api
            include_once( WP_CONTENT_DIR . '/plugins/blogtemplates/nbt-api.php' );
            nbt_load_api();
    
            // Clone the template when the new blog is created
            add_action( 'wpmu_new_blog', 'rmm_clone_template', 99, 2 );
    
            // Display Fields
            add_action( 'woocommerce_product_options_general_product_data', 'rmm_woo_blogtemplate_fields' );
    
            // Save Fields
            add_action( 'woocommerce_process_product_meta', 'rmm_woo_blogtemplate_fields_save' );
    
            // Create the new user and blog after Successful Payment
            add_action( 'woocommerce_payment_complete', 'rmm_deploy_blog');
            //add_action( 'woocommerce_order_status_processing', 'rmm_deploy_blog');
    
    ...
    ...
    ...
    
            function rmm_clone_template( $new_blog_id, $new_user_id ) {
                    $args = array(
                            'to_copy' => array(
                                    'posts'=> true,
                                    'pages'=> true,
                                    'menus'=> true,
                                    'terms'=> true,
                                    'files'=> true,
                                    'settings'=> true,
                            ),
                            'update_dates' => true
                    );
                    nbt_api_copy_contents_to_new_blog( 2, $new_blog_id, $new_user_id, $args );
            }

    Am I doing anything wrong here?
    ID 2 is the correct ID for the blog used as the template.

  • Leni Neto

    Hi guys,

    Apparently this post has been abandoned as I never got a reply from you (last reply was 15 days ago).
    I've manage to solve the problem myself, and now I have another question.

    the function nbt_api_copy_contents_to_new_blog ONLY WORKS when I hook it into action wpmu_new_blog

    Is there a way to make this function works by calling it from outside that action, like for example, calling it from another function?

  • Kasia Swiderska

    Hello Leni,

    I'm very sorry for delay on our end - Vaughan was sick for some days, so I will now jump in until he gets back to form.

    Is there a way to make this function works by calling it from outside that action, like for example, calling it from another function?

    What type of function you would want to use? I'm looking for example on forum with another action used, but I don't see it - I will ask developer if that is possible and get back to you as soon as I will get more info.

    kind regards,
    Kasia

  • Leni Neto

    Hi Kasia,

    Thanks for stepping in.
    I have a function that is triggered on woocommerce_payment_complete.
    I'd like to call the nbt_api_copy_contents_to_new_blog from that function after calling the function that creates a new blog, rather than using the wpmu_new_blog hook.

    I tried but I don't get anything cloned. The only way I got the nbt_api_copy_contents_to_new_blog function to work was by calling it from the wpmu_new_blog action hook.

    Cheers

  • Nithin

    Hi Leni Neto,

    Hope you are doing good today.

    I'm checking this with the developer so that he would be able to give a better idea about this. Will keep you posted once I get an update from the developer asap. Please do note that developers work round the clock with many critical issues, and hence have a slow response time. Either myself, or the developer will keep you posted.

    Kind Regards,
    Nithin

  • Mahlamusa

    Hello Leni,

    I am sorry for the delayed response from our side and I hope you are having a great day so far.

    The only way I got the nbt_api_copy_contents_to_new_blog function to work was by calling it from the wpmu_new_blog action hook.

    This is because each hook provides parameters that you can access, the function 'wpmu_new_blog' makes the two variable available: $new_user_id and $new_blog_id, these two variables are required by the API function, if you are not hooking to the 'wpmu_new_blog' hook then those variables are not available and using them will result in using undefined variables which will never work as the API function requires the user ID and the blog ID.

    Is there a way to make this function works by calling it from outside that action, like for example, calling it from another function?

    Yes, there is a way. All you have to do is to get the new_user_id and new_blog_id and use those with real values assigned to them in the API function. If those are not defined then the API function will not duplicate anything.

    The 'woocommerce_payment_complete' hook makes only the order_id available for use. I suggest you hook to this function requesting the parameter that it makes available like so:

    add_action( 'woocommerce_payment_complete', 'clone_blog_template', 10, 1);
    function clone_blog_template($order_id){}

    Inside your action handler, use the $order_id made available by the WooComerce hook to get customer_id from the order object like so:

    $order = new WC_Order( $order_id );
    $new_user_id = $order->customer_id;

    '$order->customer_id' is the user_id of the person who paid the order, so basically, $order->customer_id = $user_id. Now you have the user_id which you should use to create a new blog so that you can get the $new_blog_id variable like this:

    $new_blog_id = wpmu_create_blog( $newdomain, $path, $title, $user_id , array('public' => 1), $current_site_id );
    Yes, you should assign values to those parameters, I am sure you are getting this from your form maybe from the order details. I see you have a form to collect that data from the product/order page using 'rmm_woo_blogtemplate_fields'.

    Now you have both new_user_id and new_blog_id, you should then be able to call the API function without issues like so:

    $args = array('to_copy' => array('posts'=> true,'pages'=> true,'menus'=> true,'terms'=> true,'files'=> true,'settings'=> true),'update_dates' => true);
    nbt_api_copy_contents_to_new_blog( $template_blog_id, $new_blog_id, $new_user_id, $args );

    Now putting this together we have the following:

    add_action( 'woocommerce_payment_complete', 'clone_blog_template', 10, 1);
    function clone_blog_template( $order_id ) {
    	//load new blog templates api
    	include_once( WP_CONTENT_DIR . '/plugins/blogtemplates/nbt-api.php' );
            nbt_load_api();
    
    	//get the user who just paid for woocommerce product
    	$order = new WC_Order( $order_id );
    	$new_user_id = $order->customer_id;
    
    	//create the blog with the current correct info
    	$new_blog_id = wpmu_create_blog( $newdomain, $path, $title, $user_id , array('public' => 1), $current_site->id );
    
    	$template_blog_id = 2; //change this or assign directly
    	$args = array(
    	 	'to_copy' => array(
    	 	         'posts'=> true,
    	 	 	'pages'=> true,
    	 	 	'menus'=> true,
    	 	 	'terms'=> true,
    	 	 	'files'=> true,
    	 	 	'settings'=> true
    	 	),
    	 	'update_dates' => true
    	);
    	nbt_api_copy_contents_to_new_blog( $template_blog_id, $new_blog_id, $new_user_id, $args );
    }

    Please note that you still have to get the values of the variables: $newdomain, $path, $title, $current_site->id. I believe you already have a way to get these, so just make sure they have the correct values. Unfortunately, I do not know how you get those values because I only have part of your code and I do not see what you did and how you did it.

    I hope all this makes sense to you and I hope it works the way you expect it to work. Please let us know if you need any more help with regards to this.

    I wish you enjoy the rest of your day.

    Cheers,
    Mahlamusa