class-adbc-common-model.php
7 months ago
class-adbc-cron-jobs.php
2 months ago
class-adbc-database.php
5 months ago
class-adbc-options.php
4 months ago
class-adbc-post-types.php
3 months ago
class-adbc-posts-meta.php
4 months ago
class-adbc-sites.php
7 months ago
class-adbc-tables.php
3 months ago
class-adbc-transients.php
4 months ago
class-adbc-users-meta.php
4 months ago
class-adbc-database.php
141 lines
| 1 | <?php |
| 2 | |
| 3 | // Exit if accessed directly |
| 4 | if ( ! defined( 'ABSPATH' ) ) |
| 5 | exit; |
| 6 | |
| 7 | /** |
| 8 | * ADBC common database class. |
| 9 | * |
| 10 | * This class provides common database functions. |
| 11 | */ |
| 12 | class ADBC_Database { |
| 13 | |
| 14 | /** |
| 15 | * Get database size using SQL query. |
| 16 | * |
| 17 | * @param bool $formatted Whether to format the size or not. |
| 18 | * @return string|int Formatted database size or raw database size. |
| 19 | */ |
| 20 | public static function get_database_size_sql( $formatted = true ) { |
| 21 | |
| 22 | global $wpdb; |
| 23 | |
| 24 | $sql_query = "SELECT SUM(data_length + index_length) |
| 25 | FROM information_schema.tables |
| 26 | WHERE table_schema = DATABASE() |
| 27 | "; |
| 28 | |
| 29 | // Get database size. |
| 30 | $database_size = $wpdb->get_var( $sql_query ); |
| 31 | |
| 32 | if ( $formatted === true ) |
| 33 | $database_size = ADBC_Common_Utils::format_bytes( $database_size ); |
| 34 | |
| 35 | return $database_size; |
| 36 | |
| 37 | } |
| 38 | |
| 39 | /** |
| 40 | * Get number of tables. |
| 41 | * |
| 42 | * @return int Number of tables. |
| 43 | */ |
| 44 | public static function get_number_of_tables() { |
| 45 | |
| 46 | global $wpdb; |
| 47 | |
| 48 | // Get number of tables. |
| 49 | $tables = $wpdb->get_results( "SHOW TABLES", ARRAY_N ); |
| 50 | |
| 51 | return count( $tables ); |
| 52 | } |
| 53 | |
| 54 | /** |
| 55 | * Check whether collations (and charsets) are unified for a given multisite table suffix across all sites. |
| 56 | * |
| 57 | * Example: $table_suffix = 'options' -> checks wp_options, wp_2_options, ... |
| 58 | * If $check_sitemeta is true, it also includes the network sitemeta table. |
| 59 | * |
| 60 | * @param string $table_suffix Table suffix without prefix, e.g. 'options', 'posts', ... |
| 61 | * @param bool $check_sitemeta Whether to also include the base sitemeta table in the check. |
| 62 | * @param int|null $site_arg Optional filter passed to get_sites_list(); if null, caller can omit. |
| 63 | * |
| 64 | * @return bool True if unified; false if mixed or if we can't reliably determine (safe fallback). |
| 65 | */ |
| 66 | public static function is_collaction_unified( $table_suffix, $check_sitemeta = false, $site_arg = null ) { |
| 67 | |
| 68 | global $wpdb; |
| 69 | |
| 70 | $table_suffix = trim( (string) $table_suffix ); |
| 71 | if ( $table_suffix === '' ) { |
| 72 | return false; |
| 73 | } |
| 74 | |
| 75 | $sites_list = ADBC_Sites::instance()->get_sites_list( $site_arg ); |
| 76 | |
| 77 | // Build table names for all sites. |
| 78 | $table_names = []; |
| 79 | foreach ( $sites_list as $site ) { |
| 80 | if ( empty( $site['prefix'] ) ) { |
| 81 | continue; |
| 82 | } |
| 83 | $table_names[] = $site['prefix'] . $table_suffix; |
| 84 | } |
| 85 | |
| 86 | // Optionally include sitemeta (network table). |
| 87 | // In WP multisite, sitemeta is NOT per-blog; it uses the base prefix. |
| 88 | if ( $check_sitemeta ) { |
| 89 | $table_names[] = $wpdb->sitemeta; // already fully prefixed |
| 90 | } |
| 91 | |
| 92 | $table_names = array_values( array_unique( array_filter( $table_names ) ) ); |
| 93 | |
| 94 | if ( count( $table_names ) <= 1 ) { |
| 95 | return true; // single table => "unified" enough for UNION purposes. |
| 96 | } |
| 97 | |
| 98 | // Query information_schema for collation + charset. |
| 99 | $placeholders = implode( ',', array_fill( 0, count( $table_names ), '%s' ) ); |
| 100 | |
| 101 | $sql = $wpdb->prepare( |
| 102 | "SELECT TABLE_NAME, TABLE_COLLATION |
| 103 | FROM information_schema.TABLES |
| 104 | WHERE TABLE_SCHEMA = DATABASE() |
| 105 | AND TABLE_NAME IN ($placeholders)", |
| 106 | ...$table_names |
| 107 | ); |
| 108 | |
| 109 | $rows = $wpdb->get_results( $sql, ARRAY_A ); |
| 110 | |
| 111 | // If we cannot inspect (permissions) OR we didn't get all rows back, fail safe. |
| 112 | if ( empty( $rows ) || count( $rows ) < count( $table_names ) ) { |
| 113 | return false; |
| 114 | } |
| 115 | |
| 116 | $collations = []; |
| 117 | $charsets = []; |
| 118 | |
| 119 | foreach ( $rows as $r ) { |
| 120 | $coll = $r['TABLE_COLLATION'] ?? ''; |
| 121 | if ( $coll === '' ) { |
| 122 | // Some engines can return NULL; treat as mixed/unsafe for UNION. |
| 123 | return false; |
| 124 | } |
| 125 | $collations[ $coll ] = true; |
| 126 | |
| 127 | // Derive charset from collation: charset is the part before first underscore, e.g. utf8mb4_... |
| 128 | $charset = strstr( $coll, '_', true ); |
| 129 | if ( $charset === false || $charset === '' ) { |
| 130 | return false; |
| 131 | } |
| 132 | $charsets[ $charset ] = true; |
| 133 | } |
| 134 | |
| 135 | // For UNION stability, same collation is ideal. |
| 136 | // If you want to be slightly looser, you could accept same charset only; but that can still error. |
| 137 | return ( count( $collations ) === 1 && count( $charsets ) === 1 ); |
| 138 | |
| 139 | } |
| 140 | |
| 141 | } |