PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 4.6.3
Jetpack – WP Security, Backup, Speed, & Growth v4.6.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 9 years ago _inc 1 year ago bin 9 years ago css 9 years ago images 1 year ago json-endpoints 9 years ago languages 9 years ago modules 1 year ago sal 9 years ago scss 9 years ago sync 9 years ago views 9 years ago .svnignore 12 years ago changelog.txt 9 years ago class.frame-nonce-preview.php 9 years ago class.jetpack-admin.php 9 years ago class.jetpack-autoupdate.php 9 years ago class.jetpack-bbpress-json-api-compat.php 9 years ago class.jetpack-cli.php 9 years ago class.jetpack-client-server.php 9 years ago class.jetpack-client.php 9 years ago class.jetpack-connection-banner.php 9 years ago class.jetpack-constants.php 9 years ago class.jetpack-data.php 9 years ago class.jetpack-debugger.php 9 years ago class.jetpack-error.php 10 years ago class.jetpack-heartbeat.php 9 years ago class.jetpack-idc.php 9 years ago class.jetpack-ixr-client.php 10 years ago class.jetpack-jitm.php 9 years ago class.jetpack-modules-list-table.php 9 years ago class.jetpack-network-sites-list-table.php 9 years ago class.jetpack-network.php 9 years ago class.jetpack-options.php 9 years ago class.jetpack-post-images.php 9 years ago class.jetpack-signature.php 9 years ago class.jetpack-tracks.php 9 years ago class.jetpack-twitter-cards.php 9 years ago class.jetpack-user-agent.php 9 years ago class.jetpack-xmlrpc-server.php 9 years ago class.jetpack.php 9 years ago class.json-api-endpoints.php 3 years ago class.json-api.php 10 years ago class.photon.php 9 years ago composer.json 10 years ago functions.compat.php 9 years ago functions.gallery.php 10 years ago functions.global.php 9 years ago functions.opengraph.php 9 years ago functions.photon.php 9 years ago jetpack.php 1 year ago json-api-config.php 10 years ago json-endpoints.php 9 years ago locales.php 9 years ago readme.txt 1 year ago require-lib.php 10 years ago rest-api.md 9 years ago uninstall.php 9 years ago webpack.config.js 9 years ago wpml-config.xml 10 years ago
class.jetpack-twitter-cards.php
218 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 return $og_tags;
40 }
41
42 /*
43 * The following tags only apply to single pages.
44 */
45
46 $card_type = 'summary';
47
48 // Try to give priority to featured images
49 if ( class_exists('Jetpack_PostImages') ) {
50 $featured = Jetpack_PostImages::from_thumbnail( $post->ID, 240, 240 );
51 if ( !empty( $featured ) && count( $featured ) > 0 ) {
52 if ( (int) $featured[0]['src_width'] >= 280 && (int) $featured[0]['src_height'] >= 150 ) {
53 $card_type = 'summary_large_image';
54 $og_tags['twitter:image'] = esc_url( add_query_arg( 'w', 640, $featured[0]['src'] ) );
55 } else {
56 $og_tags['twitter:image'] = esc_url( add_query_arg( 'w', 240, $featured[0]['src'] ) );
57 }
58 }
59 }
60
61 // Only proceed with media analysis if a featured image has not superseded it already.
62 if ( empty( $og_tags['twitter:image'] ) && empty( $og_tags['twitter:image:src'] ) ) {
63 if ( ! class_exists( 'Jetpack_Media_Summary' ) && defined('IS_WPCOM') && IS_WPCOM ) {
64 include( WP_CONTENT_DIR . '/lib/class.wpcom-media-summary.php' );
65 }
66
67 if ( ! class_exists( 'Jetpack_Media_Summary' ) ) {
68 jetpack_require_lib( 'class.media-summary' );
69 }
70
71 // Test again, class should already be auto-loaded in Jetpack.
72 // If not, skip extra media analysis and stick with a summary card
73 if ( class_exists( 'Jetpack_Media_Summary' ) ) {
74 $extract = Jetpack_Media_Summary::get( $post->ID );
75
76 if ( 'gallery' == $extract['type'] ) {
77 list( $og_tags, $card_type ) = self::twitter_cards_define_type_based_on_image_count( $og_tags, $extract );
78 } elseif ( 'video' == $extract['type'] ) {
79 // Leave as summary, but with large pict of poster frame (we know those comply to Twitter's size requirements)
80 $card_type = 'summary_large_image';
81 $og_tags['twitter:image'] = esc_url( add_query_arg( 'w', 640, $extract['image'] ) );
82 } else {
83 list( $og_tags, $card_type ) = self::twitter_cards_define_type_based_on_image_count( $og_tags, $extract );
84 }
85 }
86 }
87
88 $og_tags['twitter:card'] = $card_type;
89
90 // If we have information on the author/creator, then include that as well
91 if ( ! empty( $post ) && ! empty( $post->post_author ) ) {
92 /** This action is documented in modules/sharedaddy/sharing-sources.php */
93 $handle = apply_filters( 'jetpack_sharing_twitter_via', '', $post->ID );
94 if ( ! empty( $handle ) && 'wordpressdotcom' != $handle && 'jetpack' != $handle ) {
95 $og_tags['twitter:creator'] = self::sanitize_twitter_user( $handle );
96 }
97 }
98
99 // Make sure we have a description for Twitter, their validator isn't happy without some content (single space not valid).
100 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
101 $has_creator = ( ! empty($og_tags['twitter:creator']) && '@wordpressdotcom' != $og_tags['twitter:creator'] ) ? true : false;
102 if ( ! empty( $extract ) && 'video' == $extract['type'] ) { // use $extract['type'] since $card_type is 'summary' for video posts
103 $og_tags['twitter:description'] = ( $has_creator ) ? sprintf( __('Video post by %s.', 'jetpack'), $og_tags['twitter:creator'] ) : __('Video post.', 'jetpack');
104 } else {
105 $og_tags['twitter:description'] = ( $has_creator ) ? sprintf( __('Post by %s.', 'jetpack'), $og_tags['twitter:creator'] ) : __('Visit the post for more.', 'jetpack');
106 }
107 }
108
109 return $og_tags;
110 }
111
112 static function sanitize_twitter_user( $str ) {
113 return '@' . preg_replace( '/^@/', '', $str );
114 }
115
116 static function prioritize_creator_over_default_site( $site_tag, $og_tags = array() ) {
117 if ( ! empty( $og_tags['twitter:creator'] ) && in_array( $site_tag, array( '@wordpressdotcom', '@jetpack' ) ) ) {
118 $site_tag = $og_tags['twitter:creator'];
119 }
120 return $site_tag;
121 }
122
123 static function twitter_cards_define_type_based_on_image_count( $og_tags, $extract ) {
124 $card_type = 'summary';
125 $img_count = $extract['count']['image'];
126
127 if ( empty( $img_count ) ) {
128
129 // No images, use Blavatar as a thumbnail for the summary type.
130 if ( function_exists('blavatar_domain') ) {
131 $blavatar_domain = blavatar_domain( site_url() );
132 if ( blavatar_exists( $blavatar_domain ) ) {
133 $og_tags['twitter:image'] = blavatar_url( $blavatar_domain, 'img', 240 );
134 }
135 }
136
137 // Second fall back, Site Logo
138 if ( empty( $og_tags['twitter:image'] ) && ( function_exists( 'jetpack_has_site_logo' ) && jetpack_has_site_logo() ) ) {
139 $og_tags['twitter:image'] = jetpack_get_site_logo( 'url' );
140 }
141
142 // Third fall back, Site Icon
143 if ( empty( $og_tags['twitter:image'] ) && ( function_exists( 'has_site_icon' ) && has_site_icon() ) ) {
144 $og_tags['twitter:image'] = get_site_icon_url( '240' );
145 }
146
147 // Not falling back on Gravatar, because there's no way to know if we end up with an auto-generated one.
148
149 } elseif ( $img_count && ( 'image' == $extract['type'] || 'gallery' == $extract['type'] ) ) {
150 // 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.
151 $card_type = 'summary_large_image';
152 $og_tags['twitter:image'] = esc_url( add_query_arg( 'w', 1400, ( empty( $extract['images'] ) ) ? $extract['image'] : $extract['images'][0]['url'] ) );
153 }
154
155 return array( $og_tags, $card_type );
156 }
157
158 static function twitter_cards_output( $og_tag ) {
159 return ( false !== strpos( $og_tag, 'twitter:' ) ) ? preg_replace( '/property="([^"]+)"/', 'name="\1"', $og_tag ) : $og_tag;
160 }
161
162 static function settings_init() {
163 add_settings_section( 'jetpack-twitter-cards-settings', 'Twitter Cards', '__return_false', 'sharing' );
164 add_settings_field(
165 'jetpack-twitter-cards-site-tag',
166 __( 'Twitter Site Tag', 'jetpack' ),
167 array( __CLASS__, 'settings_field' ),
168 'sharing',
169 'jetpack-twitter-cards-settings',
170 array(
171 'label_for' => 'jetpack-twitter-cards-site-tag',
172 )
173 );
174 }
175
176 static function sharing_global_options() {
177 do_settings_fields( 'sharing', 'jetpack-twitter-cards-settings' );
178 }
179
180 static function site_tag() {
181 $site_tag = Jetpack_Options::get_option_and_ensure_autoload( 'jetpack-twitter-cards-site-tag', '' );
182 if ( empty( $site_tag ) ) {
183 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
184 return 'wordpressdotcom';
185 } else {
186 return;
187 }
188 }
189 return $site_tag;
190 }
191
192 static function settings_field() {
193 wp_nonce_field( 'jetpack-twitter-cards-settings', 'jetpack_twitter_cards_nonce', false );
194 ?>
195 <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' ) ); ?>" />
196 <p class="description" style="width: auto;"><?php esc_html_e( 'The Twitter username of the owner of this site\'s domain.', 'jetpack' ); ?></p>
197 <?php
198 }
199
200 static function settings_validate() {
201 if ( wp_verify_nonce( $_POST['jetpack_twitter_cards_nonce'], 'jetpack-twitter-cards-settings' ) ) {
202 update_option( 'jetpack-twitter-cards-site-tag', trim( ltrim( strip_tags( $_POST['jetpack-twitter-cards-site-tag'] ), '@' ) ) );
203 }
204 }
205
206 static function init() {
207 add_filter( 'jetpack_open_graph_tags', array( __CLASS__, 'twitter_cards_tags' ) );
208 add_filter( 'jetpack_open_graph_output', array( __CLASS__, 'twitter_cards_output' ) );
209 add_filter( 'jetpack_twitter_cards_site_tag', array( __CLASS__, 'site_tag' ), -99 );
210 add_filter( 'jetpack_twitter_cards_site_tag', array( __CLASS__, 'prioritize_creator_over_default_site' ), 99, 2 );
211 add_action( 'admin_init', array( __CLASS__, 'settings_init' ) );
212 add_action( 'sharing_global_options', array( __CLASS__, 'sharing_global_options' ) );
213 add_action( 'sharing_admin_update', array( __CLASS__, 'settings_validate' ) );
214 }
215 }
216
217 Jetpack_Twitter_Cards::init();
218