PluginProbe
WordPress Beta Tester / trunk
WordPress Beta Tester vtrunk
3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.4.0 All 100 releases
wordpress-beta-tester / src / WPBT / WPBT_Core.php

WPBT_Core.php in WordPress Beta Tester trunk, at src/WPBT/WPBT_Core.php

478 lines 17.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WordPress Beta Tester
4 *
5 * @package WordPress_Beta_Tester
6 * @author Andy Fragen, original author Peter Westwood.
7 * @license GPLv2+
8 * @copyright 2009-2016 Peter Westwood (email : peter.westwood@ftwr.co.uk)
9 */
10
11 /**
12 * WPBT_Core
13 */
14 class WPBT_Core {
15 /**
16 * Placeholder for saved options.
17 *
18 * @var array
19 */
20 protected static $options;
21
22 /**
23 * Holds the WP_Beta_Tester instance.
24 *
25 * @var WP_Beta_Tester
26 */
27 protected $wp_beta_tester;
28
29 /**
30 * Constructor.
31 *
32 * @param WP_Beta_Tester $wp_beta_tester Instance of class WP_Beta_Tester.
33 * @param array $options Site options.
34 * @return void
35 */
36 public function __construct( WP_Beta_Tester $wp_beta_tester, $options ) {
37 self::$options = $options;
38 $this->wp_beta_tester = $wp_beta_tester;
39 }
40
41 /**
42 * Load hooks.
43 *
44 * @return void
45 */
46 public function load_hooks() {
47 add_filter( 'wp_beta_tester_add_settings_tabs', array( $this, 'add_settings_tab' ) );
48 add_action( 'wp_beta_tester_add_settings', array( $this, 'add_settings' ) );
49 add_action( 'wp_beta_tester_add_admin_page', array( $this, 'add_admin_page' ), 10, 2 );
50 add_action( 'wp_beta_tester_update_settings', array( $this, 'save_settings' ) );
51 }
52
53 /**
54 * Add settings tab for class.
55 *
56 * @param array $tabs Settings tabs.
57 * @return array
58 */
59 public function add_settings_tab( $tabs ) {
60 return array_merge( (array) $tabs, array( 'wp_beta_tester_core' => esc_html__( 'WP Beta Tester Settings', 'wordpress-beta-tester' ) ) );
61 }
62
63 /**
64 * Setup Settings API.
65 *
66 * @return void
67 */
68 public function add_settings() {
69 register_setting(
70 'wp_beta_tester',
71 'wp_beta_tester_core',
72 array( 'WPBT_Setting', 'sanitize' )
73 );
74
75 add_settings_section(
76 'wp_beta_tester_core',
77 esc_html__( 'Core Settings', 'wordpress-beta-tester' ),
78 array( $this, 'print_core_settings_top' ),
79 'wp_beta_tester_core'
80 );
81
82 add_settings_field(
83 'channel_settings',
84 __( 'Select the update channel you would like this website to use:', 'wordpress-beta-tester' ),
85 array( $this, 'channel_radio_group' ),
86 'wp_beta_tester_core',
87 'wp_beta_tester_core',
88 array( 'class' => 'wpbt-settings-title' )
89 );
90
91 add_settings_field(
92 'stream_settings',
93 __( 'Select one of the stream options below:', 'wordpress-beta-tester' ),
94 array( $this, 'stream_radio_group' ),
95 'wp_beta_tester_core',
96 'wp_beta_tester_core',
97 array( 'class' => 'wpbt-settings-title' )
98 );
99 }
100
101 /**
102 * Save settings.
103 *
104 * @param mixed $post_data $_POST data.
105 * @return void
106 */
107 public function save_settings( $post_data ) {
108 if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['_wpnonce'] ) ), 'wp_beta_tester_core-options' )
109 ) {
110 return;
111 }
112
113 if ( isset( $post_data['option_page'] )
114 && 'wp_beta_tester_core' === $post_data['option_page']
115 ) {
116 $option_channel = isset( $post_data['wp-beta-tester'] ) ? $post_data['wp-beta-tester'] : 'branch-development';
117 $options['channel'] = WPBT_Settings::sanitize( $option_channel );
118
119 $option_beta_rc = isset( $post_data['wp-beta-tester-beta-rc'] ) ? $post_data['wp-beta-tester-beta-rc'] : '';
120 $options['stream-option'] = WPBT_Settings::sanitize( $option_beta_rc );
121
122 $options = $this->channel_settings_migrator( $options );
123 $options = array_merge( self::$options, (array) $options );
124
125 update_site_option( 'wp_beta_tester', (array) $options );
126 add_filter( 'wp_beta_tester_save_redirect', array( $this, 'save_redirect_page' ) );
127 }
128 }
129
130 /**
131 * Redirect page/tab after saving options.
132 *
133 * @param array $option_page Settings tabs.
134 * @return array
135 */
136 public function save_redirect_page( $option_page ) {
137 return array_merge( $option_page, array( 'wp_beta_tester_core' ) );
138 }
139
140 /**
141 * Print settings section information.
142 *
143 * @return void
144 */
145 public function print_core_settings_top() {
146 $this->wp_beta_tester->action_admin_head_plugins_php(); // Check configuration.
147 $preferred = $this->wp_beta_tester->get_preferred_from_update_core();
148 if ( defined( 'WP_AUTO_UPDATE_CORE' ) && WP_AUTO_UPDATE_CORE ) {
149 echo '<div class="notice notice-warning fade"><p>';
150 echo wp_kses_post( __( '<strong>Warning:</strong> The `WP_AUTO_UPDATE_CORE` constant is set. WordPress Beta Tester settings will be overridden.', 'wordpress-beta-tester' ) );
151 echo '</p></div>';
152 }
153
154 $version = $this->get_next_version( $preferred->version );
155
156 echo '<div><p>';
157 printf(
158 /* translators: 1: link to backing up database, 2: link to make.wp.org/core, 3: link to beta support forum */
159 wp_kses_post( __( 'By their nature, these releases are unstable and should not be used anyplace where your data is important. So please <a href="%1$s">back up your database</a> before upgrading to a test release. In order to hear about the latest beta releases, your best bet is to watch the <a href="%2$s">development blog</a> and the <a href="%3$s">beta forum</a>.', 'wordpress-beta-tester' ) ),
160 esc_url( _x( 'https://wordpress.org/support/article/wordpress-backups/', 'URL to database backup instructions on HelpHub', 'wordpress-beta-tester' ) ),
161 'https://make.wordpress.org/core/',
162 esc_url( _x( 'https://wordpress.org/support/forum/alphabeta', 'URL to beta support forum', 'wordpress-beta-tester' ) )
163 );
164 echo '</p><p>';
165 printf(
166 /* translators: %s: link to new trac ticket */
167 wp_kses_post( __( 'Thank you for helping test WordPress. Please <a href="%s">report any bugs you find</a>.', 'wordpress-beta-tester' ) ),
168 'https://core.trac.wordpress.org/newticket'
169 );
170 echo '</p><p>';
171 echo wp_kses_post( __( 'By default, your WordPress installation uses the stable update channel. To return to this, please deactivate this plugin and re-install from the <a href="update-core.php">WordPress Updates</a> page.', 'wordpress-beta-tester' ) );
172 echo '</p><p>';
173 printf(
174 /* translators: %s: update version */
175 wp_kses_post( __( 'Currently your site is set to update to %s.', 'wordpress-beta-tester' ) ),
176 '<strong>' . esc_attr( $version ) . '</strong>'
177 );
178 echo '</p></div>';
179 }
180
181 /**
182 * Create channel settings radio button options.
183 *
184 * @return void
185 */
186 public function channel_radio_group() {
187 $next_versions = $this->calculate_next_versions();
188 ?>
189 <fieldset>
190 <tr>
191 <th><label><?php echo esc_html( __( 'Save after switching', 'wordpress-beta-tester' ) ); ?></label></th>
192 <td></td>
193 </tr>
194 </fieldset>
195 <fieldset>
196 <tr>
197 <th><label><input name="wp-beta-tester" id="update-stream-point-nightlies" type="radio" value="branch-development" class="tog" <?php checked( 'branch-development', self::$options['channel'] ); ?> />
198 <?php esc_html_e( 'Point release', 'wordpress-beta-tester' ); ?>
199 </label></th>
200 <td>
201 <?php
202 printf(
203 /* translators: %s: Current WordPress version base, eg 5.5 */
204 esc_html__( 'This contains the work that is occurring on a branch in preparation for a %s point release. This should also be fairly stable but will be available before the branch is ready for release.', 'wordpress-beta-tester' ),
205 esc_attr( $next_versions['point'] )
206 );
207 ?>
208 </td>
209 </tr>
210 <tr>
211 <th><label><input name="wp-beta-tester" id="update-stream-bleeding-nightlies" type="radio" value="development" class="tog" <?php checked( 'development', self::$options['channel'] ); ?> />
212 <?php esc_html_e( 'Bleeding edge', 'wordpress-beta-tester' ); ?>
213 </label></th>
214 <td><?php echo wp_kses_post( __( 'This is the bleeding edge development code from `trunk` which may be unstable at times. <em>Only use this if you really know what you are doing</em>.', 'wordpress-beta-tester' ) ); ?></td>
215 </tr>
216 </fieldset>
217 <?php
218 }
219
220 /**
221 * Create stream settings radio button options.
222 *
223 * @return void
224 */
225 public function stream_radio_group() {
226 ?>
227 <fieldset>
228 <tr>
229 <th><label><input name="wp-beta-tester-beta-rc" id="update-stream-beta" type="radio" value="" class="tog" <?php checked( false, self::$options['stream-option'] ); ?> />
230 <?php esc_html_e( 'Nightlies', 'wordpress-beta-tester' ); ?>
231 </label></th>
232 <td><?php esc_html_e( 'Latest daily updates.', 'wordpress-beta-tester' ); ?></td>
233 </tr>
234
235 <tr class="bleeding-edge-stream">
236 <th><label><input name="wp-beta-tester-beta-rc" id="update-stream-beta" type="radio" value="beta" class="tog" <?php checked( 'beta', self::$options['stream-option'] ); ?> />
237 <?php esc_html_e( 'Beta/RC Only', 'wordpress-beta-tester' ); ?>
238 </label></th>
239 <td><?php esc_html_e( 'This is for the Beta/RC releases only of the selected channel.', 'wordpress-beta-tester' ); ?></td>
240 </tr>
241 <tr class="bleeding-edge-stream">
242 <th><label><input name="wp-beta-tester-beta-rc" id="update-stream-rc" type="radio" value="rc" class="tog" <?php checked( 'rc', self::$options['stream-option'] ); ?> />
243 <?php esc_html_e( 'Release Candidates Only', 'wordpress-beta-tester' ); ?>
244 </label></th>
245 <td><?php esc_html_e( 'This is for the Release Candidate releases only of the selected channel.', 'wordpress-beta-tester' ); ?></td>
246 </tr>
247
248 <?php if ( false && 'branch-development' === self::$options['channel'] ) : ?>
249 <tr>
250 <th><label><input name="wp-beta-tester-beta-rc" id="update-stream-beta" type="radio" value="branch-beta" class="tog" <?php checked( 'branch-beta', self::$options['stream-option'] ); ?> />
251 <?php esc_html_e( 'Beta/RC Only', 'wordpress-beta-tester' ); ?>
252 </label></th>
253 <td><?php esc_html_e( 'This is for the Beta/RC releases only of the selected channel.', 'wordpress-beta-tester' ); ?></td>
254 </tr>
255 <tr>
256 <th><label><input name="wp-beta-tester-beta-rc" id="update-stream-rc" type="radio" value="branch-rc" class="tog" <?php checked( 'branch-rc', self::$options['stream-option'] ); ?> />
257 <?php esc_html_e( 'Release Candidates Only', 'wordpress-beta-tester' ); ?>
258 </label></th>
259 <td><?php esc_html_e( 'This is for the Release Candidate releases only of the selected channel.', 'wordpress-beta-tester' ); ?></td>
260 </tr>
261 <?php endif; ?>
262 </fieldset>
263 <?php
264 }
265
266 /**
267 * Create core settings page.
268 *
269 * @param array $tab Settings tab.
270 * @param string $action Settings form action.
271 * @return void
272 */
273 public function add_admin_page( $tab, $action ) {
274 ?>
275 <div>
276 <?php if ( 'wp_beta_tester_core' === $tab ) : ?>
277 <form method="post" action="<?php echo esc_attr( $action ); ?>">
278 <?php settings_fields( 'wp_beta_tester_core' ); ?>
279 <?php do_settings_sections( 'wp_beta_tester_core' ); ?>
280 <?php submit_button(); ?>
281 </form>
282 <?php endif; ?>
283 </div>
284 <script>
285 jQuery( document ).ready( function( $ ){
286 $( 'tr.wpbt-settings-title th' ).attr( 'colspan', 2 );
287 let $bleedingEdgeStream = $( '.bleeding-edge-stream' );
288
289 <?php if ( 'development' !== self::$options['channel'] ) : // Time to do our basic JS magic :). ?>
290 $bleedingEdgeStream.hide();
291 <?php endif; ?>
292
293 $( document ).on( 'change', 'input[name="wp-beta-tester"]', function() {
294 if ( $( '#update-stream-bleeding-nightlies' ).is( ":checked" ) ) {
295 $bleedingEdgeStream.show();
296 } else {
297 $bleedingEdgeStream.hide();
298 }
299 });
300 });
301 </script>
302 <?php
303 }
304
305 /**
306 * Get the next version(s) the site will be updated to.
307 *
308 * @since 2.2.0
309 *
310 * @param string $preferred_version The preferred version.
311 * @return string
312 */
313 public function get_next_version( $preferred_version ) {
314 $beta_rc = ! empty( self::$options['stream-option'] );
315 $next_version = $this->calculate_next_versions();
316
317 // Try to set actual next beta/RC.
318 if ( ( isset( $next_version['beta'] ) && version_compare( $next_version['preferred'], $next_version['beta'], '<' ) )
319 || ( isset( $next_version['rc'] ) && version_compare( $next_version['preferred'], $next_version['rc'], '<' ) )
320 ) {
321 unset( $next_version['preferred'] );
322 } else {
323 unset( $next_version['beta'] );
324 }
325
326 // Remove preferred version if it is the same as the next version to avoid confusion.
327 if ( version_compare( $preferred_version, $next_version['release'], '==' ) ) {
328 unset( $next_version['preferred'] );
329 }
330
331 // Site is not on a beta/RC stream so use the preferred version.
332 if ( ! $beta_rc && ! empty( $next_version ) ) {
333 /* translators: %s: version number */
334 return sprintf( __( 'version %s', 'wordpress-beta-tester' ), $preferred_version );
335 }
336
337 if ( 1 === count( $next_version ) ) {
338 $next_version = array_shift( $next_version );
339 } elseif ( empty( $next_version ) ) {
340 $next_version = __( 'next development version', 'wordpress-beta-tester' );
341 } else {
342 // show all versions that may come next.
343 add_filter( 'wp_sprintf_l', array( $this, 'wpbt_sprintf_or' ) );
344 /* translators: %l: next version numbers */
345 $next_version = wp_sprintf( __( 'version %l, whichever is released first', 'wordpress-beta-tester' ), $next_version );
346 remove_filter( 'wp_sprintf_l', array( $this, 'wpbt_sprintf_or' ) );
347 }
348
349 return $next_version;
350 }
351
352 /**
353 * Calculate next versions.
354 *
355 * @since 3.0.0
356 * @return array $next_versions
357 */
358 public function calculate_next_versions() {
359 $wp_version = get_bloginfo( 'version' );
360 $exploded_version = explode( '-', $wp_version );
361 $current_release = $this->wp_beta_tester->get_current_wp_release();
362 $next_release = array_map( 'intval', explode( '.', $current_release ) );
363 $is_development_version = preg_match( '/alpha|beta|RC/', $wp_version );
364 $preferred = $this->wp_beta_tester->get_preferred_from_update_core();
365
366 // User on a current release.
367 if ( ! $is_development_version ) {
368 unset( $next_release[2] );
369 $next_release[1] = $next_release[1] + 1;
370
371 // x.10 moves to (x+1).0 as core doesn't follow semver.
372 if ( 10 === $next_release[1] ) {
373 $next_release[0] = $next_release[0] + 1;
374 $next_release[1] = 0;
375 }
376 $next_release = implode( '.', $next_release );
377 $exploded_version[0] = $next_release;
378 $exploded_version[1] = '';
379 }
380
381 // Set base version for development channel if necessary.
382 $current_exploded = array_map( 'intval', explode( '.', $exploded_version[0] ) );
383
384 if ( 'development' === self::$options['channel'] && isset( $current_exploded[2] ) ) {
385 $current_exploded[1] = ++$current_exploded[1];
386 unset( $current_exploded[2] );
387 $exploded_version[0] = implode( '.', $current_exploded );
388 $exploded_version[1] = 'alpha';
389 }
390
391 preg_match( '/beta(\d+)/', $exploded_version[1], $current_beta );
392 preg_match( '/RC(\d+)/', $exploded_version[1], $current_rc );
393 $next_beta = ! empty( $current_beta ) ? $current_beta[1] + 1 : 1;
394 $next_rc = ! empty( $current_rc ) ? $current_rc[1] + 1 : 1;
395
396 // Make next point release.
397 $next_point = array_map( 'intval', explode( '.', $current_release ) );
398 $next_point[2] = isset( $next_point[2] ) ? ++$next_point[2] : 1;
399 $next_point = implode( '.', $next_point );
400 $next_point = 'development' === self::$options['channel'] && version_compare( $current_release, $wp_version, '>' ) ? $current_release : $next_point;
401
402 // Set base version for branch-development channel.
403 if ( 'branch-development' === self::$options['channel'] ) {
404 $exploded_version = (array) $next_point;
405 }
406
407 $next_versions = array(
408 'point' => $next_point,
409 'beta' => $exploded_version[0] . '-beta' . $next_beta,
410 'rc' => $exploded_version[0] . '-RC' . $next_rc,
411 'preferred' => isset( $preferred->version ) ? $preferred->version : 0,
412 'release' => $exploded_version[0],
413 );
414
415 if ( ! $next_versions['beta'] || 'rc' === self::$options['stream-option'] || 1 < $next_rc ) {
416 unset( $next_versions['beta'] );
417 }
418
419 return $next_versions;
420 }
421
422 /**
423 * Change the delimiters used by wp_sprintf_l().
424 *
425 * Placeholders (%s) are included to assist translators and then
426 * removed before the array of strings reaches the filter.
427 *
428 * Please note: Ampersands and entities should be avoided here.
429 *
430 * @since 2.2.1
431 *
432 * @param array $delimiters An array of translated delimiters.
433 */
434 public function wpbt_sprintf_or( $delimiters ) {
435 $delimiters = array(
436 /* translators: Used to join items in a list with more than 2 items. */
437 'between' => sprintf( __( '%1$s, %2$s', 'wordpress-beta-tester' ), '', '' ),
438 /* translators: Used to join last two items in a list with more than 2 times. */
439 'between_last_two' => sprintf( __( '%1$s, or %2$s', 'wordpress-beta-tester' ), '', '' ),
440 /* translators: Used to join items in a list with only 2 items. */
441 'between_only_two' => sprintf( __( '%1$s or %2$s', 'wordpress-beta-tester' ), '', '' ),
442 );
443
444 return $delimiters;
445 }
446
447 /**
448 * Migrate stream during channel switch.
449 *
450 * @param array $options Array of channel and stream options.
451 *
452 * @return array
453 */
454 private function channel_settings_migrator( $options ) {
455 if ( isset( $options['channel'], $options['stream-option'] ) ) {
456 switch ( $options['channel'] ) {
457 case 'development':
458 if ( 'branch-beta' === $options['stream-option'] ) {
459 $options['stream-option'] = 'beta';
460 } elseif ( 'branch-rc' === $options['stream-option'] ) {
461 $options['stream-option'] = 'rc';
462 }
463 break;
464 case 'branch-development':
465 if ( 'beta' === $options['stream-option'] ) {
466 $options['stream-option'] = 'branch-beta';
467 } elseif ( 'rc' === $options['stream-option'] ) {
468 $options['stream-option'] = 'branch-rc';
469 }
470 $options['stream-option'] = ''; // Hard set to Nightlies until API updated.
471 break;
472 }
473 }
474
475 return $options;
476 }
477 }
478