Completed
Push — fix/extend-amp-sharing-icons ( 3c6b33...da0a1d )
by
unknown
18:20 queued 11:15
created

Jetpack_AMP_Support::init()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 4
nop 0
dl 0
loc 52
rs 8.7361
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 //phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
3
use Automattic\Jetpack\Sync\Functions;
4
5
/**
6
 * Manages compatibility with the amp-wp plugin
7
 *
8
 * @see https://github.com/Automattic/amp-wp
9
 */
10
class Jetpack_AMP_Support {
11
12
	/**
13
	 * Apply custom AMP changes on the front-end.
14
	 */
15
	public static function init() {
16
17
		// Add Stats tracking pixel on Jetpack sites when the Stats module is active.
18
		if (
19
			Jetpack::is_module_active( 'stats' )
20
			&& ! ( defined( 'IS_WPCOM' ) && IS_WPCOM )
21
		) {
22
			add_action( 'amp_post_template_footer', array( 'Jetpack_AMP_Support', 'add_stats_pixel' ) );
23
		}
24
25
		/**
26
		 * Remove this during the init hook in case users have enabled it during
27
		 * the after_setup_theme hook, which triggers before init.
28
		 */
29
		remove_theme_support( 'jetpack-devicepx' );
30
31
		// Sharing.
32
		add_filter( 'jetpack_sharing_display_markup', array( 'Jetpack_AMP_Support', 'render_sharing_html' ), 10, 2 );
33
		add_filter( 'sharing_enqueue_scripts', array( 'Jetpack_AMP_Support', 'amp_disable_sharedaddy_css' ) );
34
		add_action( 'wp_enqueue_scripts', array( 'Jetpack_AMP_Support', 'amp_enqueue_sharing_css' ) );
35
36
		// Sharing for Reader mode.
37
		if ( function_exists( 'jetpack_social_menu_include_svg_icons' ) ) {
38
			add_action( 'amp_post_template_footer', 'jetpack_social_menu_include_svg_icons' );
39
		}
40
		add_action( 'amp_post_template_css', array( 'Jetpack_AMP_Support', 'amp_reader_sharing_css' ), 10, 0 );
41
42
		// enforce freedom mode for videopress.
43
		add_filter( 'videopress_shortcode_options', array( 'Jetpack_AMP_Support', 'videopress_enable_freedom_mode' ) );
44
45
		// include Jetpack og tags when rendering native AMP head.
46
		add_action( 'amp_post_template_head', array( 'Jetpack_AMP_Support', 'amp_post_jetpack_og_tags' ) );
47
48
		// Post rendering changes for legacy AMP.
49
		add_action( 'pre_amp_render_post', array( 'Jetpack_AMP_Support', 'amp_disable_the_content_filters' ) );
50
51
		// Transitional mode AMP should not have comment likes.
52
		add_action( 'the_content', array( 'Jetpack_AMP_Support', 'disable_comment_likes_before_the_content' ) );
53
54
		// Add post template metadata for legacy AMP.
55
		add_filter( 'amp_post_template_metadata', array( 'Jetpack_AMP_Support', 'amp_post_template_metadata' ), 10, 2 );
56
57
		// Filter photon image args for AMP Stories.
58
		add_filter( 'jetpack_photon_post_image_args', array( 'Jetpack_AMP_Support', 'filter_photon_post_image_args_for_stories' ), 10, 2 );
59
60
		// Sync the amp-options.
61
		add_filter( 'jetpack_options_whitelist', array( 'Jetpack_AMP_Support', 'filter_jetpack_options_whitelist' ) );
62
63
		// Show admin bar.
64
		add_filter( 'show_admin_bar', array( 'Jetpack_AMP_Support', 'show_admin_bar' ) );
65
		add_filter( 'jetpack_comment_likes_enabled', array( 'Jetpack_AMP_Support', 'comment_likes_enabled' ) );
66
	}
67
68
	/**
69
	 * Disable the admin bar on AMP views.
70
	 *
71
	 * @param Whether bool $show the admin bar should be shown. Default false.
72
	 */
73
	public static function show_admin_bar( $show ) {
74
		return $show && ! self::is_amp_request();
75
	}
76
77
	/**
78
	 * Disable the Comment Likes feature on AMP views.
79
	 *
80
	 * @param bool $enabled Should comment likes be enabled.
81
	 */
82
	public static function comment_likes_enabled( $enabled ) {
83
		return $enabled && ! self::is_amp_request();
84
	}
85
86
	/**
87
	 * Apply custom AMP changes in wp-admin.
88
	 */
89
	public static function admin_init() {
90
		// disable Likes metabox for post editor if AMP canonical disabled.
91
		add_filter( 'post_flair_disable', array( 'Jetpack_AMP_Support', 'is_amp_canonical' ), 99 );
92
	}
93
94
	/**
95
	 * Is the page in AMP 'canonical mode'.
96
	 * Used when themes register support for AMP with `add_theme_support( 'amp' )`.
97
	 *
98
	 * @return bool is_amp_canonical
99
	 */
100
	public static function is_amp_canonical() {
101
		return function_exists( 'amp_is_canonical' ) && amp_is_canonical();
102
	}
103
104
	/**
105
	 * Does the page return AMP content.
106
	 *
107
	 * @return bool $is_amp_request Are we on am AMP view.
108
	 */
109
	public static function is_amp_request() {
110
		$is_amp_request = ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() );
111
112
		/**
113
		 * Returns true if the current request should return valid AMP content.
114
		 *
115
		 * @since 6.2.0
116
		 *
117
		 * @param boolean $is_amp_request Is this request supposed to return valid AMP content?
118
		 */
119
		return apply_filters( 'jetpack_is_amp_request', $is_amp_request );
120
	}
