Completed
Push — try/gutenberg-separate-jetpack... ( e8dd3e...f0efb9 )
by Bernhard
39:26 queued 23:22
created

modules/publicize/publicize.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
abstract class Publicize_Base {
4
5
	/**
6
	* Services that are currently connected to the given user
7
	* through publicize.
8
	*/
9
	public $connected_services = array();
10
11
	/**
12
	* Services that are supported by publicize. They don't
13
	* necessarily need to be connected to the current user.
14
	*/
15
	public $services;
16
17
	/**
18
	* key names for post meta
19
	*/
20
	public $ADMIN_PAGE        = 'wpas';
21
	public $POST_MESS         = '_wpas_mess';
22
	public $POST_SKIP         = '_wpas_skip_'; // connection id appended to indicate that a connection should NOT be publicized to
23
	public $POST_DONE         = '_wpas_done_'; // connection id appended to indicate a connection has already been publicized to
24
	public $USER_AUTH         = 'wpas_authorize';
25
	public $USER_OPT          = 'wpas_';
26
	public $PENDING           = '_publicize_pending'; // ready for Publicize to do its thing
27
	public $POST_SERVICE_DONE = '_publicize_done_external'; // array of external ids where we've Publicized
28
29
	/**
30
	* default pieces of the message used in constructing the
31
	* content pushed out to other social networks
32
	*/
33
34
	public $default_prefix  = '';
35
	public $default_message = '%title%';
36
	public $default_suffix  = ' ';
37
38
	/**
39
	 * What WP capability is require to create/delete global connections?
40
	 * All users with this cap can un-globalize all other global connections, and globalize any of their own
41
	 * Globalized connections cannot be unselected by users without this capability when publishing
42
	 */
43
	public $GLOBAL_CAP = 'edit_others_posts';
44
45
	/**
46
	* Sets up the basics of Publicize
47
	*/
48
	function __construct() {
49
		$this->default_message = self::build_sprintf( array(
50
			/**
51
			 * Filter the default Publicize message.
52
			 *
53
			 * @module publicize
54
			 *
55
			 * @since 2.0.0
56
			 *
57
			 * @param string $this->default_message Publicize's default message. Default is the post title.
58
			 */
59
			apply_filters( 'wpas_default_message', $this->default_message ),
60
			'title',
61
			'url',
62
		) );
63
64
		$this->default_prefix = self::build_sprintf( array(
65
			/**
66
			 * Filter the message prepended to the Publicize custom message.
67
			 *
68
			 * @module publicize
69
			 *
70
			 * @since 2.0.0
71
			 *
72
			 * @param string $this->default_prefix String prepended to the Publicize custom message.
73
			 */
74
			apply_filters( 'wpas_default_prefix', $this->default_prefix ),
75
			'url',
76
		) );
77
78
		$this->default_suffix = self::build_sprintf( array(
79
			/**
80
			 * Filter the message appended to the Publicize custom message.
81
			 *
82
			 * @module publicize
83
			 *
84
			 * @since 2.0.0
85
			 *
86
			 * @param string $this->default_suffix String appended to the Publicize custom message.
87
			 */
88
			apply_filters( 'wpas_default_suffix', $this->default_suffix ),
89
			'url',
90
		) );
91
92
		/**
93
		 * Filter the capability to change global Publicize connection options.
94
		 *
95
		 * All users with this cap can un-globalize all other global connections, and globalize any of their own
96
		 * Globalized connections cannot be unselected by users without this capability when publishing.
97
		 *
98
		 * @module publicize
99
		 *
100
		 * @since 2.2.1
101
		 *
102
		 * @param string $this->GLOBAL_CAP default capability in control of global Publicize connection options. Default to edit_others_posts.
103
		 */
104
		$this->GLOBAL_CAP = apply_filters( 'jetpack_publicize_global_connections_cap', $this->GLOBAL_CAP );
105
106
		// stage 1 and 2 of 3-stage Publicize. Flag for Publicize on creation, save meta,
107
		// then check meta and publicize based on that. stage 3 implemented on wpcom
108
		add_action( 'transition_post_status', array( $this, 'flag_post_for_publicize' ), 10, 3 );
109
		add_action( 'save_post', array( &$this, 'save_meta' ), 20, 2 );
110
		add_filter( 'post_updated_messages', array( $this, 'update_published_message' ), 20, 1 );
111
112
		// Connection test callback
113
		add_action( 'wp_ajax_test_publicize_conns', array( $this, 'test_publicize_conns' ) );
114
	}
115
116
	/**
117
	* Functions to be implemented by the extended class (publicize-wpcom or publicize-jetpack)
118
	*/
119
	abstract function get_connection_id( $connection );
120
	abstract function connect_url( $service_name );
121
	abstract function disconnect_url( $service_name, $id );
122
	abstract function get_connection_meta( $connection );
123
	abstract function get_services( $filter = 'all' );
124
	abstract function get_connections( $service, $_blog_id = false, $_user_id = false );
125
	abstract function get_connection( $service, $id, $_blog_id = false, $_user_id = false );
126
	abstract function flag_post_for_publicize( $new_status, $old_status, $post );
127
	abstract function test_connection( $service_name, $connection );
128
	abstract function disconnect( $service, $connection_id, $_blog_id = false, $_user_id = false, $force_delete = false );
129
130
	/**
131
	* Shared Functions
132
	*/
133
134
	/**
135
	* Returns an external URL to the connection's profile
136
	*/
137
	function get_profile_link( $service_name, $connection ) {
138
		$cmeta = $this->get_connection_meta( $connection );
139
140
		if ( isset( $cmeta['connection_data']['meta']['link'] ) ) {
141
			if ( 'facebook' == $service_name && 0 === strpos( parse_url( $cmeta['connection_data']['meta']['link'], PHP_URL_PATH ), '/app_scoped_user_id/' ) ) {
142
				// App-scoped Facebook user IDs are not usable profile links
143
				return false;
144
			}
145
146
			return $cmeta['connection_data']['meta']['link'];
147 View Code Duplication
		} elseif ( 'facebook' == $service_name && isset( $cmeta['connection_data']['meta']['facebook_page'] ) ) {
148
			return 'https://facebook.com/' . $cmeta['connection_data']['meta']['facebook_page'];
149
		} elseif ( 'tumblr' == $service_name && isset( $cmeta['connection_data']['meta']['tumblr_base_hostname'] ) ) {
150
			 return 'http://' . $cmeta['connection_data']['meta']['tumblr_base_hostname'];
151
		} elseif ( 'twitter' == $service_name ) {
152
			return 'https://twitter.com/' . substr( $cmeta['external_display'], 1 ); // Has a leading '@'
153 View Code Duplication
		} elseif ( 'google_plus' == $service_name && isset( $cmeta['connection_data']['meta']['google_plus_page'] ) ) {
154
			return 'https://plus.google.com/' . $cmeta['connection_data']['meta']['google_plus_page'];
155
		} elseif ( 'google_plus' == $service_name ) {
156
			return 'https://plus.google.com/' . $cmeta['external_id'];
157
		} else if ( 'linkedin' == $service_name ) {
158
			if ( !isset( $cmeta['connection_data']['meta']['profile_url'] ) ) {
159
				return false;
160
			}
161
162
			$profile_url_query = parse_url( $cmeta['connection_data']['meta']['profile_url'], PHP_URL_QUERY );
163
			wp_parse_str( $profile_url_query, $profile_url_query_args );
164
			if ( isset( $profile_url_query_args['key'] ) ) {
165
				$id = $profile_url_query_args['key'];
166
			} elseif ( isset( $profile_url_query_args['id'] ) ) {
167
				$id = $profile_url_query_args['id'];
168
			} else {
169
				return false;
170
			}
171
172
			return esc_url_raw( add_query_arg( 'id', urlencode( $id ), 'http://www.linkedin.com/profile/view' ) );
173
		} else {
174
			return false; // no fallback. we just won't link it
175
		}
176
	}
177
178
	/**
179
	* Returns a display name for the connection
180
	*/
181
	function get_display_name( $service_name, $connection ) {
182
		$cmeta = $this->get_connection_meta( $connection );
183
184
		if ( isset( $cmeta['connection_data']['meta']['display_name'] ) ) {
185
			return $cmeta['connection_data']['meta']['display_name'];
186 View Code Duplication
		} elseif ( $service_name == 'tumblr' && isset( $cmeta['connection_data']['meta']['tumblr_base_hostname'] ) ) {
187
			 return $cmeta['connection_data']['meta']['tumblr_base_hostname'];
188
		} elseif ( $service_name == 'twitter' ) {
189
			return $cmeta['external_display'];
190
		} else {
191
			$connection_display = $cmeta['external_display'];
192
			if ( empty( $connection_display ) )
193
				$connection_display = $cmeta['external_name'];
194
			return $connection_display;
195
		}
196
	}
197
198
	public static function get_service_label( $service_name ) {
199
		switch ( $service_name ) {
200
			case 'linkedin':
201
				return 'LinkedIn';
202
				break;
203
			case 'google_plus':
204
				return  'Google+';
205
				break;
206
			case 'twitter':
207
			case 'facebook':
208
			case 'tumblr':
209
			default:
210
				return ucfirst( $service_name );
211
				break;
212
		}
213
	}
214
215
	function show_options_popup( $service_name, $connection ) {
216
		$cmeta = $this->get_connection_meta( $connection );
217
218
		// always show if no selection has been made for facebook
219
		if ( 'facebook' == $service_name && empty( $cmeta['connection_data']['meta']['facebook_profile'] ) && empty( $cmeta['connection_data']['meta']['facebook_page'] ) )
220
			return true;
221
222
		// always show if no selection has been made for tumblr
223
		if ( 'tumblr' == $service_name && empty ( $cmeta['connection_data']['meta']['tumblr_base_hostname'] ) )
224
			return true;
225
226
		// if we have the specific connection info..
227
		if ( isset( $_GET['id'] ) ) {
228
			if ( $cmeta['connection_data']['id'] == $_GET['id'] )
229
				return true;
230
		} else {
231
			// otherwise, just show if this is the completed step / first load
232
			if ( !empty( $_GET['action'] ) && 'completed' == $_GET['action'] && !empty( $_GET['service'] ) && $service_name == $_GET['service'] && ! in_array( $_GET['service'], array( 'facebook', 'tumblr' ) ) )
233
				return true;
234
		}
235
236
		return false;
237
	}
238
239
	function user_id() {
240
		global $current_user;
241
		return $current_user->ID;
242
	}
243
244
	function blog_id() {
245
		return get_current_blog_id();
246
	}
247
248
	/**
249
	* Returns true if a user has a connection to a particular service, false otherwise
250
	*/
251
	function is_enabled( $service, $_blog_id = false, $_user_id = false ) {
252
		if ( !$_blog_id )
253
			$_blog_id = $this->blog_id();
254
255
		if ( !$_user_id )
256
			$_user_id = $this->user_id();
257
258
		$connections = $this->get_connections( $service, $_blog_id, $_user_id );
259
		return ( is_array( $connections ) && count( $connections ) > 0 ? true : false );
260
	}
261
262
	/**
263
	* Fires when a post is saved, checks conditions and saves state in postmeta so that it
264
	* can be picked up later by @see ::publicize_post() on WordPress.com codebase.
265
	*/
266
	function save_meta( $post_id, $post ) {
267
		$cron_user = null;
268
		$submit_post = true;
269
270
		if ( ! $this->post_type_is_publicizeable( $post->post_type ) )
271
			return;
272
273
		// Don't Publicize during certain contexts:
274
275
		// - import
276
		if ( defined( 'WP_IMPORTING' ) && WP_IMPORTING  ) {
277
			$submit_post = false;
278
		}
279
280
		// - on quick edit, autosave, etc but do fire on p2, quickpress, and instapost ajax
281
		if (
282
			defined( 'DOING_AJAX' )
283
		&&
284
			DOING_AJAX
285
		&&
286
			!did_action( 'p2_ajax' )
287
		&&
288
			!did_action( 'wp_ajax_json_quickpress_post' )
289
		&&
290
			!did_action( 'wp_ajax_instapost_publish' )
291
		&&
292
			!did_action( 'wp_ajax_post_reblog' )
293
		&&
294
			!did_action( 'wp_ajax_press-this-save-post' )
295
		) {
296
			$submit_post = false;
297
		}
298
299
		// - bulk edit
300
		if ( isset( $_GET['bulk_edit'] ) ) {
301
			$submit_post = false;
302
		}
303
304
		// - API/XML-RPC Test Posts
305
		if (
306
			(
307
				defined( 'XMLRPC_REQUEST' )
308
			&&
309
				XMLRPC_REQUEST
310
			||
311
				defined( 'APP_REQUEST' )
312
			&&
313
				APP_REQUEST
314
			)
315
		&&
316
			0 === strpos( $post->post_title, 'Temporary Post Used For Theme Detection' )
317
		) {
318
			$submit_post = false;
319
		}
320
321
		// only work with certain statuses (avoids inherits, auto drafts etc)
322
		if ( !in_array( $post->post_status, array( 'publish', 'draft', 'future' ) ) ) {
323
			$submit_post = false;
324
		}
325
326
		// don't publish password protected posts
327
		if ( '' !== $post->post_password ) {
328
			$submit_post = false;
329
		}
330
331
		// Did this request happen via wp-admin?
332
		$from_web = isset( $_SERVER['REQUEST_METHOD'] )
333
			&&
334
			'post' == strtolower( $_SERVER['REQUEST_METHOD'] )
335
			&&
336
			isset( $_POST[$this->ADMIN_PAGE] );
337
338
		if ( ( $from_web || defined( 'POST_BY_EMAIL' ) ) && isset( $_POST['wpas_title'] ) ) {
339
			if ( empty( $_POST['wpas_title'] ) ) {
340
				delete_post_meta( $post_id, $this->POST_MESS );
341
			} else {
342
				update_post_meta( $post_id, $this->POST_MESS, trim( stripslashes( $_POST['wpas_title'] ) ) );
343
			}
344
		}
345
346
		// change current user to provide context for get_services() if we're running during cron
347
		if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
348
			$cron_user = (int) $GLOBALS['user_ID'];
349
			wp_set_current_user( $post->post_author );
350
		}
351
352
		/**
353
		 * In this phase, we mark connections that we want to SKIP. When Publicize is actually triggered,
354
		 * it will Publicize to everything *except* those marked for skipping.
355
		 */
356
		foreach ( (array) $this->get_services( 'connected' ) as $service_name => $connections ) {
357
			foreach ( $connections as $connection ) {
358
				$connection_data = '';
359 View Code Duplication
				if ( method_exists( $connection, 'get_meta' ) )
360
					$connection_data = $connection->get_meta( 'connection_data' );
361
				elseif ( ! empty( $connection['connection_data'] ) )
362
					$connection_data = $connection['connection_data'];
363
364
				/** This action is documented in modules/publicize/ui.php */
365
				if ( false == apply_filters( 'wpas_submit_post?', $submit_post, $post_id, $service_name, $connection_data ) ) {
366
					delete_post_meta( $post_id, $this->PENDING );
367
					continue;
368
				}
369
370 View Code Duplication
				if ( !empty( $connection->unique_id ) )
371
					$unique_id = $connection->unique_id;
372
				else if ( !empty( $connection['connection_data']['token_id'] ) )
373
					$unique_id = $connection['connection_data']['token_id'];
374
375
				// This was a wp-admin request, so we need to check the state of checkboxes
376
				if ( $from_web ) {
377
					// delete stray service-based post meta
378
					delete_post_meta( $post_id, $this->POST_SKIP . $service_name );
379
380
					// We *unchecked* this stream from the admin page, or it's set to readonly, or it's a new addition
381
					if ( empty( $_POST[$this->ADMIN_PAGE]['submit'][$unique_id] ) ) {
382
						// Also make sure that the service-specific input isn't there.
383
						// If the user connected to a new service 'in-page' then a hidden field with the service
384
						// name is added, so we just assume they wanted to Publicize to that service.
385
						if ( empty( $_POST[$this->ADMIN_PAGE]['submit'][$service_name] ) ) {
386
							// Nothing seems to be checked, so we're going to mark this one to be skipped
387
							update_post_meta( $post_id, $this->POST_SKIP . $unique_id, 1 );
388
							continue;
389
						} else {
390
							// clean up any stray post meta
391
							delete_post_meta( $post_id, $this->POST_SKIP . $unique_id );
392
						}
393
					} else {
394
						// The checkbox for this connection is explicitly checked -- make sure we DON'T skip it
395
						delete_post_meta( $post_id, $this->POST_SKIP . $unique_id );
396
					}
397
				}
398
399
				/**
400
				 * Fires right before the post is processed for Publicize.
401
				 * Users may hook in here and do anything else they need to after meta is written,
402
				 * and before the post is processed for Publicize.
403
				 *
404
				 * @since 2.1.2
405
				 *
406
				 * @param bool $submit_post Should the post be publicized.
407
				 * @param int $post->ID Post ID.
408
				 * @param string $service_name Service name.
409
				 * @param array $connection Array of connection details.
410
				 */
411
				do_action( 'publicize_save_meta', $submit_post, $post_id, $service_name, $connection );
412
			}
413
		}
414
415
		if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
416
			wp_set_current_user( $cron_user );
417
		}
