Completed
Push — add/amp-wp-support ( 6f4057...af4db8 )
by
unknown
09:35
created

Jetpack_AMP_Support   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 284
Duplicated Lines 1.41 %

Coupling/Cohesion

Components 2
Dependencies 2

Importance

Changes 0
Metric Value
dl 4
loc 284
rs 8.3673
c 0
b 0
f 0
wmc 45
lcom 2
cbo 2

17 Methods

Rating   Name   Duplication   Size   Complexity  
B init() 0 29 2
A admin_init() 0 4 1
A init_filter_jetpack_widgets() 0 8 2
A is_amp_canonical() 0 3 2
A is_amp_request() 0 10 4
A filter_available_widgets() 0 7 2
A is_supported_widget() 0 3 1
A amp_disable_the_content_filters() 0 10 3
A amp_post_template_metadata() 0 11 4
A add_blavatar_to_metadata() 0 16 2
B add_image_to_metadata() 4 33 4
A add_fallback_image_to_metadata() 0 10 1
A staticize_subdomain() 0 8 2
B extract_image_dimensions_from_getimagesize() 0 21 7
A amp_post_jetpack_og_tags() 0 6 2
A videopress_enable_freedom_mode() 0 4 1
B render_sharing_html() 0 40 5

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Jetpack_AMP_Support often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Jetpack_AMP_Support, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * Manages compatibility with the amp-wp plugin
5
 *
6
 * @see https://github.com/Automattic/amp-wp
7
 */
