Completed
Push — merge/carousel-changes ( c18873 )
by Jeremy
12:21
created

Jetpack_Carousel   D

Complexity

Total Complexity 101

Size/Duplication

Total Lines 593
Duplicated Lines 1.85 %

Coupling/Cohesion

Components 3
Dependencies 2
Metric Value
wmc 101
lcom 3
cbo 2
dl 11
loc 593
rs 4.8718

26 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
C init() 0 45 11
A maybe_disable_jp_carousel() 0 12 1
A jetpack_configuration_load() 0 4 1
A asset_version() 0 12 1
A display_bail_message() 0 9 1
D enqueue_assets() 0 135 13
A set_in_gallery() 0 4 1
C add_data_to_images() 6 67 12
B add_data_to_container() 5 37 5
C get_attachment_comments() 0 53 9
D post_attachment_comment() 0 91 18
A register_settings() 0 18 2
A carousel_section_callback() 0 3 1
A test_1or0_option() 0 8 4
A sanitize_1or0_option() 0 3 2
A settings_checkbox() 0 12 3
B settings_select() 0 16 6
A carousel_display_exif_callback() 0 3 1
A carousel_display_exif_sanitize() 0 3 1
A carousel_display_geo_callback() 0 3 1
A carousel_display_geo_sanitize() 0 3 1
A carousel_background_color_callback() 0 3 1
A carousel_background_color_sanitize() 0 3 2
A carousel_enable_it_callback() 0 3 1
A carousel_enable_it_sanitize() 0 3 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Jetpack_Carousel often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Jetpack_Carousel, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
Plugin Name: Jetpack Carousel
5
Plugin URL: http://wordpress.com/
6
Description: Transform your standard image galleries into an immersive full-screen experience.
7
Version: 0.1
8
Author: Automattic
9
10
Released under the GPL v.2 license.
11
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
*/
17
class Jetpack_Carousel {
18
19
	public $prebuilt_widths = array( 370, 700, 1000, 1200, 1400, 2000 );
20
21
	public $first_run = true;
22
23
	public $in_gallery = false;
24
25
	public $in_jetpack = true;
26
27
	function __construct() {
28
		add_action( 'init', array( $this, 'init' ) );
29
	}
30
31
	function init() {
32
		if ( $this->maybe_disable_jp_carousel() )
33
			return;
34
35
		$this->in_jetpack = ( class_exists( 'Jetpack' ) && method_exists( 'Jetpack', 'enable_module_configurable' ) ) ? true : false;
36
37
		if ( is_admin() ) {
38
			// Register the Carousel-related related settings
39
			add_action( 'admin_init', array( $this, 'register_settings' ), 5 );
40
			if ( ! $this->in_jetpack ) {
41
				if ( 0 == $this->test_1or0_option( get_option( 'carousel_enable_it' ), true ) )
42
					return; // Carousel disabled, abort early, but still register setting so user can switch it back on
43
			}
44
			// If in admin, register the ajax endpoints.
45
			add_action( 'wp_ajax_get_attachment_comments', array( $this, 'get_attachment_comments' ) );
46
			add_action( 'wp_ajax_nopriv_get_attachment_comments', array( $this, 'get_attachment_comments' ) );
47
			add_action( 'wp_ajax_post_attachment_comment', array( $this, 'post_attachment_comment' ) );
48
			add_action( 'wp_ajax_nopriv_post_attachment_comment', array( $this, 'post_attachment_comment' ) );
49
		} else {
50
			if ( ! $this->in_jetpack ) {
51
				if ( 0 == $this->test_1or0_option( get_option( 'carousel_enable_it' ), true ) )
52
					return; // Carousel disabled, abort early
53
			}
54
			// If on front-end, do the Carousel thang.
55
			/**
56
			 * Filter the array of default prebuilt widths used in Carousel.
57
			 *
58
			 * @module carousel
59
			 *
60
			 * @since 1.6.0
61
			 *
62
			 * @param array $this->prebuilt_widths Array of default widths.
63
			 */
64
			$this->prebuilt_widths = apply_filters( 'jp_carousel_widths', $this->prebuilt_widths );
65
			add_filter( 'post_gallery', array( $this, 'enqueue_assets' ), 1000, 2 ); // load later than other callbacks hooked it
66
			add_filter( 'post_gallery', array( $this, 'set_in_gallery' ), -1000 );
67
			add_filter( 'gallery_style', array( $this, 'add_data_to_container' ) );
68
			add_filter( 'wp_get_attachment_image_attributes', array( $this, 'add_data_to_images' ), 10, 2 );
69
		}
70
71
		if ( $this->in_jetpack && method_exists( 'Jetpack', 'module_configuration_load' ) ) {
72
			Jetpack::enable_module_configurable( dirname( dirname( __FILE__ ) ) . '/carousel.php' );
73
			Jetpack::module_configuration_load( dirname( dirname( __FILE__ ) ) . '/carousel.php', array( $this, 'jetpack_configuration_load' ) );
74
		}
75
	}
76
77
	function maybe_disable_jp_carousel() {
78
		/**
79
		 * Allow third-party plugins or themes to disable Carousel.
80
		 *
81
		 * @module carousel
82
		 *
83
		 * @since 1.6.0
84
		 *
85
		 * @param bool false Should Carousel be disabled? Default to fase.
86
		 */
87
		return apply_filters( 'jp_carousel_maybe_disable', false );
88
	}
89
90
	function jetpack_configuration_load() {
91
		wp_safe_redirect( admin_url( 'options-media.php#carousel_background_color' ) );
92
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method jetpack_configuration_load() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
93
	}
94
95
	function asset_version( $version ) {
96
		/**
97
		 * Filter the version string used when enqueuing Carousel assets.
98
		 *
99
		 * @module carousel
100
		 *
101
		 * @since 1.6.0
102
		 *
103
		 * @param string $version Asset version.
104
		 */
105
		return apply_filters( 'jp_carousel_asset_version', $version );
106
	}
107
108
	function display_bail_message( $output= '' ) {
109
		// Displays a message on top of gallery if carousel has bailed
110
		$message = '<div class="jp-carousel-msg"><p>';
111
		$message .= __( 'Jetpack\'s Carousel has been disabled, because another plugin or your theme is overriding the [gallery] shortcode.', 'jetpack' );
112
		$message .= '</p></div>';
113
		// put before gallery output
114
		$output = $message . $output;
115
		return $output;
116
	}
117
118
	function enqueue_assets( $output ) {
119
		if (
120
			! empty( $output ) &&
121
			/**
122
			 * Allow third-party plugins or themes to force-enable Carousel.
123
			 *
124
			 * @module carousel
125
			 *
126
			 * @since 1.9.0
127
			 *
128
			 * @param bool false Should we force enable Carousel? Default to false.
129
			 */
130
			! apply_filters( 'jp_carousel_force_enable', false )
131
		) {
132
			// Bail because someone is overriding the [gallery] shortcode.
133
			remove_filter( 'gallery_style', array( $this, 'add_data_to_container' ) );
134
			remove_filter( 'wp_get_attachment_image_attributes', array( $this, 'add_data_to_images' ) );
135
			// Display message that carousel has bailed, if user is super_admin, and if we're not on WordPress.com.
136
			if (
137
				is_super_admin() &&
138
				! ( defined( 'IS_WPCOM' ) && IS_WPCOM )
139
			) {
140
				add_filter( 'post_gallery', array( $this, 'display_bail_message' ) );
141
			}
142
			return $output;
143
		}
144
145
		/**
146
		 * Fires when thumbnails are shown in Carousel.
147
		 *
148
		 * @module carousel
149
		 *
150
		 * @since 1.6.0
151
		 **/
152
		do_action( 'jp_carousel_thumbnails_shown' );
153
154
		if ( $this->first_run ) {
155
			wp_enqueue_script( 'jetpack-carousel', plugins_url( 'jetpack-carousel.js', __FILE__ ), array( 'jquery.spin' ), $this->asset_version( '20140505' ), true );
156
157
			// Note: using  home_url() instead of admin_url() for ajaxurl to be sure  to get same domain on wpcom when using mapped domains (also works on self-hosted)
158
			// Also: not hardcoding path since there is no guarantee site is running on site root in self-hosted context.
159
			$is_logged_in = is_user_logged_in();
160
			$current_user = wp_get_current_user();
161
			$comment_registration = intval( get_option( 'comment_registration' ) );
162
			$require_name_email   = intval( get_option( 'require_name_email' ) );
163
			$localize_strings = array(
164
				'widths'               => $this->prebuilt_widths,
165
				'is_logged_in'         => $is_logged_in,
166
				'lang'                 => strtolower( substr( get_locale(), 0, 2 ) ),
167
				'ajaxurl'              => set_url_scheme( admin_url( 'admin-ajax.php' ) ),
168
				'nonce'                => wp_create_nonce( 'carousel_nonce' ),
169
				'display_exif'         => $this->test_1or0_option( get_option( 'carousel_display_exif' ), true ),
170
				'display_geo'          => $this->test_1or0_option( get_option( 'carousel_display_geo' ), true ),
171
				'background_color'     => $this->carousel_background_color_sanitize( get_option( 'carousel_background_color' ) ),
172
				'comment'              => __( 'Comment', 'jetpack' ),
173
				'post_comment'         => __( 'Post Comment', 'jetpack' ),
174
				'write_comment'        => __( 'Write a Comment...', 'jetpack' ),
175
				'loading_comments'     => __( 'Loading Comments...', 'jetpack' ),
176
				'download_original'    => sprintf( __( 'View full size <span class="photo-size">%1$s<span class="photo-size-times">&times;</span>%2$s</span>', 'jetpack' ), '{0}', '{1}' ),
177
				'no_comment_text'      => __( 'Please be sure to submit some text with your comment.', 'jetpack' ),
178
				'no_comment_email'     => __( 'Please provide an email address to comment.', 'jetpack' ),
179
				'no_comment_author'    => __( 'Please provide your name to comment.', 'jetpack' ),
180
				'comment_post_error'   => __( 'Sorry, but there was an error posting your comment. Please try again later.', 'jetpack' ),
181
				'comment_approved'     => __( 'Your comment was approved.', 'jetpack' ),
182
				'comment_unapproved'   => __( 'Your comment is in moderation.', 'jetpack' ),
183
				'camera'               => __( 'Camera', 'jetpack' ),
184
				'aperture'             => __( 'Aperture', 'jetpack' ),
185
				'shutter_speed'        => __( 'Shutter Speed', 'jetpack' ),
186
				'focal_length'         => __( 'Focal Length', 'jetpack' ),
187
				'comment_registration' => $comment_registration,
188
				'require_name_email'   => $require_name_email,
189
				/** This action is documented in core/src/wp-includes/link-template.php */
190
				'login_url'            => wp_login_url( apply_filters( 'the_permalink', get_permalink() ) ),
191
			);
192
193
			if ( ! isset( $localize_strings['jetpack_comments_iframe_src'] ) || empty( $localize_strings['jetpack_comments_iframe_src'] ) ) {
194
				// We're not using Comments after all, so fallback to standard local comments.
195
196
				if ( $is_logged_in ) {
197
					$localize_strings['local_comments_commenting_as'] = '<p id="jp-carousel-commenting-as">' . sprintf( __( 'Commenting as %s', 'jetpack' ), $current_user->data->display_name ) . '</p>';
198
				} else {
199
					if ( $comment_registration ) {
200
						$localize_strings['local_comments_commenting_as'] = '<p id="jp-carousel-commenting-as">' . __( 'You must be <a href="#" class="jp-carousel-comment-login">logged in</a> to post a comment.', 'jetpack' ) . '</p>';
201
					} else {
202
						$required = ( $require_name_email ) ? __( '%s (Required)', 'jetpack' ) : '%s';
203
						$localize_strings['local_comments_commenting_as'] = ''
204
							. '<fieldset><label for="email">' . sprintf( $required, __( 'Email', 'jetpack' ) ) . '</label> '
205
							. '<input type="text" name="email" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-email-field" /></fieldset>'
206
							. '<fieldset><label for="author">' . sprintf( $required, __( 'Name', 'jetpack' ) ) . '</label> '
207
							. '<input type="text" name="author" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-author-field" /></fieldset>'
208
							. '<fieldset><label for="url">' . __( 'Website', 'jetpack' ) . '</label> '
209
							. '<input type="text" name="url" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-url-field" /></fieldset>';
210
						}
211
				}
212
			}
213
214
			/**
215
			 * Filter the strings passed to the Carousel's js file.
216
			 *
217
			 * @module carousel
218
			 *
219
			 * @since 1.6.0
220
			 *
221
			 * @param array $localize_strings Array of strings passed to the Jetpack js file.
222
			 */
223
			$localize_strings = apply_filters( 'jp_carousel_localize_strings', $localize_strings );
224
			wp_localize_script( 'jetpack-carousel', 'jetpackCarouselStrings', $localize_strings );
225
			if( is_rtl() ) {
226
				wp_enqueue_style( 'jetpack-carousel', plugins_url( '/rtl/jetpack-carousel-rtl.css', __FILE__ ), array(), $this->asset_version( '20120629' ) );
227
			} else {
228
				wp_enqueue_style( 'jetpack-carousel', plugins_url( 'jetpack-carousel.css', __FILE__ ), array(), $this->asset_version( '20120629' ) );
229
			}
230
231
			wp_register_style( 'jetpack-carousel-ie8fix', plugins_url( 'jetpack-carousel-ie8fix.css', __FILE__ ), array(), $this->asset_version( '20121024' ) );
232
			$GLOBALS['wp_styles']->add_data( 'jetpack-carousel-ie8fix', 'conditional', 'lte IE 8' );
233
			wp_enqueue_style( 'jetpack-carousel-ie8fix' );
234
235
			/**
236
			 * Fires after carousel assets are enqueued for the first time.
237
			 * Allows for adding additional assets to the carousel page.
238
			 *
239
			 * @module carousel
240
			 *
241
			 * @since 1.6.0
242
			 *
243
			 * @param bool $first_run First load if Carousel on the page.
244
			 * @param array $localized_strings Array of strings passed to the Jetpack js file.
245
			 */
246
			do_action( 'jp_carousel_enqueue_assets', $this->first_run, $localize_strings );
247
248
			$this->first_run = false;
249
		}
250
251
		return $output;
252
	}
253
254
	function set_in_gallery( $output ) {
255
		$this->in_gallery = true;
256
		return $output;
257
	}
258
259
	function add_data_to_images( $attr, $attachment = null ) {
260
261
		// not in a gallery?
262
		if ( ! $this->in_gallery ) {
263
			return $attr;
264
		}
265
266
		$attachment_id   = intval( $attachment->ID );
267
		$orig_file       = wp_get_attachment_image_src( $attachment_id, 'full' );
268
		$orig_file       = isset( $orig_file[0] ) ? $orig_file[0] : wp_get_attachment_url( $attachment_id );
269
		$meta            = wp_get_attachment_metadata( $attachment_id );
270
		$size            = isset( $meta['width'] ) ? intval( $meta['width'] ) . ',' . intval( $meta['height'] ) : '';
271
		$img_meta        = ( ! empty( $meta['image_meta'] ) ) ? (array) $meta['image_meta'] : array();
272
		$comments_opened = intval( comments_open( $attachment_id ) );
273
274
		 /*
275
		 * Note: Cannot generate a filename from the width and height wp_get_attachment_image_src() returns because
276
		 * it takes the $content_width global variable themes can set in consideration, therefore returning sizes
277
		 * which when used to generate a filename will likely result in a 404 on the image.
278
		 * $content_width has no filter we could temporarily de-register, run wp_get_attachment_image_src(), then
279
		 * re-register. So using returned file URL instead, which we can define the sizes from through filename
280
		 * parsing in the JS, as this is a failsafe file reference.
281
		 *
282
		 * EG with Twenty Eleven activated:
283
		 * array(4) { [0]=> string(82) "http://vanillawpinstall.blah/wp-content/uploads/2012/06/IMG_3534-1024x764.jpg" [1]=> int(584) [2]=> int(435) [3]=> bool(true) }
284
		 *
285
		 * EG with Twenty Ten activated:
286
		 * array(4) { [0]=> string(82) "http://vanillawpinstall.blah/wp-content/uploads/2012/06/IMG_3534-1024x764.jpg" [1]=> int(640) [2]=> int(477) [3]=> bool(true) }
287
		 */
288
289
		$medium_file_info = wp_get_attachment_image_src( $attachment_id, 'medium' );
290
		$medium_file      = isset( $medium_file_info[0] ) ? $medium_file_info[0] : '';
291
292
		$large_file_info  = wp_get_attachment_image_src( $attachment_id, 'large' );
293
		$large_file       = isset( $large_file_info[0] ) ? $large_file_info[0] : '';
294
295
		$attachment       = get_post( $attachment_id );
296
		$attachment_title = wptexturize( $attachment->post_title );
297
		$attachment_desc  = wpautop( wptexturize( $attachment->post_content ) );
298
299
		// Not yet providing geo-data, need to "fuzzify" for privacy
300 View Code Duplication
		if ( ! empty( $img_meta ) ) {
301
			foreach ( $img_meta as $k => $v ) {
302
				if ( 'latitude' == $k || 'longitude' == $k )
303
					unset( $img_meta[$k] );
304
			}
305
		}
306
307
		// See https://github.com/Automattic/jetpack/issues/2765
308
		if ( isset( $img_meta['keywords'] ) ) {
309
			unset( $img_meta['keywords'] );
310
		}
311
312
		$img_meta = json_encode( array_map( 'strval', $img_meta ) );
313
314
		$attr['data-attachment-id']     = $attachment_id;
315
		$attr['data-orig-file']         = esc_attr( $orig_file );
316
		$attr['data-orig-size']         = $size;
317
		$attr['data-comments-opened']   = $comments_opened;
318
		$attr['data-image-meta']        = esc_attr( $img_meta );
319
		$attr['data-image-title']       = esc_attr( $attachment_title );
320
		$attr['data-image-description'] = esc_attr( $attachment_desc );
321
		$attr['data-medium-file']       = esc_attr( $medium_file );
322
		$attr['data-large-file']        = esc_attr( $large_file );
323
324
		return $attr;
325
	}
326
327
	function add_data_to_container( $html ) {
328
		global $post;
329
330
		if ( isset( $post ) ) {
331
			$blog_id = (int) get_current_blog_id();
332
333 View Code Duplication
			if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
334
				$likes_blog_id = $blog_id;
335
			} else {
336
				$likes_blog_id = Jetpack_Options::get_option( 'id' );
337
			}
338
339
			$extra_data = array(
340
				'data-carousel-extra' => array(
341
					'blog_id' => $blog_id,
342
					'permalink' => get_permalink( $post->ID ),
343
					'likes_blog_id' => $likes_blog_id
344
					)
345
				);
346
347
			/**
348
			 * Filter the data added to the Gallery container.
349
			 *
350
			 * @module carousel
351
			 *
352
			 * @since 1.6.0
353
			 *
354
			 * @param array $extra_data Array of data about the site and the post.
355
			 */
356
			$extra_data = apply_filters( 'jp_carousel_add_data_to_container', $extra_data );
357
			foreach ( (array) $extra_data as $data_key => $data_values ) {
358
				$html = str_replace( '<div ', '<div ' . esc_attr( $data_key ) . "='" . json_encode( $data_values ) . "' ", $html );
359
			}
360
		}
361
362
		return $html;
363
	}
