Completed
Push — master ( d0212e...d16ebc )
by
unknown
19:29 queued 09:04
created

Admin::show_branch()   B

Complexity

Conditions 9
Paths 33

Size

Total Lines 57

Duplication

Lines 6
Ratio 10.53 %

Importance

Changes 0
Metric Value
cc 9
nc 33
nop 5
dl 6
loc 57
rs 7.3826
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Handles the Jetpack Admin functions.
4
 *
5
 * @package automattic/jetpack-beta
6
 */
7
8
namespace Automattic\JetpackBeta;
9
10
use Jetpack;
11
use WPCom_Markdown;
12
13
/**
14
 * Handles the Jetpack Beta plugin Admin functions.
15
 */
16
class Admin {
17
18
	/** Initialize admin hooks. */
19
	public static function init() {
20
		add_action( 'admin_menu', array( self::class, 'add_actions' ), 998 );
21
		add_action( 'network_admin_menu', array( self::class, 'add_actions' ), 998 );
22
		add_action( 'admin_notices', array( self::class, 'render_banner' ) );
23
	}
24
25
	/** Attach hooks common to all Jetpack admin pages. */
26
	public static function add_actions() {
27
		$hook = self::get_page_hook();
28
		add_action( "load-$hook", array( self::class, 'admin_page_load' ) );
29
		add_action( "admin_print_styles-$hook", array( self::class, 'admin_styles' ) );
30
		add_action( "admin_print_scripts-$hook", array( self::class, 'admin_scripts' ) );
31
		add_filter( 'plugin_action_links_' . JPBETA__PLUGIN_FOLDER . '/jetpack-beta.php', array( self::class, 'admin_plugin_settings_link' ) );
32
	}
33
34
	/** Get page hook */
35
	public static function get_page_hook() {
36
		if ( Utils::is_network_active() && ! is_network_admin() ) {
37
			return;
38
		}
39
		if ( class_exists( Jetpack::class ) ) {
40
			return add_submenu_page(
41
				'jetpack',
42
				'Jetpack Beta',
43
				'Jetpack Beta',
44
				'update_plugins',
45
				'jetpack-beta',
46
				array( self::class, 'render' )
47
			);
48
		}
49
50
		return add_menu_page(
51
			'Jetpack Beta',
52
			'Jetpack Beta',
53
			'update_plugins',
54
			'jetpack-beta',
55
			array( self::class, 'render' )
56
		);
57
	}
58
59
	/** Always grab and render the latest version. */
60
	public static function render() {
61
		Utils::get_beta_manifest( true );
62
		require_once JPBETA__PLUGIN_DIR . 'src/admin/main.php';
63
	}
64
65
	/** Return the beta plugin's settings link. */
66
	public static function settings_link() {
67
		return admin_url( 'admin.php?page=jetpack-beta' );
68
	}
69
70
	/**
71
	 * Create the beta plugin's settings link.
72
	 *
73
	 * @param array $links the link being clicked.
74
	 */
75
	public static function admin_plugin_settings_link( $links ) {
76
		$settings_link = '<a href="' . esc_url( self::settings_link() ) . '">' . __( 'Settings', 'jetpack-beta' ) . '</a>';
77
		array_unshift( $links, $settings_link );
78
		return $links;
79
	}
80
81
	/** Handles Beta plugin admin page. */
82
	public static function admin_page_load() {
83
		if ( ! isset( $_GET['_nonce'] ) ) {
84
			return;
85
		}
86
		// Install and activate Jetpack Version.
87 View Code Duplication
		if ( wp_verify_nonce( $_GET['_nonce'], 'activate_branch' ) && isset( $_GET['activate-branch'] ) && isset( $_GET['section'] ) ) {
88
			$branch  = esc_html( $_GET['activate-branch'] );
89
			$section = esc_html( $_GET['section'] );
90
91
			Utils::install_and_activate( $branch, $section );
92
		}
93
94
		// Update to the latest version.
95 View Code Duplication
		if ( wp_verify_nonce( $_GET['_nonce'], 'update_branch' ) && isset( $_GET['update-branch'] ) && isset( $_GET['section'] ) ) {
96
			$branch  = esc_html( $_GET['update-branch'] );
97
			$section = esc_html( $_GET['section'] );
98
99
			Utils::update_plugin( $branch, $section );
100
		}
101
102
		// Toggle autoupdates.
103
		if ( self::is_toggle_action( 'autoupdates' ) ) {
104
			$autoupdate = (bool) Utils::is_set_to_autoupdate();
105
			update_option( 'jp_beta_autoupdate', (int) ! $autoupdate );
106
107
			if ( Utils::is_set_to_autoupdate() ) {
108
				Hooks::maybe_schedule_autoupdate();
109
			}
110
		}
111
112
		// Toggle email notifications.
113
		if ( self::is_toggle_action( 'email_notifications' ) ) {
114
			$enable_email_notifications = (bool) Utils::is_set_to_email_notifications();
115
			update_option( 'jp_beta_email_notifications', (int) ! $enable_email_notifications );
116
		}
117
		wp_safe_redirect( Utils::admin_url() );
118
119
		exit();
120
	}
121
122
	/**
123
	 * Checks if autoupdates and email notifications are toggled.
124
	 *
125
	 * @param string $option - Which option is being toggled.
126
	 */
127
	public static function is_toggle_action( $option ) {
128
		return (
129
			isset( $_GET['_nonce'] ) &&
130
			wp_verify_nonce( $_GET['_nonce'], 'enable_' . $option ) &&
131
			isset( $_GET['_action'] ) &&
132
			'toggle_enable_' . $option === $_GET['_action']
133
		);
134
	}
135
136
	/** Render beta plugin banner */
137
	public static function render_banner() {
138
		global $current_screen;
139
140
		if ( 'plugins' !== $current_screen->base ) {
141
			return;
142
		}
143
144
		if ( Utils::get_option() ) {
145
			return;
146
		}
147
148
		self::start_notice();
149
	}
150
151
	/** Enqueue admin styling from admin.css */
152
	public static function admin_styles() {
153
		wp_enqueue_style( 'jetpack-beta-admin', plugins_url( 'admin/admin.css', __FILE__ ), array(), JPBETA_VERSION );
154
	}
155
156
	/** Enqueue scripts from admin.js */
157
	public static function admin_scripts() {
158
		wp_enqueue_script( 'jetpack-admin-js', plugins_url( 'admin/admin.js', __FILE__ ), array(), JPBETA_VERSION, true );
159
		wp_localize_script(
160
			'jetpack-admin-js',
161
			'JetpackBeta',
162
			array(
163
				'activate'   => __( 'Activate', 'jetpack-beta' ),
164
				'activating' => __( 'Activating...', 'jetpack-beta' ),
165
				'updating'   => __( 'Updating...', 'jetpack-beta' ),
166
				'leaving'    => __( 'Don\'t go Plugin is still installing!', 'jetpack-beta' ),
167
			)
168
		);
169
	}
170
171
	/** Determine what we're going to test (pr, master, rc) */
172
	public static function to_test_content() {
173
		list( $branch, $section ) = Utils::get_branch_and_section();
174
		switch ( $section ) {
175
			case 'pr':
176
				return self::to_test_pr_content( $branch );
177
			case 'rc':
178
				return self::to_test_file_content();
179
			default: // Master "bleeding edge" or latest stable.
180
				return self::to_test_general_rules_content();
181
182
		}
183
	}
184
185
	/**
186
	 * General rules and recommendations for new Beta Testers.
187
	 * Displayed when no specific branch is picked.
188
	 *
189
	 * @since 2.5.0
190
	 */
191 View Code Duplication
	public static function to_test_general_rules_content() {
192
		$test_rules = JPBETA__PLUGIN_DIR . '/docs/testing/testing-tips.md';
193
		if ( ! file_exists( $test_rules ) ) {
194
			return;
195
		}
196
		WP_Filesystem();
197
		global $wp_filesystem;
198
		$content = $wp_filesystem->get_contents( $test_rules );
199
		return self::render_markdown( $content );
200
	}
201
202
	/** Return testing instructions for release candidate branch */
203 View Code Duplication
	public static function to_test_file_content() {
204
		$test_file = WP_PLUGIN_DIR . '/' . Utils::get_plugin_slug() . '/to-test.md';
205
		if ( ! file_exists( $test_file ) ) {
206
			return;
207
		}
208
		WP_Filesystem();
209
		global $wp_filesystem;
210
		$content = $wp_filesystem->get_contents( $test_file );
211
		return self::render_markdown( $content );
212
	}
213
214
	/**
215
	 * Get PR information for what we want to test
216
	 *
217
	 * @param string $branch_key The branch we're switching to.
218
	 * */
219
	public static function to_test_pr_content( $branch_key ) {
220
		$manifest = Utils::get_beta_manifest();
221
		$pr       = isset( $manifest->pr->{$branch_key}->pr ) ? $manifest->pr->{$branch_key}->pr : null;
222
223
		if ( ! $pr ) {
224
			return null;
225
		}
226
		$github_info = Utils::get_remote_data( JETPACK_GITHUB_API_URL . 'pulls/' . $pr, 'github_' . $pr );
227
228
		return self::render_markdown( $github_info->body );
229
	}
230
231
	/**
232
	 * Rendering markdown for testing instructions
233
	 *
234
	 * @param string $content - Content from testing instructions for the branch we're testing.
235
	 */
236
	public static function render_markdown( $content ) {
237
238
		add_filter( 'jetpack_beta_test_content', 'wptexturize' );
239
		add_filter( 'jetpack_beta_test_content', 'convert_smilies' );
240
		add_filter( 'jetpack_beta_test_content', 'convert_chars' );
241
		add_filter( 'jetpack_beta_test_content', 'wpautop' );
242
		add_filter( 'jetpack_beta_test_content', 'shortcode_unautop' );
243
		add_filter( 'jetpack_beta_test_content', 'prepend_attachment' );
244
245
		if ( ! function_exists( 'jetpack_require_lib' ) ) {
246
			return apply_filters( 'jetpack_beta_test_content', $content );
247
		}
248
249
		jetpack_require_lib( 'markdown' );
250
		if ( ! class_exists( WPCom_Markdown::class ) ) {
251
			if ( ! include_once WP_PLUGIN_DIR . '/' . Utils::get_plugin_slug() . '/modules/markdown/easy-markdown.php' ) {
252
				include_once WP_PLUGIN_DIR . '/jetpack/modules/markdown/easy-markdown.php';
253
			};
254
		}
255
256
		if ( ! class_exists( WPCom_Markdown::class ) ) {
257
			return apply_filters( 'jetpack_beta_test_content', $content );
258
		}
259
		$rendered_html = WPCom_Markdown::get_instance()->transform(
260
			$content,
261
			array(
262
				'id'      => false,
263
				'unslash' => false,
264
			)
265
		);
266
267
		// Lets convert #hash numbers into links to issues.
268
		$rendered_html = preg_replace( '/\#([0-9]+)/', '<a href="https://github.com/Automattic/jetpack/issues/$1">#$1</a>', $rendered_html );
269
270
		$rendered_html = apply_filters( 'jetpack_beta_test_content', $rendered_html );
271
272
		return $rendered_html;
273
	}
274
275
	/** Display the body of the start notice on the Jetpack Beta admin page */
276
	public static function start_notice() {
277
		global $current_screen;
278
279
		$is_notice = ( 'plugins' === $current_screen->base ? true : false );
280
		?>
281
		<style type="text/css">
282
			#jetpack-beta-tester__start {
283
				background: #FFF;
284
				padding: 20px;
285
				margin-top:20px;
286
				box-shadow: 0 0 0 1px rgba(200, 215, 225, 0.5), 0 1px 2px #e9eff3;
287
				position: relative;
288
			}
289
			#jetpack-beta-tester__start.updated {
290
				border-left: 3px solid #8CC258;
291
			}
