/**
  * Get all duplicable sites
  * @since 0.2.0
  * @return array of blog data
  */
 public static function get_site_list()
 {
     $site_list = array();
     $network_blogs = wp_get_sites(array('limit' => MUCD_MAX_NUMBER_OF_SITE));
     foreach ($network_blogs as $blog) {
         if (MUCD_Functions::is_duplicable($blog['blog_id']) && MUCD_SITE_DUPLICATION_EXCLUDE != $blog['blog_id']) {
             $site_list[] = $blog;
         }
     }
     return $site_list;
 }
Example #2
0
 /**
  * Duplication form validation
  * @since 0.2.0
  * @param  array $init_data default data
  * @return array $data validated data, or errors
  */
 public static function check_form($init_data)
 {
     $data = $init_data;
     $data['copy_files'] = 'no';
     $data['keep_users'] = 'no';
     $data['log'] = 'no';
     // Check referer and nonce
     if (check_admin_referer(MUCD_DOMAIN)) {
         global $current_site;
         $error = array();
         // Merge $data / $_POST['site'] to get Posted data and fill form
         $data = array_merge($data, $_POST['site']);
         // format and check source
         $data['from_site_id'] = intval($data['source']);
         if ($data['from_site_id'] < 1 || !get_blog_details($data['from_site_id'], false)) {
             $error[] = new WP_Error('mucd_error', MUCD_NETWORK_PAGE_DUPLICATE_MISSING_FIELDS);
         }
         $domain = '';
         if (preg_match('|^([a-zA-Z0-9-])+$|', $data['domain'])) {
             $domain = strtolower($data['domain']);
         }
         // If not a subdomain install, make sure the domain isn't a reserved word
         if (!is_subdomain_install()) {
             /** This filter is documented in wp-includes/ms-functions.php */
             $subdirectory_reserved_names = apply_filters('subdirectory_reserved_names', array('page', 'comments', 'blog', 'files', 'feed'));
             if (in_array($domain, $subdirectory_reserved_names)) {
                 $error[] = new WP_Error('mucd_error', sprintf(MUCD_NETWORK_PAGE_DUPLICATE_DOMAIN_ERROR_RESERVED_WORDS, implode('</code>, <code>', $subdirectory_reserved_names)));
             }
         }
         if (empty($domain)) {
             $error[] = new WP_Error('mucd_error', MUCD_NETWORK_PAGE_DUPLICATE_DOMAIN_ERROR_REQUIRE);
         }
         if (is_subdomain_install()) {
             $newdomain = $domain . '.' . preg_replace('|^www\\.|', '', $current_site->domain);
             $path = $current_site->path;
         } else {
             $newdomain = $current_site->domain;
             $path = $current_site->path . $domain . '/';
         }
         // format and check title
         if (empty($data['title'])) {
             $error[] = new WP_Error('mucd_error', MUCD_NETWORK_PAGE_DUPLICATE_TITLE_ERROR_REQUIRE);
         }
         // format and check email admin
         if (empty($data['email'])) {
             $error[] = new WP_Error('mucd_error', MUCD_NETWORK_PAGE_DUPLICATE_EMAIL_MISSING);
         }
         $valid_mail = sanitize_email($data['email']);
         if (is_email($valid_mail)) {
             $data['email'] = $valid_mail;
         } else {
             $error[] = new WP_Error('mucd_error', MUCD_NETWORK_PAGE_DUPLICATE_EMAIL_ERROR_FORMAT);
         }
         $data['domain'] = $domain;
         $data['newdomain'] = $newdomain;
         $data['path'] = $path;
         $data['public'] = !isset($data['private']);
         // Network
         $data['network_id'] = $current_site->id;
         if (isset($data['log']) && $data['log'] == 'yes' && (!isset($data['log-path']) || $data['log-path'] == "" || !MUCD_Functions::valid_path($data['log-path']))) {
             $error[] = new WP_Error('mucd_error', MUCD_NETWORK_PAGE_DUPLICATE_VIEW_LOG_PATH_EMPTY);
         }
         if (isset($error[0])) {
             $data['error'] = $error[0];
         }
     } else {
         $data['error'] = MUCD_GAL_ERROR_CAPABILITIES;
     }
     return $data;
 }
