Completed
Push — update/idc-endpoint-migration ( b3b716...4fc7c1 )
by
unknown
11:31
created

to_test_general_rules_content()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 10
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 10
loc 10
rs 9.9332
c 0
b 0
f 0
1
<?php
2
/**
3
 * Handles the Jetpack Admin functions.
4
 *
5
 * @package automattic/jetpack-beta
6
 */
7
8
/** Class Jetpack_Beta_Admin */
9
class Jetpack_Beta_Admin {
10
11
	/** Initialize admin hooks. */
12
	public static function init() {
13
		add_action( 'admin_menu', array( __CLASS__, 'add_actions' ), 998 );
14
		add_action( 'network_admin_menu', array( __CLASS__, 'add_actions' ), 998 );
15
		add_action( 'admin_notices', array( __CLASS__, 'render_banner' ) );
16
	}
17
18
	/** Attach hooks common to all Jetpack admin pages. */
19
	public static function add_actions() {
20
		$hook = self::get_page_hook();
21
		add_action( "load-$hook", array( __CLASS__, 'admin_page_load' ) );
22
		add_action( "admin_print_styles-$hook", array( __CLASS__, 'admin_styles' ) );
23
		add_action( "admin_print_scripts-$hook", array( __CLASS__, 'admin_scripts' ) );
24
		add_filter( 'plugin_action_links_' . JPBETA__PLUGIN_FOLDER . '/jetpack-beta.php', array( __CLASS__, 'admin_plugin_settings_link' ) );
25
	}
26
27
	/** Get page hook */
28
	public static function get_page_hook() {
29
		if ( Jetpack_Beta::is_network_active() && ! is_network_admin() ) {
30
			return;
31
		}
32
		if ( class_exists( 'Jetpack' ) ) {
33
			return add_submenu_page(
34
				'jetpack',
35
				'Jetpack Beta',
36
				'Jetpack Beta',
37
				'update_plugins',
38
				'jetpack-beta',
39
				array( __CLASS__, 'render' )
40
			);
41
		}
42
43
		return add_menu_page(
44
			'Jetpack Beta',
45
			'Jetpack Beta',
46
			'update_plugins',
47
			'jetpack-beta',
48
			array( __CLASS__, 'render' )
49
		);
50
	}
51
52
	/** Always grab and render the latest version. */
53
	public static function render() {
54
		Jetpack_Beta::get_beta_manifest( true );
55
		require_once JPBETA__PLUGIN_DIR . 'admin/main.php';
56
	}
57
58
	/** Return the beta plugin's settings link. */
59
	public static function settings_link() {
60
		return admin_url( 'admin.php?page=jetpack-beta' );
61
	}
62
63
	/**
64
	 * Create the beta plugin's settings link.
65
	 *
66
	 * @param array $links the link being clicked.
67
	 */
68
	public static function admin_plugin_settings_link( $links ) {
69
		$settings_link = '<a href="' . esc_url( self::settings_link() ) . '">' . __( 'Settings', 'jetpack-beta' ) . '</a>';
70
		array_unshift( $links, $settings_link );
71
		return $links;
72
	}
73
74
	/** Handles Beta plugin admin page. */
75
	public static function admin_page_load() {
76
		if ( ! isset( $_GET['_nonce'] ) ) {
77
			return;
78
		}
79
		// Install and activate Jetpack Version.
80 View Code Duplication
		if ( wp_verify_nonce( $_GET['_nonce'], 'activate_branch' ) && isset( $_GET['activate-branch'] ) && isset( $_GET['section'] ) ) {
81
			$branch  = esc_html( $_GET['activate-branch'] );
82
			$section = esc_html( $_GET['section'] );
83
84
			Jetpack_Beta::install_and_activate( $branch, $section );
85
		}
86
87
		// Update to the latest version.
88 View Code Duplication
		if ( wp_verify_nonce( $_GET['_nonce'], 'update_branch' ) && isset( $_GET['update-branch'] ) && isset( $_GET['section'] ) ) {
89
			$branch  = esc_html( $_GET['update-branch'] );
90
			$section = esc_html( $_GET['section'] );
91
92
			Jetpack_Beta::update_plugin( $branch, $section );
93
		}
94
95
		// Toggle autoupdates.
96
		if ( self::is_toggle_action( 'autoupdates' ) ) {
97
			$autoupdate = (bool) Jetpack_Beta::is_set_to_autoupdate();
98
			update_option( 'jp_beta_autoupdate', (int) ! $autoupdate );
99
100
			if ( Jetpack_Beta::is_set_to_autoupdate() ) {
101
				Jetpack_Beta::maybe_schedule_autoupdate();
102
			}
103
		}
104
105
		// Toggle email notifications.
106
		if ( self::is_toggle_action( 'email_notifications' ) ) {
107
			$enable_email_notifications = (bool) Jetpack_Beta::is_set_to_email_notifications();
108
			update_option( 'jp_beta_email_notifications', (int) ! $enable_email_notifications );
109
		}
110
		wp_safe_redirect( Jetpack_Beta::admin_url() );
111
112
		exit();
113
	}
114
115
	/**
116
	 * Checks if autoupdates and email notifications are toggled.
117
	 *
118
	 * @param string $option - Which option is being toggled.
119
	 */
120
	public static function is_toggle_action( $option ) {
121
		return (
122
			isset( $_GET['_nonce'] ) &&
123
			wp_verify_nonce( $_GET['_nonce'], 'enable_' . $option ) &&
124
			isset( $_GET['_action'] ) &&
125
			'toggle_enable_' . $option === $_GET['_action']
126
		);
127
	}
128
129
	/** Render beta plugin banner */
130
	public static function render_banner() {
131
		global $current_screen;
132
133
		if ( 'plugins' !== $current_screen->base ) {
134
			return;
135
		}
136
137
		if ( Jetpack_Beta::get_option() ) {
138
			return;
139
		}
140
141
		self::start_notice();
142
	}
143
144
	/** Enqueue admin styling from admin.css */
145
	public static function admin_styles() {
146
		wp_enqueue_style( 'jetpack-beta-admin', plugins_url( 'admin/admin.css', JPBETA__PLUGIN_FILE ), array(), JPBETA_VERSION );
147
	}
148
149
	/** Enqueue scripts from admin.js */
150
	public static function admin_scripts() {
151
		wp_enqueue_script( 'jetpack-admin-js', plugins_url( 'admin/admin.js', JPBETA__PLUGIN_FILE ), array(), JPBETA_VERSION, true );
152
		wp_localize_script(
153
			'jetpack-admin-js',
154
			'JetpackBeta',
155
			array(
156
				'activate'   => __( 'Activate', 'jetpack-beta' ),
157
				'activating' => __( 'Activating...', 'jetpack-beta' ),
158
				'updating'   => __( 'Updating...', 'jetpack-beta' ),
159
				'leaving'    => __( 'Don\'t go Plugin is still installing!', 'jetpack-beta' ),
160
			)
161
		);
162
	}
163
164
	/** Determine what we're going to test (pr, master, rc) */
165
	public static function to_test_content() {
166
		list( $branch, $section ) = Jetpack_Beta::get_branch_and_section();
167
		switch ( $section ) {
168
			case 'pr':
169
				return self::to_test_pr_content( $branch );
170
			case 'rc':
171
				return self::to_test_file_content();
172
			default: // Master "bleeding edge" or latest stable.
173
				return self::to_test_general_rules_content();
174
175
		}
176
	}
177
178
	/**
179
	 * General rules and recommendations for new Beta Testers.
180
	 * Displayed when no specific branch is picked.
181
	 *
182
	 * @since 2.5.0
183
	 */
184 View Code Duplication
	public static function to_test_general_rules_content() {
185
		$test_rules = JPBETA__PLUGIN_DIR . '/docs/testing/testing-tips.md';
186
		if ( ! file_exists( $test_rules ) ) {
187
			return;
188
		}
189
		WP_Filesystem();
190
		global $wp_filesystem;
191
		$content = $wp_filesystem->get_contents( $test_rules );
192
		return self::render_markdown( $content );
193
	}
194
195
	/** Return testing instructions for release candidate branch */
196 View Code Duplication
	public static function to_test_file_content() {
197
		$test_file = WP_PLUGIN_DIR . '/' . Jetpack_Beta::get_plugin_slug() . '/to-test.md';
198
		if ( ! file_exists( $test_file ) ) {
199
			return;
200
		}
201
		WP_Filesystem();
202
		global $wp_filesystem;
203
		$content = $wp_filesystem->get_contents( $test_file );
204
		return self::render_markdown( $content );
205
	}
206
207
	/**
208
	 * Get PR information for what we want to test
209
	 *
210
	 * @param string $branch_key The branch we're switching to.
211
	 * */
212
	public static function to_test_pr_content( $branch_key ) {
213
		$manifest = Jetpack_Beta::get_beta_manifest();
214
		$pr       = isset( $manifest->pr->{$branch_key}->pr ) ? $manifest->pr->{$branch_key}->pr : null;
215
216
		if ( ! $pr ) {
217
			return null;
218
		}
219
		$github_info = Jetpack_Beta::get_remote_data( JETPACK_GITHUB_API_URL . 'pulls/' . $pr, 'github_' . $pr );
220
221
		return self::render_markdown( $github_info->body );
222
	}
223
224
	/**
225
	 * Rendering markdown for testing instructions
226
	 *
227
	 * @param string $content - Content from testing instructions for the branch we're testing.
228
	 */
229
	public static function render_markdown( $content ) {
230
231
		add_filter( 'jetpack_beta_test_content', 'wptexturize' );
232
		add_filter( 'jetpack_beta_test_content', 'convert_smilies' );
233
		add_filter( 'jetpack_beta_test_content', 'convert_chars' );
234
		add_filter( 'jetpack_beta_test_content', 'wpautop' );
235
		add_filter( 'jetpack_beta_test_content', 'shortcode_unautop' );
236
		add_filter( 'jetpack_beta_test_content', 'prepend_attachment' );
237
238
		if ( ! function_exists( 'jetpack_require_lib' ) ) {
239
			return apply_filters( 'jetpack_beta_test_content', $content );
240
		}
241
242
		jetpack_require_lib( 'markdown' );
243
		if ( ! class_exists( 'WPCom_Markdown' ) ) {
244
			require_once WP_PLUGIN_DIR . '/' . Jetpack_Beta::get_plugin_slug() . '/modules/markdown/easy-markdown.php';
245
		}
246
		$rendered_html = WPCom_Markdown::get_instance()->transform(
247
			$content,
248
			array(
249
				'id'      => false,
250
				'unslash' => false,
251
			)
252
		);
253
254
		// Lets convert #hash numbers into links to issues.
255
		$rendered_html = preg_replace( '/\#([0-9]+)/', '<a href="https://github.com/Automattic/jetpack/issues/$1">#$1</a>', $rendered_html );
256
257
		$rendered_html = apply_filters( 'jetpack_beta_test_content', $rendered_html );
258
259
		return $rendered_html;
260
	}
261
262
	/** Display the body of the start notice on the Jetpack Beta admin page */
263
	public static function start_notice() {
264
		global $current_screen;
265
266
		$is_notice = ( 'plugins' === $current_screen->base ? true : false );
267
		?>
268
		<style type="text/css">
269
			#jetpack-beta-tester__start {
270
				background: #FFF;
271
				padding: 20px;
272
				margin-top:20px;
273
				box-shadow: 0 0 0 1px rgba(200, 215, 225, 0.5), 0 1px 2px #e9eff3;
274
				position: relative;
275
			}
276
			#jetpack-beta-tester__start.updated {
277
				border-left: 3px solid #8CC258;
278
			}
