PluginProbe
Stream – Activity Log & Audit Trail / 3.9.2
Stream – Activity Log & Audit Trail v3.9.2
4.4.0 4.3.0 4.2.2 4.2.1 trunk 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.1 3.1.1 3.10.0 3.2.0 3.2.1 3.2.2 3.2.3 All 50 releases
stream / classes / class-install.php

class-install.php in Stream – Activity Log & Audit Trail 3.9.2, at classes/class-install.php

439 lines 11.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Handles database migrations
4 *
5 * @package WP_Stream
6 */
7
8 namespace WP_Stream;
9
10 /**
11 * Class - Install
12 */
13 class Install {
14 /**
15 * Holds Instance of plugin object
16 *
17 * @var Plugin
18 */
19 public $plugin;
20
21 /**
22 * Option key to store database version
23 *
24 * @var string
25 */
26 public $option_key = 'wp_stream_db';
27
28 /**
29 * Holds version of database at last update
30 *
31 * @var string
32 */
33 public $db_version;
34
35 /**
36 * URL to the Stream Admin settings page.
37 *
38 * @var string
39 */
40 public $stream_url;
41
42 /**
43 * Array of version numbers that require database update
44 *
45 * @var array
46 */
47 public $update_versions;
48
49 /**
50 * Holds status of whether it's safe to run Stream or not
51 *
52 * @var bool
53 */
54 public $update_required = false;
55
56 /**
57 * Holds status of whether the database update worked
58 *
59 * @var bool
60 */
61 public $success_db;
62
63 /**
64 * Class constructor
65 *
66 * @param Plugin $plugin Instance of plugin object.
67 */
68 public function __construct( $plugin ) {
69 $this->plugin = $plugin;
70
71 $this->db_version = $this->get_db_version();
72 $this->stream_url = self_admin_url( $this->plugin->admin->admin_parent_page . '&page=' . $this->plugin->admin->settings_page_slug );
73
74 // Ensure the tables are created even when the plugin activation hook does not run,
75 // and run the check in WP Admin or on WP CLI to avoid extra frontend load.
76 if ( is_admin() || ( defined( 'WP_CLI' ) && WP_CLI ) ) {
77 $this->check();
78 }
79
80 register_activation_hook( $this->plugin->locations['plugin'], array( $this, 'check' ) );
81 }
82
83 /**
84 * Check db version, create/update table schema accordingly
85 * If database update required admin notice will be given
86 * on the plugin update screen
87 *
88 * @return void
89 */
90 public function check() {
91 if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
92 return;
93 }
94
95 if ( empty( $this->db_version ) ) {
96 $this->install( $this->plugin->get_version() );
97 return;
98 }
99
100 if ( $this->plugin->get_version() === $this->db_version ) {
101 return;
102 }
103
104 $update = null;
105 if ( isset( $_REQUEST['wp_stream_update'] ) && wp_verify_nonce( 'wp_stream_update_db' ) ) {
106 $update = esc_attr( $_REQUEST['wp_stream_update'] );
107 }
108
109 if ( ! $update ) {
110 $this->update_required = true;
111 $this->success_db = $this->update(
112 $this->db_version,
113 $this->plugin->get_version(),
114 array(
115 'type' => 'auto',
116 )
117 );
118 }
119
120 if ( 'update_and_continue' === $update ) {
121 $this->success_db = $this->update(
122 $this->db_version,
123 $this->plugin->get_version(),
124 array(
125 'type' => 'user',
126 )
127 );
128 }
129
130 $versions = $this->db_update_versions();
131
132 if ( ! $this->success_db && version_compare( end( $versions ), $this->db_version, '>' ) ) {
133 add_action( 'all_admin_notices', array( $this, 'update_notice_hook' ) );
134 return;
135 }
136
137 $this->update_db_option();
138 }
139
140 /**
141 * Register a routine to be called when stream or a stream connector has been updated
142 * It works by comparing the current version with the version previously stored in the database.
143 *
144 * @param string $file A reference to the main plugin file.
145 * @param string $callback The function to run when the hook is called.
146 * @param string $version The version to which the plugin is updating.
147 *
148 * @return void
149 */
150 public function register_update_hook( $file, $callback, $version ) {
151 if ( ! is_admin() ) {
152 return;
153 }
154
155 $plugin = plugin_basename( $file );
156
157 if ( $this->plugin->is_network_activated() ) {
158 $current_versions = get_site_option( $this->option_key . '_connectors', array() );
159 $network = true;
160 } elseif ( is_plugin_active( $plugin ) ) {
161 $current_versions = get_option( $this->option_key . '_connectors', array() );
162 $network = false;
163 } else {
164 return;
165 }
166
167 if ( version_compare( $version, $current_versions[ $plugin ], '>' ) ) {
168 call_user_func( $callback, $current_versions[ $plugin ], $network );
169
170 $current_versions[ $plugin ] = $version;
171 }
172
173 if ( $network ) {
174 update_site_option( $this->option_key . '_registered_connectors', $current_versions );
175 } else {
176 update_option( $this->option_key . '_registered_connectors', $current_versions );
177 }
178 }
179
180 /**
181 * Returns the database version.
182 *
183 * @return string
184 */
185 public function get_db_version() {
186 return get_site_option( $this->option_key );
187 }
188
189 /**
190 * Checks if migration was successful.
191 */
192 public function update_db_option() {
193 if ( $this->success_db ) {
194 $success_op = update_site_option( $this->option_key, $this->plugin->get_version() );
195 }
196
197 if ( ! empty( $this->success_db ) ) {
198 return;
199 }
200
201 wp_die(
202 esc_html__( 'There was an error updating the Stream database. Please try again.', 'stream' ),
203 esc_html__( 'Database Update Error', 'stream' ),
204 array(
205 'response' => 200,
206 'back_link' => 1,
207 )
208 );
209 }
210
211 /**
212 * Added to the admin_notices hook when file plugin version is higher than database plugin version
213 *
214 * @action admin_notices
215 *
216 * @return void
217 */
218 public function update_notice_hook() {
219 if ( ! current_user_can( $this->plugin->admin->view_cap ) ) {
220 return;
221 }
222
223 $update = null;
224 if ( isset( $_REQUEST['wp_stream_update'] ) && wp_verify_nonce( 'wp_stream_update_db' ) ) {
225 $update = esc_attr( $_REQUEST['wp_stream_update'] );
226 }
227
228 if ( ! $update ) {
229 $this->prompt_update();
230
231 return;
232 }
233
234 if ( 'update_and_continue' === $update ) {
235 $this->prompt_update_status();
236 }
237 }
238
239 /**
240 * Action hook callback function
241 *
242 * Adds the user controlled database upgrade routine to the plugins updated page.
243 * When database update is complete page will refresh with dismissible message to user.
244 *
245 * @return void
246 */
247 public function prompt_update() {
248 ?>
249 <div class="error">
250 <form method="post" action="<?php echo esc_url( remove_query_arg( 'wp_stream_update' ) ); ?>">
251 <?php wp_nonce_field( 'wp_stream_update_db' ); ?>
252 <input type="hidden" name="wp_stream_update" value="update_and_continue"/>
253 <p><strong><?php esc_html_e( 'Stream Database Update Required', 'stream' ); ?></strong></p>
254 <p><?php esc_html_e( 'Stream has updated! Before we send you on your way, we need to update your database to the newest version.', 'stream' ); ?></p>
255 <p><?php esc_html_e( 'This process could take a little while, so please be patient.', 'stream' ); ?></p>
256 <?php submit_button( esc_html__( 'Update Database', 'stream' ), 'primary', 'stream-update-db-submit' ); ?>
257 </form>
258 </div>
259 <?php
260 }
261
262 /**
263 * When user initiates a database update this function calls the update methods, checks for success
264 * updates the stream_db version number in the database and outputs a success and continue message
265 *
266 * @return void
267 */
268 public function prompt_update_status() {
269 check_admin_referer( 'wp_stream_update_db' );
270
271 $this->update_db_option();
272 ?>
273 <div class="updated">
274 <form method="post" action="<?php echo esc_url( remove_query_arg( 'wp_stream_update' ) ); ?>" style="display:inline;">
275 <p><strong><?php esc_html_e( 'Update Complete', 'stream' ); ?></strong></p>
276 <p>
277 <?php
278 printf(
279 /* translators: %1$s: old version, %2$s: new version (e.g. "4.2") */
280 esc_html__( 'Your Stream database has been successfully updated from %1$s to %2$s!', 'stream' ),
281 esc_html( $this->db_version ),
282 esc_html( $this->plugin->get_version() )
283 );
284 ?>
285 </p>
286 <?php submit_button( esc_html__( 'Continue', 'stream' ), 'secondary', false ); ?>
287 </form>
288 </div>
289 <?php
290 }
291
292 /**
293 * Array of database versions that require and updates
294 *
295 * To add your own stream extension database update routine
296 * use the filter and return the version that requires an update
297 * You must also make the callback function available in the global namespace on plugins loaded
298 * use the wp_stream_update_{version_number} version number must be a string of characters that represent the version with no periods
299 *
300 * @return array
301 */
302 public function db_update_versions() {
303 $db_update_versions = array(
304 '3.0.0', /* @version 3.0.0 Drop the stream_context table, changes to stream table */
305 '3.0.2', /* @version 3.0.2 Fix uppercase values in stream table, connector column */
306 '3.0.8', /* @version 3.0.8 Increase size of user role IDs, user_roll column */
307 );
308
309 /**
310 * Filter to alter the DB update versions array
311 *
312 * @param array $db_update_versions
313 *
314 * @return array
315 */
316 return apply_filters( 'wp_stream_db_update_versions', $db_update_versions );
317 }
318
319 /**
320 * Database user controlled update routine
321 *
322 * @param int $db_version Next database version.
323 * @param int $current_version Current database version.
324 * @param array $update_args Update options.
325 *
326 * @return mixed Version number on success, true on no update needed, mysql error message on error
327 */
328 public function update( $db_version, $current_version, $update_args ) {
329 $versions = $this->db_update_versions();
330 include_once $this->plugin->locations['inc_dir'] . 'db-updates.php';
331
332 foreach ( $versions as $version ) {
333 if ( ! isset( $update_args['type'] ) ) {
334 $update_args['type'] = 'user';
335 }
336
337 $function = 'wp_stream_update_' . ( 'user' === $update_args['type'] ? '' : $update_args['type'] . '_' ) . str_ireplace( '.', '', $version );
338
339 if ( version_compare( $db_version, $version, '<' ) ) {
340 $result = function_exists( $function ) ? call_user_func( $function, $db_version, $current_version ) : $current_version;
341
342 if ( $current_version !== $result ) {
343 return false;
344 }
345 }
346 }
347
348 return $current_version;
349 }
350
351 /**
352 * Initial database install routine
353 *
354 * @param string $current_version Current database version.
355 *
356 * @return string
357 */
358 public function install( $current_version ) {
359 global $wpdb;
360
361 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
362
363 $sql = "CREATE TABLE {$wpdb->base_prefix}stream (
364 ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
365 site_id bigint(20) unsigned NOT NULL DEFAULT '1',
366 blog_id bigint(20) unsigned NOT NULL DEFAULT '1',
367 object_id bigint(20) unsigned NULL,
368 user_id bigint(20) unsigned NOT NULL DEFAULT '0',
369 user_role varchar(50) NOT NULL DEFAULT '',
370 summary longtext NOT NULL,
371 created datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
372 connector varchar(100) NOT NULL,
373 context varchar(100) NOT NULL,
374 action varchar(100) NOT NULL,
375 ip varchar(39) NULL,
376 PRIMARY KEY (ID),
377 KEY site_id (site_id),
378 KEY blog_id (blog_id),
379 KEY object_id (object_id),
380 KEY user_id (user_id),
381 KEY created (created),
382 KEY connector (connector),
383 KEY context (context),
384 KEY action (action)
385 )";
386
387 if ( ! empty( $wpdb->charset ) ) {
388 $sql .= " CHARACTER SET $wpdb->charset";
389 }
390
391 if ( ! empty( $wpdb->collate ) ) {
392 $sql .= " COLLATE $wpdb->collate";
393 }
394
395 $sql .= ';';
396
397 \dbDelta( $sql );
398
399 if ( ! empty( $wpdb->charset ) ) {
400 $sql .= " CHARACTER SET $wpdb->charset";
401 }
402
403 if ( ! empty( $wpdb->collate ) ) {
404 $sql .= " COLLATE $wpdb->collate";
405 }
406
407 $sql .= ';';
408
409 \dbDelta( $sql );
410
411 $sql = "CREATE TABLE {$wpdb->base_prefix}stream_meta (
412 meta_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
413 record_id bigint(20) unsigned NOT NULL,
414 meta_key varchar(200) NOT NULL,
415 meta_value varchar(200) NOT NULL,
416 PRIMARY KEY (meta_id),
417 KEY record_id (record_id),
418 KEY meta_key (meta_key(191)),
419 KEY meta_value (meta_value(191))
420 )";
421
422 if ( ! empty( $wpdb->charset ) ) {
423 $sql .= " CHARACTER SET $wpdb->charset";
424 }
425
426 if ( ! empty( $wpdb->collate ) ) {
427 $sql .= " COLLATE $wpdb->collate";
428 }
429
430 $sql .= ';';
431
432 \dbDelta( $sql );
433
434 update_site_option( $this->option_key, $this->plugin->get_version() );
435
436 return $current_version;
437 }
438 }
439