292
			#jetpack-beta-tester__start h1 {
293
				font-weight: 400;
294
				margin: 0;
295
				font-size: 20px;
296
			}
297
			#jetpack-beta-tester__start p {
298
				margin-bottom:1em;
299
			}
300
		</style>
301
		<div id="jetpack-beta-tester__start" class="dops-card <?php echo ( $is_notice ? 'updated' : '' ); ?> ">
302
			<h1><?php esc_html_e( 'Welcome to Jetpack Beta Tester', 'jetpack-beta' ); ?></h1>
303
			<p><?php esc_html_e( 'Thank you for helping to test Jetpack!  We appreciate your time and effort.', 'jetpack-beta' ); ?></p>
304
			<p>
305
			<?php
306
			echo wp_kses_post(
307
				__(
308
					'When you select a Jetpack branch to test, Jetpack Beta Tester will install and activate it on your behalf and keep it up to date.
309
					When you are finished testing, you can switch back to the current version of Jetpack by selecting <em>Latest Stable</em>.',
310
					'jetpack-beta'
311
				)
312
			);
313
			?>
314
				</p>
315
			<p>
316
			<?php
317
			echo wp_kses_post(
318
				sprintf(
319
					// Translators: link to Jetack master testing doc in Github.
320
					__( 'Not sure where to start?  If you select <em>Bleeding Edge</em>, you\'ll get <a href="%1$s">all the cool new features</a> we\'re planning to ship in our next release.', 'jetpack-beta' ),
321
					esc_url( 'https://github.com/Automattic/jetpack/blob/master/to-test.md' )
322
				)
323
			);