364
365
	function get_attachment_comments() {
366
		if ( ! headers_sent() )
367
			header('Content-type: text/javascript');
368
369
		/**
370
		 * Allows for the checking of privileges of the blog user before comments
371
		 * are packaged as JSON and sent back from the get_attachment_comments
372
		 * AJAX endpoint
373
		 *
374
		 * @module carousel
375
		 *
376
		 * @since 1.6.0
377
		 */
378
		do_action('jp_carousel_check_blog_user_privileges');
379
380
		$attachment_id = ( isset( $_REQUEST['id'] ) ) ? (int) $_REQUEST['id'] : 0;
381
		$offset        = ( isset( $_REQUEST['offset'] ) ) ? (int) $_REQUEST['offset'] : 0;
382
383
		if ( ! $attachment_id ) {
384
			echo json_encode( __( 'Missing attachment ID.', 'jetpack' ) );
385
			die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method get_attachment_comments() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
386
		}
387
388
		if ( $offset < 1 )
389
			$offset = 0;
390
391
		$comments = get_comments( array(
392
			'status'  => 'approve',
393
			'order'   => ( 'asc' == get_option('comment_order') ) ? 'ASC' : 'DESC',
394
			'number'  => 10,
395
			'offset'  => $offset,
396
			'post_id' => $attachment_id,
397
		) );
398
399
		$out      = array();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 6 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
400
401
		// Can't just send the results, they contain the commenter's email address.
402
		foreach ( $comments as $comment ) {
403
			$avatar = get_avatar( $comment->comment_author_email, 64 );
404
			if( ! $avatar )
405
				$avatar = '';
406
			$out[] = array(
407
				'id'              => $comment->comment_ID,
408
				'parent_id'       => $comment->comment_parent,
409
				'author_markup'   => get_comment_author_link( $comment->comment_ID ),
410
				'gravatar_markup' => $avatar,
411
				'date_gmt'        => $comment->comment_date_gmt,
412
				'content'         => wpautop($comment->comment_content),
413
			);
414
		}
415
416
		die( json_encode( $out ) );
0 ignored issues
show
Coding Style Compatibility introduced by
The method get_attachment_comments() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
417
	}