418
419
		// Next up will be ::publicize_post()
420
	}
421
422
	public function update_published_message( $messages ) {
423
		global $post_type, $post_type_object, $post;
424
		if ( ! $this->post_type_is_publicizeable( $post_type ) ) {
425
			return $messages;
426
		}
427
		$view_post_link_html = '';
428
		$viewable = is_post_type_viewable( $post_type_object );
429
		if ( $viewable ) {
430
			$view_text = esc_html__( 'View post' ); // intentionally omitted domain
431
432
			if ( 'jetpack-portfolio' == $post_type ) {
433
				$view_text = esc_html__( 'View project', 'jetpack' );
434
			}
435
436
			$view_post_link_html = sprintf( ' <a href="%1$s">%2$s</a>',
437
				esc_url( get_permalink( $post ) ),
438
				$view_text
439
			);
440
		}
441
442
		$services = $this->get_publicizing_services( $post->ID );
443
		if ( empty( $services ) ) {
444
			return $messages;
445
		}
446
447
		$labels = array();
448
		foreach ( $services as $service => $display_names ) {
449
			$labels[] = sprintf(
450
				/* translators: Service name is %1$s, and account name is %2$s. */
451
				esc_html__( '%1$s (%2$s)', 'jetpack' ),
452
				esc_html( $service ),
453
				esc_html( implode( ', ', $display_names ) )
454
			);
455
		}
456
457
		$messages['post'][6] = sprintf(
458
			/* translators: %1$s is a comma-separated list of services and accounts. Ex. Facebook (@jetpack), Twitter (@jetpack) */
459
			esc_html__( 'Post published and sharing on %1$s.', 'jetpack' ),
460
			implode( ', ', $labels )
461
		) . $view_post_link_html;
462
463
		if ( $post_type == 'post' && class_exists('Jetpack_Subscriptions' ) ) {
464
			$subscription = Jetpack_Subscriptions::init();
465
			if ( $subscription->should_email_post_to_subscribers( $post ) ) {
466
				$messages['post'][6] = sprintf(
467
					/* translators: %1$s is a comma-separated list of services and accounts. Ex. Facebook (@jetpack), Twitter (@jetpack) */
468
					esc_html__( 'Post published, sending emails to subscribers and sharing post on %1$s.', 'jetpack' ),
469
					implode( ', ', $labels )
470
				) . $view_post_link_html;
471
			}
472
		}
473
474
		$messages['jetpack-portfolio'][6] = sprintf(
475
			/* translators: %1$s is a comma-separated list of services and accounts. Ex. Facebook (@jetpack), Twitter (@jetpack) */
476
			esc_html__( 'Project published and sharing project on %1$s.', 'jetpack' ),
477
			implode( ', ', $labels )
478
		) . $view_post_link_html;
479
480
		return $messages;
481
	}