279
			#jetpack-beta-tester__start h1 {
280
				font-weight: 400;
281
				margin: 0;
282
				font-size: 20px;
283
			}
284
			#jetpack-beta-tester__start p {
285
				margin-bottom:1em;
286
			}
287
		</style>
288
		<div id="jetpack-beta-tester__start" class="dops-card <?php echo ( $is_notice ? 'updated' : '' ); ?> ">
289
			<h1><?php esc_html_e( 'Welcome to Jetpack Beta Tester', 'jetpack-beta' ); ?></h1>
290
			<p><?php esc_html_e( 'Thank you for helping to test Jetpack!  We appreciate your time and effort.', 'jetpack-beta' ); ?></p>
291
			<p>
292
			<?php
293
			echo wp_kses_post(
294
				__(
295
					'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.
296
					When you are finished testing, you can switch back to the current version of Jetpack by selecting <em>Latest Stable</em>.',
297
					'jetpack-beta'
298
				)
299
			);
300
			?>
301
				</p>
302
			<p>
303
			<?php
304
			echo wp_kses_post(
305
				sprintf(
306
					// Translators: link to Jetack master testing doc in Github.
307
					__( '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' ),
308
					esc_url( 'https://github.com/Automattic/jetpack/blob/master/to-test.md' )
309
				)
310
			);