121
122
	/**
123
	 * Remove content filters added by Jetpack.
124
	 */
125
	public static function amp_disable_the_content_filters() {
126
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
127
			add_filter( 'videopress_show_2015_player', '__return_true' );
128
			add_filter( 'protected_embeds_use_form_post', '__return_false' );
129
			remove_filter( 'the_title', 'widont' );
130
		}
131
132
		remove_filter( 'pre_kses', array( 'Filter_Embedded_HTML_Objects', 'filter' ), 11 );
133
		remove_filter( 'pre_kses', array( 'Filter_Embedded_HTML_Objects', 'maybe_create_links' ), 100 );
134
	}
135
136
	/**
137
	 * Do not add comment likes on AMP requests.
138
	 *
139
	 * @param string $content Post content.
140
	 */
141
	public static function disable_comment_likes_before_the_content( $content ) {
142
		if ( self::is_amp_request() ) {
143
			remove_filter( 'comment_text', 'comment_like_button', 12, 2 );
144
		}
145
		return $content;
146
	}
147
148
	/**
149
	 * Add Jetpack stats pixel.
150
	 *
151
	 * @since 6.2.1
152
	 */
153
	public static function add_stats_pixel() {
154
		if ( ! has_action( 'wp_footer', 'stats_footer' ) ) {
155
			return;
156
		}
157
		stats_render_amp_footer( stats_build_view_data() );
158
	}
159
160
	/**
161
	 * Add publisher and image metadata to legacy AMP post.
162
	 *
163
	 * @since 6.2.0
164
	 *
165
	 * @param array   $metadata Metadata array.
166
	 * @param WP_Post $post     Post.
167
	 * @return array Modified metadata array.
168
	 */
169
	public static function amp_post_template_metadata( $metadata, $post ) {
170
		if ( isset( $metadata['publisher'] ) && ! isset( $metadata['publisher']['logo'] ) ) {
171
			$metadata = self::add_site_icon_to_metadata( $metadata );
172
		}
173
174
		if ( ! isset( $metadata['image'] ) ) {
175
			$metadata = self::add_image_to_metadata( $metadata, $post );
176
		}
177
178
		return $metadata;
179
	}
