/**
 * Add a new network
 *
 * @since 1.3
 *
 * @param string $domain Domain name for new network - for VHOST=no, this
 *                        should be FQDN, otherwise domain only
 * @param string $path Path to root of network hierarchy - should be '/' unless
 *                      WP is cohabiting with another product on a domain
 * @param string $site_name Name of the root blog to be created on the new
 *                           network
 * @param integer $clone_network ID of network whose networkmeta values are
 *                                to be copied - default NULL
 * @param array $options_to_clone Override default network meta options to copy
 *                                 when cloning - default NULL
 * @return integer ID of newly created network
 */
function add_network($domain, $path, $site_name = false, $clone_network = false, $options_to_clone = false)
{
    global $wpdb, $sites;
    // Set a default site name if one isn't set
    if (false == $site_name) {
        $site_name = __('New Network Root', 'wp-multi-network');
    }
    // If no options, fallback on defaults
    if (empty($options_to_clone)) {
        $options_to_clone = array_keys(network_options_to_copy());
    }
    // Check for existing network
    $sql = "SELECT * FROM {$wpdb->site} WHERE domain = %s AND path = %s LIMIT 1";
    $query = $wpdb->prepare($sql, $domain, $path);
    $network = $wpdb->get_row($query);
    if (!empty($network)) {
        return new WP_Error('network_exists', __('Network already exists.', 'wp-multi-network'));
    }
    // Insert new network
    $wpdb->insert($wpdb->site, array('domain' => $domain, 'path' => $path));
    $new_network_id = $wpdb->insert_id;
    // Update global network list
    $sites = $wpdb->get_results("SELECT * FROM {$wpdb->site}");
    // If network was created, create a blog for it too
    if (!empty($new_network_id)) {
        if (!defined('WP_INSTALLING')) {
            define('WP_INSTALLING', true);
        }
        // there's an ongoing error with wpmu_create_blog that throws a warning if meta is not defined:
        // http://core.trac.wordpress.org/ticket/20793
        // temporary fix -- set from current blog's value
        // Looks like a fix is in for 3.7
        $new_blog_id = wpmu_create_blog($domain, $path, $site_name, get_current_user_id(), array('public' => get_option('blog_public', false)), (int) $new_network_id);
        // Bail if blog could not be created
        if (is_a($new_blog_id, 'WP_Error')) {
            return $new_blog_id;
        }
        /**
         * Fix upload_path for main sites on secondary networks
         * This applies only to new installs (WP 3.5+)
         */
        // Switch to main network (if it exists)
        if (defined('SITE_ID_CURRENT_SITE') && network_exists(SITE_ID_CURRENT_SITE)) {
            switch_to_network(SITE_ID_CURRENT_SITE);
            $use_files_rewriting = get_site_option('ms_files_rewriting');
            restore_current_network();
        } else {
            $use_files_rewriting = get_site_option('ms_files_rewriting');
        }
        global $wp_version;
        // Create the upload_path and upload_url_path values
        if (!$use_files_rewriting && version_compare($wp_version, '3.7', '<')) {
            // WP_CONTENT_URL is locked to the current site and can't be overridden,
            //  so we have to replace the hostname the hard way
            $current_siteurl = get_option('siteurl');
            $new_siteurl = untrailingslashit(get_blogaddress_by_id($new_blog_id));
            $upload_url = str_replace($current_siteurl, $new_siteurl, WP_CONTENT_URL);
            $upload_url = $upload_url . '/uploads';
            $upload_dir = WP_CONTENT_DIR;
            if (0 === strpos($upload_dir, ABSPATH)) {
                $upload_dir = substr($upload_dir, strlen(ABSPATH));
            }
            $upload_dir .= '/uploads';
            if (defined('MULTISITE')) {
                $ms_dir = '/sites/' . $new_blog_id;
            } else {
                $ms_dir = '/' . $new_blog_id;
            }
            $upload_dir .= $ms_dir;
            $upload_url .= $ms_dir;
            update_blog_option($new_blog_id, 'upload_path', $upload_dir);
            update_blog_option($new_blog_id, 'upload_url_path', $upload_url);
        }
    }
    // Clone the network meta from an existing network
    if (!empty($clone_network) && network_exists($clone_network)) {
        $options_cache = array();
        $clone_network = (int) $clone_network;
        switch_to_network($clone_network);
        foreach ($options_to_clone as $option) {
            $options_cache[$option] = get_site_option($option);
        }
        restore_current_network();
        switch_to_network($new_network_id);
        foreach ($options_to_clone as $option) {
            if (isset($options_cache[$option])) {
                // Fix for strange bug that prevents writing the ms_files_rewriting value for new networks
                if ($option === 'ms_files_rewriting') {
                    $wpdb->insert($wpdb->sitemeta, array('site_id' => $wpdb->siteid, 'meta_key' => $option, 'meta_value' => $options_cache[$option]));
                } else {
                    add_site_option($option, $options_cache[$option]);
                }
            }
        }
        unset($options_cache);
        restore_current_network();
    }
    do_action('add_network', $new_network_id);
    return $new_network_id;
}
/**
 * Add a new network
 *
 * @since 1.3
 *
 * @param array $args  {
 *     Array of arguments.
 *     @type string  $domain           Domain name for new network - for VHOST=no,
 *                                     this should be FQDN, otherwise domain only.
 *     @type string  $path             Path to root of network hierarchy - should
 *                                     be '/' unless WP is cohabiting with another
 *                                     product on a domain.
 *     @type string  $site_name        Name of the root blog to be created on
 *                                     the new network.
 *     @type integer $user_id          ID of the user to add as the site owner.
 *                                     Defaults to current user ID.
 *     @type array   $meta             Array of metadata to save to this network.
 *                                     Defaults to array( 'public' => false ).
 *     @type integer $clone_network    ID of network whose networkmeta values are
 *                                     to be copied - default NULL.
 *     @type array   $options_to_clone Override default network meta options to copy
 *                                     when cloning - default NULL.
 * }
 *
 * @return integer ID of newly created network
 */