324
			?>
325
			</p>
326
			<?php if ( $is_notice ) { ?>
327
			<a href="<?php echo esc_url( Utils::admin_url() ); ?>"><?php esc_html_e( 'Let\'s get testing!', 'jetpack-beta' ); ?></a>
328
			<?php } ?>
329
330
		</div>
331
		<?php
332
	}
333
334
	/**
335
	 * Handles branch selection on beta plugin's admin page
336
	 *
337
	 * @param string $header Title of the branch.
338
	 * @param string $branch_key Specifies which branch.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $branch not be object|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
339
	 * @param object $branch Contains branch data (title, update date, download link, commit, etc).
340
	 * @param string $section The kind of branch we're switching to (stable, rc, master, pr).
0 ignored issues
show
Documentation introduced by
Should the type for parameter $section not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
341
	 * @param bool   $is_last Last branch in the list.
342
	 */
343
	public static function show_branch( $header, $branch_key, $branch = null, $section = null, $is_last = false ) {
344
		if ( ! is_object( $branch ) ) {
345
			$manifest = Utils::get_beta_manifest();
346
			if ( empty( $manifest->{$section} ) ) {
347
				return;
348
			}
349
			$branch = $manifest->{$section};
350
		}
351
352
		$is_compact = $is_last ? '' : 'is-compact';
353
		$more_info  = '';
354
		$pr         = '';
355
		if ( isset( $branch->pr ) && is_int( $branch->pr ) ) {
356
			$pr = sprintf( 'data-pr="%s"', esc_attr( $branch->pr ) );
357
			// translators: Translates the `More info` link.
358
			$more_info = sprintf( __( '<a target="_blank" rel="external noopener noreferrer" href="%1$s">more info #%2$s</a> - ', 'jetpack-beta' ), Utils::get_url( $branch_key, $section ), $branch->pr );
359
		}
360
361
		$update_time = ( isset( $branch->update_date )
362
			// translators: %s is how long ago the branch was updated.
363
			? sprintf( __( 'last updated %s ago', 'jetpack-beta' ), human_time_diff( strtotime( $branch->update_date ) ) )
364
			: ''
365
		);
366
367
		$branch_class                             = 'branch-card';
368
		list( $current_branch, $current_section ) = Utils::get_branch_and_section();
369 View Code Duplication
		if ( $current_branch === $branch_key && $current_section === $section ) {
370
			$action       = __( 'Active', 'jetpack-beta' );
371
			$branch_class = 'branch-card-active';
372
		} else {
373
			$action = self::activate_button( $branch_key, $section );
374
		}
375
		$header = str_replace( '-', ' ', $header );
376
		$header = str_replace( '_', ' / ', $header );
377
		?>
378
		<div <?php echo esc_attr( $pr ); ?> " class="dops-foldable-card <?php echo esc_attr( $branch_class ); ?> has-expanded-summary dops-card <?php echo esc_attr( $is_compact ); ?>">
379
			<div class="dops-foldable-card__header has-border" >
380
				<span class="dops-foldable-card__main">
381
					<div class="dops-foldable-card__header-text">
382
						<div class="dops-foldable-card__header-text branch-card-header"><?php echo esc_html( $header ); ?></div>
383
						<div class="dops-foldable-card__subheader">
384
						<?php
385
							echo wp_kses_post( $more_info );
386
							echo wp_kses_post( $update_time );
387
						?>
388
						</div>
389
					</div>
390
				</span>
391
				<span class="dops-foldable-card__secondary">
392
					<span class="dops-foldable-card__summary">
393
						<?php echo wp_kses_post( $action ); ?>
394
					</span>
395
				</span>
396
			</div>
397
		</div>
398
		<?php
399
	}
