Completed
Push — update/remove-disconnect-link ( 4b6a2c )
by
unknown
73:18 queued 63:47
created

Jetpack_Twitter_Timeline_Widget::widget()   F

Complexity

Conditions 13
Paths 576

Size

Total Lines 80
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 40
nc 576
nop 2
dl 0
loc 80
rs 2.65
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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