482
483
	function get_publicizing_services( $post_id ) {
484
		$services = array();
485
486
		foreach ( (array) $this->get_services( 'connected' ) as $service_name => $connections ) {
487
			// services have multiple connections.
488
			foreach ( $connections as $connection ) {
489
				$unique_id = '';
490 View Code Duplication
				if ( ! empty( $connection->unique_id ) )
491
					$unique_id = $connection->unique_id;
492
				else if ( ! empty( $connection['connection_data']['token_id'] ) )
493
					$unique_id = $connection['connection_data']['token_id'];
494
495
				// Did we skip this connection?
496
				if ( get_post_meta( $post_id, $this->POST_SKIP . $unique_id,  true ) ) {
497
					continue;
498
				}
499
				$services[ $this->get_service_label( $service_name ) ][] = $this->get_display_name( $service_name, $connection );
500
			}
501
		}
502
503
		return $services;
504
	}
505
506
	/**
507
	* Is a given post type Publicize-able?
508
	*
509
	* Not every CPT lends itself to Publicize-ation.  Allow CPTs to register by adding their CPT via
510
	* the publicize_post_types array filter.
511
	*
512
	* @param string $post_type The post type to check.
513
	* @return bool True if the post type can be Publicized.
514
	*/
515
	function post_type_is_publicizeable( $post_type ) {
516
		if ( 'post' == $post_type )
517
			return true;
518
519
		return post_type_supports( $post_type, 'publicize' );
520
	}
