base_prefix ); } /** * Set new database prefix in database and wp-config. * * ## OPTIONS * * [] * : New database prefix. If not passed, the 'wp_' is used. * * [--skip-success=] * : Skip success messages: * * **true**: skip success messages. * * ## EXAMPLES * * wp db-prefix set * wp db-prefix set newpref_ * wp db-prefix set newpref_ --skip-success=true */ public function set ( $args, $assoc_args) { global $wpdb; $new_prefix = isset( $args[0] ) ? $args[0] : $this->_generatePrefix(); $current_prefix = $wpdb->base_prefix; $skipSuccess = isset($assoc_args['skip-success']) ? $assoc_args['skip-success'] : 'false'; if ( 0 == strcmp( $current_prefix, $new_prefix ) ) { if ('true' !== $skipSuccess) { WP_CLI::success( "'{$new_prefix}' is current database prefix value." ); } return; } $result = $wpdb->set_prefix( $new_prefix, false ); if ( is_wp_error( $result ) ) { WP_CLI::error( WP_CLI::error_to_string( $result ), self::CODE_WRONG_PREFIX ); } $this->_maintenance_mode( true ); $plugins = $this->_deactivate_plugins(); $this->_edit_config( $new_prefix ); $this->_update_db( $new_prefix, $current_prefix ); $this->_activate_plugins( $plugins ); $this->_flush_rewrite_rules(); $this->_maintenance_mode( false ); if ('true' !== $skipSuccess) { WP_CLI::success( "Database prefix was successfully changed to '{$new_prefix}'." ); } } private function _maintenance_mode( $enable = true ) { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); $err_code = $enable ? self::CODE_FAILED_TURN_ON_MAINTENANCE_MODE : self::CODE_FAILED_TURN_OFF_MAINTENANCE_MODE; $upgrader = Utils\get_upgrader( 'WP_Upgrader' ); if ( !$upgrader->fs_connect( WP_CONTENT_DIR ) ) { WP_CLI::error( "Could not connect file system.", $err_code ); } $result = $upgrader->maintenance_mode( $enable ); if ( is_wp_error( $result ) ) { WP_CLI::error( WP_CLI::error_to_string( $result ), $err_code ); } } private function _deactivate_plugins () { require_once ABSPATH.'wp-admin/includes/plugin.php'; $active_plugins = array(); foreach ( get_plugins() as $file => $details ) { if (is_plugin_active( $file )) { deactivate_plugins( $file ); if ( is_plugin_active( $file ) ) { WP_CLI::error( "Could not deactivate the '{$details['Name']}' plugin.", self::CODE_FAILED_DEACTIVATE_PLUGIN ); } $active_plugins[] = $file; } } return $active_plugins; } private function _activate_plugins ( $plugins ) { require_once ABSPATH.'wp-admin/includes/plugin.php'; foreach ( $plugins as $file ) { activate_plugins($file); if ( !is_plugin_active( $file ) ) { $plugin_folder = get_plugins( '/' . plugin_basename( dirname( $file ) ) ); $plugin_info = $plugin_folder[basename( $file )]; WP_CLI::error( "Could not activate the '{$plugin_info['Name']}' plugin.", self::CODE_FAILED_ACTIVATE_PLUGIN ); } } } private function _edit_config( $new_prefix ) { $wp_config_path = Utils\locate_wp_config(); if ( !is_readable( $wp_config_path ) || false === ( $config_file = file_get_contents( $wp_config_path ) ) ) { WP_CLI::error( "Could not open config file.", self::CODE_FAILED_CHANGE_WP_CONFIG ); } $config_file = preg_replace( '/\$table_prefix(.*)$/m', '$table_prefix = \''. $new_prefix .'\';', $config_file ); if ( !is_writable( $wp_config_path ) || false === file_put_contents( $wp_config_path, $config_file ) ) { WP_CLI::error( "Could not modify config file.", self::CODE_FAILED_CHANGE_WP_CONFIG ); } } private function _update_db( $new_prefix, $current_prefix ) { global $wpdb; $tables = $wpdb->get_col( $wpdb->prepare( "SHOW TABLES LIKE %s", like_escape( $current_prefix ) . '%' ) ); foreach ( $tables as $table_name ) { if ( 0 === strpos( $table_name, $current_prefix ) ) { $new_table_name = str_replace( $current_prefix, $new_prefix, $table_name ); if ( false === $wpdb->query( "RENAME TABLE {$table_name} TO {$new_table_name}" ) ) { WP_CLI::error( "Could not change table '{$table_name}' name.", self::CODE_FAILED_CHANGE_DB ); } } } $result = $wpdb->set_prefix( $new_prefix ); if ( is_wp_error( $result ) ) { WP_CLI::error( WP_CLI::error_to_string( $result ), self::CODE_FAILED_CHANGE_DB ); } if ( false === $wpdb->update( $wpdb->options, array( 'option_name' => $new_prefix . 'user_roles'), array( 'option_name' => $current_prefix . 'user_roles' ) ) ) { WP_CLI::error( "Could not update table '{$wpdb->options}'.", self::CODE_FAILED_CHANGE_DB ); } $meta_keys = $wpdb->get_results( $wpdb->prepare( "SELECT user_id, meta_key FROM {$wpdb->usermeta} WHERE meta_key LIKE %s", like_escape( $current_prefix ) . '%' ) ); foreach ( $meta_keys as $meta_key ) { if ( false === $wpdb->update( $wpdb->usermeta, array( 'meta_key' => str_replace( $current_prefix, $new_prefix, $meta_key->meta_key ) ), array( 'meta_key' => $meta_key->meta_key, 'user_id' => $meta_key->user_id ) ) ) { WP_CLI::error( "Could not update table '{$wpdb->usermeta}'.", self::CODE_FAILED_CHANGE_DB ); } } } private function _flush_rewrite_rules() { WP_CLI::run_command( array( 'rewrite', 'flush' ), array( 'hard' => true ) ); } /** * Generates a prefix of random length. * * @return string */ private function _generatePrefix() { $args = array( (array)range('a', 'z'), (array)range('A', 'Z'), (array)range(0, 9), ); srand((float)microtime()*1000000); $length = rand(5, 10); $prefix = array(); // add required symbols foreach ($args as $arg) { if (count($prefix) == $length) { shuffle($prefix); return implode("", $prefix).'_'; } $prefix[] = $arg[rand(0, count($arg) - 1)]; } // add remaining symbols while (count($prefix) < $length) { $arg = $args[rand(0, count($args) - 1)]; $prefix[] = $arg[rand(0, count($arg) - 1)]; } shuffle($prefix); return implode("", $prefix).'_'; } } WP_CLI::add_command( 'db-prefix', 'DB_Prefix_Command' );