8
class Jetpack_AMP_Support {
9
10
	static function init() {
11
		if ( ! self::is_amp_request() ) {
12
			return;
13
		}
14
15
		// carousel
16
		add_filter( 'jp_carousel_maybe_disable', '__return_true' );
17
18
		// sharing
19
		add_filter( 'sharing_enqueue_scripts', '__return_false' );
20
		add_filter( 'jetpack_sharing_counts', '__return_false' );
21
		add_filter( 'sharing_js', '__return_false' );
22
		add_filter( 'jetpack_sharing_display_markup', array( 'Jetpack_AMP_Support', 'render_sharing_html' ), 10, 2 );
23
24
		// disable imploding CSS
25
		add_filter( 'jetpack_implode_frontend_css', '__return_false' );
26
27
		// enforce freedom mode for videopress
28
		add_filter( 'videopress_shortcode_options', array( 'Jetpack_AMP_Support', 'videopress_enable_freedom_mode' ) );
29
30
		// include Jetpack og tags when rendering native AMP head
31
		add_action( 'amp_post_template_head', array( 'Jetpack_AMP_Support', 'amp_post_jetpack_og_tags' ) );
32
33
		// Post rendering changes for legacy AMP
34
		add_action( 'pre_amp_render_post', array( 'Jetpack_AMP_Support', 'amp_disable_the_content_filters' ) );
35
36
		// Add post template metadata for legacy AMP
37
		add_filter( 'amp_post_template_metadata', array( 'Jetpack_AMP_Support', 'amp_post_template_metadata' ), 10, 2 );
38
	}
39
40
	static function admin_init() {
41
		// disable Likes metabox for post editor if AMP canonical disabled
42
		add_filter( 'post_flair_disable',  array( 'Jetpack_AMP_Support', 'is_amp_canonical' ), 99 );
43
	}
44
45
	static function init_filter_jetpack_widgets() {
46
		if ( ! self::is_amp_request() ) {
47
			return;
48
		}
49
50
		// widgets
51
		add_filter( 'jetpack_widgets_to_include', array( 'Jetpack_AMP_Support', 'filter_available_widgets' ) );
52
	}
53
54
	static function is_amp_canonical() {
55
		return function_exists( 'amp_is_canonical' ) && amp_is_canonical();
56
	}
57
58
	static function is_amp_request() {
59
		// can't use is_amp_endpoint() since it's not ready early enough in init.
60
		// is_amp_endpoint() implementation calls is_feed, which bails with a notice if plugins_loaded isn't finished
61
		// "Conditional query tags do not work before the query is run"
62
		return ! is_admin() // this is necessary so that modules can still be enabled/disabled/configured as per normal via Jetpack admin
63
			&&
64
				function_exists( 'amp_is_canonical' ) // this is really just testing if the plugin exists
65
			&&
66
				( amp_is_canonical() || isset( $_GET[ amp_get_slug() ] ) );
67
	}
68
69
	static function filter_available_widgets( $widgets ) {
70
		if ( self::is_amp_request() ) {
71
			$widgets = array_filter( $widgets, array( 'Jetpack_AMP_Support', 'is_supported_widget' ) );
72
		}
73
74
		return $widgets;
75
	}
76
77
	static function is_supported_widget( $widget_path ) {
78
		return substr($widget_path, -14) !== '/milestone.php';
79
	}
80
81
	static function amp_disable_the_content_filters() {
82
		if ( defined( 'WPCOM') && WPCOM ) {
83
			add_filter( 'videopress_show_2015_player', '__return_true' );
84
			add_filter( 'protected_embeds_use_form_post', '__return_false' );
85
			remove_filter( 'the_title', 'widont' );
86
		}
87
88
		remove_filter( 'pre_kses', array( 'Filter_Embedded_HTML_Objects', 'filter' ), 11 );
89
		remove_filter( 'pre_kses', array( 'Filter_Embedded_HTML_Objects', 'maybe_create_links' ), 100 );
90
	}
91
92
	/**
93
	 * Add publisher and image metadata.
94
	 *
95
	 * @since 0.3
96
	 *
97
	 * @param array   $metadata Metadata array.
98
	 * @param WP_Post $post     Post.
99
	 * @return array Modified metadata array.
100
	 */
101
	static function amp_post_template_metadata( $metadata, $post ) {
102
		if ( isset( $metadata['publisher'] ) && ! isset( $metadata['publisher']['logo'] ) ) {
103
			$metadata = self::add_blavatar_to_metadata( $metadata );
104
		}
105
106
		if ( ! isset( $metadata['image'] ) ) {
107
			$metadata = self::add_image_to_metadata( $metadata, $post );
108
		}
109
110
		return $metadata;
111
	}
112
113
	/**
114
	 * Add blavatar to metadata.
115
	 *
116
	 * @since 0.3
117
	 *
118
	 * @param array $metadata Metadata.
119
	 * @return array Metadata.
120
	 */
121
	static function add_blavatar_to_metadata( $metadata ) {
122
		if ( ! function_exists( 'blavatar_domain' ) ) {
123
			return $metadata;
124
		}
125
126
		$size = 60;
127
128
		$metadata['publisher']['logo'] = array(
129
			'@type'  => 'ImageObject',
130
			'url'    => blavatar_url( blavatar_domain( site_url() ), 'img', $size, self::staticize_subdomain( 'https://wordpress.com/i/favicons/apple-touch-icon-60x60.png' ) ),
131
			'width'  => $size,
132
			'height' => $size,
133
		);
134
135
		return $metadata;
136
	}
137
138
	/**
139
	 * Add image to metadata.
140
	 *
141
	 * @since 0.3.2
142
	 *
143
	 * @param array   $metadata Metadata.
144
	 * @param WP_Post $post     Post.
145
	 * @return array Metadata.
146
	 */
147
	static function add_image_to_metadata( $metadata, $post ) {
148
		$image = Jetpack_PostImages::get_image( $post->ID, array(
149
			'fallback_to_avatars' => true,
150
			'avatar_size'         => 200,
151
			// AMP already attempts these.
152
			'from_thumbnail'      => false,
153
			'from_attachment'     => false,
154
		) );
155
156
		if ( empty( $image ) ) {
157
			return self::add_fallback_image_to_metadata( $metadata );
158
		}
159
160
		if ( ! isset( $image['src_width'] ) ) {
161
			$dimensions = self::extract_image_dimensions_from_getimagesize( array(
162
				$image['src'] => false,
163
			) );
164
165 View Code Duplication
			if ( false !== $dimensions[ $image['src'] ] ) {
166
				$image['src_width']  = $dimensions['width'];
167
				$image['src_height'] = $dimensions['height'];
168
			}
169
		}
170
171
		$metadata['image'] = array(
172
			'@type'  => 'ImageObject',
173
			'url'    => $image['src'],
174
			'width'  => $image['src_width'],
175
			'height' => $image['src_height'],
176
		);
177
178
		return $metadata;
179
	}
180
181
	/**
182
	 * Add fallback image to metadata.
183
	 *
184
	 * @since 0.3.2
185
	 *
186
	 * @param array $metadata Metadata.
187
	 * @return array Metadata.
188
	 */
189
	static function add_fallback_image_to_metadata( $metadata ) {
190
		$metadata['image'] = array(
191
			'@type'  => 'ImageObject',
192
			'url'    => self::staticize_subdomain( 'https://wordpress.com/i/blank.jpg' ),
193
			'width'  => 200,
194
			'height' => 200,
195
		);
196
197
		return $metadata;
198
	}
199
200
	static function staticize_subdomain( $domain ) {
201
		// deal with WPCOM vs Jetpack
202
		if ( function_exists( 'staticize_subdomain' ) ) {
203
			return staticize_subdomain( $domain );
204
		} else {
205
			return Jetpack::staticize_subdomain( $domain );
206
		}
207
	}
208
209
	/**
210
	 * Extract image dimensions via wpcom/imagesize.
211
	 *
212
	 * @since 0.5
213
	 *
214
	 * @param array $dimensions Dimensions.
215
	 * @return array Dimensions.
216
	 */
217
	static function extract_image_dimensions_from_getimagesize( $dimensions ) {
218
		if ( ! ( defined('WPCOM') && WPCOM && function_exists( 'require_lib' ) ) ) {
219
			return $dimensions;
220
		}
221
		require_lib( 'wpcom/imagesize' );
222
223
		foreach ( $dimensions as $url => $value ) {
224
			if ( is_array( $value ) ) {
225
				continue;
226
			}
227
			$result = wpcom_getimagesize( $url );
228
			if ( is_array( $result ) ) {
229
				$dimensions[ $url ] = array(
230
					'width'  => $result[0],
231
					'height' => $result[1],
232
				);
233
			}
234
		}
235
236
		return $dimensions;
237
	}
238
239
	static function amp_post_jetpack_og_tags() {
240
		Jetpack::init()->check_open_graph();
241
		if ( function_exists( 'jetpack_og_tags' ) ) {
242
			jetpack_og_tags();
243
		}
244
	}
245
246
	static function videopress_enable_freedom_mode( $options ) {
247
		$options['freedom'] = true;
248
		return $options;
249
	}
250
251
	static function render_sharing_html( $markup, $sharing_enabled ) {
252
		remove_action( 'wp_footer', 'sharing_add_footer' );
253
		if ( empty( $sharing_enabled ) ) {
254
			return $markup;
255
		}
256
		$supported_services = array(
257
			'facebook'      => array(
258
				/** This filter is documented in modules/sharedaddy/sharing-sources.php */
259
				'data-param-app_id' => apply_filters( 'jetpack_sharing_facebook_app_id', '249643311490' ),
260
			),
261
			'twitter'       => array(),
262
			'pinterest'     => array(),
263
			'whatsapp'      => array(),
264
			'google-plus-1' => array(
265
				'type' => 'gplus',
266
			),
267
			'tumblr'        => array(),
268
			'linkedin'      => array(),
269
		);
270
		$sharing_links = array();
271
		foreach ( $sharing_enabled['visible'] as $id => $service ) {
272
			if ( ! isset( $supported_services[ $id ] ) ) {
273
				$sharing_links[] = "<!-- not supported: $id -->";
274
				continue;
275
			}
276
			$args = array_merge(
277
				array(
278
					'type' => $id,
279
				),
280
				$supported_services[ $id ]
281
			);
282
			$sharing_link = '<amp-social-share';
283
			foreach ( $args as $key => $value ) {
284
				$sharing_link .= sprintf( ' %s="%s"', sanitize_key( $key ), esc_attr( $value ) );
285
			}
286
			$sharing_link .= '></amp-social-share>';
287
			$sharing_links[] = $sharing_link;
288
		}
289
		return preg_replace( '#(?<=<div class="sd-content">).+?(?=</div>)#s', implode( '', $sharing_links ), $markup );
290
	}
291
}
292
293
add_action( 'init', array( 'Jetpack_AMP_Support', 'init' ), 1 );
294
295
add_action( 'admin_init', array( 'Jetpack_AMP_Support', 'admin_init' ), 1 );
296
297
// this is necessary since for better or worse Jetpack modules and widget files are loaded during plugins_loaded, which means we must
298
// take the opportunity to intercept initialisation before that point, either by adding explicit detection into the module,
299
// or preventing it from loading in the first place (better for performance)
300
add_action( 'plugins_loaded', array( 'Jetpack_AMP_Support', 'init_filter_jetpack_widgets' ), 1 );