PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 6.7.2
Jetpack – WP Security, Backup, Speed, & Growth v6.7.2
15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / class.jetpack-twitter-cards.php
jetpack Last commit date
3rd-party 7 years ago _inc 6 years ago bin 7 years ago css 7 years ago images 6 years ago json-endpoints 7 years ago languages 7 years ago modules 5 years ago sal 7 years ago scss 7 years ago sync 7 years ago views 7 years ago .svnignore 12 years ago CODE-OF-CONDUCT.md 9 years ago changelog.txt 7 years ago class.frame-nonce-preview.php 9 years ago class.jetpack-admin.php 7 years ago class.jetpack-autoupdate.php 8 years ago class.jetpack-bbpress-json-api-compat.php 9 years ago class.jetpack-cli.php 7 years ago class.jetpack-client-server.php 8 years ago class.jetpack-client.php 7 years ago class.jetpack-connection-banner.php 7 years ago class.jetpack-constants.php 8 years ago class.jetpack-data.php 7 years ago class.jetpack-debugger.php 7 years ago class.jetpack-error.php 10 years ago class.jetpack-gutenberg.php 7 years ago class.jetpack-heartbeat.php 7 years ago class.jetpack-idc.php 8 years ago class.jetpack-ixr-client.php 10 years ago class.jetpack-jitm.php 7 years ago class.jetpack-modules-list-table.php 8 years ago class.jetpack-network-sites-list-table.php 9 years ago class.jetpack-network.php 7 years ago class.jetpack-options.php 7 years ago class.jetpack-post-images.php 7 years ago class.jetpack-signature.php 7 years ago class.jetpack-tracks.php 8 years ago class.jetpack-twitter-cards.php 7 years ago class.jetpack-user-agent.php 8 years ago class.jetpack-xmlrpc-server.php 7 years ago class.jetpack.php 7 years ago class.json-api-endpoints.php 7 years ago class.json-api.php 7 years ago class.photon.php 7 years ago composer.json 7 years ago functions.compat.php 7 years ago functions.gallery.php 8 years ago functions.global.php 7 years ago functions.opengraph.php 7 years ago functions.photon.php 8 years ago jetpack.php 5 years ago json-api-config.php 10 years ago json-endpoints.php 7 years ago locales.php 9 years ago readme.txt 5 years ago require-lib.php 7 years ago uninstall.php 8 years ago wpml-config.xml 10 years ago
class.jetpack-twitter-cards.php
254 lines
1 <?php
2
3 /* Twitter Cards
4 *
5 * Hooks onto the Open Graph protocol and extends it by adding only the tags
6 * we need for twitter cards.
7 *
8 * @see /wp-content/blog-plugins/open-graph.php
9 * @see https://dev.twitter.com/cards/overview
10 */
11 class Jetpack_Twitter_Cards {
12
13 static function twitter_cards_tags( $og_tags ) {
14 global $post;
15
16 if ( post_password_required() ) {
17 return $og_tags;
18 }
19
20 /** This action is documented in class.jetpack.php */
21 if ( apply_filters( 'jetpack_disable_twitter_cards', false ) ) {
22 return $og_tags;
23 }
24
25 /*
26 * These tags apply to any page (home, archives, etc)
27 */
28
29 // If we have information on the author/creator, then include that as well
30 if ( ! empty( $post ) && ! empty( $post->post_author ) ) {
31 /** This action is documented in modules/sharedaddy/sharing-sources.php */
32 $handle = apply_filters( 'jetpack_sharing_twitter_via', '', $post->ID );
33 if ( ! empty( $handle ) && ! self::is_default_site_tag( $handle ) ) {
34 $og_tags['twitter:creator'] = self::sanitize_twitter_user( $handle );
35 }
36 }
37
38 $site_tag = self::site_tag();
39 /** This action is documented in modules/sharedaddy/sharing-sources.php */
40 $site_tag = apply_filters( 'jetpack_sharing_twitter_via', $site_tag, ( is_singular() ? $post->ID : null ) );
41 /** This action is documented in modules/sharedaddy/sharing-sources.php */
42 $site_tag = apply_filters( 'jetpack_twitter_cards_site_tag', $site_tag, $og_tags );
43 if ( ! empty( $site_tag ) ) {
44 $og_tags['twitter:site'] = self::sanitize_twitter_user( $site_tag );
45 }
46
47 if ( ! is_singular() || ! empty( $og_tags['twitter:card'] ) ) {
48 /**
49 * Filter the default Twitter card image, used when no image can be found in a post.
50 *
51 * @module sharedaddy, publicize
52 *
53 * @since 5.9.0
54 *
55 * @param string $str Default image URL.
56 */
57 $image = apply_filters( 'jetpack_twitter_cards_image_default', '' );
58 if ( ! empty( $image ) ) {
59 $og_tags['twitter:image'] = $image;
60 }
61
62 return $og_tags;
63 }
64
65 $the_title = get_the_title();
66 if ( ! $the_title ) {
67 $the_title = get_bloginfo( 'name' );
68 }
69 $og_tags['twitter:text:title'] = $the_title;
70
71 /*
72 * The following tags only apply to single pages.
73 */
74
75 $card_type = 'summary';
76
77 // Try to give priority to featured images
78 if ( class_exists('Jetpack_PostImages') ) {
79 $featured = Jetpack_PostImages::from_thumbnail( $post->ID, 240, 240 );
80 if ( !empty( $featured ) && count( $featured ) > 0 ) {
81 if ( (int) $featured[0]['src_width'] >= 280 && (int) $featured[0]['src_height'] >= 150 ) {
82 $card_type = 'summary_large_image';
83 $og_tags['twitter:image'] = esc_url( add_query_arg( 'w', 640, $featured[0]['src'] ) );
84 } else {
85 $og_tags['twitter:image'] = esc_url( add_query_arg( 'w', 240, $featured[0]['src'] ) );
86 }
87 }
88 }
89
90 // Only proceed with media analysis if a featured image has not superseded it already.
91 if ( empty( $og_tags['twitter:image'] ) && empty( $og_tags['twitter:image:src'] ) ) {
92 if ( ! class_exists( 'Jetpack_Media_Summary' ) && defined('IS_WPCOM') && IS_WPCOM ) {
93 include( WP_CONTENT_DIR . '/lib/class.wpcom-media-summary.php' );
94 }
95
96 if ( ! class_exists( 'Jetpack_Media_Summary' ) ) {
97 jetpack_require_lib( 'class.media-summary' );
98 }
99
100 // Test again, class should already be auto-loaded in Jetpack.
101 // If not, skip extra media analysis and stick with a summary card
102 if ( class_exists( 'Jetpack_Media_Summary' ) ) {
103 $extract = Jetpack_Media_Summary::get( $post->ID );
104
105 if ( 'gallery' == $extract['type'] ) {
106 list( $og_tags, $card_type ) = self::twitter_cards_define_type_based_on_image_count( $og_tags, $extract );
107 } elseif ( 'video' == $extract['type'] ) {
108 // Leave as summary, but with large pict of poster frame (we know those comply to Twitter's size requirements)
109 $card_type = 'summary_large_image';
110 $og_tags['twitter:image'] = esc_url( add_query_arg( 'w', 640, $extract['image'] ) );
111 } else {
112 list( $og_tags, $card_type ) = self::twitter_cards_define_type_based_on_image_count( $og_tags, $extract );
113 }
114 }
115 }
116
117 $og_tags['twitter:card'] = $card_type;
118
119 // Make sure we have a description for Twitter, their validator isn't happy without some content (single space not valid).
120 if ( ! isset( $og_tags['og:description'] ) || '' == trim( $og_tags['og:description'] ) || __('Visit the post for more.', 'jetpack') == $og_tags['og:description'] ) { // empty( trim( $og_tags['og:description'] ) ) isn't valid php
121 $has_creator = ( ! empty($og_tags['twitter:creator']) && '@wordpressdotcom' != $og_tags['twitter:creator'] ) ? true : false;
122 if ( ! empty( $extract ) && 'video' == $extract['type'] ) { // use $extract['type'] since $card_type is 'summary' for video posts
123 /* translators: %s is the post author */
124 $og_tags['twitter:description'] = ( $has_creator ) ? sprintf( __( 'Video post by %s.', 'jetpack' ), $og_tags['twitter:creator'] ) : __( 'Video post.', 'jetpack' );
125 } else {
126 /* translators: %s is the post author */
127 $og_tags['twitter:description'] = ( $has_creator ) ? sprintf( __( 'Post by %s.', 'jetpack' ), $og_tags['twitter:creator'] ) : __( 'Visit the post for more.', 'jetpack');
128 }
129 }
130
131 if ( empty( $og_tags['twitter:image'] ) && empty( $og_tags['twitter:image:src'] ) ) {
132 /** This action is documented in class.jetpack-twitter-cards.php */
133 $image = apply_filters( 'jetpack_twitter_cards_image_default', '' );
134 if ( ! empty( $image ) ) {
135 $og_tags['twitter:image'] = $image;
136 }
137 }
138
139 return $og_tags;
140 }
141
142 static function sanitize_twitter_user( $str ) {
143 return '@' . preg_replace( '/^@/', '', $str );
144 }
145
146 static function is_default_site_tag( $site_tag ) {
147 return in_array( $site_tag, array( '@wordpressdotcom', '@jetpack', 'wordpressdotcom', 'jetpack' ) );
148 }
149
150 static function prioritize_creator_over_default_site( $site_tag, $og_tags = array() ) {
151 if ( ! empty( $og_tags['twitter:creator'] ) && self::is_default_site_tag( $site_tag ) ) {
152 return $og_tags['twitter:creator'];
153 }
154 return $site_tag;
155 }
156
157 static function twitter_cards_define_type_based_on_image_count( $og_tags, $extract ) {
158 $card_type = 'summary';
159 $img_count = $extract['count']['image'];
160
161 if ( empty( $img_count ) ) {
162
163 // No images, use Blavatar as a thumbnail for the summary type.
164 if ( function_exists('blavatar_domain') ) {
165 $blavatar_domain = blavatar_domain( site_url() );
166 if ( blavatar_exists( $blavatar_domain ) ) {
167 $og_tags['twitter:image'] = blavatar_url( $blavatar_domain, 'img', 240 );
168 }
169 }
170
171 // Second fall back, Site Logo
172 if ( empty( $og_tags['twitter:image'] ) && ( function_exists( 'jetpack_has_site_logo' ) && jetpack_has_site_logo() ) ) {
173 $og_tags['twitter:image'] = jetpack_get_site_logo( 'url' );
174 }
175
176 // Third fall back, Site Icon
177 if ( empty( $og_tags['twitter:image'] ) && ( function_exists( 'has_site_icon' ) && has_site_icon() ) ) {
178 $og_tags['twitter:image'] = get_site_icon_url( '240' );
179 }
180
181 // Not falling back on Gravatar, because there's no way to know if we end up with an auto-generated one.
182
183 } elseif ( $img_count && ( 'image' == $extract['type'] || 'gallery' == $extract['type'] ) ) {
184 // Test for $extract['type'] to limit to image and gallery, so we don't send a potential fallback image like a Gravatar as a photo post.
185 $card_type = 'summary_large_image';
186 $og_tags['twitter:image'] = esc_url( add_query_arg( 'w', 1400, ( empty( $extract['images'] ) ) ? $extract['image'] : $extract['images'][0]['url'] ) );
187 }
188
189 return array( $og_tags, $card_type );
190 }
191
192 static function twitter_cards_output( $og_tag ) {
193 return ( false !== strpos( $og_tag, 'twitter:' ) ) ? preg_replace( '/property="([^"]+)"/', 'name="\1"', $og_tag ) : $og_tag;
194 }
195
196 static function settings_init() {
197 add_settings_section( 'jetpack-twitter-cards-settings', 'Twitter Cards', '__return_false', 'sharing' );
198 add_settings_field(
199 'jetpack-twitter-cards-site-tag',
200 __( 'Twitter Site Tag', 'jetpack' ),
201 array( __CLASS__, 'settings_field' ),
202 'sharing',
203 'jetpack-twitter-cards-settings',
204 array(
205 'label_for' => 'jetpack-twitter-cards-site-tag',
206 )
207 );
208 }
209
210 static function sharing_global_options() {
211 do_settings_fields( 'sharing', 'jetpack-twitter-cards-settings' );
212 }
213
214 static function site_tag() {
215 $site_tag = ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ?
216 trim( get_option( 'twitter_via' ) ) :
217 Jetpack_Options::get_option_and_ensure_autoload( 'jetpack-twitter-cards-site-tag', '' );
218 if ( empty( $site_tag ) ) {
219 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
220 return 'wordpressdotcom';
221 } else {
222 return;
223 }
224 }
225 return $site_tag;
226 }
227
228 static function settings_field() {
229 wp_nonce_field( 'jetpack-twitter-cards-settings', 'jetpack_twitter_cards_nonce', false );
230 ?>
231 <input type="text" id="jetpack-twitter-cards-site-tag" class="regular-text" name="jetpack-twitter-cards-site-tag" value="<?php echo esc_attr( get_option( 'jetpack-twitter-cards-site-tag' ) ); ?>" />
232 <p class="description" style="width: auto;"><?php esc_html_e( 'The Twitter username of the owner of this site\'s domain.', 'jetpack' ); ?></p>
233 <?php
234 }
235
236 static function settings_validate() {
237 if ( wp_verify_nonce( $_POST['jetpack_twitter_cards_nonce'], 'jetpack-twitter-cards-settings' ) ) {
238 update_option( 'jetpack-twitter-cards-site-tag', trim( ltrim( strip_tags( $_POST['jetpack-twitter-cards-site-tag'] ), '@' ) ) );
239 }
240 }
241
242 static function init() {
243 add_filter( 'jetpack_open_graph_tags', array( __CLASS__, 'twitter_cards_tags' ) );
244 add_filter( 'jetpack_open_graph_output', array( __CLASS__, 'twitter_cards_output' ) );
245 add_filter( 'jetpack_twitter_cards_site_tag', array( __CLASS__, 'site_tag' ), -99 );
246 add_filter( 'jetpack_twitter_cards_site_tag', array( __CLASS__, 'prioritize_creator_over_default_site' ), 99, 2 );
247 add_action( 'admin_init', array( __CLASS__, 'settings_init' ) );
248 add_action( 'sharing_global_options', array( __CLASS__, 'sharing_global_options' ) );
249 add_action( 'sharing_admin_update', array( __CLASS__, 'settings_validate' ) );
250 }
251 }
252
253 Jetpack_Twitter_Cards::init();
254