311
			?>
312
			</p>
313
			<?php if ( $is_notice ) { ?>
314
			<a href="<?php echo esc_url( Jetpack_Beta::admin_url() ); ?>"><?php esc_html_e( 'Let\'s get testing!', 'jetpack-beta' ); ?></a>
315
			<?php } ?>
316
317
		</div>
318
		<?php
319
	}
320
321
	/**
322
	 * Handles branch selection on beta plugin's admin page
323
	 *
324
	 * @param string $header Title of the branch.
325
	 * @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...
326
	 * @param object $branch Contains branch data (title, update date, download link, commit, etc).
327
	 * @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...
328
	 * @param bool   $is_last Last branch in the list.
329
	 */
330
	public static function show_branch( $header, $branch_key, $branch = null, $section = null, $is_last = false ) {
331
		if ( ! is_object( $branch ) ) {
332
			$manifest = Jetpack_Beta::get_beta_manifest();
333
			if ( empty( $manifest->{$section} ) ) {
334
				return;
335
			}
336
			$branch = $manifest->{$section};
337
		}
338
339
		$is_compact = $is_last ? '' : 'is-compact';
340
		$more_info  = '';
341
		$pr         = '';
342
		if ( isset( $branch->pr ) && is_int( $branch->pr ) ) {
343
			$pr = sprintf( 'data-pr="%s"', esc_attr( $branch->pr ) );
344
			// translators: Translates the `More info` link.
345
			$more_info = sprintf( __( '<a target="_blank" rel="external noopener noreferrer" href="%1$s">more info #%2$s</a> - ', 'jetpack-beta' ), Jetpack_Beta::get_url( $branch_key, $section ), $branch->pr );
346
		}
347
348
		$update_time = ( isset( $branch->update_date )
349
			// translators: %s is how long ago the branch was updated.
350
			? sprintf( __( 'last updated %s ago', 'jetpack-beta' ), human_time_diff( strtotime( $branch->update_date ) ) )
351
			: ''
352
		);
353
354
		$branch_class                             = 'branch-card';
355
		list( $current_branch, $current_section ) = Jetpack_Beta::get_branch_and_section();
356 View Code Duplication
		if ( $current_branch === $branch_key && $current_section === $section ) {
357
			$action       = __( 'Active', 'jetpack-beta' );
358
			$branch_class = 'branch-card-active';
359
		} else {
360
			$action = self::activate_button( $branch_key, $section );
361
		}
362
		$header = str_replace( '-', ' ', $header );
363
		$header = str_replace( '_', ' / ', $header );
364
		?>
365
		<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 ); ?>">
