PluginProbe
bbPress / trunk
bbPress vtrunk
trunk 2.0 2.0-beta-1 2.0-beta-2b 2.0-beta-3 2.0-beta-3b 2.0-rc-2 2.0-rc-3 2.0-rc-4 2.0-rc-5 2.0.1 2.0.2 2.0.3 2.1 2.1-beta-1 2.1-rc1 2.1-rc2 2.1-rc3 2.1-rc4 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.2.2 All 71 releases
bbpress / includes / core / update.php

update.php in bbPress trunk, at includes/core/update.php

654 lines 16.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * bbPress Updater.
5 *
6 * @package bbPress
7 * @subpackage Core
8 */
9
10 // Exit if accessed directly
11 defined( 'ABSPATH' ) || exit;
12
13 /**
14 * If there is no raw DB version, this is the first installation.
15 *
16 * @since 2.1.0 bbPress (r3764)
17 *
18 * @return bool True if update, False if not.
19 */
20 function bbp_is_install() {
21 return ! bbp_get_db_version_raw();
22 }
23
24 /**
25 * Compare the bbPress version to the DB version to determine if updating.
26 *
27 * @since 2.0.0 bbPress (r3421)
28 *
29 * @return bool True if update, False if not.
30 */
31 function bbp_is_update() {
32 $raw = (int) bbp_get_db_version_raw();
33 $cur = (int) bbp_get_db_version();
34 $retval = (bool) ( $raw < $cur );
35 return $retval;
36 }
37
38 /**
39 * Determine if bbPress is being activated.
40 *
41 * Note that this function currently is not used in bbPress core and is here
42 * for third party plugins to use to check for bbPress activation.
43 *
44 * @since 2.0.0 bbPress (r3421)
45 *
46 * @global string $pagenow The filename of the current screen.
47 *
48 * @param string $basename Plugin base name.
49 *
50 * @return bool True if activating bbPress, false if not.
51 */
52 function bbp_is_activation( $basename = '' ) {
53 global $pagenow;
54
55 $bbp = bbpress();
56 $action = false;
57
58 // Bail if not in admin/plugins
59 if ( ! ( is_admin() && ( 'plugins.php' === $pagenow ) ) ) {
60 return false;
61 }
62
63 if ( ! empty( $_REQUEST['action'] ) && ( '-1' !== $_REQUEST['action'] ) ) {
64 $action = $_REQUEST['action'];
65 } elseif ( ! empty( $_REQUEST['action2'] ) && ( '-1' !== $_REQUEST['action2'] ) ) {
66 $action = $_REQUEST['action2'];
67 }
68
69 // Bail if not activating
70 if ( empty( $action ) || ! in_array( $action, array( 'activate', 'activate-selected' ), true ) ) {
71 return false;
72 }
73
74 // The plugin(s) being activated
75 if ( 'activate' === $action ) {
76 $plugins = isset( $_GET['plugin'] ) ? array( $_GET['plugin'] ) : array();
77 } else {
78 $plugins = isset( $_POST['checked'] ) ? (array) $_POST['checked'] : array();
79 }
80
81 // Set basename if empty
82 if ( empty( $basename ) && ! empty( $bbp->basename ) ) {
83 $basename = $bbp->basename;
84 }
85
86 // Bail if no basename
87 if ( empty( $basename ) ) {
88 return false;
89 }
90
91 // Is bbPress being activated?
92 return in_array( $basename, $plugins, true );
93 }
94
95 /**
96 * Determine if bbPress is being deactivated.
97 *
98 * @since 2.0.0 bbPress (r3421)
99 *
100 * @global string $pagenow The filename of the current screen.
101 *
102 * @param string $basename Plugin base name.
103 *
104 * @return bool True if deactivating bbPress, false if not.
105 */
106 function bbp_is_deactivation( $basename = '' ) {
107 global $pagenow;
108
109 $bbp = bbpress();
110 $action = false;
111
112 // Bail if not in admin/plugins
113 if ( ! ( is_admin() && ( 'plugins.php' === $pagenow ) ) ) {
114 return false;
115 }
116
117 if ( ! empty( $_REQUEST['action'] ) && ( '-1' !== $_REQUEST['action'] ) ) {
118 $action = $_REQUEST['action'];
119 } elseif ( ! empty( $_REQUEST['action2'] ) && ( '-1' !== $_REQUEST['action2'] ) ) {
120 $action = $_REQUEST['action2'];
121 }
122
123 // Bail if not deactivating
124 if ( empty( $action ) || ! in_array( $action, array( 'deactivate', 'deactivate-selected' ), true ) ) {
125 return false;
126 }
127
128 // The plugin(s) being deactivated
129 if ( 'deactivate' === $action ) {
130 $plugins = isset( $_GET['plugin'] ) ? array( $_GET['plugin'] ) : array();
131 } else {
132 $plugins = isset( $_POST['checked'] ) ? (array) $_POST['checked'] : array();
133 }
134
135 // Set basename if empty
136 if ( empty( $basename ) && ! empty( $bbp->basename ) ) {
137 $basename = $bbp->basename;
138 }
139
140 // Bail if no basename
141 if ( empty( $basename ) ) {
142 return false;
143 }
144
145 // Is bbPress being deactivated?
146 return in_array( $basename, $plugins, true );
147 }
148
149 /**
150 * Update the DB to the latest version.
151 *
152 * @since 2.0.0 bbPress (r3421)
153 */
154 function bbp_version_bump() {
155 update_option( '_bbp_db_version', bbp_get_db_version() );
156 }
157
158 /**
159 * Setup the bbPress updater.
160 *
161 * @since 2.0.0 bbPress (r3419)
162 */
163 function bbp_setup_updater() {
164
165 // Bail if no update needed
166 if ( ! bbp_is_update() ) {
167 return;
168 }
169
170 // Call the automated updater
171 bbp_version_updater();
172 }
173
174 /**
175 * Runs when a new site is created in a multisite network, and bbPress is active
176 * on that site (hooked to `bbp_new_site`).
177 *
178 * @since 2.6.0 bbPress (r6779)
179 *
180 * @param int $site_id Side id.
181 */
182 function bbp_setup_new_site( $site_id = 0 ) {
183
184 // Look for initial content
185 $created = is_multisite()
186 ? get_blog_option( $site_id, '_bbp_flag_initial_content', false )
187 : get_option( '_bbp_flag_initial_content', false );
188
189 // Maybe create the initial content
190 if ( ! empty( $created ) ) {
191 bbp_create_initial_content();
192
193 // Flag initial content as created
194 is_multisite()
195 ? update_blog_option( $site_id, '_bbp_flag_initial_content', true )
196 : update_option( '_bbp_flag_initial_content', true );
197 }
198 }
199
200 /**
201 * Create a default forum, topic, and reply.
202 *
203 * @since 2.1.0 bbPress (r3767)
204 *
205 * @param array $args Array of arguments to override default values.
206 */
207 function bbp_create_initial_content( $args = array() ) {
208
209 // Cannot use bbp_get_current_user_id() during activation process
210 $user_id = get_current_user_id();
211
212 // Parse arguments against default values
213 $r = bbp_parse_args(
214 $args,
215 array(
216 'forum_author' => $user_id,
217 'forum_parent' => 0,
218 'forum_status' => 'publish',
219 'forum_title' => esc_html__( 'General', 'bbpress' ),
220 'forum_content' => esc_html__( 'General Discussion', 'bbpress' ),
221
222 'topic_author' => $user_id,
223 'topic_title' => esc_html__( 'Hello World!', 'bbpress' ),
224 'topic_content' => esc_html__( 'This is the very first topic in these forums.', 'bbpress' ),
225
226 'reply_author' => $user_id,
227 'reply_content' => esc_html__( 'And this is the very first reply.', 'bbpress' ),
228 ),
229 'create_initial_content'
230 );
231
232 // Use the same time for each post
233 // phpcs:disable WordPress.DateTime.RestrictedFunctions.date_date
234 $current_time = time();
235 $forum_time = date( 'Y-m-d H:i:s', $current_time - 60 * 60 * 80 );
236 $topic_time = date( 'Y-m-d H:i:s', $current_time - 60 * 60 * 60 );
237 $reply_time = date( 'Y-m-d H:i:s', $current_time - 60 * 60 * 40 );
238 // phpcs:enable
239
240 // Create the initial forum
241 $forum_id = bbp_insert_forum(
242 array(
243 'post_author' => $r['forum_author'],
244 'post_parent' => $r['forum_parent'],
245 'post_status' => $r['forum_status'],
246 'post_title' => $r['forum_title'],
247 'post_content' => $r['forum_content'],
248 'post_date' => $forum_time
249 )
250 );
251
252 // Create the initial topic
253 $topic_id = bbp_insert_topic(
254 array(
255 'post_author' => $r['topic_author'],
256 'post_parent' => $forum_id,
257 'post_title' => $r['topic_title'],
258 'post_content' => $r['topic_content'],
259 'post_date' => $topic_time,
260 ),
261 array(
262 'forum_id' => $forum_id
263 )
264 );
265
266 // Create the initial reply
267 $reply_id = bbp_insert_reply(
268 array(
269 'post_author' => $r['reply_author'],
270 'post_parent' => $topic_id,
271 'post_content' => $r['reply_content'],
272 'post_date' => $reply_time
273 ),
274 array(
275 'forum_id' => $forum_id,
276 'topic_id' => $topic_id
277 )
278 );
279
280 return array(
281 'forum_id' => $forum_id,
282 'topic_id' => $topic_id,
283 'reply_id' => $reply_id
284 );
285 }
286
287 /**
288 * The version updater looks at what the current database version is, and
289 * runs whatever other code is needed.
290 *
291 * This is most-often used when the data schema changes, but should also be used
292 * to correct issues with bbPress meta-data silently on software update.
293 *
294 * @since 2.2.0 bbPress (r4104)
295 */
296 function bbp_version_updater() {
297
298 // Get the raw database version
299 $raw_db_version = (int) bbp_get_db_version_raw();
300
301 // Only run updater if previous installation exists
302 if ( ! empty( $raw_db_version ) ) {
303
304 /** 2.0 Branch ********************************************************/
305
306 // 2.0, 2.0.1, 2.0.2, 2.0.3
307 // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedIf
308 if ( $raw_db_version < 200 ) {
309 // No changes
310 }
311
312 /** 2.1 Branch ********************************************************/
313
314 // 2.1, 2.1.1
315 if ( $raw_db_version < 211 ) {
316
317 /**
318 * Repair private and hidden forum data
319 *
320 * @link https://bbpress.trac.wordpress.org/ticket/1891
321 */
322 bbp_admin_repair_forum_visibility();
323 }
324
325 /** 2.2 Branch ********************************************************/
326
327 // 2.2.x
328 if ( $raw_db_version < 220 ) {
329
330 // Remove any old bbPress roles
331 bbp_remove_roles();
332
333 // Remove capabilities
334 bbp_remove_caps();
335 }
336
337 /** 2.3 Branch ********************************************************/
338
339 // 2.3.x
340 // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedIf
341 if ( $raw_db_version < 230 ) {
342 // No changes
343 }
344
345 /** 2.4 Branch ********************************************************/
346
347 // 2.4.x
348 // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedIf
349 if ( $raw_db_version < 240 ) {
350 // No changes
351 }
352
353 /** 2.5 Branch ********************************************************/
354
355 // 2.5.x
356 // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedIf
357 if ( $raw_db_version < 250 ) {
358 // No changes
359 }
360
361 /** 2.6 Branch ********************************************************/
362
363 // Smaller installs run the upgrades directly
364 if ( ! bbp_is_large_install() ) {
365
366 /**
367 * Upgrade user favorites and subscriptions
368 */
369 if ( $raw_db_version < 261 ) {
370 bbp_admin_upgrade_user_favorites();
371 bbp_admin_upgrade_user_topic_subscriptions();
372 bbp_admin_upgrade_user_forum_subscriptions();
373 }
374
375 /**
376 * Upgrade user engagements
377 */
378 if ( $raw_db_version < 262 ) {
379 bbp_admin_upgrade_user_engagements();
380 }
381
382 /**
383 * Repair forum hidden reply count
384 */
385 if ( $raw_db_version < 263 ) {
386 bbp_admin_repair_forum_hidden_reply_count();
387 }
388
389 // Large installs require manual intervention
390 } else {
391
392 /**
393 * Upgrade user favorites and subscriptions
394 */
395 if ( $raw_db_version < 261 ) {
396 bbp_add_pending_upgrade( 'bbp-user-favorites-move' );
397 bbp_add_pending_upgrade( 'bbp-user-topic-subscriptions-move' );
398 bbp_add_pending_upgrade( 'bbp-user-forum-subscriptions-move' );
399
400 // Set strategy to pre-2.6 on large network
401 update_option( '_bbp_engagements_strategy', 'user' );
402 }
403
404 /**
405 * Upgrade user engagements
406 */
407 if ( $raw_db_version < 262 ) {
408 bbp_add_pending_upgrade( 'bbp-user-topic-engagements-move' );
409
410 // Set strategy to pre-2.6 on large network
411 update_option( '_bbp_engagements_strategy', 'user' );
412 }
413
414 /**
415 * Upgrade user engagements
416 */
417 if ( $raw_db_version < 263 ) {
418 bbp_add_pending_upgrade( 'bbp-forum-hidden-replies' );
419 }
420 }
421 }
422
423 /** All done! *************************************************************/
424
425 // Bump the version
426 bbp_version_bump();
427
428 // Delete rewrite rules to force a flush
429 bbp_delete_rewrite_rules();
430 }
431
432 /**
433 * Redirect user to the "What's New" page on activation.
434 *
435 * @since 2.2.0 bbPress (r4389)
436 *
437 * @internal Used internally to redirect bbPress to the about page on activation.
438 *
439 * @return If network admin or bulk activation.
440 */
441 function bbp_add_activation_redirect() {
442
443 // Bail if activating from network, or bulk
444 if ( is_network_admin() || isset( $_GET['activate-multi'] ) ) {
445 return;
446 }
447
448 // Add the redirect trigger
449 update_user_option( get_current_user_id(), '_bbp_activation_redirect', true );
450 }
451
452 /**
453 * Redirect user to "What's New" page on activation.
454 *
455 * @since 2.2.0 bbPress (r4389)
456 *
457 * @internal Used internally to redirect bbPress to the about page on activation.
458 *
459 * @return If no transient, or in network admin, or is bulk activation.
460 */
461 function bbp_do_activation_redirect() {
462
463 // Bail if no redirect trigger
464 if ( ! get_user_option( '_bbp_activation_redirect' ) ) {
465 return;
466 }
467
468 // Delete the redirect trigger
469 delete_user_option( get_current_user_id(), '_bbp_activation_redirect' );
470
471 // Bail if activating from network, or bulk
472 if ( is_network_admin() || isset( $_GET['activate-multi'] ) ) {
473 return;
474 }
475
476 // Bail if the current user cannot see the about page
477 if ( ! current_user_can( 'bbp_about_page' ) ) {
478 return;
479 }
480
481 // Redirect to bbPress about page
482 bbp_redirect( add_query_arg( array( 'page' => 'bbp-about' ), admin_url( 'index.php' ) ) );
483 }
484
485 /**
486 * Hooked to the 'bbp_activate' action, this helper function automatically makes
487 * the current user a Keymaster in the forums if they just activated bbPress,
488 * regardless of the bbp_allow_global_access() setting.
489 *
490 * @since 2.4.0 bbPress (r4910)
491 *
492 * @internal Used to internally make the current user a keymaster on activation.
493 *
494 * @return If user can't activate plugins or is already a keymaster.
495 */
496 function bbp_make_current_user_keymaster() {
497
498 // Catch all, to prevent premature user initialization
499 if ( ! did_action( 'set_current_user' ) ) {
500 return;
501 }
502
503 // Bail if not logged in or already a member of this site
504 if ( ! is_user_logged_in() ) {
505 return;
506 }
507
508 // Bail if the current user can't activate plugins since previous pageload
509 if ( ! current_user_can( 'activate_plugins' ) ) {
510 return;
511 }
512
513 // Cannot use bbp_get_current_user_id() during activation process
514 $user_id = get_current_user_id();
515
516 // Get the current blog ID, to know if they should be promoted here
517 $blog_id = get_current_blog_id();
518
519 // Bail if user is not actually a member of this site
520 if ( ! is_user_member_of_blog( $user_id, $blog_id ) ) {
521 return;
522 }
523
524 // Bail if the current user already has a forum role to prevent
525 // unexpected role and capability escalation.
526 if ( bbp_get_user_role( $user_id ) ) {
527 return;
528 }
529
530 // Make the current user a keymaster
531 bbp_set_user_role( $user_id, bbp_get_keymaster_role() );
532
533 // Reload the current user so caps apply immediately
534 wp_get_current_user();
535 }
536
537 /** Pending Upgrades **********************************************************/
538
539 /**
540 * Return the number of pending upgrades.
541 *
542 * @since 2.6.0 bbPress (r6895)
543 *
544 * @param string $type Type of pending upgrades (upgrade|repair|empty).
545 *
546 * @return int
547 */
548 function bbp_get_pending_upgrade_count( $type = '' ) {
549 return count( (array) bbp_get_pending_upgrades( $type ) );
550 }
551
552 /**
553 * Return an array of pending upgrades.
554 *
555 * @since 2.6.0 bbPress (r6895)
556 *
557 * @param string $type Type of pending upgrades (upgrade|repair|empty).
558 *
559 * @return array
560 */
561 function bbp_get_pending_upgrades( $type = '' ) {
562
563 // Get the pending upgrades
564 $retval = (array) get_option( '_bbp_db_pending_upgrades', array() );
565
566 // Looking for a specific type?
567 if ( ! empty( $type ) ) {
568 $tools = bbp_get_admin_repair_tools( $type );
569 $plucked = array_keys( wp_list_pluck( $tools, 'type' ) );
570 $retval = array_intersect( $retval, $plucked );
571 }
572
573 return (array) $retval;
574 }
575
576 /**
577 * Add an upgrade ID to pending upgrades array.
578 *
579 * @since 2.6.0 bbPress (r6895)
580 *
581 * @param string $upgrade_id
582 */
583 function bbp_add_pending_upgrade( $upgrade_id = '' ) {
584
585 // Get the pending upgrades option
586 $pending = bbp_get_pending_upgrades();
587
588 // Maybe add upgrade ID to end of pending array
589 if ( false === array_search( $upgrade_id, $pending, true ) ) {
590 array_push( $pending, $upgrade_id );
591 }
592
593 // Update and return
594 return update_option( '_bbp_db_pending_upgrades', $pending );
595 }
596
597 /**
598 * Add an upgrade ID to pending upgrades array.
599 *
600 * @since 2.6.0 bbPress (r6895)
601 *
602 * @param string $upgrade_id
603 */
604 function bbp_remove_pending_upgrade( $upgrade_id = '' ) {
605
606 // Get the pending upgrades option
607 $pending = bbp_get_pending_upgrades();
608
609 // Look for this upgrade ID
610 $index = array_search( $upgrade_id, $pending, true );
611
612 // Maybe remove upgrade ID from pending array
613 if ( false !== $index ) {
614 unset( $pending[ $index ] );
615 }
616
617 // Update and return
618 return update_option( '_bbp_db_pending_upgrades', $pending );
619 }
620
621 /**
622 * Delete all pending upgrades.
623 *
624 * @since 2.6.0 bbPress (r6895)
625 */
626 function bbp_clear_pending_upgrades() {
627 return delete_option( '_bbp_db_pending_upgrades' );
628 }
629
630 /**
631 * Maybe append an upgrade count to a string.
632 *
633 * @since 2.6.0 bbPress (r6896)
634 *
635 * @param string $text Text to append count to.
636 * @param string $type Type of pending upgrades (upgrade|repair|empty).
637 *
638 * @return string
639 */
640 function bbp_maybe_append_pending_upgrade_count( $text = '', $type = '' ) {
641
642 // Look for an upgrade count
643 $count = bbp_get_pending_upgrade_count( $type );
644
645 // Append the count to the string
646 if ( ! empty( $count ) ) {
647 $suffix = ' <span class="awaiting-mod count-' . absint( $count ) . '"><span class="pending-count">' . bbp_number_format( $count ) . '</span></span>';
648 $text = "{$text}{$suffix}";
649 }
650
651 // Return the text, maybe with a count
652 return $text;
653 }
654