400
401
	/**
402
	 * Handles list of available Jetpack tags to select specific Jetpack version number.
403
	 *
404
	 * @param string $header Title of tag.
405
	 * @param string $tag Jetpack tag (for selecting a specific version of Jetpack).
406
	 * @param string $url Download link for Jetpack version.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $url not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
407
	 * @param string $section The kind of version we're switching to (in this case 'tags').
0 ignored issues
show
Documentation introduced by
Should the type for parameter $section not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
408
	 * @param bool   $is_last last version in the list.
409
	 */
410
	public static function show_tag( $header, $tag, $url = null, $section = null, $is_last = false ) {
411
		$is_compact = $is_last ? '' : 'is-compact';
412
		if ( isset( $url ) ) {
413
			$data_tag = sprintf( 'data-tag="%s"', $tag );
414
		}
415
416
		$class_name                               = 'tag-card';
417
		list( $current_branch, $current_section ) = Utils::get_branch_and_section();
418 View Code Duplication
		if ( $current_branch === $tag && $current_section === $section ) {
419
			$action     = __( 'Active', 'jetpack-beta' );
420
			$class_name = 'tag-card-active';
421
		} else {
422
			$action = self::activate_button( $tag, $section );
423
		}
424
425
		$header = str_replace( '-', ' ', $header );
426
		$header = str_replace( '_', ' / ', $header );
427
		?>
428
		<div <?php echo wp_kses_post( $data_tag ); ?> " class="dops-foldable-card <?php echo esc_attr( $class_name ); ?> has-expanded-summary dops-card <?php echo esc_attr( $is_compact ); ?>">
0 ignored issues
show
Bug introduced by
The variable $data_tag does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
429
			<div class="dops-foldable-card__header has-border">
430
				<span class="dops-foldable-card__main">
431
					<div class="dops-foldable-card__header-text">
432
						<div class="dops-foldable-card__header-text tag-card-header">Jetpack <?php echo esc_html( $header ); ?></div>
433
						<div class="dops-foldable-card__subheader">
434
						<?php
435
						sprintf(
436
							// Translators: Which release is being selected.
437
							__( 'Public release (%1$s) <a href="https://plugins.trac.wordpress.org/browser/jetpack/tags/%2$s" target="_blank" rel="">available on WordPress.org</a>', 'jetpack-beta' ),
438
							esc_html( $tag ),
439
							esc_attr( $tag )
440
						);
441
						?>
442
						</div>
443
					</div>
444
				</span>
445
				<span class="dops-foldable-card__secondary">
446
					<span class="dops-foldable-card__summary">
447
						<?php echo wp_kses_post( $action ); ?>
448
					</span>
449
				</span>
450
			</div>
451
		</div>
452
		<?php
453
	}