366
			<div class="dops-foldable-card__header has-border" >
367
				<span class="dops-foldable-card__main">
368
					<div class="dops-foldable-card__header-text">
369
						<div class="dops-foldable-card__header-text branch-card-header"><?php echo esc_html( $header ); ?></div>
370
						<div class="dops-foldable-card__subheader">
371
						<?php
372
							echo wp_kses_post( $more_info );
373
							echo wp_kses_post( $update_time );
374
						?>
375
						</div>
376
					</div>
377
				</span>
378
				<span class="dops-foldable-card__secondary">
379
					<span class="dops-foldable-card__summary">
380
						<?php echo wp_kses_post( $action ); ?>
381
					</span>
382
				</span>
383
			</div>
384
		</div>
385
		<?php
386
	}
387
388
	/**
389
	 * Handles list of available Jetpack tags to select specific Jetpack version number.
390
	 *
391
	 * @param string $header Title of tag.
392
	 * @param string $tag Jetpack tag (for selecting a specific version of Jetpack).
393
	 * @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...
394
	 * @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...
395
	 * @param bool   $is_last last version in the list.
396
	 */
397
	public static function show_tag( $header, $tag, $url = null, $section = null, $is_last = false ) {
398
		$is_compact = $is_last ? '' : 'is-compact';
399
		if ( isset( $url ) ) {
400
			$data_tag = sprintf( 'data-tag="%s"', $tag );
401
		}
402
403
		$class_name                               = 'tag-card';
404
		list( $current_branch, $current_section ) = Jetpack_Beta::get_branch_and_section();
405 View Code Duplication
		if ( $current_branch === $tag && $current_section === $section ) {
406
			$action     = __( 'Active', 'jetpack-beta' );
407
			$class_name = 'tag-card-active';
408
		} else {
409
			$action = self::activate_button( $tag, $section );
410
		}
411
412
		$header = str_replace( '-', ' ', $header );
413
		$header = str_replace( '_', ' / ', $header );
414
		?>
415
		<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...
416
			<div class="dops-foldable-card__header has-border">
417
				<span class="dops-foldable-card__main">
418
					<div class="dops-foldable-card__header-text">
419
						<div class="dops-foldable-card__header-text tag-card-header">Jetpack <?php echo esc_html( $header ); ?></div>
420
						<div class="dops-foldable-card__subheader">
421
						<?php
422
						sprintf(
423
							// Translators: Which release is being selected.
424
							__( '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' ),
425
							esc_html( $tag ),
426
							esc_attr( $tag )
427
						);
428
						?>
429
						</div>
430
					</div>
431
				</span>
432
				<span class="dops-foldable-card__secondary">
433
					<span class="dops-foldable-card__summary">
434
						<?php echo wp_kses_post( $action ); ?>
435
					</span>
436
				</span>
437
			</div>
438
		</div>
439
		<?php
440
	}