521
522
	/**
523
	 * Runs tests on all the connections and returns the results to the caller
524
	 */
525
	function test_publicize_conns() {
526
		$test_results = array();
527
528
		foreach ( (array) $this->get_services( 'connected' ) as $service_name => $connections ) {
529
			foreach ( $connections as $connection ) {
530
531
				$id = $this->get_connection_id( $connection );
532
533
				$connection_test_passed = true;
534
				$connection_test_message = __( 'This connection is working correctly.' , 'jetpack' );
535
				$user_can_refresh = false;
536
				$refresh_text = '';
537
				$refresh_url = '';
538
539
				$connection_test_result = true;
540
				if ( method_exists( $this, 'test_connection' ) ) {
541
					$connection_test_result = $this->test_connection( $service_name, $connection );
542
				}
543
544
				if ( is_wp_error( $connection_test_result ) ) {
545
					$connection_test_passed = false;
546
					$connection_test_message = $connection_test_result->get_error_message();
547
					$error_data = $connection_test_result->get_error_data();
548
549
					$user_can_refresh = $error_data['user_can_refresh'];
550
					$refresh_text = $error_data['refresh_text'];
551
					$refresh_url = $error_data['refresh_url'];
552
				}
553
554
				$test_results[] = array(
555
					'connectionID'          => $id,
556
					'serviceName'           => $service_name,
557
					'connectionTestPassed'  => $connection_test_passed,
558
					'connectionTestMessage' => esc_attr( $connection_test_message ),
559
					'userCanRefresh'        => $user_can_refresh,
560
					'refreshText'           => esc_attr( $refresh_text ),
561
					'refreshURL'            => $refresh_url
562
				);
563
			}
564
		}
565
566
		wp_send_json_success( $test_results );
567
	}