454
455
	/**
456
	 * Handles the activation buttons.
457
	 *
458
	 * @param object $branch specifies which branch.
459
	 * @param string $section The kind of branch we're switching to (stable, rc, master, pr).
460
	 */
461
	public static function activate_button( $branch, $section ) {
462
		if ( is_object( $section ) && 'master' === $branch ) {
463
			$section = 'master';
464
		}
465
466
		if ( is_object( $section ) && 'rc' === $branch ) {
467
			$section = 'rc';
468
		}
469
		$query = array(
470
			'page'            => 'jetpack-beta',
471
			'activate-branch' => $branch,
472
			'section'         => $section,
473
			'_nonce'          => wp_create_nonce( 'activate_branch' ),
474
		);
475
		$url   = Utils::admin_url( '?' . build_query( $query ) );
476
477
		return sprintf(
478
			'<a href="%1$s" class="is-primary jp-form-button activate-branch dops-button is-compact jptracks" data-jptracks-name="%2$s" data-jptracks-prop="%3$s">%4$s</a>',
479
			esc_url( $url ),
480
			'jetpack_beta_activate_branch',
481
			esc_attr( $branch ),
482
			esc_html__( 'Activate', 'jetpack-beta' )
483
		);
484
	}
485
486
	/**
487
	 * Display the branch header
488
	 *
489
	 * @param string $title - The title of the branch.
490
	 */