441
442
	/**
443
	 * Handles the activation buttons.
444
	 *
445
	 * @param object $branch specifies which branch.
446
	 * @param string $section The kind of branch we're switching to (stable, rc, master, pr).
447
	 */
448
	public static function activate_button( $branch, $section ) {
449
		if ( is_object( $section ) && 'master' === $branch ) {
450
			$section = 'master';
451
		}
452
453
		if ( is_object( $section ) && 'rc' === $branch ) {
454
			$section = 'rc';
455
		}
456
		$query = array(
457
			'page'            => 'jetpack-beta',
458
			'activate-branch' => $branch,
459
			'section'         => $section,
460
			'_nonce'          => wp_create_nonce( 'activate_branch' ),
461
		);
462
		$url   = Jetpack_Beta::admin_url( '?' . build_query( $query ) );
463
464
		return sprintf(
465
			'<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>',
466
			esc_url( $url ),
467
			'jetpack_beta_activate_branch',
468
			esc_attr( $branch ),
469
			esc_html__( 'Activate', 'jetpack-beta' )
470
		);
471
	}
472
473
	/**
474
	 * Display the branch header
475
	 *
476
	 * @param string $title - The title of the branch.
477
	 */
478
	public static function header( $title ) {
479
		echo '<header><h2 class="jp-jetpack-connect__container-subtitle">' . esc_html( $title ) . '</h2></header>';
480
	}