418
419
	function post_attachment_comment() {
420
		if ( ! headers_sent() )
421
			header('Content-type: text/javascript');
422
423
		if ( empty( $_POST['nonce'] ) || ! wp_verify_nonce($_POST['nonce'], 'carousel_nonce') )
424
			die( json_encode( array( 'error' => __( 'Nonce verification failed.', 'jetpack' ) ) ) );
0 ignored issues
show
Coding Style Compatibility introduced by
The method post_attachment_comment() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
425
426
		$_blog_id = (int) $_POST['blog_id'];
427
		$_post_id = (int) $_POST['id'];
428
		$comment = $_POST['comment'];
429
430
		if ( empty( $_blog_id ) )
431
			die( json_encode( array( 'error' => __( 'Missing target blog ID.', 'jetpack' ) ) ) );
0 ignored issues
show
Coding Style Compatibility introduced by
The method post_attachment_comment() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
432
433
		if ( empty( $_post_id ) )
434
			die( json_encode( array( 'error' => __( 'Missing target post ID.', 'jetpack' ) ) ) );
0 ignored issues
show
Coding Style Compatibility introduced by
The method post_attachment_comment() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
435
436
		if ( empty( $comment ) )
437
			die( json_encode( array( 'error' => __( 'No comment text was submitted.', 'jetpack' ) ) ) );
0 ignored issues
show
Coding Style Compatibility introduced by
The method post_attachment_comment() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
438
439
		// Used in context like NewDash
440
		$switched = false;
441
		if ( is_multisite() && $_blog_id != get_current_blog_id() ) {
442
			switch_to_blog( $_blog_id );
443
			$switched = true;
444
		}
445
446
		/** This action is documented in modules/carousel/jetpack-carousel.php */
447
		do_action('jp_carousel_check_blog_user_privileges');
448
449
		if ( ! comments_open( $_post_id ) )
450
			die( json_encode( array( 'error' => __( 'Comments on this post are closed.', 'jetpack' ) ) ) );
0 ignored issues
show
Coding Style Compatibility introduced by
The method post_attachment_comment() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
451
452
		if ( is_user_logged_in() ) {
453
			$user         = wp_get_current_user();
454
			$user_id      = $user->ID;
455
			$display_name = $user->display_name;
456
			$email        = $user->user_email;
457
			$url          = $user->user_url;
458
459
			if ( empty( $user_id ) )
460
				die( json_encode( array( 'error' => __( 'Sorry, but we could not authenticate your request.', 'jetpack' ) ) ) );
0 ignored issues
show
Coding Style Compatibility introduced by
The method post_attachment_comment() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
461
		} else {
462
			$user_id      = 0;
463
			$display_name = $_POST['author'];
464
			$email        = $_POST['email'];
465
			$url          = $_POST['url'];
466
467
			if ( get_option( 'require_name_email' ) ) {
468
				if ( empty( $display_name ) )
469
					die( json_encode( array( 'error' => __( 'Please provide your name.', 'jetpack' ) ) ) );
0 ignored issues
show
Coding Style Compatibility introduced by
The method post_attachment_comment() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
470
471
				if ( empty( $email ) )
472
					die( json_encode( array( 'error' => __( 'Please provide an email address.', 'jetpack' ) ) ) );
0 ignored issues
show
Coding Style Compatibility introduced by
The method post_attachment_comment() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
473
474
				if ( ! is_email( $email ) )
475
					die( json_encode( array( 'error' => __( 'Please provide a valid email address.', 'jetpack' ) ) ) );
0 ignored issues
show
Coding Style Compatibility introduced by
The method post_attachment_comment() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
476
			}
477
		}
478
479
		$comment_data =  array(
480
			'comment_content'      => $comment,
481
			'comment_post_ID'      => $_post_id,
482
			'comment_author'       => $display_name,
483
			'comment_author_email' => $email,
484
			'comment_author_url'   => $url,
485
			'comment_approved'     => 0,
486
			'comment_type'         => '',
487
		);
488
489
		if ( ! empty( $user_id ) )
490
			$comment_data['user_id'] = $user_id;
491
492
		// Note: wp_new_comment() sanitizes and validates the values (too).
493
		$comment_id = wp_new_comment( $comment_data );
494
495
		/**
496
		 * Fires before adding a new comment to the database via the get_attachment_comments ajax endpoint.
497
		 *
498
		 * @module carousel
499
		 *
500
		 * @since 1.6.0
501
		 */
502
		do_action( 'jp_carousel_post_attachment_comment' );
503
		$comment_status = wp_get_comment_status( $comment_id );
504
505
		if ( true == $switched )
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
506
			restore_current_blog();
507
508
		die( json_encode( array( 'comment_id' => $comment_id, 'comment_status' => $comment_status ) ) );
0 ignored issues
show
Coding Style Compatibility introduced by
The method post_attachment_comment() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
509
	}