function add_network($args = array())
{
    global $wpdb;
    // Backward compatibility with old method of passing arguments
    if (!is_array($args) || func_num_args() > 1) {
        _deprecated_argument(__METHOD__, '1.7.0', sprintf(__('Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'wp-multi-network'), __METHOD__, __FILE__));
        // Juggle function parameters
        $func_args = func_get_args();
        $old_args_keys = array(0 => 'domain', 1 => 'path', 2 => 'site_name', 3 => 'clone_network', 4 => 'options_to_clone');
        // Reset array
        $args = array();
        // Rejig args
        foreach ($old_args_keys as $arg_num => $arg_key) {
            if (isset($func_args[$arg_num])) {
                $args[$arg_key] = $func_args[$arg_num];
            }
        }
    }
    // Parse args
    $r = wp_parse_args($args, array('domain' => '', 'path' => '/', 'site_name' => __('New Network', 'wp-multi-network'), 'user_id' => get_current_user_id(), 'meta' => array('public' => get_option('blog_public', false)), 'clone_network' => false, 'options_to_clone' => array_keys(network_options_to_copy())));
    // Bail if no user with this ID
    if (empty($r['user_id']) || !get_userdata($r['user_id'])) {
        return new WP_Error('network_user', __('User does not exist.', 'wp-multi-network'));
    }
    // Permissive sanitization for super admin usage
    $r['domain'] = str_replace(' ', '', strtolower($r['domain']));
    $r['path'] = str_replace(' ', '', strtolower($r['path']));
    // Check for existing network
    $network = get_network_by_path($r['domain'], $r['path']);
    if (!empty($network)) {
        return new WP_Error('network_exists', __('Network already exists.', 'wp-multi-network'));
    }
    // Insert new network
    $wpdb->insert($wpdb->site, array('domain' => $r['domain'], 'path' => $r['path']));
    $new_network_id = $wpdb->insert_id;
    // If network was created, create a blog for it too
    if (!empty($new_network_id)) {
        if (!defined('WP_INSTALLING')) {
            define('WP_INSTALLING', true);
        }
        // Create the site for the root of this network
        $new_blog_id = wpmu_create_blog($r['domain'], $r['path'], $r['site_name'], $r['user_id'], $r['meta'], $new_network_id);
        // Bail if blog could not be created
        if (is_a($new_blog_id, 'WP_Error')) {
            return $new_blog_id;
        }
        /**
         * Fix upload_path for main sites on secondary networks
         * This applies only to new installs (WP 3.5+)
         */
        // Switch to main network (if it exists)
        if (defined('SITE_ID_CURRENT_SITE') && wp_get_network(SITE_ID_CURRENT_SITE)) {
            switch_to_network(SITE_ID_CURRENT_SITE);
            $use_files_rewriting = get_site_option('ms_files_rewriting');
            restore_current_network();
        } else {
            $use_files_rewriting = get_site_option('ms_files_rewriting');
        }
        global $wp_version;
        // Create the upload_path and upload_url_path values
        if (!$use_files_rewriting && version_compare($wp_version, '3.7', '<')) {
            // WP_CONTENT_URL is locked to the current site and can't be overridden,
            //  so we have to replace the hostname the hard way
            $current_siteurl = get_option('siteurl');
            $new_siteurl = untrailingslashit(get_blogaddress_by_id($new_blog_id));
            $upload_url = str_replace($current_siteurl, $new_siteurl, WP_CONTENT_URL);
            $upload_url = $upload_url . '/uploads';
            $upload_dir = WP_CONTENT_DIR;
            if (0 === strpos($upload_dir, ABSPATH)) {
                $upload_dir = substr($upload_dir, strlen(ABSPATH));
            }
            $upload_dir .= '/uploads';
            if (defined('MULTISITE')) {
                $ms_dir = '/sites/' . $new_blog_id;
            } else {
                $ms_dir = '/' . $new_blog_id;
            }
            $upload_dir .= $ms_dir;
            $upload_url .= $ms_dir;
            update_blog_option($new_blog_id, 'upload_path', $upload_dir);
            update_blog_option($new_blog_id, 'upload_url_path', $upload_url);
        }
    }
    // Clone the network meta from an existing network
    if (!empty($r['clone_network']) && wp_get_network($r['clone_network'])) {
        $options_cache = array();
        // Old network
        switch_to_network($r['clone_network']);
        foreach ($r['options_to_clone'] as $option) {
            $options_cache[$option] = get_site_option($option);
        }
        restore_current_network();
        // New network
        switch_to_network($new_network_id);
        foreach ($r['options_to_clone'] as $option) {
            if (isset($options_cache[$option])) {
                // Fix for bug that prevents writing the ms_files_rewriting
                // value for new networks.
                if ('ms_files_rewriting' === $option) {
                    $wpdb->insert($wpdb->sitemeta, array('site_id' => $wpdb->siteid, 'meta_key' => $option, 'meta_value' => $options_cache[$option]));
                } else {
                    add_site_option($option, $options_cache[$option]);
                }
            }
        }
        unset($options_cache);
        restore_current_network();
    }
    do_action('add_network', $new_network_id);
    return $new_network_id;
}
 /**
  * Handle the request to add a new network
  *
  * @since 2.0.0
  */
 private function handle_add_network()
 {
     // Unslash posted data for sanitization
     $posted = wp_unslash($_POST);
     // Options to copy
     if (isset($posted['options_to_clone']) && is_array($posted['options_to_clone'])) {
         $options_to_clone = array_keys($posted['options_to_clone']);
     } else {
         $options_to_clone = array_keys(network_options_to_copy());
     }
     // Clone from
     $clone = isset($posted['clone_network']) ? (int) $posted['clone_network'] : get_current_site()->id;
     // Title
     $network_title = isset($posted['title']) ? strip_tags($posted['title']) : '';
     // Domain
     $network_domain = isset($posted['domain']) ? str_replace(' ', '', strtolower($posted['domain'])) : '';
     // Path
     $network_path = isset($posted['path']) ? str_replace(' ', '', strtolower($posted['path'])) : '';
     // Site name
     $site_name = !empty($posted['new_site']) ? strip_tags($posted['new_site']) : $network_title;
     // Bail if missing fields
     if (empty($network_title) || empty($network_domain) || empty($network_path)) {
         $this->handle_redirect(array('page' => 'add-new-network', 'network_created' => '0'));
     }
     // Add the network
     $result = add_network(array('domain' => $network_domain, 'path' => $network_path, 'site_name' => $site_name, 'user_id' => get_current_user_id(), 'clone_network' => $clone, 'options_to_clone' => $options_to_clone));
     // Update title
     if (!empty($result) && !is_wp_error($result)) {
         // Maybe update the site name
         if (!empty($posted['title'])) {
             update_network_option($result, 'site_name', $posted['title']);
         }
         // Activate WPMN on this new network
         update_network_option($result, 'active_sitewide_plugins', array('wp-multi-network/wpmn-loader.php' => time()));
         // Redirect args
         $r = array('network_created' => '1');
         // Failure
     } else {
         $r = array('network_created' => '0');
     }
     // Handle redirect
     $this->handle_redirect($r);
 }
 /**
  * Handle the request to add a new network
  *
  * @since 1.7.0
  */
 private function add_network_handler()
 {
     // Options to copy
     if (isset($_POST['options_to_clone']) && is_array($_POST['options_to_clone'])) {
         $options_to_clone = array_keys($_POST['options_to_clone']);
     } else {
         $options_to_clone = array_keys(network_options_to_copy());
     }
     // Clone from
     $clone = isset($_POST['clone_network']) ? (int) $_POST['clone_network'] : get_current_site()->id;
     // Title
     $network_title = isset($_POST['title']) ? $_POST['title'] : '';
     // Domain
     $network_domain = isset($_POST['domain']) ? $_POST['domain'] : '';
     // Path
     $network_path = isset($_POST['path']) ? $_POST['path'] : '';
     // Path
     $site_name = !empty($_POST['new_site']) ? $_POST['new_site'] : $network_title;
     // Bail if missing fields
     if (empty($network_title) || empty($network_domain) || empty($network_path)) {
         $this->handler_redirect(array('page' => 'add-new-network', 'network_created' => '0'));
     }
     // Add the network
     $result = add_network(array('domain' => $network_domain, 'path' => $network_path, 'site_name' => $site_name, 'user_id' => get_current_user_id(), 'clone_network' => $clone, 'options_to_clone' => $options_to_clone));
     // Update title
     if (!empty($result) && !is_wp_error($result)) {
         switch_to_network($result);
         if (!empty($_POST['title'])) {
             update_site_option('site_name', $_POST['title']);
         }
         // Activate WPMN on this new network
         update_site_option('active_sitewide_plugins', array('wp-multi-network/wpmn-loader.php' => time()));
         restore_current_network();
         // Redirect args
         $r = array('network_created' => '1');
         // Failure
     } else {
         $r = array('network_created' => '0');
     }
     // Handle redirect
     $this->handler_redirect($r);
 }
 /**
  *
  */
 public function add_network_handler()
 {
     global $current_site;
     if (isset($_POST['add']) && isset($_POST['domain']) && isset($_POST['path'])) {
         /** grab custom options to clone if set */
         if (isset($_POST['options_to_clone']) && is_array($_POST['options_to_clone'])) {
             $options_to_clone = array_keys($_POST['options_to_clone']);
         } else {
             $options_to_clone = array_keys(network_options_to_copy());
         }
         $result = add_network($_POST['domain'], $_POST['path'], isset($_POST['newSite']) ? $_POST['newSite'] : esc_attr__('New Network Created', 'wp-multi-network'), isset($_POST['cloneNetwork']) ? $_POST['cloneNetwork'] : $current_site->id, $options_to_clone);
         if ($result && !is_wp_error($result)) {
             if (!empty($_POST['name'])) {
                 switch_to_network($result);
                 add_site_option('site_name', $_POST['name']);
                 add_site_option('active_sitewide_plugins', array('wp-multi-network/wpmn-loader.php' => time()));
                 restore_current_network();
             }
             $_GET['added'] = 'yes';
             $_GET['action'] = 'saved';
         } else {
             foreach ($result->errors as $i => $error) {
                 echo "<h2>Error: " . $error[0] . "</h2>";
             }
         }
     }
 }