481
482
	/**
483
	 * Display the branch list
484
	 *
485
	 * @param string $section - The kind of branch we're switching to (stable, rc, master, pr).
486
	 * @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...
487
	 */
488 View Code Duplication
	public static function show_branches( $section, $title = null ) {
489
		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...
490
			$title .= ': ';
491
		}
492
		echo '<div id="section-' . esc_attr( $section ) . '">';
493
494
		$manifest = Jetpack_Beta::get_beta_manifest();
495
		$count    = 0;
496
		if ( empty( $manifest->{$section} ) ) {
497
			return;
498
		}
499
		$branches  = (array) $manifest->{$section};
500
		$count_all = count( $branches );
501
502
		foreach ( $branches as $branch_name => $branch ) {
503
			$count ++;
504
			$is_last = $count_all === $count ? true : false;
505
			self::show_branch( $title . $branch_name, $branch_name, $branch, $section, $is_last );
506
		}
507
		echo '</div>';
508
	}
509
510
	/**
511
	 * Show list of available Jetpack tags to select specific Jetpack version number.
512
	 *
513
	 * @param string $section - The kind of version we're switching to (in this case 'tags').
514
	 * @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...
515
	 */
516 View Code Duplication
	public static function show_tags( $section, $title = null ) {
517
		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...
518
			$title .= ': ';
519
		}
520
		echo '<div id="section-' . esc_attr( $section ) . '">';
521
522
		$manifest = Jetpack_Beta::get_org_data();
523
		$count    = 0;
524
		if ( empty( $manifest->versions ) ) {
525
			return;
526
		}
527
		$tags      = array_reverse( (array) $manifest->versions );
528
		$count_all = count( $tags );
529
530
		foreach ( $tags as $tag => $url ) {
531
			$count ++;
532
			$is_last = $count_all === $count ? true : false;
533
			self::show_tag( $title . $tag, $tag, $url, $section, $is_last );
534
		}
535
		echo '</div>';
536
	}
537
538
	/** Display the stable branch */
539
	public static function show_stable_branch() {
540
		$org_data = Jetpack_Beta::get_org_data();
541
542
		self::show_branch(
543
			__( 'Latest Stable', 'jetpack-beta' ),
544
			'stable',
545
			(object) array(
546
				'branch'      => 'stable',
547
				'update_date' => $org_data->last_updated,
548
			),
549
			'stable'
550
		);
551
	}
552
553
	/** Show search bar for PRs */
554 View Code Duplication
	public static function show_search_prs() {
555
		$manifest = Jetpack_Beta::get_beta_manifest();
556
		if ( empty( $manifest->pr ) ) {
557
			return;
558
		}
559
		?>
560
		<div class="dops-navigation">
561
			<div class="dops-section-nav has-pinned-items">
562
				<div class="dops-section-nav__panel">
563
					<div class="is-pinned is-open dops-search" role="search">
564
						<div aria-controls="search-component" aria-label="<?php esc_attr_e( 'Open Search', 'jetpack-beta' ); ?>" tabindex="-1">
565
							<svg class="gridicon gridicons-search dops-search-open__icon" height="24"
566
								viewbox="0 0 24 24" width="24">
567
								<g>
568
									<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>
569
								</g>
570
							</svg>
571
						</div>
572
						<input aria-hidden="false" class="dops-search__input" id="search-component-prs"
573
							placeholder="<?php esc_attr_e( 'Search for a Jetpack Feature Branch', 'jetpack-beta' ); ?>" role="search" type="search" value="">
574
						<span aria-controls="search-component" id="search-component-prs-close" aria-label="<?php esc_attr_e( 'Close Search', 'jetpack-beta' ); ?>"
575
							tabindex="0">
576
							<svg class="gridicon gridicons-cross dops-search-close__icon" height="24"
577
								viewbox="0 0 24 24" width="24">
578
								<g>
579
									<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>
580
								</g>
581
							</svg>
582
						</span>
583
					</div>
584
				</div>
585
			</div>
586
		</div>
587
		<?php
588
	}