510
511
	function register_settings() {
512
		add_settings_section('carousel_section', __( 'Image Gallery Carousel', 'jetpack' ), array( $this, 'carousel_section_callback' ), 'media');
513
514
		if ( ! $this->in_jetpack ) {
515
			add_settings_field('carousel_enable_it', __( 'Enable carousel', 'jetpack' ), array( $this, 'carousel_enable_it_callback' ), 'media', 'carousel_section' );
516
			register_setting( 'media', 'carousel_enable_it', array( $this, 'carousel_enable_it_sanitize' ) );
517
		}
518
519
		add_settings_field('carousel_background_color', __( 'Background color', 'jetpack' ), array( $this, 'carousel_background_color_callback' ), 'media', 'carousel_section' );
520
		register_setting( 'media', 'carousel_background_color', array( $this, 'carousel_background_color_sanitize' ) );
521
522
		add_settings_field('carousel_display_exif', __( 'Metadata', 'jetpack'), array( $this, 'carousel_display_exif_callback' ), 'media', 'carousel_section' );
523
		register_setting( 'media', 'carousel_display_exif', array( $this, 'carousel_display_exif_sanitize' ) );
524
525
		// No geo setting yet, need to "fuzzify" data first, for privacy
526
		// add_settings_field('carousel_display_geo', __( 'Geolocation', 'jetpack' ), array( $this, 'carousel_display_geo_callback' ), 'media', 'carousel_section' );
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
527
		// register_setting( 'media', 'carousel_display_geo', array( $this, 'carousel_display_geo_sanitize' ) );
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
528
	}
