PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 7.8
Jetpack – WP Security, Backup, Speed, & Growth v7.8
16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 All 501 releases
jetpack / modules / widgets / twitter-timeline.php

twitter-timeline.php in Jetpack – WP Security, Backup, Speed, & Growth 7.8, at modules/widgets/twitter-timeline.php

506 lines 15.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 * Based on Evolution Twitter Timeline
5 * (https://wordpress.org/extend/plugins/evolution-twitter-timeline/)
6 * For details on Twitter Timelines see:
7 * - https://twitter.com/settings/widgets
8 * - https://dev.twitter.com/docs/embedded-timelines
9 */
10
11 use Automattic\Jetpack\Assets;
12
13 /**
14 * Register the widget for use in Appearance -> Widgets
15 */
16 add_action( 'widgets_init', 'jetpack_twitter_timeline_widget_init' );
17
18 function jetpack_twitter_timeline_widget_init() {
19 register_widget( 'Jetpack_Twitter_Timeline_Widget' );
20 }
21
22 class Jetpack_Twitter_Timeline_Widget extends WP_Widget {
23 /**
24 * Register widget with WordPress.
25 */
26 public function __construct() {
27 parent::__construct(
28 'twitter_timeline',
29 /** This filter is documented in modules/widgets/facebook-likebox.php */
30 apply_filters( 'jetpack_widget_name', esc_html__( 'Twitter Timeline', 'jetpack' ) ),
31 array(
32 'classname' => 'widget_twitter_timeline',
33 'description' => __( 'Display an official Twitter Embedded Timeline widget.', 'jetpack' ),
34 'customize_selective_refresh' => true,
35 )
36 );
37
38 if ( is_active_widget( false, false, $this->id_base ) || is_active_widget( false, false, 'monster' ) || is_customize_preview() ) {
39 add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
40 }
41
42 add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) );
43 }
44
45 /**
46 * Enqueue scripts.
47 */
48 public function enqueue_scripts() {
49 wp_enqueue_script( 'jetpack-twitter-timeline' );
50 }
51
52 /**
53 * Enqueue Twitter's widget library.
54 *
55 * @deprecated
56 */
57 public function library() {
58 _deprecated_function( __METHOD__, '4.0.0' );
59 wp_print_scripts( array( 'jetpack-twitter-timeline' ) );
60 }
61
62 /**
63 * Enqueue script to improve admin UI
64 */
65 public function admin_scripts( $hook ) {
66 // This is still 'widgets.php' when managing widgets via the Customizer.
67 if ( 'widgets.php' === $hook ) {
68 wp_enqueue_script(
69 'twitter-timeline-admin',
70 Assets::get_file_url_for_environment(
71 '_inc/build/widgets/twitter-timeline-admin.min.js',
72 'modules/widgets/twitter-timeline-admin.js'
73 )
74 );
75 }
76 }
77
78 /**
79 * Front-end display of widget.
80 *
81 * @see WP_Widget::widget()
82 *
83 * @param array $args Widget arguments.
84 * @param array $instance Saved values from database.
85 */
86 public function widget( $args, $instance ) {
87 // Twitter deprecated `data-widget-id` on 2018-05-25,
88 // with cease support deadline on 2018-07-27.
89 if ( isset( $instance['type'] ) && 'widget-id' === $instance['type'] ) {
90 if ( current_user_can( 'edit_theme_options' ) ) {
91 echo $args['before_widget'];
92 echo $args['before_title'] . esc_html__( 'Twitter Timeline', 'jetpack' ) . $args['after_title'];
93 echo '<p>' . esc_html__( "The Twitter Timeline widget can't display tweets based on searches or hashtags. To display a simple list of tweets instead, change the Widget ID to a Twitter username. Otherwise, delete this widget.", 'jetpack' ) . '</p>';
94 echo '<p>' . esc_html__( '(Only administrators will see this message.)', 'jetpack' ) . '</p>';
95 echo $args['after_widget'];
96 }
97 return;
98 }
99
100 $instance['lang'] = substr( strtoupper( get_locale() ), 0, 2 );
101
102 echo $args['before_widget'];
103
104 $title = isset( $instance['title'] ) ? $instance['title'] : '';
105
106 /** This filter is documented in core/src/wp-includes/default-widgets.php */
107 $title = apply_filters( 'widget_title', $title );
108 if ( ! empty( $title ) ) {
109 echo $args['before_title'] . $title . $args['after_title'];
110 }
111
112 if ( isset( $instance['type'] ) && 'widget-id' === $instance['type'] && current_user_can( 'edit_theme_options' ) ) {
113 echo '<p>' . esc_html__( 'As of July 27, 2018, the Twitter Timeline widget will no longer display tweets based on searches or hashtags. To display a simple list of tweets instead, change the Widget ID to a Twitter username.', 'jetpack' ) . '</p>';
114 echo '<p>' . esc_html__( '(Only administrators will see this message.)', 'jetpack' ) . '</p>';
115 }
116
117 // Start tag output
118 // This tag is transformed into the widget markup by Twitter's
119 // widgets.js code
120 echo '<a class="twitter-timeline"';
121
122 $data_attribs = array(
123 'width',
124 'height',
125 'theme',
126 'link-color',
127 'border-color',
128 'tweet-limit',
129 'lang',
130 );
131 foreach ( $data_attribs as $att ) {
132 if ( ! empty( $instance[ $att ] ) && ! is_array( $instance[ $att ] ) ) {
133 echo ' data-' . esc_attr( $att ) . '="' . esc_attr( $instance[ $att ] ) . '"';
134 }
135 }
136
137 /** This filter is documented in modules/shortcodes/tweet.php */
138 $partner = apply_filters( 'jetpack_twitter_partner_id', 'jetpack' );
139 if ( ! empty( $partner ) ) {
140 echo ' data-partner="' . esc_attr( $partner ) . '"';
141 }
142
143 /**
144 * Allow the activation of Do Not Track for the Twitter Timeline Widget.
145 *
146 * @see https://developer.twitter.com/en/docs/twitter-for-websites/timelines/guides/parameter-reference.html
147 *
148 * @module widgets
149 *
150 * @since 6.9.0
151 *
152 * @param bool false Should the Twitter Timeline use the DNT attribute? Default to false.
153 */
154 $dnt = apply_filters( 'jetpack_twitter_timeline_default_dnt', false );
155 if ( true === $dnt ) {
156 echo ' data-dnt="true"';
157 }
158
159 if ( ! empty( $instance['chrome'] ) && is_array( $instance['chrome'] ) ) {
160 echo ' data-chrome="' . esc_attr( join( ' ', $instance['chrome'] ) ) . '"';
161 }
162
163 $type = ( isset( $instance['type'] ) ? $instance['type'] : '' );
164 $widget_id = ( isset( $instance['widget-id'] ) ? $instance['widget-id'] : '' );
165 switch ( $type ) {
166 case 'profile':
167 echo ' href="https://twitter.com/' . esc_attr( $widget_id ) . '"';
168 break;
169 case 'widget-id':
170 default:
171 echo ' data-widget-id="' . esc_attr( $widget_id ) . '"';
172 break;
173 }
174 echo ' href="https://twitter.com/' . esc_attr( $widget_id ) . '"';
175
176 // End tag output
177 echo '>';
178
179 $timeline_placeholder = __( 'My Tweets', 'jetpack' );
180
181 /**
182 * Filter the Timeline placeholder text.
183 *
184 * @module widgets
185 *
186 * @since 3.4.0
187 *
188 * @param string $timeline_placeholder Timeline placeholder text.
189 */
190 $timeline_placeholder = apply_filters( 'jetpack_twitter_timeline_placeholder', $timeline_placeholder );
191
192 echo esc_html( $timeline_placeholder ) . '</a>';
193
194 // End tag output
195
196 echo $args['after_widget'];
197
198 /** This action is documented in modules/widgets/gravatar-profile.php */
199 do_action( 'jetpack_stats_extra', 'widget_view', 'twitter_timeline' );
200 }
201
202
203 /**
204 * Sanitize widget form values as they are saved.
205 *
206 * @see WP_Widget::update()
207 *
208 * @param array $new_instance Values just sent to be saved.
209 * @param array $old_instance Previously saved values from database.
210 *
211 * @return array Updated safe values to be saved.
212 */
213 public function update( $new_instance, $old_instance ) {
214 $instance = array();
215
216 $instance['title'] = sanitize_text_field( $new_instance['title'] );
217
218 $width = (int) $new_instance['width'];
219 if ( $width ) {
220 // From publish.twitter.com: 220 <= width <= 1200
221 $instance['width'] = min( max( $width, 220 ), 1200 );
222 } else {
223 $instance['width'] = '';
224 }
225
226 $height = (int) $new_instance['height'];
227 if ( $height ) {
228 // From publish.twitter.com: height >= 200
229 $instance['height'] = max( $height, 200 );
230 } else {
231 $instance['height'] = '';
232 }
233
234 $tweet_limit = (int) $new_instance['tweet-limit'];
235 if ( $tweet_limit ) {
236 $instance['tweet-limit'] = min( max( $tweet_limit, 1 ), 20 );
237 /**
238 * A timeline with a specified limit is expanded to the height of those Tweets.
239 * The specified height value no longer applies, so reject the height value
240 * when a valid limit is set: a widget attempting to save both limit 5 and
241 * height 400 would be saved with just limit 5.
242 */
243 $instance['height'] = '';
244 } else {
245 $instance['tweet-limit'] = null;
246 }
247
248 // If they entered something that might be a full URL, try to parse it out
249 if ( is_string( $new_instance['widget-id'] ) ) {
250 if ( preg_match(
251 '#https?://twitter\.com/settings/widgets/(\d+)#s',
252 $new_instance['widget-id'],
253 $matches
254 ) ) {
255 $new_instance['widget-id'] = $matches[1];
256 }
257 }
258
259 $instance['widget-id'] = sanitize_text_field( $new_instance['widget-id'] );
260
261 $hex_regex = '/#([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?\b/';
262 foreach ( array( 'link-color', 'border-color' ) as $color ) {
263 $new_color = sanitize_text_field( $new_instance[ $color ] );
264 if ( preg_match( $hex_regex, $new_color ) ) {
265 $instance[ $color ] = $new_color;
266 }
267 }
268
269 $instance['type'] = 'profile';
270
271 $instance['theme'] = 'light';
272 if ( in_array( $new_instance['theme'], array( 'light', 'dark' ) ) ) {
273 $instance['theme'] = $new_instance['theme'];
274 }
275
276 $instance['chrome'] = array();
277 $chrome_settings = array(
278 'noheader',
279 'nofooter',
280 'noborders',
281 'transparent',
282 'noscrollbar',
283 );
284 if ( isset( $new_instance['chrome'] ) ) {
285 foreach ( $new_instance['chrome'] as $chrome ) {
286 if ( in_array( $chrome, $chrome_settings ) ) {
287 $instance['chrome'][] = $chrome;
288 }
289 }
290 }
291
292 return $instance;
293 }
294
295 /**
296 * Returns a link to the documentation for a feature of this widget on
297 * Jetpack or WordPress.com.
298 */
299 public function get_docs_link( $hash = '' ) {
300 if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
301 $base_url = 'https://support.wordpress.com/widgets/twitter-timeline-widget/';
302 } else {
303 $base_url = 'https://jetpack.com/support/extra-sidebar-widgets/twitter-timeline-widget/';
304 }
305 return '<a href="' . $base_url . $hash . '" target="_blank">( ? )</a>';
306 }
307
308 /**
309 * Back end widget form.
310 *
311 * @see WP_Widget::form()
312 *
313 * @param array $instance Previously saved values from database.
314 */
315 public function form( $instance ) {
316 $defaults = array(
317 'title' => esc_html__( 'Follow me on Twitter', 'jetpack' ),
318 'width' => '',
319 'height' => '400',
320 'type' => 'profile',
321 'widget-id' => '',
322 'link-color' => '#f96e5b',
323 'border-color' => '#e8e8e8',
324 'theme' => 'light',
325 'chrome' => array(),
326 'tweet-limit' => null,
327 );
328
329 $instance = wp_parse_args( (array) $instance, $defaults );
330
331 if ( 'widget-id' === $instance['type'] ) {
332 $instance['widget-id'] = '';
333 }
334
335 $instance['type'] = 'profile';
336 ?>
337
338 <p>
339 <label for="<?php echo $this->get_field_id( 'title' ); ?>">
340 <?php esc_html_e( 'Title:', 'jetpack' ); ?>
341 </label>
342 <input
343 class="widefat"
344 id="<?php echo $this->get_field_id( 'title' ); ?>"
345 name="<?php echo $this->get_field_name( 'title' ); ?>"
346 type="text"
347 value="<?php echo esc_attr( $instance['title'] ); ?>"
348 />
349 </p>
350
351 <p>
352 <label for="<?php echo $this->get_field_id( 'width' ); ?>">
353 <?php esc_html_e( 'Maximum Width (px; 220 to 1200):', 'jetpack' ); ?>
354 </label>
355 <input
356 class="widefat"
357 id="<?php echo $this->get_field_id( 'width' ); ?>"
358 name="<?php echo $this->get_field_name( 'width' ); ?>"
359 type="number" min="220" max="1200"
360 value="<?php echo esc_attr( $instance['width'] ); ?>"
361 />
362 </p>
363
364 <p>
365 <label for="<?php echo $this->get_field_id( 'height' ); ?>">
366 <?php esc_html_e( 'Height (px; at least 200):', 'jetpack' ); ?>
367 </label>
368 <input
369 class="widefat"
370 id="<?php echo $this->get_field_id( 'height' ); ?>"
371 name="<?php echo $this->get_field_name( 'height' ); ?>"
372 type="number" min="200"
373 value="<?php echo esc_attr( $instance['height'] ); ?>"
374 />
375 </p>
376
377 <p>
378 <label for="<?php echo $this->get_field_id( 'tweet-limit' ); ?>">
379 <?php esc_html_e( '# of Tweets Shown (1 to 20):', 'jetpack' ); ?>
380 </label>
381 <input
382 class="widefat"
383 id="<?php echo $this->get_field_id( 'tweet-limit' ); ?>"
384 name="<?php echo $this->get_field_name( 'tweet-limit' ); ?>"
385 type="number" min="1" max="20"
386 value="<?php echo esc_attr( $instance['tweet-limit'] ); ?>"
387 />
388 </p>
389
390 <p class="jetpack-twitter-timeline-widget-id-container">
391 <label for="<?php echo $this->get_field_id( 'widget-id' ); ?>">
392 <?php esc_html_e( 'Twitter Username:', 'jetpack' ); ?>
393 <?php echo $this->get_docs_link( '#twitter-username' ); ?>
394 </label>
395 <input
396 class="widefat"
397 id="<?php echo $this->get_field_id( 'widget-id' ); ?>"
398 name="<?php echo $this->get_field_name( 'widget-id' ); ?>"
399 type="text"
400 value="<?php echo esc_attr( $instance['widget-id'] ); ?>"
401 />
402 </p>
403
404 <p>
405 <label for="<?php echo $this->get_field_id( 'chrome-noheader' ); ?>">
406 <?php esc_html_e( 'Layout Options:', 'jetpack' ); ?>
407 </label>
408 <br />
409 <input
410 type="checkbox"<?php checked( in_array( 'noheader', $instance['chrome'] ) ); ?>
411 id="<?php echo $this->get_field_id( 'chrome-noheader' ); ?>"
412 name="<?php echo $this->get_field_name( 'chrome' ); ?>[]"
413 value="noheader"
414 />
415 <label for="<?php echo $this->get_field_id( 'chrome-noheader' ); ?>">
416 <?php esc_html_e( 'No Header', 'jetpack' ); ?>
417 </label>
418 <br />
419 <input
420 type="checkbox"<?php checked( in_array( 'nofooter', $instance['chrome'] ) ); ?>
421 id="<?php echo $this->get_field_id( 'chrome-nofooter' ); ?>"
422 name="<?php echo $this->get_field_name( 'chrome' ); ?>[]"
423 value="nofooter"
424 />
425 <label for="<?php echo $this->get_field_id( 'chrome-nofooter' ); ?>">
426 <?php esc_html_e( 'No Footer', 'jetpack' ); ?>
427 </label>
428 <br />
429 <input
430 type="checkbox"<?php checked( in_array( 'noborders', $instance['chrome'] ) ); ?>
431 id="<?php echo $this->get_field_id( 'chrome-noborders' ); ?>"
432 name="<?php echo $this->get_field_name( 'chrome' ); ?>[]"
433 value="noborders"
434 />
435 <label for="<?php echo $this->get_field_id( 'chrome-noborders' ); ?>">
436 <?php esc_html_e( 'No Borders', 'jetpack' ); ?>
437 </label>
438 <br />
439 <input
440 type="checkbox"<?php checked( in_array( 'noscrollbar', $instance['chrome'] ) ); ?>
441 id="<?php echo $this->get_field_id( 'chrome-noscrollbar' ); ?>"
442 name="<?php echo $this->get_field_name( 'chrome' ); ?>[]"
443 value="noscrollbar"
444 />
445 <label for="<?php echo $this->get_field_id( 'chrome-noscrollbar' ); ?>">
446 <?php esc_html_e( 'No Scrollbar', 'jetpack' ); ?>
447 </label>
448 <br />
449 <input
450 type="checkbox"<?php checked( in_array( 'transparent', $instance['chrome'] ) ); ?>
451 id="<?php echo $this->get_field_id( 'chrome-transparent' ); ?>"
452 name="<?php echo $this->get_field_name( 'chrome' ); ?>[]"
453 value="transparent"
454 />
455 <label for="<?php echo $this->get_field_id( 'chrome-transparent' ); ?>">
456 <?php esc_html_e( 'Transparent Background', 'jetpack' ); ?>
457 </label>
458 </p>
459
460 <p>
461 <label for="<?php echo $this->get_field_id( 'link-color' ); ?>">
462 <?php _e( 'Link Color (hex):', 'jetpack' ); ?>
463 </label>
464 <input
465 class="widefat"
466 id="<?php echo $this->get_field_id( 'link-color' ); ?>"
467 name="<?php echo $this->get_field_name( 'link-color' ); ?>"
468 type="text"
469 value="<?php echo esc_attr( $instance['link-color'] ); ?>"
470 />
471 </p>
472
473 <p>
474 <label for="<?php echo $this->get_field_id( 'border-color' ); ?>">
475 <?php _e( 'Border Color (hex):', 'jetpack' ); ?>
476 </label>
477 <input
478 class="widefat"
479 id="<?php echo $this->get_field_id( 'border-color' ); ?>"
480 name="<?php echo $this->get_field_name( 'border-color' ); ?>"
481 type="text"
482 value="<?php echo esc_attr( $instance['border-color'] ); ?>"
483 />
484 </p>
485
486 <p>
487 <label for="<?php echo $this->get_field_id( 'theme' ); ?>">
488 <?php _e( 'Timeline Theme:', 'jetpack' ); ?>
489 </label>
490 <select
491 name="<?php echo $this->get_field_name( 'theme' ); ?>"
492 id="<?php echo $this->get_field_id( 'theme' ); ?>"
493 class="widefat"
494 >
495 <option value="light"<?php selected( $instance['theme'], 'light' ); ?>>
496 <?php esc_html_e( 'Light', 'jetpack' ); ?>
497 </option>
498 <option value="dark"<?php selected( $instance['theme'], 'dark' ); ?>>
499 <?php esc_html_e( 'Dark', 'jetpack' ); ?>
500 </option>
501 </select>
502 </p>
503 <?php
504 }
505 }
506