180
181
	/**
182
	 * Add blavatar to legacy AMP post metadata.
183
	 *
184
	 * @since 6.2.0
185
	 *
186
	 * @param array $metadata Metadata.
187
	 *
188
	 * @return array Metadata.
189
	 */
190
	private static function add_site_icon_to_metadata( $metadata ) {
191
		$size          = 60;
192
		$site_icon_url = class_exists( 'Automattic\\Jetpack\\Sync\\Functions' ) ? Functions::site_icon_url( $size ) : '';
193
194
		if ( function_exists( 'blavatar_domain' ) ) {
195
			$metadata['publisher']['logo'] = array(
196
				'@type'  => 'ImageObject',
197
				'url'    => blavatar_url( blavatar_domain( site_url() ), 'img', $size, self::staticize_subdomain( 'https://wordpress.com/i/favicons/apple-touch-icon-60x60.png' ) ),
198
				'width'  => $size,
199
				'height' => $size,
200
			);
201
		} elseif ( $site_icon_url ) {
202
			$metadata['publisher']['logo'] = array(
203
				'@type'  => 'ImageObject',
204
				'url'    => $site_icon_url,
205
				'width'  => $size,
206
				'height' => $size,
207
			);
208
		}
209
210
		return $metadata;
211
	}
212
213
	/**
214
	 * Add image to legacy AMP post metadata.
215
	 *
216
	 * @since 6.2.0
217
	 *
218
	 * @param array   $metadata Metadata.
219
	 * @param WP_Post $post     Post.
220
	 * @return array Metadata.
221
	 */
222
	private static function add_image_to_metadata( $metadata, $post ) {
223
		$image = Jetpack_PostImages::get_image(
224
			$post->ID,
225
			array(
226
				'fallback_to_avatars' => true,
227
				'avatar_size'         => 200,
228
				// AMP already attempts these.
229
				'from_thumbnail'      => false,
230
				'from_attachment'     => false,
231
			)
232
		);
233
234
		if ( empty( $image ) ) {
235
			return self::add_fallback_image_to_metadata( $metadata );
236
		}
237
238
		if ( ! isset( $image['src_width'] ) ) {
239
			$dimensions = self::extract_image_dimensions_from_getimagesize(
240
				array(
241
					$image['src'] => false,
242
				)
243
			);
244
245 View Code Duplication
			if ( false !== $dimensions[ $image['src'] ] ) {
246
				$image['src_width']  = $dimensions['width'];
247
				$image['src_height'] = $dimensions['height'];
248
			}
249
		}
250
251
		$metadata['image'] = array(
252
			'@type' => 'ImageObject',
253
			'url'   => $image['src'],
254
		);
255
		if ( isset( $image['src_width'] ) ) {
256
			$metadata['image']['width'] = $image['src_width'];
257
		}
258
		if ( isset( $image['src_width'] ) ) {
259
			$metadata['image']['height'] = $image['src_height'];
260
		}
261
262
		return $metadata;
263
	}
264
265
	/**
266
	 * Add fallback image to legacy AMP post metadata.
267
	 *
268
	 * @since 6.2.0
269
	 *
270
	 * @param array $metadata Metadata.
271
	 * @return array Metadata.
272
	 */
273
	private static function add_fallback_image_to_metadata( $metadata ) {
274
		/** This filter is documented in functions.opengraph.php */
275
		$default_image = apply_filters( 'jetpack_open_graph_image_default', 'https://wordpress.com/i/blank.jpg' );
276
277
		$metadata['image'] = array(
278
			'@type'  => 'ImageObject',
279
			'url'    => self::staticize_subdomain( $default_image ),
280
			'width'  => 200,
281
			'height' => 200,
282
		);
283
284
		return $metadata;
285
	}
286
287
	/**
288
	 * Return static WordPress.com domain to use to load resources from WordPress.com.
289
	 *
290
	 * @param string $domain Asset URL.
291
	 */
292
	private static function staticize_subdomain( $domain ) {
293
		// deal with WPCOM vs Jetpack.
294
		if ( function_exists( 'staticize_subdomain' ) ) {
295
			return staticize_subdomain( $domain );
296
		} else {
297
			return Jetpack::staticize_subdomain( $domain );
298
		}
299
	}
