PluginProbe
Stream – Activity Log & Audit Trail / 3.0.2
Stream – Activity Log & Audit Trail v3.0.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.0.2, at classes/class-install.php

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