/** * Get/set sys version. * * @since 160531 Sys options. * * @param string $key Sys option key. * @param mixed|null $value If setting value. * @param bool $autoload Autoload option key? * * @return mixed|null Sys option value or `null`. */ public function __invoke(string $key, $value = null, bool $autoload = true) { $key = $this->App->Config->©brand['©var'] . '_' . $key; if ($this->App->Config->§specs['§is_network_wide'] && $this->Wp->is_multisite) { if (isset($value)) { update_network_option(null, $key, $value); } if (($value = get_network_option(null, $key)) === null || $value === false) { add_network_option(null, $key, ':null'); // Autoload impossible. // These will not autoload and there is no way to change this. } } else { // Default. if (isset($value)) { update_option($key, $value); } if (($value = get_option($key)) === null || $value === false) { add_option($key, ':null', '', $autoload ? 'yes' : 'no'); } } return $value === null || $value === false || $value === ':null' ? null : $value; }
/** * Set/update the value of a site transient. * * You do not need to serialize values, if the value needs to be serialize, then * it will be serialized before it is set. * * @since 2.9.0 * * @see set_transient() * * @param string $transient Transient name. Expected to not be SQL-escaped. Must be * 40 characters or fewer in length. * @param mixed $value Transient value. Expected to not be SQL-escaped. * @param int $expiration Optional. Time until expiration in seconds. Default 0. * @return bool False if value was not set and true if value was set. */ function set_site_transient($transient, $value, $expiration = 0) { /** * Filter the value of a specific site transient before it is set. * * The dynamic portion of the hook name, `$transient`, refers to the transient name. * * @since 3.0.0 * @since 4.4.0 The `$transient` parameter was added * * @param mixed $value Value of site transient. * @param string $transient Transient name. */ $value = apply_filters('pre_set_site_transient_' . $transient, $value, $transient); $expiration = (int) $expiration; if (wp_using_ext_object_cache()) { $result = wp_cache_set($transient, $value, 'site-transient', $expiration); } else { $transient_timeout = '_site_transient_timeout_' . $transient; $option = '_site_transient_' . $transient; if (false === get_network_option($option)) { if ($expiration) { add_network_option($transient_timeout, time() + $expiration); } $result = add_network_option($option, $value); } else { if ($expiration) { update_network_option($transient_timeout, time() + $expiration); } $result = update_network_option($option, $value); } } if ($result) { /** * Fires after the value for a specific site transient has been set. * * The dynamic portion of the hook name, `$transient`, refers to the transient name. * * @since 3.0.0 * @since 4.4.0 The `$transient` parameter was added * * @param mixed $value Site transient value. * @param int $expiration Time until expiration in seconds. Default 0. * @param string $transient Transient name. */ do_action('set_site_transient_' . $transient, $value, $expiration, $transient); /** * Fires after the value for a site transient has been set. * * @since 3.0.0 * * @param string $transient The name of the site transient. * @param mixed $value Site transient value. * @param int $expiration Time until expiration in seconds. Default 0. */ do_action('setted_site_transient', $transient, $value, $expiration); } return $result; }
/** * Update the value of a network option that was already added. * * @since 4.4.0 * * @see update_option() * * @global wpdb $wpdb * * @param int $network_id ID of the network. Can be null to default to the current network ID. * @param string $option Name of option. Expected to not be SQL-escaped. * @param mixed $value Option value. Expected to not be SQL-escaped. * @return bool False if value was not updated and true if value was updated. */ function update_network_option($network_id, $option, $value) { global $wpdb; if ($network_id && !is_numeric($network_id)) { return false; } $network_id = (int) $network_id; // Fallback to the current network if a network ID is not specified. if (!$network_id) { $network_id = get_current_network_id(); } wp_protect_special_option($option); $old_value = get_network_option($network_id, $option, false); /** * Filters a specific network option before its value is updated. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * @since 2.9.0 As 'pre_update_site_option_' . $key * @since 3.0.0 * @since 4.4.0 The `$option` parameter was added. * @since 4.7.0 The `$network_id` parameter was added. * * @param mixed $value New value of the network option. * @param mixed $old_value Old value of the network option. * @param string $option Option name. * @param int $network_id ID of the network. */ $value = apply_filters("pre_update_site_option_{$option}", $value, $old_value, $option, $network_id); if ($value === $old_value) { return false; } if (false === $old_value) { return add_network_option($network_id, $option, $value); } $notoptions_key = "{$network_id}:notoptions"; $notoptions = wp_cache_get($notoptions_key, 'site-options'); if (is_array($notoptions) && isset($notoptions[$option])) { unset($notoptions[$option]); wp_cache_set($notoptions_key, $notoptions, 'site-options'); } if (!is_multisite()) { $result = update_option($option, $value, 'no'); } else { $value = sanitize_option($option, $value); $serialized_value = maybe_serialize($value); $result = $wpdb->update($wpdb->sitemeta, array('meta_value' => $serialized_value), array('site_id' => $network_id, 'meta_key' => $option)); if ($result) { $cache_key = "{$network_id}:{$option}"; wp_cache_set($cache_key, $value, 'site-options'); } } if ($result) { /** * Fires after the value of a specific network option has been successfully updated. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * @since 2.9.0 As "update_site_option_{$key}" * @since 3.0.0 * @since 4.7.0 The `$network_id` parameter was added. * * @param string $option Name of the network option. * @param mixed $value Current value of the network option. * @param mixed $old_value Old value of the network option. * @param int $network_id ID of the network. */ do_action("update_site_option_{$option}", $option, $value, $old_value, $network_id); /** * Fires after the value of a network option has been successfully updated. * * @since 3.0.0 * @since 4.7.0 The `$network_id` parameter was added. * * @param string $option Name of the network option. * @param mixed $value Current value of the network option. * @param mixed $old_value Old value of the network option. * @param int $network_id ID of the network. */ do_action('update_site_option', $option, $value, $old_value, $network_id); return true; } return false; }
/** * @dataProvider data_network_id_parameter * * @param $network_id * @param $expected_response */ function test_add_network_option_network_id_parameter($network_id, $expected_response) { $option = rand_str(); $value = rand_str(); $this->assertEquals($expected_response, add_network_option($network_id, $option, $value)); }
/** * Processes new site registrations. * * Checks the data provided by the user during blog signup. Verifies * the validity and uniqueness of blog paths and domains. * * This function prevents the current user from registering a new site * with a blogname equivalent to another user's login name. Passing the * $user parameter to the function, where $user is the other user, is * effectively an override of this limitation. * * Filter 'wpmu_validate_blog_signup' if you want to modify * the way that WordPress validates new site signups. * * @since MU * * @global wpdb $wpdb * @global string $domain * * @param string $blogname The blog name provided by the user. Must be unique. * @param string $blog_title The blog title provided by the user. * @param WP_User|string $user Optional. The user object to check against the new site name. * @return array Contains the new site data and error messages. */ function wpmu_validate_blog_signup($blogname, $blog_title, $user = '') { global $wpdb, $domain; $current_site = get_current_site(); $base = $current_site->path; $blog_title = strip_tags($blog_title); $errors = new WP_Error(); $illegal_names = get_network_option('illegal_names'); if ($illegal_names == false) { $illegal_names = array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator'); add_network_option('illegal_names', $illegal_names); } /* * On sub dir installs, some names are so illegal, only a filter can * spring them from jail. */ if (!is_subdomain_install()) { $illegal_names = array_merge($illegal_names, apply_filters('subdirectory_reserved_names', array('page', 'comments', 'blog', 'files', 'feed', 'wp-admin', 'wp-content', 'wp-includes', 'wp-json'))); } if (empty($blogname)) { $errors->add('blogname', __('Please enter a site name.')); } if (preg_match('/[^a-z0-9]+/', $blogname)) { $errors->add('blogname', __('Only lowercase letters (a-z) and numbers are allowed.')); } if (in_array($blogname, $illegal_names)) { $errors->add('blogname', __('That name is not allowed.')); } if (strlen($blogname) < 4 && !is_super_admin()) { $errors->add('blogname', __('Site name must be at least 4 characters.')); } if (strpos($blogname, '_') !== false) { $errors->add('blogname', __('Sorry, site names may not contain the character “_”!')); } // do not allow users to create a blog that conflicts with a page on the main blog. if (!is_subdomain_install() && $wpdb->get_var($wpdb->prepare("SELECT post_name FROM " . $wpdb->get_blog_prefix($current_site->blog_id) . "posts WHERE post_type = 'page' AND post_name = %s", $blogname))) { $errors->add('blogname', __('Sorry, you may not use that site name.')); } // all numeric? if (preg_match('/^[0-9]*$/', $blogname)) { $errors->add('blogname', __('Sorry, site names must have letters too!')); } /** * Filter the new site name during registration. * * The name is the site's subdomain or the site's subdirectory * path depending on the network settings. * * @since MU * * @param string $blogname Site name. */ $blogname = apply_filters('newblogname', $blogname); $blog_title = wp_unslash($blog_title); if (empty($blog_title)) { $errors->add('blog_title', __('Please enter a site title.')); } // Check if the domain/path has been used already. if (is_subdomain_install()) { $mydomain = $blogname . '.' . preg_replace('|^www\\.|', '', $domain); $path = $base; } else { $mydomain = "{$domain}"; $path = $base . $blogname . '/'; } if (domain_exists($mydomain, $path, $current_site->id)) { $errors->add('blogname', __('Sorry, that site already exists!')); } if (username_exists($blogname)) { if (!is_object($user) || is_object($user) && $user->user_login != $blogname) { $errors->add('blogname', __('Sorry, that site is reserved!')); } } // Has someone already signed up for this domain? $signup = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->signups} WHERE domain = %s AND path = %s", $mydomain, $path)); // TODO: Check email too? if (!empty($signup)) { $diff = current_time('timestamp', true) - mysql2date('U', $signup->registered); // If registered more than two days ago, cancel registration and let this signup go through. if ($diff > 2 * DAY_IN_SECONDS) { $wpdb->delete($wpdb->signups, array('domain' => $mydomain, 'path' => $path)); } else { $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.')); } } $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors); /** * Filter site details and error messages following registration. * * @since MU * * @param array $result { * Array of domain, path, blog name, blog title, user and error messages. * * @type string $domain Domain for the site. * @type string $path Path for the site. Used in subdirectory installs. * @type string $blogname The unique site name (slug). * @type string $blog_title Blog title. * @type string|WP_User $user By default, an empty string. A user object if provided. * @type WP_Error $errors WP_Error containing any errors found. * } */ return apply_filters('wpmu_validate_blog_signup', $result); }
function add_global_option($option, $value = '', $autoload = 'yes') { global $wpdb; $option = trim($option); if (empty($option)) { return false; } wp_protect_special_option($option); if (is_object($value)) { $value = clone $value; } if (!is_multinetwork()) { $result = add_network_option(null, $option, $value, '', 'no'); if (!$result) { return false; } } else { $value = sanitize_option($option, $value); // Make sure the option doesn't already exist. We can check the 'notoptions' cache before we ask for a db query $notoptions = wp_cache_get('notoptions', 'global-options'); if (!is_array($notoptions) || !isset($notoptions[$option])) { /** This filter is documented in wp-includes/option.php */ if (apply_filters('default_global_option_' . $option, false, $option) !== get_global_option($option)) { return false; } } $serialized_value = maybe_serialize($value); $autoload = 'no' === $autoload || false === $autoload ? 'no' : 'yes'; /** * Fires before a global option is added. * * @since 1.0.0 * * @param string $option Name of the option to add. * @param mixed $value Value of the option. */ do_action('add_global_option', $option, $value); $result = $wpdb->query($wpdb->prepare("INSERT INTO `{$wpdb->global_options}` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)", $option, $serialized_value, $autoload)); if (!$result) { return false; } if (!wp_installing()) { if ('yes' == $autoload) { $alloptions = wp_load_global_alloptions(); $alloptions[$option] = $serialized_value; wp_cache_set('alloptions', $alloptions, 'global-options'); } else { wp_cache_set($option, $serialized_value, 'global-options'); } } // This option exists now $notoptions = wp_cache_get('notoptions', 'global-options'); // yes, again... we need it to be fresh if (is_array($notoptions) && isset($notoptions[$option])) { unset($notoptions[$option]); wp_cache_set('notoptions', $notoptions, 'global-options'); } } /** * Fires after a specific global option has been added. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * @since 1.0.0 * * @param string $option Name of the option to add. * @param mixed $value Value of the option. */ do_action("add_global_option_{$option}", $option, $value); /** * Fires after a global option has been added. * * @since 1.0.0 * * @param string $option Name of the added option. * @param mixed $value Value of the option. */ do_action('added_global_option', $option, $value); return true; }
/** * Update the value of a network option that was already added. * * @since 4.4.0 * * @see update_option() * * @global wpdb $wpdb * @global object $current_site * * @param int $network_id ID of the network. Can be null to default to the current network ID. * @param string $option Name of option. Expected to not be SQL-escaped. * @param mixed $value Option value. Expected to not be SQL-escaped. * @return bool False if value was not updated and true if value was updated. */ function update_network_option($network_id, $option, $value) { global $wpdb, $current_site; if ($network_id && !is_numeric($network_id)) { return false; } $network_id = (int) $network_id; wp_protect_special_option($option); $old_value = get_network_option($network_id, $option, false); /** * Filter a specific network option before its value is updated. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * @since 2.9.0 As 'pre_update_site_option_' . $key * @since 3.0.0 * @since 4.4.0 The `$option` parameter was added * * @param mixed $value New value of the network option. * @param mixed $old_value Old value of the network option. * @param string $option Option name. */ $value = apply_filters('pre_update_site_option_' . $option, $value, $old_value, $option); if ($value === $old_value) { return false; } if (false === $old_value) { return add_network_option($network_id, $option, $value); } $notoptions_key = "{$network_id}:notoptions"; $notoptions = wp_cache_get($notoptions_key, 'site-options'); if (is_array($notoptions) && isset($notoptions[$option])) { unset($notoptions[$option]); wp_cache_set($notoptions_key, $notoptions, 'site-options'); } $result = update_option($option, $value); if ($result) { /** * Fires after the value of a specific network option has been successfully updated. * * The dynamic portion of the hook name, `$option`, refers to the option name. * * @since 2.9.0 As "update_site_option_{$key}" * @since 3.0.0 * * @param string $option Name of the network option. * @param mixed $value Current value of the network option. * @param mixed $old_value Old value of the network option. */ do_action('update_site_option_' . $option, $option, $value, $old_value); /** * Fires after the value of a network option has been successfully updated. * * @since 3.0.0 * * @param string $option Name of the network option. * @param mixed $value Current value of the network option. * @param mixed $old_value Old value of the network option. */ do_action('update_site_option', $option, $value, $old_value); return true; } return false; }
/** * Execute changes made in WordPress 3.0. * * @since 3.0.0 * * @global int $wp_current_db_version * @global wpdb $wpdb */ function upgrade_300() { global $wp_current_db_version, $wpdb; if ($wp_current_db_version < 15093) { populate_roles_300(); } if ($wp_current_db_version < 14139 && is_multisite() && is_main_site() && !defined('MULTISITE') && get_network_option('siteurl') === false) { add_network_option('siteurl', ''); } // 3.0 screen options key name changes. if (wp_should_upgrade_global_tables()) { $sql = "DELETE FROM {$wpdb->usermeta}\n\t\t\tWHERE meta_key LIKE %s\n\t\t\tOR meta_key LIKE %s\n\t\t\tOR meta_key LIKE %s\n\t\t\tOR meta_key LIKE %s\n\t\t\tOR meta_key LIKE %s\n\t\t\tOR meta_key LIKE %s\n\t\t\tOR meta_key = 'manageedittagscolumnshidden'\n\t\t\tOR meta_key = 'managecategoriescolumnshidden'\n\t\t\tOR meta_key = 'manageedit-tagscolumnshidden'\n\t\t\tOR meta_key = 'manageeditcolumnshidden'\n\t\t\tOR meta_key = 'categories_per_page'\n\t\t\tOR meta_key = 'edit_tags_per_page'"; $prefix = $wpdb->esc_like($wpdb->base_prefix); $wpdb->query($wpdb->prepare($sql, $prefix . '%' . $wpdb->esc_like('meta-box-hidden') . '%', $prefix . '%' . $wpdb->esc_like('closedpostboxes') . '%', $prefix . '%' . $wpdb->esc_like('manage-') . '%' . $wpdb->esc_like('-columns-hidden') . '%', $prefix . '%' . $wpdb->esc_like('meta-box-order') . '%', $prefix . '%' . $wpdb->esc_like('metaboxorder') . '%', $prefix . '%' . $wpdb->esc_like('screen_layout') . '%')); } }