PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 6.1.3
Jetpack – WP Security, Backup, Speed, & Growth v6.1.3
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 8 years ago _inc 6 years ago bin 8 years ago css 8 years ago images 6 years ago json-endpoints 8 years ago languages 8 years ago modules 5 years ago sal 8 years ago scss 8 years ago sync 8 years ago views 8 years ago wpcom-test-backup 6 years ago .svnignore 12 years ago CODE-OF-CONDUCT.md 9 years ago changelog.txt 8 years ago class.frame-nonce-preview.php 9 years ago class.jetpack-admin.php 8 years ago class.jetpack-autoupdate.php 8 years ago class.jetpack-bbpress-json-api-compat.php 9 years ago class.jetpack-cli.php 8 years ago class.jetpack-client-server.php 8 years ago class.jetpack-client.php 8 years ago class.jetpack-connection-banner.php 8 years ago class.jetpack-constants.php 8 years ago class.jetpack-data.php 9 years ago class.jetpack-debugger.php 8 years ago class.jetpack-error.php 10 years ago class.jetpack-heartbeat.php 9 years ago class.jetpack-idc.php 8 years ago class.jetpack-ixr-client.php 10 years ago class.jetpack-jitm.php 8 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 8 years ago class.jetpack-options.php 8 years ago class.jetpack-post-images.php 8 years ago class.jetpack-signature.php 8 years ago class.jetpack-tracks.php 8 years ago class.jetpack-twitter-cards.php 8 years ago class.jetpack-user-agent.php 8 years ago class.jetpack-xmlrpc-server.php 8 years ago class.jetpack.php 8 years ago class.json-api-endpoints.php 8 years ago class.json-api.php 8 years ago class.photon.php 8 years ago composer.json 8 years ago functions.compat.php 9 years ago functions.gallery.php 8 years ago functions.global.php 8 years ago functions.opengraph.php 8 years ago functions.photon.php 9 years ago jetpack.php 5 years ago json-api-config.php 10 years ago json-endpoints.php 8 years ago locales.php 9 years ago phpcs.xml 8 years ago readme.txt 5 years ago require-lib.php 8 years ago uninstall.php 8 years ago wpml-config.xml 10 years ago
class.jetpack-twitter-cards.php
248 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 $site_tag = self::site_tag();
30 /** This action is documented in modules/sharedaddy/sharing-sources.php */
31 $site_tag = apply_filters( 'jetpack_sharing_twitter_via', $site_tag, ( is_singular() ? $post->ID : null ) );
32 /** This action is documented in modules/sharedaddy/sharing-sources.php */
33 $site_tag = apply_filters( 'jetpack_twitter_cards_site_tag', $site_tag, $og_tags );
34 if ( ! empty( $site_tag ) ) {
35 $og_tags['twitter:site'] = self::sanitize_twitter_user( $site_tag );
36 }
37
38 if ( ! is_singular() || ! empty( $og_tags['twitter:card'] ) ) {
39 /**
40 * Filter the default Twitter card image, used when no image can be found in a post.
41 *
42 * @module sharedaddy, publicize
43 *
44 * @since 5.9.0
45 *
46 * @param string $str Default image URL.
47 */
48 $image = apply_filters( 'jetpack_twitter_cards_image_default', '' );
49 if ( ! empty( $image ) ) {
50 $og_tags['twitter:image'] = $image;
51 }
52
53 return $og_tags;
54 }
55
56 $the_title = get_the_title();
57 if ( ! $the_title ) {
58 $the_title = get_bloginfo( 'name' );
59 }
60 $og_tags['twitter:text:title'] = $the_title;
61
62 /*
63 * The following tags only apply to single pages.
64 */
65
66 $card_type = 'summary';
67
68 // Try to give priority to featured images
69 if ( class_exists('Jetpack_PostImages') ) {
70 $featured = Jetpack_PostImages::from_thumbnail( $post->ID, 240, 240 );
71 if ( !empty( $featured ) && count( $featured ) > 0 ) {
72 if ( (int) $featured[0]['src_width'] >= 280 && (int) $featured[0]['src_height'] >= 150 ) {
73 $card_type = 'summary_large_image';
74 $og_tags['twitter:image'] = esc_url( add_query_arg( 'w', 640, $featured[0]['src'] ) );
75 } else {
76 $og_tags['twitter:image'] = esc_url( add_query_arg( 'w', 240, $featured[0]['src'] ) );
77 }
78 }
79 }
80
81 // Only proceed with media analysis if a featured image has not superseded it already.
82 if ( empty( $og_tags['twitter:image'] ) && empty( $og_tags['twitter:image:src'] ) ) {
83 if ( ! class_exists( 'Jetpack_Media_Summary' ) && defined('IS_WPCOM') && IS_WPCOM ) {
84 include( WP_CONTENT_DIR . '/lib/class.wpcom-media-summary.php' );
85 }
86
87 if ( ! class_exists( 'Jetpack_Media_Summary' ) ) {
88 jetpack_require_lib( 'class.media-summary' );
89 }
90
91 // Test again, class should already be auto-loaded in Jetpack.
92 // If not, skip extra media analysis and stick with a summary card
93 if ( class_exists( 'Jetpack_Media_Summary' ) ) {
94 $extract = Jetpack_Media_Summary::get( $post->ID );
95
96 if ( 'gallery' == $extract['type'] ) {
97 list( $og_tags, $card_type ) = self::twitter_cards_define_type_based_on_image_count( $og_tags, $extract );
98 } elseif ( 'video' == $extract['type'] ) {
99 // Leave as summary, but with large pict of poster frame (we know those comply to Twitter's size requirements)
100 $card_type = 'summary_large_image';
101 $og_tags['twitter:image'] = esc_url( add_query_arg( 'w', 640, $extract['image'] ) );
102 } else {
103 list( $og_tags, $card_type ) = self::twitter_cards_define_type_based_on_image_count( $og_tags, $extract );
104 }
105 }
106 }
107
108 $og_tags['twitter:card'] = $card_type;
109
110 // If we have information on the author/creator, then include that as well
111 if ( ! empty( $post ) && ! empty( $post->post_author ) ) {
112 /** This action is documented in modules/sharedaddy/sharing-sources.php */
113 $handle = apply_filters( 'jetpack_sharing_twitter_via', '', $post->ID );
114 if ( ! empty( $handle ) && 'wordpressdotcom' != $handle && 'jetpack' != $handle ) {
115 $og_tags['twitter:creator'] = self::sanitize_twitter_user( $handle );
116 }
117 }
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 prioritize_creator_over_default_site( $site_tag, $og_tags = array() ) {
147 if ( ! empty( $og_tags['twitter:creator'] ) && in_array( $site_tag, array( '@wordpressdotcom', '@jetpack' ) ) ) {
148 $site_tag = $og_tags['twitter:creator'];
149 }
150 return $site_tag;
151 }
152
153 static function twitter_cards_define_type_based_on_image_count( $og_tags, $extract ) {
154 $card_type = 'summary';
155 $img_count = $extract['count']['image'];
156
157 if ( empty( $img_count ) ) {
158
159 // No images, use Blavatar as a thumbnail for the summary type.
160 if ( function_exists('blavatar_domain') ) {
161 $blavatar_domain = blavatar_domain( site_url() );
162 if ( blavatar_exists( $blavatar_domain ) ) {
163 $og_tags['twitter:image'] = blavatar_url( $blavatar_domain, 'img', 240 );
164 }
165 }
166
167 // Second fall back, Site Logo
168 if ( empty( $og_tags['twitter:image'] ) && ( function_exists( 'jetpack_has_site_logo' ) && jetpack_has_site_logo() ) ) {
169 $og_tags['twitter:image'] = jetpack_get_site_logo( 'url' );
170 }
171
172 // Third fall back, Site Icon
173 if ( empty( $og_tags['twitter:image'] ) && ( function_exists( 'has_site_icon' ) && has_site_icon() ) ) {
174 $og_tags['twitter:image'] = get_site_icon_url( '240' );
175 }
176
177 // Not falling back on Gravatar, because there's no way to know if we end up with an auto-generated one.
178
179 } elseif ( $img_count && ( 'image' == $extract['type'] || 'gallery' == $extract['type'] ) ) {
180 // 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.
181 $card_type = 'summary_large_image';
182 $og_tags['twitter:image'] = esc_url( add_query_arg( 'w', 1400, ( empty( $extract['images'] ) ) ? $extract['image'] : $extract['images'][0]['url'] ) );
183 }
184
185 return array( $og_tags, $card_type );
186 }
187
188 static function twitter_cards_output( $og_tag ) {
189 return ( false !== strpos( $og_tag, 'twitter:' ) ) ? preg_replace( '/property="([^"]+)"/', 'name="\1"', $og_tag ) : $og_tag;
190 }
191
192 static function settings_init() {
193 add_settings_section( 'jetpack-twitter-cards-settings', 'Twitter Cards', '__return_false', 'sharing' );
194 add_settings_field(
195 'jetpack-twitter-cards-site-tag',
196 __( 'Twitter Site Tag', 'jetpack' ),
197 array( __CLASS__, 'settings_field' ),
198 'sharing',
199 'jetpack-twitter-cards-settings',
200 array(
201 'label_for' => 'jetpack-twitter-cards-site-tag',
202 )
203 );
204 }
205
206 static function sharing_global_options() {
207 do_settings_fields( 'sharing', 'jetpack-twitter-cards-settings' );
208 }
209
210 static function site_tag() {
211 $site_tag = Jetpack_Options::get_option_and_ensure_autoload( 'jetpack-twitter-cards-site-tag', '' );
212 if ( empty( $site_tag ) ) {
213 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
214 return 'wordpressdotcom';
215 } else {
216 return;
217 }
218 }
219 return $site_tag;
220 }
221
222 static function settings_field() {
223 wp_nonce_field( 'jetpack-twitter-cards-settings', 'jetpack_twitter_cards_nonce', false );
224 ?>
225 <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' ) ); ?>" />
226 <p class="description" style="width: auto;"><?php esc_html_e( 'The Twitter username of the owner of this site\'s domain.', 'jetpack' ); ?></p>
227 <?php
228 }
229
230 static function settings_validate() {
231 if ( wp_verify_nonce( $_POST['jetpack_twitter_cards_nonce'], 'jetpack-twitter-cards-settings' ) ) {
232 update_option( 'jetpack-twitter-cards-site-tag', trim( ltrim( strip_tags( $_POST['jetpack-twitter-cards-site-tag'] ), '@' ) ) );
233 }
234 }
235
236 static function init() {
237 add_filter( 'jetpack_open_graph_tags', array( __CLASS__, 'twitter_cards_tags' ) );
238 add_filter( 'jetpack_open_graph_output', array( __CLASS__, 'twitter_cards_output' ) );
239 add_filter( 'jetpack_twitter_cards_site_tag', array( __CLASS__, 'site_tag' ), -99 );
240 add_filter( 'jetpack_twitter_cards_site_tag', array( __CLASS__, 'prioritize_creator_over_default_site' ), 99, 2 );
241 add_action( 'admin_init', array( __CLASS__, 'settings_init' ) );
242 add_action( 'sharing_global_options', array( __CLASS__, 'sharing_global_options' ) );
243 add_action( 'sharing_admin_update', array( __CLASS__, 'settings_validate' ) );
244 }
245 }
246
247 Jetpack_Twitter_Cards::init();
248