491
	public static function header( $title ) {
492
		echo '<header><h2 class="jp-jetpack-connect__container-subtitle">' . esc_html( $title ) . '</h2></header>';
493
	}
494
495
	/**
496
	 * Display the branch list
497
	 *
498
	 * @param string $section - The kind of branch we're switching to (stable, rc, master, pr).
499
	 * @param string $title - The title of the branch.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $title not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
500
	 */
501 View Code Duplication
	public static function show_branches( $section, $title = null ) {
502
		if ( $title ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $title of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
503
			$title .= ': ';
504
		}
505
		echo '<div id="section-' . esc_attr( $section ) . '">';
506
507
		$manifest = Utils::get_beta_manifest();
508
		$count    = 0;
509
		if ( empty( $manifest->{$section} ) ) {
510
			return;
511
		}
512
		$branches  = (array) $manifest->{$section};
513
		$count_all = count( $branches );
514
515
		foreach ( $branches as $branch_name => $branch ) {
516
			$count ++;
517
			$is_last = $count_all === $count ? true : false;
518
			self::show_branch( $title . $branch_name, $branch_name, $branch, $section, $is_last );
519
		}
520
		echo '</div>';
521
	}
522
523
	/**
524
	 * Show list of available Jetpack tags to select specific Jetpack version number.
525
	 *
526
	 * @param string $section - The kind of version we're switching to (in this case 'tags').
527
	 * @param string $title - The name of the Jetpack tag.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $title not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
528
	 */
529 View Code Duplication
	public static function show_tags( $section, $title = null ) {
530
		if ( $title ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $title of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
531
			$title .= ': ';
532
		}
533
		echo '<div id="section-' . esc_attr( $section ) . '">';
534
535
		$manifest = Utils::get_org_data();
536
		$count    = 0;
537
		if ( empty( $manifest->versions ) ) {
538
			return;
539
		}
540
		$tags      = array_reverse( (array) $manifest->versions );
541
		$count_all = count( $tags );
542
543
		foreach ( $tags as $tag => $url ) {
544
			$count ++;
545
			$is_last = $count_all === $count ? true : false;
546
			self::show_tag( $title . $tag, $tag, $url, $section, $is_last );
547
		}
548
		echo '</div>';
549
	}
550
551
	/** Display the stable branch */
552
	public static function show_stable_branch() {
553
		$org_data = Utils::get_org_data();
554
555
		self::show_branch(
556
			__( 'Latest Stable', 'jetpack-beta' ),
557
			'stable',
558
			(object) array(
559
				'branch'      => 'stable',
560
				'update_date' => $org_data->last_updated,
561
			),
562
			'stable'
563
		);
564
	}
565
566
	/** Show search bar for PRs */
567 View Code Duplication
	public static function show_search_prs() {
568
		$manifest = Utils::get_beta_manifest();
569
		if ( empty( $manifest->pr ) ) {
570
			return;
571
		}
572
		?>
573
		<div class="dops-navigation">
574
			<div class="dops-section-nav has-pinned-items">
575
				<div class="dops-section-nav__panel">
576
					<div class="is-pinned is-open dops-search" role="search">
577
						<div aria-controls="search-component" aria-label="<?php esc_attr_e( 'Open Search', 'jetpack-beta' ); ?>" tabindex="-1">
578
							<svg class="gridicon gridicons-search dops-search-open__icon" height="24"
579
								viewbox="0 0 24 24" width="24">
580
								<g>
581
									<path d="M21 19l-5.154-5.154C16.574 12.742 17 11.42 17 10c0-3.866-3.134-7-7-7s-7 3.134-7 7 3.134 7 7 7c1.42 0 2.742-.426 3.846-1.154L19 21l2-2zM5 10c0-2.757 2.243-5 5-5s5 2.243 5 5-2.243 5-5 5-5-2.243-5-5z"></path>
582
								</g>
583
							</svg>
584
						</div>
585
						<input aria-hidden="false" class="dops-search__input" id="search-component-prs"
586
							placeholder="<?php esc_attr_e( 'Search for a Jetpack Feature Branch', 'jetpack-beta' ); ?>" role="search" type="search" value="">
587
						<span aria-controls="search-component" id="search-component-prs-close" aria-label="<?php esc_attr_e( 'Close Search', 'jetpack-beta' ); ?>"
588
							tabindex="0">
589
							<svg class="gridicon gridicons-cross dops-search-close__icon" height="24"
590
								viewbox="0 0 24 24" width="24">
591
								<g>
592
									<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"></path>
593
								</g>
594
							</svg>
595
						</span>
596
					</div>
597
				</div>
598
			</div>
599
		</div>
600
		<?php
601
	}
