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

490 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
117 return;
118 }
119
120 if ( 'update_and_continue' === $update ) {
121 $this->success_db = $this->update( $this->db_version, $this->plugin->get_version(), array( 'type' => 'user' ) );
122 }
123
124 $versions = $this->db_update_versions();
125
126 if ( version_compare( end( $versions ), $this->db_version, '>' ) ) {
127 add_action( 'all_admin_notices', array( $this, 'update_notice_hook' ) );
128
129 return;
130 }
131
132 $this->update_db_option();
133 }
134
135 /**
136 * Verify that the required DB tables exists
137 *
138 * @return void
139 */
140 public function verify_db() {
141 /**
142 * Filter will halt install() if set to true
143 *
144 * @param bool
145 *
146 * @return bool
147 */
148 if ( apply_filters( 'wp_stream_no_tables', false ) ) {
149 return;
150 }
151
152 if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
153 require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
154 }
155
156 /**
157 * Fires before admin notices are triggered for missing database tables.
158 */
159 do_action( 'wp_stream_before_db_notices' );
160
161 global $wpdb;
162
163 $database_message = '';
164 $uninstall_message = '';
165
166 // Check if all needed DB is present
167 $missing_tables = array();
168
169 foreach ( $this->plugin->db->get_table_names() as $table_name ) {
170 if ( $wpdb->get_var( "SHOW TABLES LIKE '$table_name'" ) !== $table_name ) {
171 $missing_tables[] = $table_name;
172 }
173 }
174
175 if ( $missing_tables ) {
176 $database_message .= sprintf(
177 '%s <strong>%s</strong>',
178 _n(
179 'The following table is not present in the WordPress database:',
180 'The following tables are not present in the WordPress database:',
181 count( $missing_tables ),
182 'stream'
183 ),
184 esc_html( implode( ', ', $missing_tables ) )
185 );
186 }
187
188 if ( is_plugin_active_for_network( $this->plugin->locations['plugin'] ) && current_user_can( 'manage_network_plugins' ) ) {
189 $uninstall_message = sprintf( __( 'Please <a href="%s">uninstall</a> the Stream plugin and activate it again.', 'stream' ), network_admin_url( 'plugins.php#stream' ) );
190 } elseif ( current_user_can( 'activate_plugins' ) ) {
191 $uninstall_message = sprintf( __( 'Please <a href="%s">uninstall</a> the Stream plugin and activate it again.', 'stream' ), admin_url( 'plugins.php#stream' ) );
192 }
193
194 if ( ! empty( $database_message ) ) {
195 $this->plugin->admin->notice( $database_message );
196
197 if ( ! empty( $uninstall_message ) ) {
198 $this->plugin->admin->notice( $uninstall_message );
199 }
200 }
201 }
202
203 /**
204 * Register a routine to be called when stream or a stream connector has been updated
205 * It works by comparing the current version with the version previously stored in the database.
206 *
207 * @param string $file A reference to the main plugin file
208 * @param string $callback The function to run when the hook is called.
209 * @param string $version The version to which the plugin is updating.
210 *
211 * @return void
212 */
213 public function register_update_hook( $file, $callback, $version ) {
214 if ( ! is_admin() ) {
215 return;
216 }
217
218 $plugin = plugin_basename( $file );
219
220 if ( is_plugin_active_for_network( $plugin ) ) {
221 $current_versions = get_site_option( $this->option_key . '_connectors', array() );
222 $network = true;
223 } elseif ( is_plugin_active( $plugin ) ) {
224 $current_versions = get_option( $this->option_key . '_connectors', array() );
225 $network = false;
226 } else {
227 return;
228 }
229
230 if ( version_compare( $version, $current_versions[ $plugin ], '>' ) ) {
231 call_user_func( $callback, $current_versions[ $plugin ], $network );
232
233 $current_versions[ $plugin ] = $version;
234 }
235
236 if ( $network ) {
237 update_site_option( $this->option_key . '_registered_connectors', $current_versions );
238 } else {
239 update_option( $this->option_key . '_registered_connectors', $current_versions );
240 }
241
242 return;
243 }
244
245 /**
246 * @return string
247 */
248 public function get_db_version() {
249 return get_site_option( $this->option_key );
250 }
251
252 /**
253 * @return void
254 */
255 public function update_db_option() {
256 if ( $this->success_db ) {
257 $success_op = update_site_option( $this->option_key, $this->plugin->get_version() );
258 }
259
260 if ( ! empty( $this->success_db ) && ! empty( $success_op ) ) {
261 return;
262 }
263
264 wp_die(
265 esc_html__( 'There was an error updating the Stream database. Please try again.', 'stream' ),
266 esc_html__( 'Database Update Error', 'stream' ),
267 array(
268 'response' => 200,
269 'back_link' => 1,
270 )
271 );
272 }
273
274 /**
275 * Added to the admin_notices hook when file plugin version is higher than database plugin version
276 *
277 * @action admin_notices
278 *
279 * @return void
280 */
281 public function update_notice_hook() {
282 if ( ! current_user_can( $this->plugin->admin->view_cap ) ) {
283 return;
284 }
285
286 $update = isset( $_REQUEST['wp_stream_update'] ) ? $_REQUEST['wp_stream_update'] : null;
287
288 if ( ! $update ) {
289 $this->prompt_update();
290
291 return;
292 }
293
294 if ( 'update_and_continue' === $update ) {
295 $this->prompt_update_status();
296 }
297 }
298
299 /**
300 * Action hook callback function
301 *
302 * Adds the user controlled database upgrade routine to the plugins updated page.
303 * When database update is complete page will refresh with dismissible message to user.
304 *
305 * @return void
306 */
307 public function prompt_update() {
308 ?>
309 <div class="error">
310 <form method="post" action="<?php echo esc_url( remove_query_arg( 'wp_stream_update' ) ) ?>">
311 <?php wp_nonce_field( 'wp_stream_update_db' ) ?>
312 <input type="hidden" name="wp_stream_update" value="update_and_continue"/>
313 <p><strong><?php esc_html_e( 'Stream Database Update Required', 'stream' ) ?></strong></p>
314 <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>
315 <p><?php esc_html_e( 'This process could take a little while, so please be patient.', 'stream' ) ?></p>
316 <?php submit_button( esc_html__( 'Update Database', 'stream' ), 'primary', 'stream-update-db-submit' ) ?>
317 </form>
318 </div>
319 <?php
320 }
321
322 /**
323 * When user initiates a database update this function calls the update methods, checks for success
324 * updates the stream_db version number in the database and outputs a success and continue message
325 *
326 * @return void
327 */
328 public function prompt_update_status() {
329 check_admin_referer( 'wp_stream_update_db' );
330
331 $this->update_db_option();
332 ?>
333 <div class="updated">
334 <form method="post" action="<?php echo esc_url( remove_query_arg( 'wp_stream_update' ) ) ?>" style="display:inline;">
335 <p><strong><?php esc_html_e( 'Update Complete', 'stream' ) ?></strong></p>
336 <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( WP_Stream::VERSION ) ), 'stream' ) ?></p>
337 <?php submit_button( esc_html__( 'Continue', 'stream' ), 'secondary', false ) ?>
338 </form>
339 </div>
340 <?php
341 }
342
343 /**
344 * Array of database versions that require and updates
345 *
346 * To add your own stream extension database update routine
347 * use the filter and return the version that requires an update
348 * You must also make the callback function available in the global namespace on plugins loaded
349 * use the wp_stream_update_{version_number} version number must be a string of characters that represent the version with no periods
350 *
351 * @return array
352 */
353 public function db_update_versions() {
354 $db_update_versions = array(
355 '3.0.0' /* @version 3.0.0 Drop the stream_context table, changes to stream table */,
356 );
357
358 /**
359 * Filter to alter the DB update versions array
360 *
361 * @param array $db_update_versions
362 *
363 * @return array
364 */
365 return apply_filters( 'wp_stream_db_update_versions', $db_update_versions );
366 }
367
368 /**
369 * Database user controlled update routine
370 *
371 * @param int $db_version
372 * @param int $current_version
373 * @param array $update_args
374 *
375 * @return mixed Version number on success, true on no update needed, mysql error message on error
376 */
377 public function update( $db_version, $current_version, $update_args ) {
378 $versions = $this->db_update_versions();
379 include_once( $this->plugin->locations['inc_dir'] . 'db-updates.php' );
380
381 foreach ( $versions as $version ) {
382 if ( ! isset( $update_args['type'] ) ) {
383 $update_args['type'] = 'user';
384 }
385
386 $function = 'wp_stream_update_' . ( 'user' === $update_args['type'] ? '' : $update_args['type'] . '_' ) . str_ireplace( '.', '', $version );
387
388 if ( version_compare( $db_version, $version, '<' ) ) {
389 $result = function_exists( $function ) ? call_user_func( $function, $db_version, $current_version ) : $current_version;
390
391 if ( $current_version !== $result ) {
392 return false;
393 }
394 }
395 }
396
397 return $current_version;
398 }
399
400 /**
401 * Initial database install routine
402 *
403 * @param string $current_version
404 *
405 * @return string
406 */
407 public function install( $current_version ) {
408 global $wpdb;
409
410 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
411
412 $prefix = $this->table_prefix;
413
414 $sql = "CREATE TABLE {$prefix}stream (
415 ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
416 site_id bigint(20) unsigned NOT NULL DEFAULT '1',
417 blog_id bigint(20) unsigned NOT NULL DEFAULT '1',
418 object_id bigint(20) unsigned NULL,
419 user_id bigint(20) unsigned NOT NULL DEFAULT '0',
420 user_role varchar(20) NOT NULL DEFAULT '',
421 summary longtext NOT NULL,
422 created datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
423 connector varchar(100) NOT NULL,
424 context varchar(100) NOT NULL,
425 action varchar(100) NOT NULL,
426 ip varchar(39) NULL,
427 PRIMARY KEY (ID),
428 KEY site_id (site_id),
429 KEY blog_id (blog_id),
430 KEY object_id (object_id),
431 KEY user_id (user_id),
432 KEY created (created),
433 KEY connector (connector),
434 KEY context (context),
435 KEY action (action)
436 )";
437
438 if ( ! empty( $wpdb->charset ) ) {
439 $sql .= " CHARACTER SET $wpdb->charset";
440 }
441
442 if ( ! empty( $wpdb->collate ) ) {
443 $sql .= " COLLATE $wpdb->collate";
444 }
445
446 $sql .= ';';
447
448 \dbDelta( $sql );
449
450 if ( ! empty( $wpdb->charset ) ) {
451 $sql .= " CHARACTER SET $wpdb->charset";
452 }
453
454 if ( ! empty( $wpdb->collate ) ) {
455 $sql .= " COLLATE $wpdb->collate";
456 }
457
458 $sql .= ';';
459
460 \dbDelta( $sql );
461
462 $sql = "CREATE TABLE {$prefix}stream_meta (
463 meta_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
464 record_id bigint(20) unsigned NOT NULL,
465 meta_key varchar(200) NOT NULL,
466 meta_value varchar(200) NOT NULL,
467 PRIMARY KEY (meta_id),
468 KEY record_id (record_id),
469 KEY meta_key (meta_key),
470 KEY meta_value (meta_value)
471 )";
472
473 if ( ! empty( $wpdb->charset ) ) {
474 $sql .= " CHARACTER SET $wpdb->charset";
475 }
476
477 if ( ! empty( $wpdb->collate ) ) {
478 $sql .= " COLLATE $wpdb->collate";
479 }
480
481 $sql .= ';';
482
483 \dbDelta( $sql );
484
485 update_site_option( $this->option_key, $this->plugin->get_version() );
486
487 return $current_version;
488 }
489 }
490