PluginProbe
404 Solution / 4.3.0
404 Solution v4.3.0
4.3.5 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 4.2.0 4.1.19 4.1.18 4.1.17 4.1.16 4.1.15 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.1.7 4.1.6 4.1.5 4.1.4 4.1.3 trunk 2.30.0 All 109 releases
404-solution / includes / uninstall / UninstallDatabaseDefaultsReader.php

UninstallDatabaseDefaultsReader.php in 404 Solution 4.3.0, at includes/uninstall/UninstallDatabaseDefaultsReader.php

137 lines 4.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // allow-no-test-found: covered by tests/UninstallDiagnosticsEntryPointTest.php public uninstall modal/email entry points
3
4 if (!defined('ABSPATH')) {
5 exit;
6 }
7
8 /**
9 * Reads database-level version, charset, and collation defaults for uninstall
10 * feedback diagnostics.
11 */
12 class ABJ_404_Solution_UninstallDatabaseDefaultsReader {
13
14 /**
15 * @return array{version:string,charset:string,collation:string}
16 */
17 public function getDatabaseInfo(): array {
18 $info = array(
19 'version' => $this->databaseVersion(),
20 'charset' => 'Unknown',
21 'collation' => 'Unknown',
22 );
23
24 if (!defined('DB_NAME')) {
25 return $this->applyWpdbDefaults($info, false);
26 }
27
28 $schemaDefaults = $this->schemaDefaults();
29 if ($schemaDefaults !== null) {
30 $info['charset'] = $schemaDefaults['charset'];
31 $info['collation'] = $schemaDefaults['collation'];
32 return $info;
33 }
34
35 $variableDefaults = $this->serverVariableDefaults();
36 $info['charset'] = $variableDefaults['charset'];
37 $info['collation'] = $variableDefaults['collation'];
38
39 return $this->applyWpdbDefaults($info, true);
40 }
41
42 private function databaseVersion(): string {
43 global $wpdb;
44
45 // DAO-bypass-approved: Diagnostic MySQL VERSION() for support email
46 $version = $wpdb->get_var("SELECT VERSION()");
47 return is_scalar($version) && (string)$version !== '' ? (string)$version : 'Unknown';
48 }
49
50 /**
51 * @return array{charset:string,collation:string}|null
52 */
53 private function schemaDefaults(): ?array {
54 global $wpdb;
55
56 // DAO-bypass-approved: Diagnostic database-default charset/collation probe.
57 $charsetQuery = $wpdb->prepare(
58 "SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME " .
59 "FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = %s",
60 DB_NAME
61 );
62 // DAO-bypass-approved: Diagnostic information_schema.SCHEMATA probe
63 $dbResult = $wpdb->get_row($charsetQuery, ARRAY_A);
64 if (!is_array($dbResult)) {
65 return null;
66 }
67
68 $charset = $this->rowValue($dbResult, 'DEFAULT_CHARACTER_SET_NAME');
69 if ($charset === null || $charset === '') {
70 return null;
71 }
72
73 $collation = $this->rowValue($dbResult, 'DEFAULT_COLLATION_NAME');
74 return array(
75 'charset' => $charset,
76 'collation' => $collation !== null && $collation !== '' ? $collation : 'Unknown',
77 );
78 }
79
80 /**
81 * @return array{charset:string,collation:string}
82 */
83 private function serverVariableDefaults(): array {
84 global $wpdb;
85
86 // DAO-bypass-approved: Diagnostic server variable readout for support email
87 $charsetResult = $wpdb->get_row("SHOW VARIABLES LIKE 'character_set_database'", ARRAY_A);
88 // DAO-bypass-approved: Diagnostic server variable readout for support email
89 $collationResult = $wpdb->get_row("SHOW VARIABLES LIKE 'collation_database'", ARRAY_A);
90
91 return array(
92 'charset' => is_array($charsetResult) ? ($this->rowValue($charsetResult, 'Value') ?: 'Unknown') : 'Unknown',
93 'collation' => is_array($collationResult) ? ($this->rowValue($collationResult, 'Value') ?: 'Unknown') : 'Unknown',
94 );
95 }
96
97 /**
98 * @param array{version:string,charset:string,collation:string} $info
99 * @return array{version:string,charset:string,collation:string}
100 */
101 private function applyWpdbDefaults(array $info, bool $allowDbCharsetConstant): array {
102 if ($info['charset'] === 'Unknown') {
103 $charset = $this->wpdbStringProperty('charset');
104 $info['charset'] = $charset !== '' ? $charset : $this->defaultCharset($allowDbCharsetConstant);
105 }
106 if ($info['collation'] === 'Unknown') {
107 $collation = $this->wpdbStringProperty('collate');
108 $info['collation'] = $collation !== '' ? $collation : 'utf8mb4_unicode_ci';
109 }
110 return $info;
111 }
112
113 private function defaultCharset(bool $allowDbCharsetConstant): string {
114 return $allowDbCharsetConstant && defined('DB_CHARSET') && DB_CHARSET ? DB_CHARSET : 'utf8mb4';
115 }
116
117 private function wpdbStringProperty(string $property): string {
118 global $wpdb;
119
120 return isset($wpdb->$property) && is_string($wpdb->$property) ? $wpdb->$property : '';
121 }
122
123 /**
124 * @param array<array-key, mixed> $row
125 * @param string $key
126 * @return string|null
127 */
128 private function rowValue(array $row, string $key): ?string {
129 foreach ($row as $rowKey => $value) {
130 if (is_string($rowKey) && strcasecmp($rowKey, $key) === 0) {
131 return is_string($value) ? $value : null;
132 }
133 }
134 return null;
135 }
136 }
137