529
530
	// Fulfill the settings section callback requirement by returning nothing
531
	function carousel_section_callback() {
532
		return;
533
	}
534
535
	function test_1or0_option( $value, $default_to_1 = true ) {
536
		if ( true == $default_to_1 ) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
537
			// Binary false (===) of $value means it has not yet been set, in which case we do want to default sites to 1
538
			if ( false === $value )
539
				$value = 1;
540
		}
541
		return ( 1 == $value ) ? 1 : 0;
542
	}
543
544
	function sanitize_1or0_option( $value ) {
545
		return ( 1 == $value ) ? 1 : 0;
546
	}
547
548
	function settings_checkbox($name, $label_text, $extra_text = '', $default_to_checked = true) {
549
		if ( empty( $name ) )
550
			return;
551
		$option = $this->test_1or0_option( get_option( $name ), $default_to_checked );
552
		echo '<fieldset>';
553
		echo '<input type="checkbox" name="'.esc_attr($name).'" id="'.esc_attr($name).'" value="1" ';
554
		checked( '1', $option );
555
		echo '/> <label for="'.esc_attr($name).'">'.$label_text.'</label>';
556
		if ( ! empty( $extra_text ) )
557
			echo '<p class="description">'.$extra_text.'</p>';
558
		echo '</fieldset>';
559
	}