Example #3
0
 /**
  * Stop process on SQL Error, print and log error, removes the new blog
  * @since 0.2.0
  * @param  string  $sql_query the query
  * @param  string  $sql_error the error
  */
 public static function sql_error($sql_query, $sql_error)
 {
     $error_1 = 'ERROR SQL ON : ' . $sql_query;
     MUCD_Duplicate::write_log($error_1);
     $error_2 = 'WPDB ERROR : ' . $sql_error;
     MUCD_Duplicate::write_log($error_2);
     MUCD_Duplicate::write_log('Duplication interrupted on SQL ERROR');
     echo '<br />Duplication failed :<br /><br />' . $error_1 . '<br /><br />' . $error_2 . '<br /><br />';
     if ($log_url = MUCD_Duplicate::log_url()) {
         echo '<a href="' . $log_url . '">' . MUCD_NETWORK_PAGE_DUPLICATE_VIEW_LOG . '</a>';
     }
     MUCD_Functions::remove_blog(self::$to_site_id);
     wp_die();
 }
 require_once realpath(dirname(__FILE__)) . '/include/config.php';
 // Plugin options
 require_once MUCD_COMPLETE_PATH . '/include/option.php';
 // Load textdomain
 load_plugin_textdomain(MUCD_DOMAIN, NULL, MUCD_PATH . '/language/');
 // Load language
 require_once MUCD_COMPLETE_PATH . '/include/lang.php';
 // Load Functions
 require_once MUCD_COMPLETE_PATH . '/lib/functions.php';
 if (is_admin()) {
     require_once MUCD_COMPLETE_PATH . '/include/admin.php';
     MUCD_Admin::hooks();
 }
 if (defined('WP_CLI') && WP_CLI) {
     require_once MUCD_COMPLETE_PATH . '/lib/duplicate.php';
     MUCD_Functions::set_locale_to_en_US();
     require_once MUCD_COMPLETE_PATH . '/wp-cli/wp-cli-site-duplicate-subcommand.php';
 }
 /**
  * Main class of the plugin
  */
 class MUCD
 {
     /**
      * Register hooks used by the plugin
      */
     public static function hooks()
     {
         // Register (de)activation hook
         register_activation_hook(__FILE__, array(__CLASS__, 'activate'));
         register_deactivation_hook(__FILE__, array(__CLASS__, 'deactivate'));
 /**
  * Duplicate a site in a multisite install.
  *
  * ## OPTIONS
  *
  * --slug=<slug>
  * : Path for the new site. Subdomain on subdomain installs, directory on subdirectory installs.
  *
  * --source=<site_id>
  * : ID of the site to duplicate.
  *
  * [--title=<title>]
  * : Title of the new site. Default: prettified slug.
  *
  * [--email=<email>]
  * : Email for Admin user. User will be created if none exists. Assignement to Super Admin if not included.
  *
  * [--network_id=<network-id>]
  * : Network to associate new site with. Defaults to current network (typically 1).
  *
  * [--private]
  * : If set, the new site will be non-public (not indexed)
  *
  * [--porcelain]
  * : If set, only the site id will be output on success.
  *
  * [--v]
  * : If set, print more details about the new site (Verbose mode). Do not work if --procelain is set.
  *
  * [--do_not_copy_files]
  * : If set, files of the duplicated site will not be copied.
  *
  * [--keep_users]
  * : If set, the new site will have the same users as the duplicated site.
  *
  * [--log=<dir_path>]
  * : If set, a log will be written in this directory (please check this directory is writable).
  *
  * @alias clone
  *
  * @synopsis --slug=<slug> --source=<site_id> [--title=<title>] [--email=<email>] [--network_id=<network-id>] [--private] [--porcelain] [--v] [--do_not_copy_files] [--keep_users] [--log=<dir_path>]
  */
 public function __invoke($_, $assoc_args)
 {
     if (!is_multisite()) {
         WP_CLI::error('This is not a multisite install.');
     }
     global $wpdb, $current_site;
     $base = $assoc_args['slug'];
     $title = isset($assoc_args['title']) ? $assoc_args['title'] : ucfirst($base);
     $email = empty($assoc_args['email']) ? '' : $assoc_args['email'];
     // Network
     if (!empty($assoc_args['network_id'])) {
         $network = MUCD_Functions::get_network($assoc_args['network_id']);
         if ($network === false) {
             WP_CLI::error(sprintf('Network with id %d does not exist.', $assoc_args['network_id']));
         }
     } else {
         $network = $current_site;
     }
     $network_id = $network->id;
     $public = !isset($assoc_args['private']);
     // Sanitize
     if (preg_match('|^([a-zA-Z0-9-])+$|', $base)) {
         $base = strtolower($base);
     }
     // If not a subdomain install, make sure the domain isn't a reserved word
     if (!is_subdomain_install()) {
         $subdirectory_reserved_names = apply_filters('subdirectory_reserved_names', array('page', 'comments', 'blog', 'files', 'feed'));
         if (in_array($base, $subdirectory_reserved_names)) {
             WP_CLI::error('The following words are reserved and cannot be used as blog names: ' . implode(', ', $subdirectory_reserved_names));
         }
     }
     // Check for valid email, if not, use the first Super Admin found
     // Probably a more efficient way to do this so we dont query for the
     // User twice if super admin
     $email = sanitize_email($email);
     if (empty($email) || !is_email($email)) {
         $super_admins = get_super_admins();
         $email = '';
         if (!empty($super_admins) && is_array($super_admins)) {
             // Just get the first one
             $super_login = $super_admins[0];
             $super_user = get_user_by('login', $super_login);
             if ($super_user) {
                 $email = $super_user->user_email;
             }
         }
     }
     if (is_subdomain_install()) {
         $newdomain = $base . '.' . preg_replace('|^www\\.|', '', $network->domain);
         $path = $network->path;
     } else {
         $newdomain = $network->domain;
         $path = $network->path . $base . '/';
     }
     // Source ?
     $source = $assoc_args['source'];
     if (!intval($source) != 0) {
         WP_CLI::error($source . ' is not a valid site ID.');
     }
     if (!MUCD_Functions::site_exists($source)) {
         WP_CLI::error('There is no site with ID=' . $source . '. The site to duplicate must be an existing site of the network.');
     }
     // Copy files ?
     $copy_files = isset($assoc_args['do_not_copy_files']) ? 'no' : 'yes';
     // Keep users ?
     $keep_users = isset($assoc_args['keep_users']) ? 'yes' : 'no';
     // Write log
     if (isset($assoc_args['log'])) {
         $log = 'yes';
         $log_path = $assoc_args['log'];
     } else {
         $log = 'no';
         $log_path = '';
     }
     $data = array('source' => $source, 'domain' => $base, 'title' => $title, 'email' => $email, 'copy_files' => $copy_files, 'keep_users' => $keep_users, 'log' => $log, 'log-path' => $log_path, 'from_site_id' => $source, 'newdomain' => $newdomain, 'path' => $path, 'public' => $public, 'network_id' => $network_id);
     $wpdb->hide_errors();
     $form_message = MUCD_Duplicate::duplicate_site($data);
     $wpdb->show_errors();
     if (isset($form_message['error'])) {
         WP_CLI::error($form_message['error']);
     } else {
         if (isset($assoc_args['porcelain'])) {
             WP_CLI::line($form_message['site_id']);
         } else {
             switch_to_blog($form_message['site_id']);
             if (!isset($assoc_args['v'])) {
                 WP_CLI::success('Site ' . $form_message['site_id'] . ' created: ' . get_site_url());
             } else {
                 // Verbose mode
                 WP_CLI::success($form_message['msg']);
                 $user = get_current_user_id();
                 WP_CLI::line("ID        : " . $form_message['site_id']);
                 WP_CLI::line("Title     : " . get_bloginfo('name'));
                 WP_CLI::line("Front     : " . get_site_url());
                 WP_CLI::line("Dashboard : " . admin_url());
                 WP_CLI::line("Customize : " . admin_url('customize.php'));
             }
             restore_current_blog();
         }
     }
 }
Example #6
0
 /**
  * Stop process on Creating dir Error, print and log error, removes the new blog
  * @since 0.2.0
  * @param  string  $dir_path the path
  */
 public static function mkdir_error($dir_path)
 {
     $error_1 = 'ERROR DURING FILE COPY : CANNOT CREATE ' . $dir_path;
     MUCD_Duplicate::write_log($error_1);
     $error_2 = sprintf(MUCD_NETWORK_PAGE_DUPLICATE_COPY_FILE_ERROR, MUCD_Functions::get_primary_upload_dir());
     MUCD_Duplicate::write_log($error_2);
     MUCD_Duplicate::write_log('Duplication interrupted on FILE COPY ERROR');
     echo '<br />Duplication failed :<br /><br />' . $error_1 . '<br /><br />' . $error_2 . '<br /><br />';
     if ($log_url = MUCD_Duplicate::log_url()) {
         echo '<a href="' . $log_url . '">' . MUCD_NETWORK_PAGE_DUPLICATE_VIEW_LOG . '</a>';
     }
     MUCD_Functions::remove_blog(self::$to_site_id);
     wp_die();
 }