|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* Facebook embeds |
|
4
|
|
|
* |
|
5
|
|
|
* @package Jetpack |
|
6
|
|
|
*/ |
|
7
|
|
|
|
|
8
|
|
|
use Automattic\Jetpack\Connection\Client; |
|
9
|
|
|
use Automattic\Jetpack\Constants; |
|
10
|
|
|
|
|
11
|
|
|
define( 'JETPACK_FACEBOOK_EMBED_REGEX', '#^https?://(www.)?facebook\.com/([^/]+)/(posts|photos)/([^/]+)?#' ); |
|
12
|
|
|
define( 'JETPACK_FACEBOOK_ALTERNATE_EMBED_REGEX', '#^https?://(www.)?facebook\.com/permalink.php\?([^\s]+)#' ); |
|
13
|
|
|
define( 'JETPACK_FACEBOOK_PHOTO_EMBED_REGEX', '#^https?://(www.)?facebook\.com/photo.php\?([^\s]+)#' ); |
|
14
|
|
|
define( 'JETPACK_FACEBOOK_PHOTO_ALTERNATE_EMBED_REGEX', '#^https?://(www.)?facebook\.com/([^/]+)/photos/([^/]+)?#' ); |
|
15
|
|
|
define( 'JETPACK_FACEBOOK_VIDEO_EMBED_REGEX', '#^https?://(www.)?facebook\.com/(?:video.php|watch\/?)\?([^\s]+)#' ); |
|
16
|
|
|
define( 'JETPACK_FACEBOOK_VIDEO_ALTERNATE_EMBED_REGEX', '#^https?://(www.)?facebook\.com/([^/]+)/videos/([^/]+)?#' ); |
|
17
|
|
|
|
|
18
|
|
|
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) { |
|
19
|
|
|
add_action( 'init', 'jetpack_facebook_enable_embeds' ); |
|
20
|
|
|
} else { |
|
21
|
|
|
jetpack_facebook_enable_embeds(); |
|
22
|
|
|
} |
|
23
|
|
|
|
|
24
|
|
|
/** |
|
25
|
|
|
* Register Facebook as oembed provider, and add required filters for the API request. |
|
26
|
|
|
* Register [facebook] shortcode. |
|
27
|
|
|
* |
|
28
|
|
|
* @since 9.2.0 |
|
29
|
|
|
*/ |
|
30
|
|
|
function jetpack_facebook_enable_embeds() { |
|
31
|
|
|
$facebook_oembeds = array( |
|
32
|
|
|
'#https?://www\.facebook\.com/.*/posts/.*#i' => array( 'https://graph.facebook.com/v9.0/oembed_post', true ), |
|
33
|
|
|
'#https?://www\.facebook\.com/.*/activity/.*#i' => array( 'https://graph.facebook.com/v9.0/oembed_post', true ), |
|
34
|
|
|
'#https?://www\.facebook\.com/.*/photos/.*#i' => array( 'https://graph.facebook.com/v9.0/oembed_post', true ), |
|
35
|
|
|
'#https?://www\.facebook\.com/photo(s/|\.php).*#i' => array( 'https://graph.facebook.com/v9.0/oembed_post', true ), |
|
36
|
|
|
'#https?://www\.facebook\.com/permalink\.php.*#i' => array( 'https://graph.facebook.com/v9.0/oembed_post', true ), |
|
37
|
|
|
'#https?://www\.facebook\.com/media/.*#i' => array( 'https://graph.facebook.com/v9.0/oembed_post', true ), |
|
38
|
|
|
'#https?://www\.facebook\.com/questions/.*#i' => array( 'https://graph.facebook.com/v9.0/oembed_post', true ), |
|
39
|
|
|
'#https?://www\.facebook\.com/notes/.*#i' => array( 'https://graph.facebook.com/v9.0/oembed_post', true ), |
|
40
|
|
|
'#https?://www\.facebook\.com/.*/videos/.*#i' => array( 'https://graph.facebook.com/v9.0/oembed_video', true ), |
|
41
|
|
|
'#https?://www\.facebook\.com/video\.php.*#i' => array( 'https://graph.facebook.com/v9.0/oembed_video', true ), |
|
42
|
|
|
); |
|
43
|
|
|
|
|
44
|
|
|
foreach ( $facebook_oembeds as $pattern => $embed_data ) { |
|
45
|
|
|
wp_oembed_remove_provider( $pattern ); // Remove Core's oEmbed handler, if present (WP <= 5.5.2). |
|
46
|
|
|
wp_oembed_add_provider( $pattern, $embed_data[0], $embed_data[1] ); |
|
47
|
|
|
} |
|
48
|
|
|
|
|
49
|
|
|
/** |
|
50
|
|
|
* Add auth token required by Facebook's oEmbed REST API, or proxy through WP.com. |
|
51
|
|
|
*/ |
|
52
|
|
|
add_filter( 'oembed_fetch_url', 'jetpack_facebook_oembed_fetch_url', 10, 2 ); |
|
53
|
|
|
|
|
54
|
|
|
/** |
|
55
|
|
|
* Add JP auth headers if we're proxying through WP.com. |
|
56
|
|
|
*/ |
|
57
|
|
|
add_filter( 'oembed_remote_get_args', 'jetpack_facebook_oembed_remote_get_args', 10, 2 ); |
|
58
|
|
|
|
|
59
|
|
|
/** |
|
60
|
|
|
* Add the shortcode. |
|
61
|
|
|
*/ |
|
62
|
|
|
add_shortcode( 'facebook', 'jetpack_facebook_shortcode_handler' ); |
|
63
|
|
|
} |
|
64
|
|
|
|
|
65
|
|
|
/** |
|
66
|
|
|
* Add auth token required by Facebook's oEmbed REST API, or proxy through WP.com. |
|
67
|
|
|
* |
|
68
|
|
|
* @since 9.2.0 |
|
69
|
|
|
* |
|
70
|
|
|
* @param string $provider URL of the oEmbed provider. |
|
71
|
|
|
* @param string $url URL of the content to be embedded. |
|
72
|
|
|
* |
|
73
|
|
|
* @return string |
|
74
|
|
|
*/ |
|
75
|
|
|
function jetpack_facebook_oembed_fetch_url( $provider, $url ) { |
|
76
|
|
|
if ( ! wp_startswith( $provider, 'https://graph.facebook.com/v9.0/oembed_' ) ) { |
|
77
|
|
|
return $provider; |
|
78
|
|
|
} |
|
79
|
|
|
|
|
80
|
|
|
// Get a set of URL and parameters supported by Facebook. |
|
81
|
|
|
$clean_parameters = array(); // jetpack_facebook_get_allowed_parameters( $url ); // FIXME! |
|
82
|
|
|
|
|
83
|
|
|
// Replace existing URL by our clean version. |
|
84
|
|
View Code Duplication |
if ( ! empty( $clean_parameters['url'] ) ) { |
|
85
|
|
|
$provider = add_query_arg( 'url', rawurlencode( $clean_parameters['url'] ), $provider ); |
|
86
|
|
|
} |
|
87
|
|
|
|
|
88
|
|
|
// Our shortcode supports the width param, but the API expects maxwidth. |
|
89
|
|
|
if ( ! empty( $clean_parameters['width'] ) ) { |
|
90
|
|
|
$provider = add_query_arg( 'maxwidth', $clean_parameters['width'], $provider ); |
|
91
|
|
|
} |
|
92
|
|
|
|
|
93
|
|
|
if ( ! empty( $clean_parameters['hidecaption'] ) ) { |
|
94
|
|
|
$provider = add_query_arg( 'hidecaption', true, $provider ); |
|
95
|
|
|
} |
|
96
|
|
|
|
|
97
|
|
|
$access_token = jetpack_facebook_get_access_token(); |
|
98
|
|
|
|
|
99
|
|
|
if ( ! empty( $access_token ) ) { |
|
100
|
|
|
return add_query_arg( 'access_token', $access_token, $provider ); |
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
|
|
// If we don't have an access token, we go through the WP.com proxy instead. |
|
104
|
|
|
// To that end, we need to make sure that we're connected to WP.com. |
|
105
|
|
|
if ( ! Jetpack::is_active_and_not_offline_mode() ) { |
|
106
|
|
|
return $provider; |
|
107
|
|
|
} |
|
108
|
|
|
|
|
109
|
|
|
$site_id = \Jetpack_Options::get_option( 'id' ); |
|
110
|
|
|
$wpcom_oembed_proxy = Constants::get_constant( 'JETPACK__WPCOM_JSON_API_BASE' ) . "/oembed/1.0/sites/$site_id/proxy"; |
|
111
|
|
|
return str_replace( |
|
112
|
|
|
array( |
|
113
|
|
|
'https://graph.facebook.com/v9.0/oembed_page', |
|
114
|
|
|
'https://graph.facebook.com/v9.0/oembed_post', |
|
115
|
|
|
'https://graph.facebook.com/v9.0/oembed_video', |
|
116
|
|
|
), |
|
117
|
|
|
$wpcom_oembed_proxy, |
|
118
|
|
|
$provider |
|
119
|
|
|
); |
|
120
|
|
|
} |
|
121
|
|
|
|
|
122
|
|
|
/** |
|
123
|
|
|
* Add JP auth headers if we're proxying through WP.com. |
|
124
|
|
|
* |
|
125
|
|
|
* @since 9.2.0 |
|
126
|
|
|
* |
|
127
|
|
|
* @param array $args oEmbed remote get arguments. |
|
128
|
|
|
* @param string $url URL to be inspected. |
|
129
|
|
|
*/ |
|
130
|
|
View Code Duplication |
function jetpack_facebook_oembed_remote_get_args( $args, $url ) { |
|
|
|
|
|
|
131
|
|
|
if ( ! wp_startswith( $url, Constants::get_constant( 'JETPACK__WPCOM_JSON_API_BASE' ) . '/oembed/1.0/' ) ) { |
|
132
|
|
|
return $args; |
|
133
|
|
|
} |
|
134
|
|
|
|
|
135
|
|
|
$method = 'GET'; |
|
136
|
|
|
$signed_request = Client::build_signed_request( |
|
137
|
|
|
compact( 'url', 'method' ) |
|
138
|
|
|
); |
|
139
|
|
|
|
|
140
|
|
|
return $signed_request['request']; |
|
141
|
|
|
} |
|
142
|
|
|
|
|
143
|
|
|
/** |
|
144
|
|
|
* Fetches a Facebook API access token used for query for Facebook embed information, if one is set. |
|
145
|
|
|
* |
|
146
|
|
|
* @return string The access token or '' |
|
147
|
|
|
*/ |
|
148
|
|
|
function jetpack_facebook_get_access_token() { |
|
149
|
|
|
/** |
|
150
|
|
|
* Filters the Facebook embed token that is used for querying the Facebook API. |
|
151
|
|
|
* |
|
152
|
|
|
* When this token is set, requests are not proxied through the WordPress.com API. Instead, a request is made directly to the |
|
153
|
|
|
* Facebook API to query for information about the embed which should provide a performance benefit. |
|
154
|
|
|
* |
|
155
|
|
|
* @module shortcodes |
|
156
|
|
|
* |
|
157
|
|
|
* @since 9.2.0 |
|
158
|
|
|
* |
|
159
|
|
|
* @param string string The access token set via the JETPACK_FACEBOOK_EMBED_TOKEN constant. |
|
160
|
|
|
*/ |
|
161
|
|
|
return (string) apply_filters( 'jetpack_facebook_embed_token', (string) Constants::get_constant( 'JETPACK_FACEBOOK_EMBED_TOKEN' ) ); |
|
162
|
|
|
} |
|
163
|
|
|
|
|
164
|
|
|
/** |
|
165
|
|
|
* Shortcode handler. |
|
166
|
|
|
* |
|
167
|
|
|
* @param array $atts Shortcode attributes. |
|
168
|
|
|
*/ |
|
169
|
|
|
function jetpack_facebook_shortcode_handler( $atts ) { |
|
170
|
|
|
global $wp_embed; |
|
171
|
|
|
|
|
172
|
|
|
if ( empty( $atts['url'] ) ) { |
|
173
|
|
|
return; |
|
174
|
|
|
} |
|
175
|
|
|
|
|
176
|
|
|
if ( ! preg_match( JETPACK_FACEBOOK_EMBED_REGEX, $atts['url'] ) |
|
177
|
|
|
&& ! preg_match( JETPACK_FACEBOOK_PHOTO_EMBED_REGEX, $atts['url'] ) |
|
178
|
|
|
&& ! preg_match( JETPACK_FACEBOOK_VIDEO_EMBED_REGEX, $atts['url'] ) |
|
179
|
|
|
&& ! preg_match( JETPACK_FACEBOOK_VIDEO_ALTERNATE_EMBED_REGEX, $atts['url'] ) ) { |
|
180
|
|
|
return; |
|
181
|
|
|
} |
|
182
|
|
|
|
|
183
|
|
|
return $wp_embed->shortcode( $atts, $atts['url'] ); |
|
184
|
|
|
} |
|
185
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.