PluginProbe
Redirection / 5.9.0
Redirection v5.9.0
5.10.0 5.9.0 5.8.1 5.8.0 3.7.2 3.7.3 4.0 4.0.1 4.1 4.1.1 4.2 4.2.1 4.2.2 4.2.3 4.3 4.3.1 4.3.2 4.3.3 4.4 4.4.1 4.4.2 4.5 4.5.1 4.6.2 4.7.1 All 130 releases
redirection / database / database-upgrader.php

database-upgrader.php in Redirection 5.9.0, at database/database-upgrader.php

178 lines 4.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 require_once __DIR__ . '/database-upgrade.php';
4
5 abstract class Red_Database_Upgrader {
6 /**
7 * @var list<string>
8 */
9 private $queries = [];
10
11 /**
12 * @var bool
13 */
14 private $live = true;
15
16 /**
17 * Return an array of all the stages for an upgrade
18 *
19 * @return array<string, string> stage name => reason
20 */
21 abstract public function get_stages();
22
23 /**
24 * @param string $stage
25 * @return string
26 */
27 public function get_reason( string $stage ): string {
28 $stages = $this->get_stages();
29
30 if ( isset( $stages[ $stage ] ) ) {
31 return $stages[ $stage ];
32 }
33
34 return 'Unknown';
35 }
36
37 /**
38 * Run a particular stage on the current upgrader
39 *
40 * @param Red_Database_Status $status
41 * @return void
42 */
43 public function perform_stage( Red_Database_Status $status ): void {
44 global $wpdb;
45
46 $stage = $status->get_current_stage();
47 if ( is_string( $stage ) && $this->has_stage( $stage ) && method_exists( $this, $stage ) ) {
48 try {
49 $this->invoke_stage( $stage, $wpdb, true );
50 $status->set_ok( $this->get_reason( $stage ) );
51 } catch ( Exception $e ) {
52 $status->set_error( $e->getMessage() );
53 }
54 } else {
55 $status->set_error( 'No stage found for upgrade ' . $stage );
56 }
57 }
58
59 /**
60 * @param string $stage
61 * @return list<string>
62 */
63 public function get_queries_for_stage( string $stage ): array {
64 global $wpdb;
65
66 $this->queries = [];
67 $this->live = false;
68 $this->invoke_stage( $stage, $wpdb, false );
69 $this->live = true;
70
71 return $this->queries;
72 }
73
74 /**
75 * Returns the current database charset
76 *
77 * @return string Database charset
78 */
79 public function get_charset(): string {
80 global $wpdb;
81
82 $charset_collate = '';
83 if ( ! empty( $wpdb->charset ) ) {
84 // Fix some common invalid charset values
85 $fixes = [
86 'utf-8',
87 'utf',
88 ];
89
90 $charset = $wpdb->charset;
91 if ( in_array( strtolower( $charset ), $fixes, true ) ) {
92 $charset = 'utf8';
93 }
94
95 $charset_collate = "DEFAULT CHARACTER SET $charset";
96 }
97
98 if ( ! empty( $wpdb->collate ) ) {
99 $charset_collate .= " COLLATE=$wpdb->collate";
100 }
101
102 return $charset_collate;
103 }
104
105 /**
106 * Performs a $wpdb->query, and throws an exception if an error occurs
107 *
108 * @param wpdb $wpdb WordPress database instance.
109 * @param string $sql SQL query.
110 * @return bool true if query is performed ok, otherwise an exception is thrown
111 */
112 protected function do_query( wpdb $wpdb, string $sql ): bool {
113 if ( ! $this->live ) {
114 $this->queries[] = $sql;
115 return true;
116 }
117
118 // These are known queries without user input
119 // phpcs:ignore
120 $result = $wpdb->query( $sql );
121
122 if ( $result === false ) {
123 /* translators: 1: SQL string */
124 throw new Exception( sprintf( 'Failed to perform query "%s"', $sql ) ); // phpcs:ignore
125 }
126
127 return true;
128 }
129
130 /**
131 * Load a database upgrader class
132 *
133 * @param Red_Database_Upgrade $version
134 * @return Red_Database_Upgrader Database upgrader
135 */
136 public static function get( Red_Database_Upgrade $version ): Red_Database_Upgrader {
137 include_once __DIR__ . '/schema/' . str_replace( [ '..', '/' ], '', $version->get_file() );
138
139 $class = $version->get_class();
140
141 return new $class();
142 }
143
144 /**
145 * @param string $stage
146 * @return bool
147 */
148 private function has_stage( string $stage ): bool {
149 return in_array( $stage, array_keys( $this->get_stages() ), true );
150 }
151
152 /**
153 * @param string $stage
154 * @param wpdb $wpdb
155 * @param bool $live
156 * @return void
157 */
158 private function invoke_stage( string $stage, wpdb $wpdb, bool $live ): void {
159 if ( ! method_exists( $this, $stage ) ) {
160 return;
161 }
162
163 // Methods that accept both $wpdb and $live parameters
164 // Most stage methods only accept $wpdb, but some (like create_groups) accept both
165 $two_param_methods = [ 'create_groups' ];
166
167 if ( in_array( $stage, $two_param_methods, true ) ) {
168 /** @var callable(wpdb, bool): void $callable */
169 $callable = [ $this, $stage ];
170 call_user_func( $callable, $wpdb, $live );
171 } else {
172 /** @var callable(wpdb): void $callable */
173 $callable = [ $this, $stage ];
174 call_user_func( $callable, $wpdb );
175 }
176 }
177 }
178