| 1 |
<?php |
| 2 |
/** |
| 3 |
* Actions to run when the module gets activated. |
| 4 |
* |
| 5 |
* @since 1.8.0 |
| 6 |
* @package performance-lab |
| 7 |
*/ |
| 8 |
|
| 9 |
/** |
| 10 |
* Copies the db.php file in wp-content and reloads the page. |
| 11 |
* |
| 12 |
* @since 1.8.0 |
| 13 |
*/ |
| 14 |
return function() { |
| 15 |
// Bail early if the SQLite3 class does not exist. |
| 16 |
if ( ! class_exists( 'SQLite3' ) ) { |
| 17 |
return; |
| 18 |
} |
| 19 |
|
| 20 |
$destination = WP_CONTENT_DIR . '/db.php'; |
| 21 |
|
| 22 |
// Place database drop-in if not present yet, except in case there is |
| 23 |
// another database drop-in present already. |
| 24 |
if ( ! defined( 'PERFLAB_SQLITE_DB_DROPIN_VERSION' ) && ! file_exists( $destination ) ) { |
| 25 |
// Init the filesystem to allow copying the file. |
| 26 |
global $wp_filesystem; |
| 27 |
|
| 28 |
require_once ABSPATH . '/wp-admin/includes/file.php'; |
| 29 |
|
| 30 |
// Init the filesystem if needed, then copy the file, replacing contents as needed. |
| 31 |
if ( ( $wp_filesystem || WP_Filesystem() ) && $wp_filesystem->touch( $destination ) ) { |
| 32 |
|
| 33 |
// Get the db.copy.php file contents, replace placeholders and write it to the destination. |
| 34 |
$file_contents = str_replace( |
| 35 |
'{SQLITE_IMPLEMENTATION_FOLDER_PATH}', |
| 36 |
__DIR__, |
| 37 |
file_get_contents( __DIR__ . '/db.copy.php' ) |
| 38 |
); |
| 39 |
|
| 40 |
$wp_filesystem->put_contents( $destination, $file_contents ); |
| 41 |
} |
| 42 |
} |
| 43 |
|
| 44 |
// Do not automatically set up SQLite DB on a multisite as that is notably |
| 45 |
// more complex. Potentially it can be added in the future. |
| 46 |
if ( is_multisite() ) { |
| 47 |
return; |
| 48 |
} |
| 49 |
|
| 50 |
// As an extra safety check, bail if the current user cannot update |
| 51 |
// (or install) WordPress core. |
| 52 |
if ( ! current_user_can( 'update_core' ) ) { |
| 53 |
return; |
| 54 |
} |
| 55 |
|
| 56 |
// Otherwise install WordPress in the SQLite database before the redirect, |
| 57 |
// so that the user does not end up on the WordPress installation screen |
| 58 |
// but rather remains in the Performance Lab modules screen. |
| 59 |
add_filter( |
| 60 |
'wp_redirect', |
| 61 |
function( $redirect_location ) { |
| 62 |
if ( ! defined( 'DATABASE_TYPE' ) ) { |
| 63 |
define( 'DATABASE_TYPE', 'sqlite' ); |
| 64 |
} |
| 65 |
require_once __DIR__ . '/constants.php'; |
| 66 |
|
| 67 |
// If the SQLite DB already exists, simply ensure the module is |
| 68 |
// active there. |
| 69 |
if ( file_exists( FQDB ) ) { |
| 70 |
require_once __DIR__ . '/wp-includes/sqlite/db.php'; |
| 71 |
wp_set_wpdb_vars(); |
| 72 |
global $wpdb; |
| 73 |
$row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", PERFLAB_MODULES_SETTING ) ); |
| 74 |
if ( is_object( $row ) ) { |
| 75 |
$value = maybe_unserialize( $row->option_value ); |
| 76 |
if ( is_array( $value ) && ( ! isset( $value['database/sqlite'] ) || ! $value['database/sqlite']['enabled'] ) ) { |
| 77 |
$value['database/sqlite'] = array( 'enabled' => true ); |
| 78 |
$wpdb->update( $wpdb->options, array( 'option_value' => maybe_serialize( $value ) ), array( 'option_name' => PERFLAB_MODULES_SETTING ) ); |
| 79 |
} |
| 80 |
} |
| 81 |
return $redirect_location; |
| 82 |
} |
| 83 |
|
| 84 |
// Get current basic setup data to install WordPress in the new DB. |
| 85 |
$blog_title = get_bloginfo( 'name' ); |
| 86 |
$is_public = (bool) get_option( 'blog_public' ); |
| 87 |
$language = get_option( 'WPLANG' ); |
| 88 |
$admin_email = get_option( 'admin_email' ); |
| 89 |
$admin_user = get_user_by( 'email', $admin_email ); |
| 90 |
if ( ! $admin_user ) { |
| 91 |
$admin_user = wp_get_current_user(); |
| 92 |
} |
| 93 |
|
| 94 |
// Look up the data for the current user (in case they're not the |
| 95 |
// admin email user). Additionally, attempt to keep them |
| 96 |
// logged-in by retaining their current session. Depending on the |
| 97 |
// site configuration, this is not 100% reliable as sites may store |
| 98 |
// session tokens outside of user meta. However that does not lead |
| 99 |
// to any problem, the user would simply be required to sign in |
| 100 |
// again. |
| 101 |
$current_user = wp_get_current_user(); |
| 102 |
$current_user_sessions = get_user_meta( $current_user->ID, 'session_tokens', true ); |
| 103 |
|
| 104 |
// Get current data to keep the Performance Lab plugin and relevant |
| 105 |
// modules active in the new DB. |
| 106 |
$active_plugins_option = array( plugin_basename( PERFLAB_MAIN_FILE ) ); |
| 107 |
$active_modules_option = get_option( PERFLAB_MODULES_SETTING, array() ); |
| 108 |
|
| 109 |
// Load and set up SQLite database. |
| 110 |
require_once __DIR__ . '/wp-includes/sqlite/db.php'; |
| 111 |
wp_set_wpdb_vars(); |
| 112 |
|
| 113 |
// Load WordPress installation API functions. |
| 114 |
require_once ABSPATH . 'wp-admin/includes/upgrade.php'; |
| 115 |
|
| 116 |
// Install WordPress in the SQLite database with the same base |
| 117 |
// configuration as the MySQL database. |
| 118 |
// Since $admin_user->user_pass is already hashed, add a filter to |
| 119 |
// ensure it is inserted into the database like that, instead of |
| 120 |
// being re-hashed. |
| 121 |
$unhash_user_pass = function( $data, $update, $user_id, $userdata ) use ( $admin_user, $current_user ) { |
| 122 |
// Double check this is actually the already hashed password, |
| 123 |
// to prevent any chance of accidentally putting another |
| 124 |
// password into the database which would then be plain text. |
| 125 |
if ( |
| 126 |
! empty( $userdata['user_pass'] ) |
| 127 |
&& ( |
| 128 |
$userdata['user_pass'] === $admin_user->user_pass |
| 129 |
|| $userdata['user_pass'] === $current_user->user_pass |
| 130 |
) |
| 131 |
) { |
| 132 |
$data['user_pass'] = $userdata['user_pass']; |
| 133 |
} |
| 134 |
return $data; |
| 135 |
}; |
| 136 |
add_filter( 'wp_pre_insert_user_data', $unhash_user_pass, 10, 4 ); |
| 137 |
wp_install( $blog_title, $admin_user->user_login, $admin_user->user_email, $is_public, '', $admin_user->user_pass, $language ); |
| 138 |
// If the current user is not the admin user, create an account for that user too. |
| 139 |
if ( $current_user->user_login !== $admin_user->user_login ) { |
| 140 |
wp_create_user( $current_user->user_login, $current_user->user_pass, $current_user->user_email ); |
| 141 |
} |
| 142 |
remove_filter( 'wp_pre_insert_user_data', $unhash_user_pass ); |
| 143 |
|
| 144 |
// If the admin email was originally not attached to any user |
| 145 |
// (e.g. when the original admin email user was deleted), reset |
| 146 |
// the option to the original admin email again (by default |
| 147 |
// `wp_install()` will set it to the same email as the initial |
| 148 |
// admin user email). |
| 149 |
if ( 0 !== strcasecmp( $admin_user->user_email, $admin_email ) ) { |
| 150 |
update_option( 'admin_email', $admin_email ); |
| 151 |
} |
| 152 |
|
| 153 |
// If user sessions are found, migrate them over so that the |
| 154 |
// current user remains logged in. |
| 155 |
if ( $current_user_sessions ) { |
| 156 |
$session_user = get_user_by( 'login', $current_user->user_login ); |
| 157 |
if ( $session_user ) { |
| 158 |
update_user_meta( $session_user->ID, 'session_tokens', $current_user_sessions ); |
| 159 |
} |
| 160 |
} |
| 161 |
|
| 162 |
// Activate the Performance Lab plugin and its modules. |
| 163 |
// Use direct database query for Performance Lab modules to |
| 164 |
// prevent module activation logic from firing again. |
| 165 |
update_option( 'active_plugins', $active_plugins_option ); |
| 166 |
global $wpdb; |
| 167 |
$wpdb->insert( |
| 168 |
$wpdb->options, |
| 169 |
array( |
| 170 |
'option_name' => PERFLAB_MODULES_SETTING, |
| 171 |
'option_value' => maybe_serialize( $active_modules_option ), |
| 172 |
'autoload' => 'yes', |
| 173 |
) |
| 174 |
); |
| 175 |
|
| 176 |
return $redirect_location; |
| 177 |
} |
| 178 |
); |
| 179 |
}; |
| 180 |
|