300
301
	/**
302
	 * Extract image dimensions via wpcom/imagesize, only on WPCOM
303
	 *
304
	 * @since 6.2.0
305
	 *
306
	 * @param array $dimensions Dimensions.
307
	 * @return array Dimensions.
308
	 */
309
	private static function extract_image_dimensions_from_getimagesize( $dimensions ) {
310
		if ( ! ( defined( 'IS_WPCOM' ) && IS_WPCOM && function_exists( 'require_lib' ) ) ) {
311
			return $dimensions;
312
		}
313
		require_lib( 'wpcom/imagesize' );
314
315
		foreach ( $dimensions as $url => $value ) {
316
			if ( is_array( $value ) ) {
317
				continue;
318
			}
319
			$result = wpcom_getimagesize( $url );
320
			if ( is_array( $result ) ) {
321
				$dimensions[ $url ] = array(
322
					'width'  => $result[0],
323
					'height' => $result[1],
324
				);
325
			}
326
		}
327
328
		return $dimensions;
329
	}
330
331
	/**
332
	 * Display Open Graph Meta tags in AMP views.
333
	 */
334
	public static function amp_post_jetpack_og_tags() {
335
		if ( ! ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ) {
336
			Jetpack::init()->check_open_graph();
337
		}
338
339
		if ( function_exists( 'jetpack_og_tags' ) ) {
340
			jetpack_og_tags();
341
		}
342
	}
343
344
	/**
345
	 * Force Freedom mode in VideoPress.
346
	 *
347
	 * @param array $options Array of VideoPress shortcode options.
348
	 */
349
	public static function videopress_enable_freedom_mode( $options ) {
350
		if ( self::is_amp_request() ) {
351
			$options['freedom'] = true;
352
		}
353
		return $options;
354
	}
355
356
	/**
357
	 * Display custom markup for the sharing buttons when in an AMP view.
358
	 *
359
	 * @param string $markup          Content markup of the Jetpack sharing links.
360
	 * @param array  $sharing_enabled Array of Sharing Services currently enabled.
361
	 */
362
	public static function render_sharing_html( $markup, $sharing_enabled ) {
363
		global $post;
364
365
		if ( empty( $post ) ) {
366
			return '';
367
		}
368
369
		if ( ! self::is_amp_request() ) {
370
			return $markup;
371
		}
372
373
		remove_action( 'wp_footer', 'sharing_add_footer' );
374
		if ( empty( $sharing_enabled ) ) {
375
			return $markup;
376
		}
377
378
		$sharing_links = array();
379
		foreach ( $sharing_enabled['visible'] as $id => $service ) {
380
			$sharing_link = $service->get_amp_display( $post );
381
			if ( ! empty( $sharing_link ) ) {
382
				$sharing_links[] = $sharing_link;
383
			}
384
		}
385
386
		// Replace the existing unordered list with AMP sharing buttons.
387
		$markup = preg_replace( '#<ul>(.+)</ul>#', implode( '', $sharing_links ), $markup );
388
389
		// Remove any lingering share-end list items.
390
		$markup = str_replace( '<li class="share-end"></li>', '', $markup );
391
392
		return $markup;
393
	}
394
395
	/**
396
	 * Tells Jetpack not to enqueue CSS for share buttons.
397
	 *
398
	 * @param  bool $enqueue Whether or not to enqueue.
399
	 * @return bool          Whether or not to enqueue.
400
	 */
401
	public static function amp_disable_sharedaddy_css( $enqueue ) {
402
		if ( self::is_amp_request() ) {
403
			$enqueue = false;
404
		}
405
406
		return $enqueue;
407
	}
408
409
	/**
410
	 * Enqueues the AMP specific sharing styles for the sharing icons.
411
	 */
412
	public static function amp_enqueue_sharing_css() {
413
		if ( self::is_amp_request() ) {
414
			wp_enqueue_style( 'sharedaddy-amp', plugin_dir_url( dirname( __FILE__ ) ) . 'modules/sharedaddy/amp-sharing.css', array( 'social-logos' ), JETPACK__VERSION );
415
		}
416
	}
