Wordpress 3.1.2版本 --- network/网络管理员 创建多站点的过程分析
form提交表单 中 :
一个隐藏的input 参数为 _wp_http_referer
站点地址 blog[domain] 赋值为 hongkong
站点标题 blog[title] 赋值为 香港
----------------------------------------------------------------
---------------------------------------------------------------- /wp-admin/network/site-new.php 的程序分析
/** Load WordPress Administration Bootstrap */
require_once( './admin.php' ); // 11行
if ( isset($_REQUEST['action']) && 'add-site' == $_REQUEST['action'] )
{
// 创建新的站点的过程
// 28行 检查refer来源
check_admin_referer( 'add-blog', '_wpnonce_add-blog' );
// 30行 判断当前用户是否有权限 管理站点
if ( ! current_user_can( 'manage_sites' ) )
// 33行 判断用户是否输入站点的信息 地址/标题/邮件email地址
if ( ! is_array( $_POST['blog'] ) )
// 37行 对站点的域名地址 做了过滤 并全部转为了 小写字符
if ( ! preg_match( '/(--)/', $blog['domain'] ) && preg_match( '|^([a-zA-Z0-9-])+$|', $blog['domain'] ) )
$domain = strtolower( $blog['domain'] );
// 40行
// 如果开启了子站点,需要检查 用户自定义的站点域名url地址 不和子站点的地址冲突
// If not a subdomain install, make sure the domain isn't a reserved word
if ( ! is_subdomain_install() ) {}
if ( is_subdomain_install() ) {
$newdomain = $domain . '.' . preg_replace( '|^www\.|', '', $current_site->domain ); // 类是启用 三级子域名的功能
$path = $base; // $base='/'
} else {
$newdomain = $current_site->domain; // 当前域名
$path = $base . $domain . '/';
}
// 66行 对用户注册时提交的email 做检验
// 若电子邮件地址在数据库中不存在,新用户将被创建。
$user_id = email_exists($email);
if ( !$user_id ) { // Create a new user with a random password 创建一个新用户-- 增加用户
$password = wp_generate_password( 12, false ); // 随机密码
$user_id =
wpmu_create_user( $domain, $password, $email );
// 创建新的用户 $domain=
hongkong $email=longchen@eic.org.cn // 得到用户ID $user_id 用$domain 作为了新用户的登录用户名
if ( false == $user_id )
wp_die( __( 'There was an error creating the user.' ) );
else
wp_new_user_notification( $user_id, $password );
}
$wpdb->hide_errors();
// 77行处 wpmu_create_blog() 创建新de站点
//$newdomain=test.com
// $path=/hongkong/
// $title=香港
// $user_id为 上边66行处 新增加的用户id
// $current_site->id= 为数据库表中 前缀_site id | domain | path ==》 id= | 1 | domain=
test.com path= | / | )
$id = wpmu_create_blog( $newdomain, $path, $title, $user_id , array( 'public' => 1 ), $current_site->id );
// 错误信息处理
$wpdb->show_errors();
if ( !is_wp_error( $id ) ) {
if ( !is_super_admin( $user_id ) && !get_user_option( 'primary_blog', $user_id ) )
update_user_option( $user_id, 'primary_blog', $id, true );
$content_mail = sprintf( __( "New site created by %1s\n\nAddress: http://%2s\nName: %3s"), $current_user- >user_login , $newdomain . $path, stripslashes ( $title ) );
wp_mail( get_site_option('admin_email'), sprintf( __( '[%s] New Site Created' ), $current_site- >site_name ), $content_mail, 'From: "Site Admin" <' . get_site_option( 'admin_email' ) . '>' );
wpmu_welcome_notification( $id, $user_id, $password, $title, array( 'public' => 1 ) );
wp_redirect( add_query_arg( array('update' => 'added'), 'site-new.php' ) );
exit;
} else {
wp_die( $id->get_error_message() );
}
}
if ( isset($_GET['update']) )
{
// site-new.php?update=added 时 设置了 提示信息的数组
$messages[] = __('Site added.');
}
require('../admin-header.php'); // 110行
// 中间是 form表单
require('../admin-footer.php'); // 144行
----------------------------------------------------------------
---------------------------------------------------------------- -------- wpmu_create_user()函数的定义 -------- wp-includes/ms-functions.php文件中 1002行处
/**
* Create a user.
*
* This function runs when a user self-registers as well as when
* a Super Admin creates a new user. Hook to 'wpmu_new_user' for events
* that should affect all new users, but only on Multisite (otherwise
* use 'user_register').
*
* @since MU
* @uses wp_create_user()
*
* @param string $user_name The new user's login name.
* @param string $password The new user's password.
* @param string $email The new user's email address.
* @return mixed Returns false on failure, or int $user_id on success
*/
function wpmu_create_user( $user_name, $password, $email)
{
$user_name = preg_replace( '/\s+/', '', sanitize_user( $user_name, true ) );
$user_id = wp_create_user( $user_name, $password, $email ); // 创建新用户 并返回用户id
if ( is_wp_error($user_id) )
return false;
// Newly created users have no roles or caps until they are added to a blog.
// 新创建的用户 没有任何角色和权限 需要把用户增加到一个博客管理用户中去
delete_user_option( $user_id, 'capabilities' );
delete_user_option( $user_id, 'user_level' );
do_action( 'wpmu_new_user', $user_id );
return $user_id;
}
----------------------------------------------------------------
---------------------------------------------------------------- -------- wp_create_user()函数的定义 -------- wp-includes/user.php文件中 1592行处
function wp_create_user($username, $password, $email = '')
{
$user_login = esc_sql( $username );
$user_email = esc_sql( $email );
$user_pass = $password;
$userdata = compact('user_login', 'user_email', 'user_pass');
return wp_insert_user($userdata); // 想数据库中写入用户信息
}
----------------------------------------------------------------
---------------------------------------------------------------- -------- wp_insert_user()函数的定义
-------- wp-includes/user.php文件中 1382行处
function wp_insert_user($userdata)
{
global $wpdb;
extract($userdata, EXTR_SKIP);
// 新创建用户 OR 更新用户
if ( $update ) {
$wpdb->update( $wpdb->users, $data, compact( 'ID' ) ); // $wpdb->users 指定了 用户表 (wordpress指定的数据库表的前缀_users表)
$user_id = (int) $ID;
} else {
$wpdb->insert( $wpdb->users, $data + compact( 'user_login' ) );
$user_id = (int) $wpdb->insert_id;
}
// 更新 数据库表 (wordpress指定的数据库表的前缀_usermeta表)
update_user_meta( $user_id, 'first_name', $first_name );
update_user_meta( $user_id, 'last_name', $last_name );
update_user_meta( $user_id, 'nickname', $nickname );
update_user_meta( $user_id, 'description', $description );
update_user_meta( $user_id, 'rich_editing', $rich_editing );
update_user_meta( $user_id, 'comment_shortcuts', $comment_shortcuts );
update_user_meta( $user_id, 'admin_color', $admin_color );
update_user_meta( $user_id, 'use_ssl', $use_ssl );
update_user_meta( $user_id, 'show_admin_bar_front', $show_admin_bar_front );
update_user_meta( $user_id, 'show_admin_bar_admin', $show_admin_bar_admin );
$user = new WP_User($user_id); // 根据用户ID $user_id 实例化了一个 用户对象实例 $user
// 设置用户权限的操作
if ( isset($role) )
$user->set_role($role);
elseif ( !$update )
$user->set_role(get_option('default_role'));
// 删除了 用户的缓存
wp_cache_delete($user_id, 'users');
wp_cache_delete($user_login, 'userlogins');
}
----------------------------------------------------------------
---------------------------------------------------------------- -------- set_role()函数的定义 -------- wp-includes/capabilities.php文件中 605行处
function set_role( $role )
{
foreach ( (array) $this->roles as $oldrole )
unset( $this->caps[$oldrole] );
if ( 1 == count( $this->roles ) && $role == $this->roles[0] )
return;
if ( !empty( $role ) ) {
$this->caps[$role] = true;
$this->roles = array( $role => true );
} else {
$this->roles = false;
}
update_user_meta( $this->ID, $this->cap_key, $this->caps );
$this->get_role_caps();
$this->update_user_level_from_caps();
do_action( 'set_user_role', $this->ID, $role );
}
----------------------------------------------------------------
---------------------------------------------------------------- -------- wpmu_create_blog()函数的定义 -------- wp-includes/ms-functions.php文件中 1044行处
/**
* Create a site.
*
* This function runs when a user self-registers a new site as well
* as when a Super Admin creates a new site. Hook to 'wpmu_new_blog'
* for events that should affect all new sites.
*
* On subdirectory installs, $domain is the same as the main site's
* domain, and the path is the subdirectory name (eg 'example.com'
* and '/blog1/'). On subdomain installs, $domain is the new subdomain +
* root domain (eg 'blog1.example.com'), and $path is '/'.
*
* @since MU
* @uses domain_exists()
* @uses insert_blog()
* @uses wp_install_defaults()
* @uses add_user_to_blog()
*
* @param string $domain The new site's domain.
* @param string $path The new site's path.
* @param string $title The new site's title.
* @param int $user_id The user ID of the new site's admin.
* @param array $meta Optional. Used to set initial site options.
* @param int $site_id Optional. Only relevant on multi-network installs.
* @return mixed Returns WP_Error object on failure, int $blog_id on success
*/
/*
假设数据
//$newdomain=test.com
// $path=/hongkong/
// $title=香港
// $user_id为 上边66行处 新增加的用户id
// $current_site->id= 为数据库表中 前缀_site id | domain | path ==》 id= | 1 | domain=
test.com path= | / | )
*/
function wpmu_create_blog($domain, $path, $title, $user_id, $meta = '', $site_id = 1)
{
$domain = preg_replace( '/\s+/', '', sanitize_user( $domain, true ) );
// 检查子域名 是否开启
if ( is_subdomain_install() )
$domain = str_replace( '@', '', $domain );
$title = strip_tags( $title );
$user_id = (int) $user_id;
if ( empty($path) )
$path = '/';
// 检查新的站点的url 是否已经存在
// Check if the domain has been used already. We should return an error message.
if ( domain_exists($domain, $path, $site_id) )
return new WP_Error('blog_taken', __('Site already exists.'));
if ( !defined('WP_INSTALLING') )
define( 'WP_INSTALLING', true );
// 新创建一个blog insert_blog()函数
if ( ! $blog_id = insert_blog($domain, $path, $site_id) )
return new WP_Error('insert_blog', __('Could not create site.'));
// 切换什么信息呢? 设置了wpdb中对 表的处理 :表前缀_blogid_表名
switch_to_blog($blog_id);
// 安装blog
install_blog($blog_id, $title);
// 写入默认的一些信息: 默认博文/默认评论/默认页面/默认友情链接等
wp_install_defaults($user_id);
// 把用户 增加到 这个博客的管理员组中 用户有了管理此博客的权限
add_user_to_blog($blog_id, $user_id, 'administrator');
if ( is_array($meta) ) foreach ($meta as $key => $value) {
if ( $key == 'public' || $key == 'archived' || $key == 'mature' || $key == 'spam' || $key == 'deleted' || $key == 'lang_id' )
update_blog_status( $blog_id, $key, $value ); // 更新博客状态
else
update_option( $key, $value ); // 更新option表中的设置信息
}
add_option( 'WPLANG', get_site_option( 'WPLANG' ) );
update_option( 'blog_public', (int)$meta['public'] ); // 向option表中 增加blog_public
if ( !is_super_admin() && ! get_user_meta( $user_id, 'primary_blog', true ) )
update_user_meta( $user_id, 'primary_blog', $blog_id ); // 更新 user_meta信息,绑定用户id和博客id
restore_current_blog(); // 此函数未分析
do_action( 'wpmu_new_blog', $blog_id, $user_id, $domain, $path, $site_id, $meta );
return $blog_id;
}
----------------------------------------------------------------
---------------------------------------------------------------- -------- insert_blog()函数的定义 -------- wp-includes/ms-functions.php文件中 1192行处
function insert_blog($domain, $path, $site_id) {
global $wpdb;
// 1198行处 $wpdb->blogs 为 wordpress指定的数据库表的前缀_blogs表
$result = $wpdb->insert( $wpdb->blogs, array('site_id' => $site_id, 'domain' => $domain, 'path' => $path, 'registered' => current_time('mysql')) );
}
----------------------------------------------------------------
---------------------------------------------------------------- -------- switch_to_blog()函数的定义 -------- wp-includes/ms-blogs.php文件中 454行处
/**
* Switch the current blog.
*
* This function is useful if you need to pull posts, or other information,
* from other blogs. You can switch back afterwards using restore_current_blog().
*
* Things that aren't switched:
* - autoloaded options. See #14992
* - plugins. See #14941
*
* @see restore_current_blog()
* @since MU
*
* @param int $new_blog The id of the blog you want to switch to. Default: current blog
* @param bool $validate Whether to check if $new_blog exists before proceeding
* @return bool True on success, False if the validation failed
*/
function switch_to_blog( $new_blog, $validate = false ) {
global $wpdb, $table_prefix, $blog_id, $switched, $switched_stack, $wp_roles, $wp_object_cache;
// 477行
$wpdb->set_blog_id($new_blog); // 函数定义在 wp-includes/wp-db.php文件中 617行处 function set_blog_id( $blog_id, $site_id = 0 ) { }
$table_prefix = $wpdb->prefix; // 数据库表前缀
$prev_blog_id = $blog_id; // 前一个的博客id为 $blog_id
$blog_id = $new_blog; // 当前的blog_id为 要switch to的博客ID
}
----------------------------------------------------------------
---------------------------------------------------------------- -------- set_blog_id()函数的定义 -------- wp-includes/wp-db.php文件中 617行处
function set_blog_id( $blog_id, $site_id = 0 ) {
if ( ! empty( $site_id ) )
$this->siteid = $site_id;
$old_blog_id = $this->blogid; // 当前对象中 保存的 blogid 另存为 old_blog_id
$this->blogid = $blog_id;
$this->prefix = $this->get_blog_prefix(); // 要合并到一个数据库表中 需要修改这个函数部分
foreach ( $this->tables( 'blog' ) as $table => $prefixed_table )
$this->$table = $prefixed_table;
foreach ( $this->tables( 'old' ) as $table => $prefixed_table )
$this->$table = $prefixed_table;
return $old_blog_id;
}
----------------------------------------------------------------
---------------------------------------------------------------- -------- get_blog_prefix()函数的定义 -------- wp-includes/wp-db.php文件中 635行处
/**
* Gets blog prefix.
*
* @uses is_multisite()
* @since 3.0.0
* @param int $blog_id Optional.
* @return string Blog prefix.
*/
function get_blog_prefix( $blog_id = null ) {
if ( is_multisite() ) {
if ( null === $blog_id )
$blog_id = $this->blogid;
if ( defined( 'MULTISITE' ) && ( 0 == $blog_id || 1 == $blog_id ) )
return $this->base_prefix; // 返回总站点的 操作的数据库表
else
return $this->base_prefix . $blog_id . '_';
// 返回 分站点 要操作的 数据库表 "wordpress数据库的前缀_$blog_id_"
// 例如: 数据库的前缀为“eclg_”, $blog_id=5 的 "eclg_5_posts"的 "wp_5_"
// wordpress每创建一个站点,就会创建9张数据库表 (表名称中 使用 wordpress数据库的前缀_博客ID_tablename )
/*
eclg_5_commentmeta
eclg_5_comments
eclg_5_links
eclg_5_options
eclg_5_postmeta
eclg_5_posts
eclg_5_terms
eclg_5_term_relationships
eclg_5_term_taxonomy
*/
}
else
{
return $this->base_prefix;
}
}
----------------------------------------------------------------
---------------------------------------------------------------- -------- tables()函数的定义 -------- wp-includes/wp-db.php文件中 684行处
/**
* Returns an array of WordPress tables.
*
* Also allows for the CUSTOM_USER_TABLE and CUSTOM_USER_META_TABLE to
* override the WordPress users and usersmeta tables that would otherwise
* be determined by the prefix.
*
* The scope argument can take one of the following:
*
* 'all' - returns 'all' and 'global' tables. No old tables are returned.
* 'blog' - returns the blog-level tables for the queried blog.
* 'global' - returns the global tables for the installation, returning multisite tables only if running multisite.
* 'ms_global' - returns the multisite global tables, regardless if current installation is multisite.
* 'old' - returns tables which are deprecated.
*
* @since 3.0.0
* @uses wpdb::$tables
* @uses wpdb::$old_tables
* @uses wpdb::$global_tables
* @uses wpdb::$ms_global_tables
* @uses is_multisite()
*
* @param string $scope Optional. Can be all, global, ms_global, blog, or old tables. Defaults to all.
* @param bool $prefix Optional. Whether to include table prefixes. Default true. If blog
* prefix is requested, then the custom users and usermeta tables will be mapped.
* @param int $blog_id Optional. The blog_id to prefix. Defaults to wpdb::$blogid. Used only when prefix is requested.
* @return array Table names. When a prefix is requested, the key is the unprefixed table name.
*/
/*
var $tables = array( 'posts', 'comments', 'links', 'options', 'postmeta',
'terms', 'term_taxonomy', 'term_relationships', 'commentmeta' ); // 新站点时要创建的9个表 的表名主要部分
var $old_tables = array( 'categories', 'post2cat', 'link2cat' ); // 兼容老版本的 博文分类/链接分类表
var $global_tables = array( 'users', 'usermeta' ); // 全局 用户表
var $ms_global_tables = array( 'blogs', 'signups', 'site', 'sitemeta',
'sitecategories', 'registration_log', 'blog_versions' ); // 全局表
*/
function tables( $scope = 'all', $prefix = true, $blog_id = 0 )
{
// 返回数据库中的表名的列表
switch ( $scope ) {
case 'all' :
$tables = array_merge( $this->global_tables, $this->tables );
if ( is_multisite() )
$tables = array_merge( $tables, $this->ms_global_tables );
break;
case 'blog' :
$tables = $this->tables;
break;
case 'global' :
$tables = $this->global_tables;
if ( is_multisite() )
$tables = array_merge( $tables, $this->ms_global_tables );
break;
case 'ms_global' :
$tables = $this->ms_global_tables;
break;
case 'old' :
$tables = $this->old_tables;
break;
default :
return array();
break;
}
if ( $prefix ) { // 如果有 数据库表前缀的设置
if ( ! $blog_id )
$blog_id = $this->blogid;
$blog_prefix = $this->get_blog_prefix( $blog_id ); // 返回 wordpress设置中的数据库表前缀_blogid_$tablename
$base_prefix = $this->base_prefix; // 返回 wordpress设置中的数据库表前缀_
$global_tables = array_merge( $this->global_tables, $this->ms_global_tables );
foreach ( $tables as $k => $table )
{
if ( in_array( $table, $global_tables ) ) // 如果是 global 全局表
$tables[ $table ] = $base_prefix . $table; // 表为 wordpress设置中的数据库表前缀_$tablename
else
$tables[ $table ] = $blog_prefix . $table; // 表为 wordpress设置中的数据库表前缀_$blogid_$tablename
unset( $tables[ $k ] );
}
if ( isset( $tables['users'] ) && defined( 'CUSTOM_USER_TABLE' ) )
$tables['users'] = CUSTOM_USER_TABLE;
if ( isset( $tables['usermeta'] ) && defined( 'CUSTOM_USER_META_TABLE' ) )
$tables['usermeta'] = CUSTOM_USER_META_TABLE;
}
return $tables;
}
----------------------------------------------------------------
---------------------------------------------------------------- -------- install_blog()函数的定义 -------- wp-includes/ms-functions.php文件中 1220行处
/**
* Install an empty blog.
*
* Creates the new blog tables and options. If calling this function 创建表和站点设置信息
* directly, be sure to use switch_to_blog() first, so that $wpdb
* points to the new blog.
*
* @since MU
* @uses make_db_current_silent()
* @uses populate_roles()
*
* @param int $blog_id The value returned by insert_blog().
* @param string $blog_title The title of the new site.
*/
function install_blog($blog_id, $blog_title = '') {
global $wpdb, $table_prefix, $wp_roles;
}
----------------------------------------------------------------
---------------------------------------------------------------- -------- wp_install_defaults()函数的定义 -------- wp-admin/includes/upgrade.php文件中 105行处
function wp_install_defaults($user_id)
{
global $wpdb, $wp_rewrite, $current_site, $table_prefix;
// 116行处 博文分类
$wpdb->insert( $wpdb->sitecategories, array('cat_ID' => 0, 'cat_name' => $cat_name, 'category_nicename' => $cat_slug, 'last_updated' => current_time('mysql', true)) );
$cat_id = $wpdb->insert_id;
// 124行处 博文分类 分类对应的数据库表
$wpdb->insert( $wpdb->terms, array('term_id' => $cat_id, 'name' => $cat_name, 'slug' => $cat_slug, 'term_group' => 0) );
$wpdb->insert( $wpdb->term_taxonomy, array('term_id' => $cat_id, 'taxonomy' => 'category', 'description' => '', 'parent' => 0, 'count' => 1));
// Now drop in some default links
// 185行 友情链接 分类对应的数据库表
foreach ( $default_links as $link ) {
$wpdb->insert( $wpdb->links, $link);
$wpdb->insert( $wpdb->term_relationships, array('term_taxonomy_id' => $blogroll_tt_id, 'object_id' => $wpdb->insert_id) );
}
// First post
// 207行 第一篇博文
$wpdb->insert( $wpdb->posts, array(
$wpdb->insert( $wpdb->term_relationships, array('term_taxonomy_id' => $cat_tt_id, 'object_id' => 1) );
// Default comment
// 235行 第一个博文呢评论
$wpdb->insert( $wpdb->comments, array(
if ( is_multisite() )
// 255行 第一个 页面
$first_page = get_site_option( 'first_page', $first_page );
$first_post_guid = get_option('home') . '/?page_id=2';
$wpdb->insert( $wpdb->posts, array(
// 275行
$wpdb->insert( $wpdb->postmeta, array( 'post_id' => 2, 'meta_key' => '_wp_page_template', 'meta_value' => 'default' ) );
// Set up default widgets for default theme.
}
----------------------------------------------------------------
---------------------------------------------------------------- -------- add_user_to_blog()函数的定义 -------- wp-includes/ms-functions.php文件中 207行处
function add_user_to_blog( $blog_id, $user_id, $role )
{
switch_to_blog($blog_id);
$user = new WP_User($user_id);
if ( !get_user_meta($user_id, 'primary_blog', true) ) {
update_user_meta($user_id, 'primary_blog', $blog_id);
$details = get_blog_details($blog_id);
update_user_meta($user_id, 'source_domain', $details->domain);
}
}
评论