560
561
	function settings_select($name, $values, $extra_text = '') {
562
		if ( empty( $name ) || ! is_array( $values ) || empty( $values ) )
563
			return;
564
		$option = get_option( $name );
565
		echo '<fieldset>';
566
		echo '<select name="'.esc_attr($name).'" id="'.esc_attr($name).'">';
567
		foreach( $values as $key => $value ) {
568
			echo '<option value="'.esc_attr($key).'" ';
569
			selected( $key, $option );
570
			echo '>'.esc_html($value).'</option>';
571
		}
572
		echo '</select>';
573
		if ( ! empty( $extra_text ) )
574
			echo '<p class="description">'.$extra_text.'</p>';
575
		echo '</fieldset>';
576
	}
577
578
	function carousel_display_exif_callback() {
579
		$this->settings_checkbox( 'carousel_display_exif', __( 'Show photo metadata (<a href="http://en.wikipedia.org/wiki/Exchangeable_image_file_format" target="_blank">Exif</a>) in carousel, when available.', 'jetpack' ) );
580
	}
581
582
	function carousel_display_exif_sanitize( $value ) {
583
		return $this->sanitize_1or0_option( $value );
584
	}
585
586
	function carousel_display_geo_callback() {
587
		$this->settings_checkbox( 'carousel_display_geo', __( 'Show map of photo location in carousel, when available.', 'jetpack' ) );
588
	}
589
590
	function carousel_display_geo_sanitize( $value ) {
591
		return $this->sanitize_1or0_option( $value );
592
	}
593
594
	function carousel_background_color_callback() {
595
		$this->settings_select( 'carousel_background_color', array( 'black' => __( 'Black', 'jetpack' ), 'white' => __( 'White', 'jetpack', 'jetpack' ) ) );
596
	}
597
598
	function carousel_background_color_sanitize( $value ) {
599
		return ( 'white' == $value ) ? 'white' : 'black';
600
	}
601
602
	function carousel_enable_it_callback() {
603
		$this->settings_checkbox( 'carousel_enable_it', __( 'Display images in full-size carousel slideshow.', 'jetpack' ) );
604
	}
605
606
	function carousel_enable_it_sanitize( $value ) {
607
		return $this->sanitize_1or0_option( $value );
608
	}
609
}
610
611
new Jetpack_Carousel;
612