417
418
	/**
419
	 * For the AMP Reader mode template, include styles that we need.
420
	 */
421
	public static function amp_reader_sharing_css() {
422
		echo file_get_contents( plugin_dir_path( dirname( __FILE__ ) ) . '_inc/social-logos/social-logos.css' ); // phpcs:ignore
423
		echo file_get_contents( plugin_dir_path( dirname( __FILE__ ) ) . 'modules/sharedaddy/amp-sharing.css' ); // phpcs:ignore
424
	}
425
426
	/**
427
	 * Ensure proper Photon image dimensions for AMP Stories.
428
	 *
429
	 * @param array $args Array of Photon Arguments.
430
	 * @param array $details {
431
	 *     Array of image details.
432
	 *
433
	 *     @type string    $tag            Image tag (Image HTML output).
434
	 *     @type string    $src            Image URL.
435
	 *     @type string    $src_orig       Original Image URL.
436
	 *     @type int|false $width          Image width.
437
	 *     @type int|false $height         Image height.
438
	 *     @type int|false $width_orig     Original image width before constrained by content_width.
439
	 *     @type int|false $height_orig    Original Image height before constrained by content_width.
440
	 *     @type string    $transform_orig Original transform before constrained by content_width.
441
	 * }
442
	 * @return array Args.
443
	 */
444
	public static function filter_photon_post_image_args_for_stories( $args, $details ) {
445
		if ( ! is_singular( 'amp_story' ) ) {
446
			return $args;
447
		}
448
449
		// Percentage-based dimensions are not allowed in AMP, so this shouldn't happen, but short-circuit just in case.
450
		if ( false !== strpos( $details['width_orig'], '%' ) || false !== strpos( $details['height_orig'], '%' ) ) {
451
			return $args;
452
		}
453
454
		$max_height = 1280; // See image size with the slug \AMP_Story_Post_Type::MAX_IMAGE_SIZE_SLUG.
455
		$transform  = $details['transform_orig'];
456
		$width      = $details['width_orig'];
457
		$height     = $details['height_orig'];
458
459
		// If height is available, constrain to $max_height.
460
		if ( false !== $height ) {
461
			if ( $height > $max_height && false !== $height ) {
462
				$width  = ( $max_height * $width ) / $height;
463
				$height = $max_height;
464
			} elseif ( $height > $max_height ) {
465
				$height = $max_height;
466
			}
467
		}
468
469
		/*
470
		 * Set a height if none is found.
471
		 * If height is set in this manner and height is available, use `fit` instead of `resize` to prevent skewing.
472
		 */
473
		if ( false === $height ) {
474
			$height = $max_height;
475
			if ( false !== $width ) {
476
				$transform = 'fit';
477
			}
478
		}
479
480
		// Build array of Photon args and expose to filter before passing to Photon URL function.
481
		$args = array();
482
483
		if ( false !== $width && false !== $height ) {
484
			$args[ $transform ] = $width . ',' . $height;
485
		} elseif ( false !== $width ) {
486
			$args['w'] = $width;
487
		} elseif ( false !== $height ) {
488
			$args['h'] = $height;
489
		}
490
491
		return $args;
492
	}
493
494
	/**
495
	 *  Adds amp-options to the list of options to sync, if AMP is available
496
	 *
497
	 * @param array $options_whitelist Whitelist of options to sync.
498
	 * @return array Updated options whitelist
499
	 */
500
	public static function filter_jetpack_options_whitelist( $options_whitelist ) {
501
		if ( function_exists( 'is_amp_endpoint' ) ) {
502
			$options_whitelist[] = 'amp-options';
503
		}
504
		return $options_whitelist;
505
	}
506
}
507
508
add_action( 'init', array( 'Jetpack_AMP_Support', 'init' ), 1 );
509
510
add_action( 'admin_init', array( 'Jetpack_AMP_Support', 'admin_init' ), 1 );
511