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