602
603
	/** Show search bar for tags */
604 View Code Duplication
	public static function show_search_org_tags() {
605
		$org_data = Utils::get_org_data();
606
		if ( empty( $org_data->versions ) ) {
607
			return;
608
		}
609
		?>
610
		<div class="dops-navigation">
611
			<div class="dops-section-nav has-pinned-items">
612
				<div class="dops-section-nav__panel">
613
					<div class="is-pinned is-open dops-search" role="search">
614
						<div aria-controls="search-component" aria-label="<?php esc_attr_e( 'Open Search', 'jetpack-beta' ); ?>" tabindex="-1">
615
							<svg class="gridicon gridicons-search dops-search-open__icon" height="24"
616
								viewbox="0 0 24 24" width="24">
617
								<g>
618
									<path d="M21 19l-5.154-5.154C16.574 12.742 17 11.42 17 10c0-3.866-3.134-7-7-7s-7 3.134-7 7 3.134 7 7 7c1.42 0 2.742-.426 3.846-1.154L19 21l2-2zM5 10c0-2.757 2.243-5 5-5s5 2.243 5 5-2.243 5-5 5-5-2.243-5-5z"></path>
619
								</g>
620
							</svg>
621
						</div>
622
						<input aria-hidden="false" class="dops-search__input" id="search-component-tags"
623
							placeholder="<?php esc_attr_e( 'Search for a Jetpack tag', 'jetpack-beta' ); ?>" role="search" type="search" value="">
624
						<span aria-controls="search-component" id="search-component-tags-close" aria-label="<?php esc_attr_e( 'Close Search', 'jetpack-beta' ); ?>"
625
							tabindex="0">
626
							<svg class="gridicon gridicons-cross dops-search-close__icon" height="24"
627
								viewbox="0 0 24 24" width="24">
628
								<g>
629
									<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"></path>
630
								</g>
631
							</svg>
632
						</span>
633
					</div>
634
				</div>
635
			</div>
636
		</div>
637
		<?php
638
	}
639
640
	/** Display autoupdate toggle */
641
	public static function show_toggle_autoupdates() {
642
		$autoupdate = (bool) Utils::is_set_to_autoupdate();
643
		self::show_toggle( __( 'Autoupdates', 'jetpack-beta' ), 'autoupdates', $autoupdate );
644
	}
645
646
	/** Display email notification toggle */
647
	public static function show_toggle_emails() {
648
		if ( ! Utils::is_set_to_autoupdate() || defined( 'JETPACK_BETA_SKIP_EMAIL' ) ) {
649
			return;
650
		}
651
		$email_notification = (bool) Utils::is_set_to_email_notifications();
652
		self::show_toggle( __( 'Email Notifications', 'jetpack-beta' ), 'email_notifications', $email_notification );
653
	}
654
655
	/**
656
	 * Display autoupdate and email notification toggles
657
	 *
658
	 * @param string $name name of toggle.
659
	 * @param string $option Which toggle (autoupdates, email_notification).
660
	 * @param bool   $value If toggle is active or not.
661
	 */
662
	public static function show_toggle( $name, $option, $value ) {
663
		$query = array(
664
			'page'    => 'jetpack-beta',
665
			'_action' => 'toggle_enable_' . $option,
666
			'_nonce'  => wp_create_nonce( 'enable_' . $option ),
667
		);
668
669
		?>
670
		<a
671
			href="<?php echo esc_url( Utils::admin_url( '?' . build_query( $query ) ) ); ?>"
672
			class="form-toggle__label <?php echo ( $value ? 'is-active' : '' ); ?>"
673
			data-jptracks-name="jetpack_beta_toggle_<?php echo esc_attr( $option ); ?>"
674
			data-jptracks-prop="<?php echo absint( ! $value ); ?>"
675
		>
676
			<span class="form-toggle-explanation" ><?php echo esc_html( $name ); ?></span>
677
			<span class="form-toggle__switch" tabindex="0" ></span>
678
			<span class="form-toggle__label-content" ></span>
679
		</a>
680
		<?php
681
	}
