Make WordPress Core

Changeset 43628


Ignore:
Timestamp:
09/05/2018 10:44:02 AM (6 years ago)
Author:
flixos90
Message:

Upgrade/Install: Introduce populate_network_meta(), moving logic out of populate_network().

Fixes #44895. See #41333.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/schema.php

    r43627 r43628  
    384384
    385385    // If WP_DEFAULT_THEME doesn't exist, fall back to the latest core default theme.
    386     $stylesheet = $template = WP_DEFAULT_THEME;
     386    $stylesheet = WP_DEFAULT_THEME;
     387    $template   = WP_DEFAULT_THEME;
    387388    $theme      = wp_get_theme( WP_DEFAULT_THEME );
    388389    if ( ! $theme->exists() ) {
     
    403404     * for all timezone strings supported by PHP.
    404405     */
    405     $offset_or_tz = _x( '0', 'default GMT offset or timezone string' );
     406    $offset_or_tz = _x( '0', 'default GMT offset or timezone string' ); // phpcs:ignore WordPress.WP.I18n.NoEmptyStrings
    406407    if ( is_numeric( $offset_or_tz ) ) {
    407408        $gmt_offset = $offset_or_tz;
     
    563564
    564565    $keys             = "'" . implode( "', '", array_keys( $options ) ) . "'";
    565     $existing_options = $wpdb->get_col( "SELECT option_name FROM $wpdb->options WHERE option_name in ( $keys )" );
     566    $existing_options = $wpdb->get_col( "SELECT option_name FROM $wpdb->options WHERE option_name in ( $keys )" ); // phpcs:ignore WordPress.WP.PreparedSQL.NotPrepared
    566567
    567568    $insert = '';
     
    586587
    587588    if ( ! empty( $insert ) ) {
    588         $wpdb->query( "INSERT INTO $wpdb->options (option_name, option_value, autoload) VALUES " . $insert );
     589        $wpdb->query( "INSERT INTO $wpdb->options (option_name, option_value, autoload) VALUES " . $insert ); // phpcs:ignore WordPress.WP.PreparedSQL.NotPrepared
    589590    }
    590591
     
    961962 * @global wpdb       $wpdb
    962963 * @global object     $current_site
    963  * @global int        $wp_db_version
    964964 * @global WP_Rewrite $wp_rewrite
    965965 *
     
    975975 */
    976976function populate_network( $network_id = 1, $domain = '', $email = '', $site_name = '', $path = '/', $subdomain_install = false ) {
    977     global $wpdb, $current_site, $wp_db_version, $wp_rewrite;
     977    global $wpdb, $current_site, $wp_rewrite;
    978978
    979979    $errors = new WP_Error();
     
    10031003    if ( $errors->has_errors() ) {
    10041004        return $errors;
    1005     }
    1006 
    1007     // If a user with the provided email does not exist, default to the current user as the new network admin.
    1008     $site_user = get_user_by( 'email', $email );
    1009     if ( false === $site_user ) {
    1010         $site_user = wp_get_current_user();
    1011     }
    1012 
    1013     // Set up site tables.
    1014     $template       = get_option( 'template' );
    1015     $stylesheet     = get_option( 'stylesheet' );
    1016     $allowed_themes = array( $stylesheet => true );
    1017 
    1018     if ( $template != $stylesheet ) {
    1019         $allowed_themes[ $template ] = true;
    1020     }
    1021 
    1022     if ( WP_DEFAULT_THEME != $stylesheet && WP_DEFAULT_THEME != $template ) {
    1023         $allowed_themes[ WP_DEFAULT_THEME ] = true;
    1024     }
    1025 
    1026     // If WP_DEFAULT_THEME doesn't exist, also whitelist the latest core default theme.
    1027     if ( ! wp_get_theme( WP_DEFAULT_THEME )->exists() ) {
    1028         if ( $core_default = WP_Theme::get_core_default_theme() ) {
    1029             $allowed_themes[ $core_default->get_stylesheet() ] = true;
    1030         }
    10311005    }
    10321006
     
    10511025    }
    10521026
     1027    populate_network_meta(
     1028        $network_id,
     1029        array(
     1030            'admin_email'       => $email,
     1031            'site_name'         => $site_name,
     1032            'subdomain_install' => $subdomain_install,
     1033        )
     1034    );
     1035
     1036    $site_user = get_userdata( (int) $wpdb->get_var( $wpdb->prepare( "SELECT meta_value FROM $wpdb->sitemeta WHERE meta_key = %s AND site_id = %d", 'admin_user_id', $network_id ) ) );
     1037
     1038    /*
     1039     * When upgrading from single to multisite, assume the current site will
     1040     * become the main site of the network. When using populate_network()
     1041     * to create another network in an existing multisite environment, skip
     1042     * these steps since the main site of the new network has not yet been
     1043     * created.
     1044     */
     1045    if ( ! is_multisite() ) {
     1046        $current_site            = new stdClass;
     1047        $current_site->domain    = $domain;
     1048        $current_site->path      = $path;
     1049        $current_site->site_name = ucfirst( $domain );
     1050        $wpdb->insert(
     1051            $wpdb->blogs,
     1052            array(
     1053                'site_id'    => $network_id,
     1054                'blog_id'    => 1,
     1055                'domain'     => $domain,
     1056                'path'       => $path,
     1057                'registered' => current_time( 'mysql' ),
     1058            )
     1059        );
     1060        $current_site->blog_id = $wpdb->insert_id;
     1061        update_user_meta( $site_user->ID, 'source_domain', $domain );
     1062        update_user_meta( $site_user->ID, 'primary_blog', $current_site->blog_id );
     1063
     1064        if ( $subdomain_install ) {
     1065            $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%day%/%postname%/' );
     1066        } else {
     1067            $wp_rewrite->set_permalink_structure( '/blog/%year%/%monthnum%/%day%/%postname%/' );
     1068        }
     1069
     1070        flush_rewrite_rules();
     1071
     1072        if ( ! $subdomain_install ) {
     1073            return true;
     1074        }
     1075
     1076        $vhost_ok = false;
     1077        $errstr   = '';
     1078        $hostname = substr( md5( time() ), 0, 6 ) . '.' . $domain; // Very random hostname!
     1079        $page     = wp_remote_get(
     1080            'http://' . $hostname,
     1081            array(
     1082                'timeout'     => 5,
     1083                'httpversion' => '1.1',
     1084            )
     1085        );
     1086        if ( is_wp_error( $page ) ) {
     1087            $errstr = $page->get_error_message();
     1088        } elseif ( 200 == wp_remote_retrieve_response_code( $page ) ) {
     1089                $vhost_ok = true;
     1090        }
     1091
     1092        if ( ! $vhost_ok ) {
     1093            $msg = '<p><strong>' . __( 'Warning! Wildcard DNS may not be configured correctly!' ) . '</strong></p>';
     1094
     1095            $msg .= '<p>' . sprintf(
     1096                /* translators: %s: host name */
     1097                __( 'The installer attempted to contact a random hostname (%s) on your domain.' ),
     1098                '<code>' . $hostname . '</code>'
     1099            );
     1100            if ( ! empty( $errstr ) ) {
     1101                /* translators: %s: error message */
     1102                $msg .= ' ' . sprintf( __( 'This resulted in an error message: %s' ), '<code>' . $errstr . '</code>' );
     1103            }
     1104            $msg .= '</p>';
     1105
     1106            $msg .= '<p>' . sprintf(
     1107                /* translators: %s: asterisk symbol (*) */
     1108                __( 'To use a subdomain configuration, you must have a wildcard entry in your DNS. This usually means adding a %s hostname record pointing at your web server in your DNS configuration tool.' ),
     1109                '<code>*</code>'
     1110            ) . '</p>';
     1111
     1112            $msg .= '<p>' . __( 'You can still use your site but any subdomain you create may not be accessible. If you know your DNS is correct, ignore this message.' ) . '</p>';
     1113
     1114            return new WP_Error( 'no_wildcard_dns', $msg );
     1115        }
     1116    }
     1117
     1118    return true;
     1119}
     1120
     1121/**
     1122 * Creates WordPress network meta and sets the default values.
     1123 *
     1124 * @since 5.0.0
     1125 *
     1126 * @global wpdb $wpdb          WordPress database abstraction object.
     1127 * @global int  $wp_db_version WordPress database version.
     1128 *
     1129 * @param int   $network_id Network ID to populate meta for.
     1130 * @param array $meta       Optional. Custom meta $key => $value pairs to use. Default empty array.
     1131 */
     1132function populate_network_meta( $network_id, array $meta = array() ) {
     1133    global $wpdb, $wp_db_version;
     1134
     1135    $network_id = (int) $network_id;
     1136
     1137    $email             = ! empty( $meta['admin_email'] ) ? $meta['admin_email'] : '';
     1138    $subdomain_install = isset( $meta['subdomain_install'] ) ? (int) $meta['subdomain_install'] : 0;
     1139
     1140    // If a user with the provided email does not exist, default to the current user as the new network admin.
     1141    $site_user = ! empty( $email ) ? get_user_by( 'email', $email ) : false;
     1142    if ( false === $site_user ) {
     1143        $site_user = wp_get_current_user();
     1144    }
     1145
     1146    if ( empty( $email ) ) {
     1147        $email = $site_user->user_email;
     1148    }
     1149
     1150    $template       = get_option( 'template' );
     1151    $stylesheet     = get_option( 'stylesheet' );
     1152    $allowed_themes = array( $stylesheet => true );
     1153
     1154    if ( $template != $stylesheet ) {
     1155        $allowed_themes[ $template ] = true;
     1156    }
     1157
     1158    if ( WP_DEFAULT_THEME != $stylesheet && WP_DEFAULT_THEME != $template ) {
     1159        $allowed_themes[ WP_DEFAULT_THEME ] = true;
     1160    }
     1161
     1162    // If WP_DEFAULT_THEME doesn't exist, also whitelist the latest core default theme.
     1163    if ( ! wp_get_theme( WP_DEFAULT_THEME )->exists() ) {
     1164        $core_default = WP_Theme::get_core_default_theme();
     1165        if ( $core_default ) {
     1166            $allowed_themes[ $core_default->get_stylesheet() ] = true;
     1167        }
     1168    }
     1169
    10531170    wp_cache_delete( 'networks_have_paths', 'site-options' );
    10541171
     
    10901207    );
    10911208
    1092     $misc_exts        = array(
     1209    $misc_exts = array(
    10931210        // Images.
    10941211        'jpg',
     
    11231240
    11241241    $sitemeta = array(
    1125         'site_name'                   => $site_name,
     1242        'site_name'                   => __( 'My Network' ),
    11261243        'admin_email'                 => $email,
    11271244        'admin_user_id'               => $site_user->ID,
     
    11411258        'add_new_users'               => '0',
    11421259        'upload_space_check_disabled' => is_multisite() ? get_site_option( 'upload_space_check_disabled' ) : '1',
    1143         'subdomain_install'           => intval( $subdomain_install ),
     1260        'subdomain_install'           => $subdomain_install,
    11441261        'global_terms_enabled'        => global_terms_enabled() ? '1' : '0',
    11451262        'ms_files_rewriting'          => is_multisite() ? get_site_option( 'ms_files_rewriting' ) : '0',
     
    11511268        $sitemeta['illegal_names'][] = 'blog';
    11521269    }
     1270
     1271    $sitemeta = wp_parse_args( $meta, $sitemeta );
    11531272
    11541273    /**
     
    11721291        $insert .= $wpdb->prepare( '( %d, %s, %s)', $network_id, $meta_key, $meta_value );
    11731292    }
    1174     $wpdb->query( "INSERT INTO $wpdb->sitemeta ( site_id, meta_key, meta_value ) VALUES " . $insert );
    1175 
    1176     /*
    1177      * When upgrading from single to multisite, assume the current site will
    1178      * become the main site of the network. When using populate_network()
    1179      * to create another network in an existing multisite environment, skip
    1180      * these steps since the main site of the new network has not yet been
    1181      * created.
    1182      */
    1183     if ( ! is_multisite() ) {
    1184         $current_site            = new stdClass;
    1185         $current_site->domain    = $domain;
    1186         $current_site->path      = $path;
    1187         $current_site->site_name = ucfirst( $domain );
    1188         $wpdb->insert(
    1189             $wpdb->blogs,
    1190             array(
    1191                 'site_id'    => $network_id,
    1192                 'blog_id'    => 1,
    1193                 'domain'     => $domain,
    1194                 'path'       => $path,
    1195                 'registered' => current_time( 'mysql' ),
    1196             )
    1197         );
    1198         $current_site->blog_id = $blog_id = $wpdb->insert_id;
    1199         update_user_meta( $site_user->ID, 'source_domain', $domain );
    1200         update_user_meta( $site_user->ID, 'primary_blog', $blog_id );
    1201 
    1202         if ( $subdomain_install ) {
    1203             $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%day%/%postname%/' );
    1204         } else {
    1205             $wp_rewrite->set_permalink_structure( '/blog/%year%/%monthnum%/%day%/%postname%/' );
    1206         }
    1207 
    1208         flush_rewrite_rules();
    1209 
    1210         if ( ! $subdomain_install ) {
    1211             return true;
    1212         }
    1213 
    1214         $vhost_ok = false;
    1215         $errstr   = '';
    1216         $hostname = substr( md5( time() ), 0, 6 ) . '.' . $domain; // Very random hostname!
    1217         $page     = wp_remote_get(
    1218             'http://' . $hostname,
    1219             array(
    1220                 'timeout'     => 5,
    1221                 'httpversion' => '1.1',
    1222             )
    1223         );
    1224         if ( is_wp_error( $page ) ) {
    1225             $errstr = $page->get_error_message();
    1226         } elseif ( 200 == wp_remote_retrieve_response_code( $page ) ) {
    1227                 $vhost_ok = true;
    1228         }
    1229 
    1230         if ( ! $vhost_ok ) {
    1231             $msg = '<p><strong>' . __( 'Warning! Wildcard DNS may not be configured correctly!' ) . '</strong></p>';
    1232 
    1233             $msg .= '<p>' . sprintf(
    1234                 /* translators: %s: host name */
    1235                 __( 'The installer attempted to contact a random hostname (%s) on your domain.' ),
    1236                 '<code>' . $hostname . '</code>'
    1237             );
    1238             if ( ! empty( $errstr ) ) {
    1239                 /* translators: %s: error message */
    1240                 $msg .= ' ' . sprintf( __( 'This resulted in an error message: %s' ), '<code>' . $errstr . '</code>' );
    1241             }
    1242             $msg .= '</p>';
    1243 
    1244             $msg .= '<p>' . sprintf(
    1245                 /* translators: %s: asterisk symbol (*) */
    1246                 __( 'To use a subdomain configuration, you must have a wildcard entry in your DNS. This usually means adding a %s hostname record pointing at your web server in your DNS configuration tool.' ),
    1247                 '<code>*</code>'
    1248             ) . '</p>';
    1249 
    1250             $msg .= '<p>' . __( 'You can still use your site but any subdomain you create may not be accessible. If you know your DNS is correct, ignore this message.' ) . '</p>';
    1251 
    1252             return new WP_Error( 'no_wildcard_dns', $msg );
    1253         }
    1254     }
    1255 
    1256     return true;
     1293    $wpdb->query( "INSERT INTO $wpdb->sitemeta ( site_id, meta_key, meta_value ) VALUES " . $insert ); // phpcs:ignore WordPress.WP.PreparedSQL.NotPrepared
    12571294}
  • trunk/tests/phpunit/tests/admin/includesSchema.php

    r43627 r43628  
    11<?php
     2// phpcs:ignoreFile WordPress.WP.PreparedSQL.NotPrepared
    23
    34/**
     
    78
    89    private static $options;
     10    private static $sitemeta;
    911
    1012    /**
     
    1517
    1618        self::$options  = 'testprefix_options';
    17 
    18         $options = self::$options;
     19        self::$sitemeta = 'testprefix_sitemeta';
     20
     21        $options  = self::$options;
     22        $sitemeta = self::$sitemeta;
    1923
    2024        require_once( ABSPATH . 'wp-admin/includes/schema.php' );
     
    3539            "
    3640        );
     41        $wpdb->query(
     42            "
     43            CREATE TABLE {$sitemeta} (
     44                meta_id bigint(20) unsigned NOT NULL auto_increment,
     45                site_id bigint(20) unsigned NOT NULL default '0',
     46                meta_key varchar(255) default NULL,
     47                meta_value longtext,
     48                PRIMARY KEY  (meta_id),
     49                KEY meta_key (meta_key({$max_index_length})),
     50                KEY site_id (site_id)
     51            ) {$charset_collate}
     52            "
     53        );
    3754    }
    3855
     
    4360        global $wpdb;
    4461
    45         $options = self::$options;
     62        $options  = self::$options;
     63        $sitemeta = self::$sitemeta;
    4664
    4765        $wpdb->query( "DROP TABLE IF EXISTS {$options}" );
     66        $wpdb->query( "DROP TABLE IF EXISTS {$sitemeta}" );
    4867    }
    4968
     
    5473    function test_populate_options( $options, $expected ) {
    5574        global $wpdb;
    56 
    57         remove_all_filters( 'option_admin_email' );
    58         remove_all_filters( 'pre_option_admin_email' );
    59         remove_all_filters( 'default_option_admin_email' );
    6075
    6176        $orig_options  = $wpdb->options;
     
    93108            array(
    94109                array(
    95                     'posts_per_rss'    => 7,
    96                     'rss_use_excerpt'  => 1,
     110                    'posts_per_rss'   => 7,
     111                    'rss_use_excerpt' => 1,
    97112                ),
    98113                array(
     
    130145            array(
    131146                array(
    132                     'rss_0123456789abcdef0123456789abcdef'    => '1',
     147                    'rss_0123456789abcdef0123456789abcdef' => '1',
    133148                    'rss_0123456789abcdef0123456789abcdef_ts' => '1',
    134149                ),
    135150                array(
    136151                    // These options would be obsolete magpie cache data and should never exist.
    137                     'rss_0123456789abcdef0123456789abcdef'    => false,
     152                    'rss_0123456789abcdef0123456789abcdef' => false,
    138153                    'rss_0123456789abcdef0123456789abcdef_ts' => false,
    139154                ),
     
    141156        );
    142157    }
     158
     159    /**
     160     * @ticket 44895
     161     * @dataProvider data_populate_network_meta
     162     */
     163    function test_populate_network_meta( $meta, $expected ) {
     164        global $wpdb;
     165
     166        $orig_sitemeta  = $wpdb->sitemeta;
     167        $wpdb->sitemeta = self::$sitemeta;
     168
     169        populate_network_meta( 42, $meta );
     170
     171        $results = array();
     172        foreach ( $expected as $meta_key => $value ) {
     173            if ( is_multisite() ) {
     174                $results[ $meta_key ] = get_network_option( 42, $meta_key );
     175            } else {
     176                $results[ $meta_key ] = $wpdb->get_var( $wpdb->prepare( "SELECT meta_value FROM {$wpdb->sitemeta} WHERE meta_key = %s AND site_id = %d", $meta_key, 42 ) );
     177            }
     178        }
     179
     180        $wpdb->query( "TRUNCATE TABLE {$wpdb->sitemeta}" );
     181
     182        $wpdb->sitemeta = $orig_sitemeta;
     183
     184        $this->assertEquals( $expected, $results );
     185    }
     186
     187    public function data_populate_network_meta() {
     188        return array(
     189            array(
     190                array(),
     191                array(
     192                    // Random meta to check.
     193                    'registration'      => 'none',
     194                    'blog_upload_space' => 100,
     195                    'fileupload_maxk'   => 1500,
     196                ),
     197            ),
     198            array(
     199                array(
     200                    'site_name' => 'My Great Network',
     201                    'WPLANG'    => 'fr_FR',
     202                ),
     203                array(
     204                    // Random meta to check.
     205                    'site_name'         => 'My Great Network',
     206                    'registration'      => 'none',
     207                    'blog_upload_space' => 100,
     208                    'fileupload_maxk'   => 1500,
     209                    'WPLANG'            => 'fr_FR',
     210                ),
     211            ),
     212            array(
     213                array(
     214                    'custom_meta' => '1',
     215                ),
     216                array(
     217                    // Random meta to check.
     218                    'custom_meta'       => '1',
     219                    'registration'      => 'none',
     220                    'blog_upload_space' => 100,
     221                    'fileupload_maxk'   => 1500,
     222                ),
     223            ),
     224        );
     225    }
    143226}
Note: See TracChangeset for help on using the changeset viewer.