301 lines
7.8 KiB
PHP
301 lines
7.8 KiB
PHP
<?php
|
|
/**
|
|
* Configuration mode and settings helper.
|
|
*
|
|
* On Multisite the plugin can run in two modes, controlled from the
|
|
* Network Admin by a super administrator:
|
|
*
|
|
* - "per-site" (default): every site keeps its own settings and its own
|
|
* log table, managed by each site administrator.
|
|
* - "global": one shared configuration and one central log table (on the
|
|
* main site) collect the outbound requests of the whole network.
|
|
*
|
|
* @package RobotstxtTelemetry
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
if ( ! class_exists( 'Robotstxt_Telemetry_Network' ) ) {
|
|
/**
|
|
* Class Robotstxt_Telemetry_Network
|
|
*/
|
|
class Robotstxt_Telemetry_Network {
|
|
|
|
/**
|
|
* Option name storing the configuration mode.
|
|
*
|
|
* @var string
|
|
*/
|
|
const MODE_OPTION = 'robotstxt_telemetry_config_mode';
|
|
|
|
/**
|
|
* Plugin settings and their defaults.
|
|
*
|
|
* @var array
|
|
*/
|
|
const SETTINGS = array(
|
|
'robotstxt_telemetry_useragent_url' => 'hash',
|
|
'robotstxt_telemetry_wp_version' => 'actual',
|
|
'robotstxt_telemetry_mask_locale' => false,
|
|
'robotstxt_telemetry_replace_news_feed' => true,
|
|
'robotstxt_telemetry_replace_events_api' => true,
|
|
'robotstxt_telemetry_disable_browse_happy' => true,
|
|
'robotstxt_telemetry_wp_core_check' => 'safe',
|
|
'robotstxt_telemetry_wp_themes_check' => 'safe',
|
|
'robotstxt_telemetry_wp_plugins_check' => 'safe',
|
|
'robotstxt_telemetry_hidden_plugins' => array(),
|
|
'robotstxt_telemetry_plugin_modes' => array(),
|
|
'robotstxt_telemetry_retention_period' => '12hours',
|
|
'robotstxt_telemetry_delete_on_uninstall' => false,
|
|
);
|
|
|
|
/**
|
|
* Whether the network runs in global mode.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public static function is_global() {
|
|
return is_multisite() && 'global' === get_site_option( self::MODE_OPTION, 'per-site' );
|
|
}
|
|
|
|
/**
|
|
* Whether the current request is a Network Admin screen.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public static function is_network_admin() {
|
|
return is_network_admin();
|
|
}
|
|
|
|
/**
|
|
* Capability required to manage the plugin on the current screen.
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function manage_capability() {
|
|
return self::is_network_admin() ? 'manage_network_options' : 'manage_options';
|
|
}
|
|
|
|
/**
|
|
* Base admin URL for the current screen context.
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function base_url() {
|
|
return self::is_network_admin() ? network_admin_url( 'admin.php' ) : admin_url( 'admin.php' );
|
|
}
|
|
|
|
/**
|
|
* Read a plugin setting honoring the configuration mode.
|
|
*
|
|
* @param string $name Option name.
|
|
* @param mixed $default_value Default value.
|
|
* @return mixed
|
|
*/
|
|
public static function get_setting( $name, $default_value = null ) {
|
|
if ( self::is_global() ) {
|
|
return get_site_option( $name, $default_value );
|
|
}
|
|
|
|
return get_option( $name, $default_value );
|
|
}
|
|
|
|
/**
|
|
* Write a plugin setting honoring the configuration mode.
|
|
*
|
|
* @param string $name Option name.
|
|
* @param mixed $value Value.
|
|
* @return bool
|
|
*/
|
|
public static function update_setting( $name, $value ) {
|
|
if ( self::is_global() ) {
|
|
return update_site_option( $name, $value );
|
|
}
|
|
|
|
return update_option( $name, $value );
|
|
}
|
|
|
|
/**
|
|
* Delete a plugin setting honoring the configuration mode.
|
|
*
|
|
* @param string $name Option name.
|
|
* @return bool
|
|
*/
|
|
public static function delete_setting( $name ) {
|
|
if ( self::is_global() ) {
|
|
return delete_site_option( $name );
|
|
}
|
|
|
|
return delete_option( $name );
|
|
}
|
|
|
|
/**
|
|
* The main site ID of the current network.
|
|
*
|
|
* @return int
|
|
*/
|
|
public static function main_site_id() {
|
|
if ( function_exists( 'get_main_site_id' ) ) {
|
|
return (int) get_main_site_id();
|
|
}
|
|
|
|
$current_site = get_current_site();
|
|
|
|
return max( 1, (int) $current_site->blog_id );
|
|
}
|
|
|
|
/**
|
|
* All site IDs of the network.
|
|
*
|
|
* @return int[]
|
|
*/
|
|
public static function get_site_ids() {
|
|
if ( function_exists( 'get_sites' ) ) {
|
|
$sites = get_sites(
|
|
array(
|
|
'fields' => 'ids',
|
|
'number' => 0,
|
|
)
|
|
);
|
|
|
|
return array_map( 'intval', $sites );
|
|
}
|
|
|
|
// WordPress 3.7 - 4.5 fallback.
|
|
$site_ids = array();
|
|
|
|
// phpcs:ignore WordPress.WP.DeprecatedFunctions.wp_get_sitesFound -- Only called when get_sites() is unavailable (WordPress 3.7 - 4.5).
|
|
foreach ( (array) wp_get_sites( array( 'limit' => 100000 ) ) as $site ) {
|
|
if ( ! empty( $site['blog_id'] ) ) {
|
|
$site_ids[] = (int) $site['blog_id'];
|
|
}
|
|
}
|
|
|
|
return $site_ids;
|
|
}
|
|
|
|
/**
|
|
* Sanitize the configuration mode value.
|
|
*
|
|
* @param mixed $value Raw input value.
|
|
* @return string
|
|
*/
|
|
public static function sanitize_mode( $value ) {
|
|
return 'global' === $value ? 'global' : 'per-site';
|
|
}
|
|
|
|
/**
|
|
* The plugin basenames never sent to the WordPress.org update check.
|
|
*
|
|
* The telemetry plugin itself is always included.
|
|
*
|
|
* @return string[]
|
|
*/
|
|
public static function get_hidden_plugins() {
|
|
$hidden = self::get_setting( 'robotstxt_telemetry_hidden_plugins', array() );
|
|
|
|
if ( ! is_array( $hidden ) ) {
|
|
$hidden = array();
|
|
}
|
|
|
|
$hidden[] = 'robotstxt-telemetry/robotstxt-telemetry.php';
|
|
|
|
return array_values( array_unique( $hidden ) );
|
|
}
|
|
|
|
/**
|
|
* Get the per-plugin safe-mode map (slug => safe|original).
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function get_plugin_modes() {
|
|
$modes = self::get_setting( 'robotstxt_telemetry_plugin_modes', array() );
|
|
|
|
return is_array( $modes ) ? $modes : array();
|
|
}
|
|
|
|
/**
|
|
* Get the mode of a single plugin (Safe by default).
|
|
*
|
|
* @param string $slug Plugin slug.
|
|
* @return string
|
|
*/
|
|
public static function get_plugin_mode( $slug ) {
|
|
$modes = self::get_plugin_modes();
|
|
|
|
return isset( $modes[ $slug ] ) && 'original' === $modes[ $slug ] ? 'original' : 'safe';
|
|
}
|
|
|
|
/**
|
|
* The User-Agent URL mode: 'url', 'hash' (default), or 'none'.
|
|
*
|
|
* Falls back to the legacy boolean option when the new option is
|
|
* not set yet, so existing installations keep their behavior.
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function get_useragent_url_mode() {
|
|
$mode = self::get_setting( 'robotstxt_telemetry_useragent_url', '' );
|
|
|
|
if ( in_array( $mode, array( 'url', 'hash', 'none' ), true ) ) {
|
|
return $mode;
|
|
}
|
|
|
|
$legacy = self::get_setting( 'robotstxt_telemetry_hash_useragent_url', true );
|
|
|
|
return (bool) $legacy ? 'hash' : 'url';
|
|
}
|
|
|
|
/**
|
|
* The WordPress version mode: 'actual' (default), 'major', or 'nulled'.
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function get_wp_version_mode() {
|
|
$mode = self::get_setting( 'robotstxt_telemetry_wp_version', 'actual' );
|
|
|
|
return in_array( $mode, array( 'actual', 'major', 'nulled' ), true ) ? $mode : 'actual';
|
|
}
|
|
|
|
/**
|
|
* Mask a WordPress version value according to the mode.
|
|
*
|
|
* 'major' keeps the first two segments and replaces the rest with
|
|
* an "n" (for example "6.9.1" becomes "6.9.n", "7.0" becomes
|
|
* "7.0.n"); 'nulled' always returns "0.0.0".
|
|
*
|
|
* @param string $version Version value.
|
|
* @param string $mode Version mode.
|
|
* @return string
|
|
*/
|
|
public static function mask_wp_version( $version, $mode ) {
|
|
if ( 'nulled' === $mode ) {
|
|
return '0.0.0';
|
|
}
|
|
|
|
if ( 'major' === $mode && preg_match( '/^(\d+\.\d+)/', (string) $version, $matches ) ) {
|
|
return $matches[1] . '.n';
|
|
}
|
|
|
|
return (string) $version;
|
|
}
|
|
|
|
/**
|
|
* Seed the network settings from the main site when switching to
|
|
* global mode, so the network keeps behaving like the main site.
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function seed_network_settings() {
|
|
$main_site_id = self::main_site_id();
|
|
|
|
foreach ( self::SETTINGS as $name => $default ) {
|
|
if ( false === get_site_option( $name, false ) ) {
|
|
update_site_option( $name, get_blog_option( $main_site_id, $name, $default ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|