589
590
	/** Show search bar for tags */
591 View Code Duplication
	public static function show_search_org_tags() {
592
		$org_data = Jetpack_Beta::get_org_data();
593
		if ( empty( $org_data->versions ) ) {
594
			return;
595
		}
596
		?>
597
		<div class="dops-navigation">
598
			<div class="dops-section-nav has-pinned-items">
599
				<div class="dops-section-nav__panel">
600
					<div class="is-pinned is-open dops-search" role="search">
601
						<div aria-controls="search-component" aria-label="<?php esc_attr_e( 'Open Search', 'jetpack-beta' ); ?>" tabindex="-1">
602
							<svg class="gridicon gridicons-search dops-search-open__icon" height="24"
603
								viewbox="0 0 24 24" width="24">
604
								<g>
605
									<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>
606
								</g>
607
							</svg>
608
						</div>
609
						<input aria-hidden="false" class="dops-search__input" id="search-component-tags"
610
							placeholder="<?php esc_attr_e( 'Search for a Jetpack tag', 'jetpack-beta' ); ?>" role="search" type="search" value="">
611
						<span aria-controls="search-component" id="search-component-tags-close" aria-label="<?php esc_attr_e( 'Close Search', 'jetpack-beta' ); ?>"
612
							tabindex="0">
613
							<svg class="gridicon gridicons-cross dops-search-close__icon" height="24"
614
								viewbox="0 0 24 24" width="24">
615
								<g>
616
									<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>
617
								</g>
618
							</svg>
619
						</span>
620
					</div>
621
				</div>
622
			</div>
623
		</div>
624
		<?php
625
	}
626
627
	/** Display autoupdate toggle */
628
	public static function show_toggle_autoupdates() {
629
		$autoupdate = (bool) Jetpack_Beta::is_set_to_autoupdate();
630
		self::show_toggle( __( 'Autoupdates', 'jetpack-beta' ), 'autoupdates', $autoupdate );
631
	}
632
633
	/** Display email notification toggle */
634
	public static function show_toggle_emails() {
635
		if ( ! Jetpack_Beta::is_set_to_autoupdate() || defined( 'JETPACK_BETA_SKIP_EMAIL' ) ) {
636
			return;
637
		}
638
		$email_notification = (bool) Jetpack_Beta::is_set_to_email_notifications();
639
		self::show_toggle( __( 'Email Notifications', 'jetpack-beta' ), 'email_notifications', $email_notification );
640
	}
641
642
	/**
643
	 * Display autoupdate and email notification toggles
644
	 *
645
	 * @param string $name name of toggle.
646
	 * @param string $option Which toggle (autoupdates, email_notification).
647
	 * @param bool   $value If toggle is active or not.
648
	 */
649
	public static function show_toggle( $name, $option, $value ) {
650
		$query = array(
651
			'page'    => 'jetpack-beta',
652
			'_action' => 'toggle_enable_' . $option,
653
			'_nonce'  => wp_create_nonce( 'enable_' . $option ),
654
		);
655
656
		?>
657
		<a
658
			href="<?php echo esc_url( Jetpack_Beta::admin_url( '?' . build_query( $query ) ) ); ?>"
659
			class="form-toggle__label <?php echo ( $value ? 'is-active' : '' ); ?>"
660
			data-jptracks-name="jetpack_beta_toggle_<?php echo esc_attr( $option ); ?>"
661
			data-jptracks-prop="<?php echo absint( ! $value ); ?>"
662
		>
663
			<span class="form-toggle-explanation" ><?php echo esc_html( $name ); ?></span>
664
			<span class="form-toggle__switch" tabindex="0" ></span>
665
			<span class="form-toggle__label-content" ></span>
666
		</a>
667
		<?php
668
	}