568
569
	protected static function build_sprintf( $args ) {
570
		$search = array();
571
		$replace = array();
572
		foreach ( $args as $k => $arg ) {
573
			if ( 0 == $k ) {
574
				$string = $arg;
575
				continue;
576
			}
577
			$search[] = "%$arg%";
578
			$replace[] = "%$k\$s";
579
		}
580
		return str_replace( $search, $replace, $string );
581
	}
582
}
583
584
function publicize_calypso_url() {
585
	$calypso_sharing_url = 'https://wordpress.com/sharing/';
586
	if ( class_exists( 'Jetpack' ) && method_exists( 'Jetpack', 'build_raw_urls' ) ) {
587
		$site_suffix = Jetpack::build_raw_urls( home_url() );
588
	} elseif ( class_exists( 'WPCOM_Masterbar' ) && method_exists( 'WPCOM_Masterbar', 'get_calypso_site_slug' ) ) {
589
		$site_suffix = WPCOM_Masterbar::get_calypso_site_slug( get_current_blog_id() );
590
	}
591
592
	if ( $site_suffix ) {
593
		return $calypso_sharing_url . $site_suffix;
0 ignored issues
show
The variable $site_suffix 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...
594
	} else {
595
		return $calypso_sharing_url;
596
	}
597
}
598