682
683
	/** Check if Jetpack and branch versions are up to date */
684
	public static function show_needed_updates() {
685
		$should_update_stable_version = Utils::should_update_stable_version();
686
		$should_update_dev_version    = Utils::should_update_dev_version();
687
		$should_update_dev_to_master  = Utils::should_update_dev_to_master();
688
689
		// Return if there are no updates available.
690
		if ( ! $should_update_stable_version
691
			&& ! $should_update_dev_version
692
			&& ! $should_update_dev_to_master ) {
693
			return;
694
		}
695
696
		?>
697
		<div class="jetpack-beta__wrap jetpack-beta__update-needed">
698
			<h2><?php esc_html_e( 'Some updates are required', 'jetpack-beta' ); ?></h2>
699
		<?php
700
701
		// Stable up to date?
702 View Code Duplication
		if ( $should_update_stable_version ) {
703
			self::update_card(
704
				__( 'Latest Stable', 'jetpack-beta' ),
705
				__( 'Needs an update', 'jetpack-beta' ),
706
				self::update_action_url( 'stable', 'stable' )
707
			);
708
		}
709
		// Jetpack Dev Folder not up to date?
710
		if ( $should_update_dev_version ) {
711
			list( $dev_branch, $dev_section ) = Utils::get_branch_and_section_dev();
712
			self::update_card(
713
				Utils::get_jetpack_plugin_pretty_version( true ),
714
				__( 'Is not running the latest version', 'jetpack-beta' ),
715
				self::update_action_url( $dev_branch, $dev_section )
716
			);
717
		}
718
719 View Code Duplication
		if ( $should_update_dev_to_master ) {
720
			self::update_card(
721
				__( 'Feature Branch was merged', 'jetpack-beta' ),
722
				__( 'Go back to Jetpack\'s Bleeding Edge version.', 'jetpack-beta' ),
723
				self::update_action_url( 'master', 'master' )
724
			);
725
		}
726
		?>
727
		</div>
728
		<?php
729
	}
730
731
	/**
732
	 * Handles card that notifies when there's an update available on a branch.
733
	 *
734
	 * @param string $header - Title of the branch that's ready for update.
735
	 * @param string $sub_header - Detailed information about the update.
736
	 * @param string $url - URL where branch can be updated.
737
	 */
738
	public static function update_card( $header, $sub_header, $url ) {
739
		?>
740
		<div class="dops-foldable-card has-expanded-summary dops-card is-compact">
741
			<div class="dops-foldable-card__header has-border" >
742
				<span class="dops-foldable-card__main">
743
					<div class="dops-foldable-card__header-text">
744
						<div class="dops-foldable-card__header-text branch-card-header"><?php echo esc_html( $header ); ?></div>
745
						<div class="dops-foldable-card__subheader"><?php echo esc_html( $sub_header ); ?></div>
746
					</div>
747
				</span>
748
				<span class="dops-foldable-card__secondary">
749
					<span class="dops-foldable-card__summary">
750
						<a
751
							href="<?php echo esc_url( $url ); ?>"
752
							class="is-primary jp-form-button activate-branch dops-button is-compact"><?php esc_html_e( 'Update', 'jetpack-beta' ); ?></a>
753
					</span>
754
				</span>
755
			</div>
756
		</div>
757
		<?php
758
	}
759
760
	/**
761
	 * Handles update button for branches
762
	 *
763
	 * @param string $branch - Branch that's ready for update.
764
	 * @param string $section - What kind of branch we're updated (master, rc, pr).
765
	 */
766
	public static function update_action_url( $branch, $section ) {
767
		$query = array(
768
			'page'          => 'jetpack-beta',
769
			'update-branch' => $branch,
770
			'section'       => $section,
771
			'_nonce'        => wp_create_nonce( 'update_branch' ),
772
		);
773
774
		return Utils::admin_url( '?' . build_query( $query ) );
775
	}
776
}
777