669
670
	/** Check if Jetpack and branch versions are up to date */
671
	public static function show_needed_updates() {
672
		$should_update_stable_version = Jetpack_Beta::should_update_stable_version();
673
		$should_update_dev_version    = Jetpack_Beta::should_update_dev_version();
674
		$should_update_dev_to_master  = Jetpack_Beta::should_update_dev_to_master();
675
676
		// Return if there are no updates available.
677
		if ( ! $should_update_stable_version
678
			&& ! $should_update_dev_version
679
			&& ! $should_update_dev_to_master ) {
680
			return;
681
		}
682
683
		?>
684
		<div class="jetpack-beta__wrap jetpack-beta__update-needed">
685
			<h2><?php esc_html_e( 'Some updates are required', 'jetpack-beta' ); ?></h2>
686
		<?php
687
688
		// Stable up to date?
689 View Code Duplication
		if ( $should_update_stable_version ) {
690
			self::update_card(
691
				__( 'Latest Stable', 'jetpack-beta' ),
692
				__( 'Needs an update', 'jetpack-beta' ),
693
				self::update_action_url( 'stable', 'stable' )
694
			);
695
		}
696
		// Jetpack Dev Folder not up to date?
697
		if ( $should_update_dev_version ) {
698
			list( $dev_branch, $dev_section ) = Jetpack_Beta::get_branch_and_section_dev();
699
			self::update_card(
700
				Jetpack_Beta::get_jetpack_plugin_pretty_version( true ),
701
				__( 'Is not running the latest version', 'jetpack-beta' ),
702
				self::update_action_url( $dev_branch, $dev_section )
703
			);
704
		}
705
706 View Code Duplication
		if ( $should_update_dev_to_master ) {
707
			self::update_card(
708
				__( 'Feature Branch was merged', 'jetpack-beta' ),
709
				__( 'Go back to Jetpack\'s Bleeding Edge version.', 'jetpack-beta' ),
710
				self::update_action_url( 'master', 'master' )
711
			);
712
		}
713
		?>
714
		</div>
715
		<?php
716
	}
717
718
	/**
719
	 * Handles card that notifies when there's an update available on a branch.
720
	 *
721
	 * @param string $header - Title of the branch that's ready for update.
722
	 * @param string $sub_header - Detailed information about the update.
723
	 * @param string $url - URL where branch can be updated.
724
	 */
725
	public static function update_card( $header, $sub_header, $url ) {
726
		?>
727
		<div class="dops-foldable-card has-expanded-summary dops-card is-compact">
728
			<div class="dops-foldable-card__header has-border" >
729
				<span class="dops-foldable-card__main">
730
					<div class="dops-foldable-card__header-text">
731
						<div class="dops-foldable-card__header-text branch-card-header"><?php echo esc_html( $header ); ?></div>
732
						<div class="dops-foldable-card__subheader"><?php echo esc_html( $sub_header ); ?></div>
733
					</div>
734
				</span>
735
				<span class="dops-foldable-card__secondary">
736
					<span class="dops-foldable-card__summary">
737
						<a
738
							href="<?php echo esc_url( $url ); ?>"
739
							class="is-primary jp-form-button activate-branch dops-button is-compact"><?php esc_html_e( 'Update', 'jetpack-beta' ); ?></a>
740
					</span>
741
				</span>
742
			</div>
743
		</div>
744
		<?php
745
	}
746
747
	/**
748
	 * Handles update button for branches
749
	 *
750
	 * @param string $branch - Branch that's ready for update.
751
	 * @param string $section - What kind of branch we're updated (master, rc, pr).
752
	 */
753
	public static function update_action_url( $branch, $section ) {
754
		$query = array(
755
			'page'          => 'jetpack-beta',
756
			'update-branch' => $branch,
757
			'section'       => $section,
758
			'_nonce'        => wp_create_nonce( 'update_branch' ),
759
		);
760
761
		return Jetpack_Beta::admin_url( '?' . build_query( $query ) );
762
	}
763
}
764