WordPress build repository browser

source: trunk/wp-admin/install.php

Last change on this file was 56792, checked in by swissspidy, 7 months ago

Upgrade/Install: Fix JavaScript localization on install page.

Blocks registration causes scripts to be initialized and localized very early, before the current locale has been properly set on the installation page.

This changes determine_locale() so that the locale chosen during installation is recognized and loaded earlier, ensuring proper script localization.

Props sabernhardt, NekoJonez, jornp, costdev.
Fixes #58696
Built from https://develop.svn.wordpress.org/trunk@57286

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.1 KB
Line 
1<?php
2/**
3 * WordPress Installer
4 *
5 * @package WordPress
6 * @subpackage Administration
7 */
8
9// Confidence check.
10if ( false ) {
11        ?>
12<!DOCTYPE html>
13<html>
14<head>
15        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
16        <title>Error: PHP is not running</title>
17</head>
18<body class="wp-core-ui">
19        <p id="logo"><a href="https://wordpress.org/">WordPress</a></p>
20        <h1>Error: PHP is not running</h1>
21        <p>WordPress requires that your web server is running PHP. Your server does not have PHP installed, or PHP is turned off.</p>
22</body>
23</html>
24        <?php
25}
26
27/**
28 * We are installing WordPress.
29 *
30 * @since 1.5.1
31 * @var bool
32 */
33define( 'WP_INSTALLING', true );
34
35/** Load WordPress Bootstrap */
36require_once dirname( __DIR__ ) . '/wp-load.php';
37
38/** Load WordPress Administration Upgrade API */
39require_once ABSPATH . 'wp-admin/includes/upgrade.php';
40
41/** Load WordPress Translation Install API */
42require_once ABSPATH . 'wp-admin/includes/translation-install.php';
43
44/** Load wpdb */
45require_once ABSPATH . WPINC . '/class-wpdb.php';
46
47nocache_headers();
48
49$step = isset( $_GET['step'] ) ? (int) $_GET['step'] : 0;
50
51/**
52 * Display installation header.
53 *
54 * @since 2.5.0
55 *
56 * @param string $body_classes
57 */
58function display_header( $body_classes = '' ) {
59        header( 'Content-Type: text/html; charset=utf-8' );
60        if ( is_rtl() ) {
61                $body_classes .= 'rtl';
62        }
63        if ( $body_classes ) {
64                $body_classes = ' ' . $body_classes;
65        }
66        ?>
67<!DOCTYPE html>
68<html <?php language_attributes(); ?>>
69<head>
70        <meta name="viewport" content="width=device-width" />
71        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
72        <meta name="robots" content="noindex,nofollow" />
73        <title><?php _e( 'WordPress &rsaquo; Installation' ); ?></title>
74        <?php wp_admin_css( 'install', true ); ?>
75</head>
76<body class="wp-core-ui<?php echo $body_classes; ?>">
77<p id="logo"><?php _e( 'WordPress' ); ?></p>
78
79        <?php
80} // End display_header().
81
82/**
83 * Displays installer setup form.
84 *
85 * @since 2.8.0
86 *
87 * @global wpdb $wpdb WordPress database abstraction object.
88 *
89 * @param string|null $error
90 */
91function display_setup_form( $error = null ) {
92        global $wpdb;
93
94        $user_table = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $wpdb->users ) ) ) !== null );
95
96        // Ensure that sites appear in search engines by default.
97        $blog_public = 1;
98        if ( isset( $_POST['weblog_title'] ) ) {
99                $blog_public = isset( $_POST['blog_public'] ) ? (int) $_POST['blog_public'] : $blog_public;
100        }
101
102        $weblog_title = isset( $_POST['weblog_title'] ) ? trim( wp_unslash( $_POST['weblog_title'] ) ) : '';
103        $user_name    = isset( $_POST['user_name'] ) ? trim( wp_unslash( $_POST['user_name'] ) ) : '';
104        $admin_email  = isset( $_POST['admin_email'] ) ? trim( wp_unslash( $_POST['admin_email'] ) ) : '';
105
106        if ( ! is_null( $error ) ) {
107                ?>
108<h1><?php _ex( 'Welcome', 'Howdy' ); ?></h1>
109<p class="message"><?php echo $error; ?></p>
110<?php } ?>
111<form id="setup" method="post" action="install.php?step=2" novalidate="novalidate">
112        <table class="form-table" role="presentation">
113                <tr>
114                        <th scope="row"><label for="weblog_title"><?php _e( 'Site Title' ); ?></label></th>
115                        <td><input name="weblog_title" type="text" id="weblog_title" size="25" value="<?php echo esc_attr( $weblog_title ); ?>" /></td>
116                </tr>
117                <tr>
118                        <th scope="row"><label for="user_login"><?php _e( 'Username' ); ?></label></th>
119                        <td>
120                        <?php
121                        if ( $user_table ) {
122                                _e( 'User(s) already exists.' );
123                                echo '<input name="user_name" type="hidden" value="admin" />';
124                        } else {
125                                ?>
126                                <input name="user_name" type="text" id="user_login" size="25" aria-describedby="user-name-desc" value="<?php echo esc_attr( sanitize_user( $user_name, true ) ); ?>" />
127                                <p id="user-name-desc"><?php _e( 'Usernames can have only alphanumeric characters, spaces, underscores, hyphens, periods, and the @ symbol.' ); ?></p>
128                                <?php
129                        }
130                        ?>
131                        </td>
132                </tr>
133                <?php if ( ! $user_table ) : ?>
134                <tr class="form-field form-required user-pass1-wrap">
135                        <th scope="row">
136                                <label for="pass1">
137                                        <?php _e( 'Password' ); ?>
138                                </label>
139                        </th>
140                        <td>
141                                <div class="wp-pwd">
142                                        <?php $initial_password = isset( $_POST['admin_password'] ) ? stripslashes( $_POST['admin_password'] ) : wp_generate_password( 18 ); ?>
143                                        <div class="password-input-wrapper">
144                                                <input type="password" name="admin_password" id="pass1" class="regular-text" autocomplete="new-password" spellcheck="false" data-reveal="1" data-pw="<?php echo esc_attr( $initial_password ); ?>" aria-describedby="pass-strength-result admin-password-desc" />
145                                                <div id="pass-strength-result" aria-live="polite"></div>
146                                        </div>
147                                        <button type="button" class="button wp-hide-pw hide-if-no-js" data-start-masked="<?php echo (int) isset( $_POST['admin_password'] ); ?>" data-toggle="0" aria-label="<?php esc_attr_e( 'Hide password' ); ?>">
148                                                <span class="dashicons dashicons-hidden"></span>
149                                                <span class="text"><?php _e( 'Hide' ); ?></span>
150                                        </button>
151                                </div>
152                                <p id="admin-password-desc"><span class="description important hide-if-no-js">
153                                <strong><?php _e( 'Important:' ); ?></strong>
154                                <?php /* translators: The non-breaking space prevents 1Password from thinking the text "log in" should trigger a password save prompt. */ ?>
155                                <?php _e( 'You will need this password to log&nbsp;in. Please store it in a secure location.' ); ?></span></p>
156                        </td>
157                </tr>
158                <tr class="form-field form-required user-pass2-wrap hide-if-js">
159                        <th scope="row">
160                                <label for="pass2"><?php _e( 'Repeat Password' ); ?>
161                                        <span class="description"><?php _e( '(required)' ); ?></span>
162                                </label>
163                        </th>
164                        <td>
165                                <input type="password" name="admin_password2" id="pass2" autocomplete="new-password" spellcheck="false" />
166                        </td>
167                </tr>
168                <tr class="pw-weak">
169                        <th scope="row"><?php _e( 'Confirm Password' ); ?></th>
170                        <td>
171                                <label>
172                                        <input type="checkbox" name="pw_weak" class="pw-checkbox" />
173                                        <?php _e( 'Confirm use of weak password' ); ?>
174                                </label>
175                        </td>
176                </tr>
177                <?php endif; ?>
178                <tr>
179                        <th scope="row"><label for="admin_email"><?php _e( 'Your Email' ); ?></label></th>
180                        <td><input name="admin_email" type="email" id="admin_email" size="25" aria-describedby="admin-email-desc" value="<?php echo esc_attr( $admin_email ); ?>" />
181                        <p id="admin-email-desc"><?php _e( 'Double-check your email address before continuing.' ); ?></p></td>
182                </tr>
183                <tr>
184                        <th scope="row"><?php has_action( 'blog_privacy_selector' ) ? _e( 'Site visibility' ) : _e( 'Search engine visibility' ); ?></th>
185                        <td>
186                                <fieldset>
187                                        <legend class="screen-reader-text"><span>
188                                                <?php
189                                                has_action( 'blog_privacy_selector' )
190                                                        /* translators: Hidden accessibility text. */
191                                                        ? _e( 'Site visibility' )
192                                                        /* translators: Hidden accessibility text. */
193                                                        : _e( 'Search engine visibility' );
194                                                ?>
195                                        </span></legend>
196                                        <?php
197                                        if ( has_action( 'blog_privacy_selector' ) ) {
198                                                ?>
199                                                <input id="blog-public" type="radio" name="blog_public" value="1" <?php checked( 1, $blog_public ); ?> />
200                                                <label for="blog-public"><?php _e( 'Allow search engines to index this site' ); ?></label><br />
201                                                <input id="blog-norobots" type="radio" name="blog_public"  aria-describedby="public-desc" value="0" <?php checked( 0, $blog_public ); ?> />
202                                                <label for="blog-norobots"><?php _e( 'Discourage search engines from indexing this site' ); ?></label>
203                                                <p id="public-desc" class="description"><?php _e( 'Note: Discouraging search engines does not block access to your site &mdash; it is up to search engines to honor your request.' ); ?></p>
204                                                <?php
205                                                /** This action is documented in wp-admin/options-reading.php */
206                                                do_action( 'blog_privacy_selector' );
207                                        } else {
208                                                ?>
209                                                <label for="blog_public"><input name="blog_public" type="checkbox" id="blog_public" aria-describedby="privacy-desc" value="0" <?php checked( 0, $blog_public ); ?> />
210                                                <?php _e( 'Discourage search engines from indexing this site' ); ?></label>
211                                                <p id="privacy-desc" class="description"><?php _e( 'It is up to search engines to honor this request.' ); ?></p>
212                                        <?php } ?>
213                                </fieldset>
214                        </td>
215                </tr>
216        </table>
217        <p class="step"><?php submit_button( __( 'Install WordPress' ), 'large', 'Submit', false, array( 'id' => 'submit' ) ); ?></p>
218        <input type="hidden" name="language" value="<?php echo isset( $_REQUEST['language'] ) ? esc_attr( $_REQUEST['language'] ) : ''; ?>" />
219</form>
220        <?php
221} // End display_setup_form().
222
223// Let's check to make sure WP isn't already installed.
224if ( is_blog_installed() ) {
225        display_header();
226        die(
227                '<h1>' . __( 'Already Installed' ) . '</h1>' .
228                '<p>' . __( 'You appear to have already installed WordPress. To reinstall please clear your old database tables first.' ) . '</p>' .
229                '<p class="step"><a href="' . esc_url( wp_login_url() ) . '">' . __( 'Log In' ) . '</a></p>' .
230                '</body></html>'
231        );
232}
233
234/**
235 * @global string $wp_version             The WordPress version string.
236 * @global string $required_php_version   The required PHP version string.
237 * @global string $required_mysql_version The required MySQL version string.
238 * @global wpdb   $wpdb                   WordPress database abstraction object.
239 */
240global $wp_version, $required_php_version, $required_mysql_version, $wpdb;
241
242$php_version   = PHP_VERSION;
243$mysql_version = $wpdb->db_version();
244$php_compat    = version_compare( $php_version, $required_php_version, '>=' );
245$mysql_compat  = version_compare( $mysql_version, $required_mysql_version, '>=' ) || file_exists( WP_CONTENT_DIR . '/db.php' );
246
247$version_url = sprintf(
248        /* translators: %s: WordPress version. */
249        esc_url( __( 'https://wordpress.org/documentation/wordpress-version/version-%s/' ) ),
250        sanitize_title( $wp_version )
251);
252
253$php_update_message = '</p><p>' . sprintf(
254        /* translators: %s: URL to Update PHP page. */
255        __( '<a href="%s">Learn more about updating PHP</a>.' ),
256        esc_url( wp_get_update_php_url() )
257);
258
259$annotation = wp_get_update_php_annotation();
260
261if ( $annotation ) {
262        $php_update_message .= '</p><p><em>' . $annotation . '</em>';
263}
264
265if ( ! $mysql_compat && ! $php_compat ) {
266        $compat = sprintf(
267                /* translators: 1: URL to WordPress release notes, 2: WordPress version number, 3: Minimum required PHP version number, 4: Minimum required MySQL version number, 5: Current PHP version number, 6: Current MySQL version number. */
268                __( 'You cannot install because <a href="%1$s">WordPress %2$s</a> requires PHP version %3$s or higher and MySQL version %4$s or higher. You are running PHP version %5$s and MySQL version %6$s.' ),
269                $version_url,
270                $wp_version,
271                $required_php_version,
272                $required_mysql_version,
273                $php_version,
274                $mysql_version
275        ) . $php_update_message;
276} elseif ( ! $php_compat ) {
277        $compat = sprintf(
278                /* translators: 1: URL to WordPress release notes, 2: WordPress version number, 3: Minimum required PHP version number, 4: Current PHP version number. */
279                __( 'You cannot install because <a href="%1$s">WordPress %2$s</a> requires PHP version %3$s or higher. You are running version %4$s.' ),
280                $version_url,
281                $wp_version,
282                $required_php_version,
283                $php_version
284        ) . $php_update_message;
285} elseif ( ! $mysql_compat ) {
286        $compat = sprintf(
287                /* translators: 1: URL to WordPress release notes, 2: WordPress version number, 3: Minimum required MySQL version number, 4: Current MySQL version number. */
288                __( 'You cannot install because <a href="%1$s">WordPress %2$s</a> requires MySQL version %3$s or higher. You are running version %4$s.' ),
289                $version_url,
290                $wp_version,
291                $required_mysql_version,
292                $mysql_version
293        );
294}
295
296if ( ! $mysql_compat || ! $php_compat ) {
297        display_header();
298        die( '<h1>' . __( 'Requirements Not Met' ) . '</h1><p>' . $compat . '</p></body></html>' );
299}
300
301if ( ! is_string( $wpdb->base_prefix ) || '' === $wpdb->base_prefix ) {
302        display_header();
303        die(
304                '<h1>' . __( 'Configuration Error' ) . '</h1>' .
305                '<p>' . sprintf(
306                        /* translators: %s: wp-config.php */
307                        __( 'Your %s file has an empty database table prefix, which is not supported.' ),
308                        '<code>wp-config.php</code>'
309                ) . '</p></body></html>'
310        );
311}
312
313// Set error message if DO_NOT_UPGRADE_GLOBAL_TABLES isn't set as it will break install.
314if ( defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) {
315        display_header();
316        die(
317                '<h1>' . __( 'Configuration Error' ) . '</h1>' .
318                '<p>' . sprintf(
319                        /* translators: %s: DO_NOT_UPGRADE_GLOBAL_TABLES */
320                        __( 'The constant %s cannot be defined when installing WordPress.' ),
321                        '<code>DO_NOT_UPGRADE_GLOBAL_TABLES</code>'
322                ) . '</p></body></html>'
323        );
324}
325
326/**
327 * @global string    $wp_local_package Locale code of the package.
328 * @global WP_Locale $wp_locale        WordPress date and time locale object.
329 */
330$language = '';
331if ( ! empty( $_REQUEST['language'] ) ) {
332        $language = sanitize_locale_name( $_REQUEST['language'] );
333} elseif ( isset( $GLOBALS['wp_local_package'] ) ) {
334        $language = $GLOBALS['wp_local_package'];
335}
336
337$scripts_to_print = array( 'jquery' );
338
339switch ( $step ) {
340        case 0: // Step 0.
341                if ( wp_can_install_language_pack() && empty( $language ) ) {
342                        $languages = wp_get_available_translations();
343                        if ( $languages ) {
344                                $scripts_to_print[] = 'language-chooser';
345                                display_header( 'language-chooser' );
346                                echo '<form id="setup" method="post" action="?step=1">';
347                                wp_install_language_form( $languages );
348                                echo '</form>';
349                                break;
350                        }
351                }
352
353                // Deliberately fall through if we can't reach the translations API.
354
355        case 1: // Step 1, direct link or from language chooser.
356                if ( ! empty( $language ) ) {
357                        $loaded_language = wp_download_language_pack( $language );
358                        if ( $loaded_language ) {
359                                load_default_textdomain( $loaded_language );
360                                $GLOBALS['wp_locale'] = new WP_Locale();
361                        }
362                }
363
364                $scripts_to_print[] = 'user-profile';
365
366                display_header();
367                ?>
368<h1><?php _ex( 'Welcome', 'Howdy' ); ?></h1>
369<p><?php _e( 'Welcome to the famous five-minute WordPress installation process! Just fill in the information below and you&#8217;ll be on your way to using the most extendable and powerful personal publishing platform in the world.' ); ?></p>
370
371<h2><?php _e( 'Information needed' ); ?></h2>
372<p><?php _e( 'Please provide the following information. Do not worry, you can always change these settings later.' ); ?></p>
373
374                <?php
375                display_setup_form();
376                break;
377        case 2:
378                if ( ! empty( $language ) && load_default_textdomain( $language ) ) {
379                        $loaded_language      = $language;
380                        $GLOBALS['wp_locale'] = new WP_Locale();
381                } else {
382                        $loaded_language = 'en_US';
383                }
384
385                if ( ! empty( $wpdb->error ) ) {
386                        wp_die( $wpdb->error->get_error_message() );
387                }
388
389                $scripts_to_print[] = 'user-profile';
390
391                display_header();
392                // Fill in the data we gathered.
393                $weblog_title         = isset( $_POST['weblog_title'] ) ? trim( wp_unslash( $_POST['weblog_title'] ) ) : '';
394                $user_name            = isset( $_POST['user_name'] ) ? trim( wp_unslash( $_POST['user_name'] ) ) : '';
395                $admin_password       = isset( $_POST['admin_password'] ) ? wp_unslash( $_POST['admin_password'] ) : '';
396                $admin_password_check = isset( $_POST['admin_password2'] ) ? wp_unslash( $_POST['admin_password2'] ) : '';
397                $admin_email          = isset( $_POST['admin_email'] ) ? trim( wp_unslash( $_POST['admin_email'] ) ) : '';
398                $public               = isset( $_POST['blog_public'] ) ? (int) $_POST['blog_public'] : 1;
399
400                // Check email address.
401                $error = false;
402                if ( empty( $user_name ) ) {
403                        // TODO: Poka-yoke.
404                        display_setup_form( __( 'Please provide a valid username.' ) );
405                        $error = true;
406                } elseif ( sanitize_user( $user_name, true ) !== $user_name ) {
407                        display_setup_form( __( 'The username you provided has invalid characters.' ) );
408                        $error = true;
409                } elseif ( $admin_password !== $admin_password_check ) {
410                        // TODO: Poka-yoke.
411                        display_setup_form( __( 'Your passwords do not match. Please try again.' ) );
412                        $error = true;
413                } elseif ( empty( $admin_email ) ) {
414                        // TODO: Poka-yoke.
415                        display_setup_form( __( 'You must provide an email address.' ) );
416                        $error = true;
417                } elseif ( ! is_email( $admin_email ) ) {
418                        // TODO: Poka-yoke.
419                        display_setup_form( __( 'Sorry, that is not a valid email address. Email addresses look like <code>username@example.com</code>.' ) );
420                        $error = true;
421                }
422
423                if ( false === $error ) {
424                        $wpdb->show_errors();
425                        $result = wp_install( $weblog_title, $user_name, $admin_email, $public, '', wp_slash( $admin_password ), $loaded_language );
426                        ?>
427
428<h1><?php _e( 'Success!' ); ?></h1>
429
430<p><?php _e( 'WordPress has been installed. Thank you, and enjoy!' ); ?></p>
431
432<table class="form-table install-success">
433        <tr>
434                <th><?php _e( 'Username' ); ?></th>
435                <td><?php echo esc_html( sanitize_user( $user_name, true ) ); ?></td>
436        </tr>
437        <tr>
438                <th><?php _e( 'Password' ); ?></th>
439                <td>
440                        <?php if ( ! empty( $result['password'] ) && empty( $admin_password_check ) ) : ?>
441                                <code><?php echo esc_html( $result['password'] ); ?></code><br />
442                        <?php endif; ?>
443                        <p><?php echo $result['password_message']; ?></p>
444                </td>
445        </tr>
446</table>
447
448<p class="step"><a href="<?php echo esc_url( wp_login_url() ); ?>"><?php _e( 'Log In' ); ?></a></p>
449
450                        <?php
451                }
452                break;
453}
454
455if ( ! wp_is_mobile() ) {
456        ?>
457<script type="text/javascript">var t = document.getElementById('weblog_title'); if (t){ t.focus(); }</script>
458        <?php
459}
460
461wp_print_scripts( $scripts_to_print );
462?>
463<script type="text/javascript">
464jQuery( function( $ ) {
465        $( '.hide-if-no-js' ).removeClass( 'hide-if-no-js' );
466} );
467</script>
468</body>
469</html>
Note: See TracBrowser for help on using the repository browser.