Completed
Push — master-stable ( 3c2c70...0c40f5 )
by
unknown
36:44 queued 28:26
created

Jetpack_Carousel::settings_select()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 16
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 14
nc 5
nop 3
dl 0
loc 16
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
/*
4
Plugin Name: Jetpack Carousel
5
Plugin URL: https://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 false.
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( '20160325' ), 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( Jetpack_Options::get_option_and_ensure_autoload( 'carousel_display_exif', true ) ),
170
				'display_geo'          => $this->test_1or0_option( Jetpack_Options::get_option_and_ensure_autoload( 'carousel_display_geo', true ) ),
171
				'background_color'     => $this->carousel_background_color_sanitize( Jetpack_Options::get_option_and_ensure_autoload( '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
			 * Handle WP stats for images in full-screen.
216
			 * Build string with tracking info.
217
			 */
218
219
			/**
220
			 * Filter if Jetpack should enable stats collection on carousel views
221
			 *
222
			 * @module carousel
223
			 *
224
			 * @since 4.3.2
225
			 *
226
			 * @param bool Enable Jetpack Carousel stat collection. Default false.
227
			 */
228
			if ( apply_filters( 'jetpack_enable_carousel_stats', false ) && in_array( 'stats', Jetpack::get_active_modules() ) && ! Jetpack::is_development_mode() ) {
229
				$localize_strings['stats'] = 'blog=' . Jetpack_Options::get_option( 'id' ) . '&host=' . parse_url( get_option( 'home' ), PHP_URL_HOST ) . '&v=ext&j=' . JETPACK__API_VERSION . ':' . JETPACK__VERSION;
230
231
				// Set the stats as empty if user is logged in but logged-in users shouldn't be tracked.
232 View Code Duplication
				if ( is_user_logged_in() && function_exists( 'stats_get_options' ) ) {
233
					$stats_options = stats_get_options();
234
					$track_loggedin_users = isset( $stats_options['reg_users'] ) ? (bool) $stats_options['reg_users'] : false;
235
236
					if ( ! $track_loggedin_users ) {
237
						$localize_strings['stats'] = '';
238
					}
239
				}
240
			}
241
242
			/**
243
			 * Filter the strings passed to the Carousel's js file.
244
			 *
245
			 * @module carousel
246
			 *
247
			 * @since 1.6.0
248
			 *
249
			 * @param array $localize_strings Array of strings passed to the Jetpack js file.
250
			 */
251
			$localize_strings = apply_filters( 'jp_carousel_localize_strings', $localize_strings );
252
			wp_localize_script( 'jetpack-carousel', 'jetpackCarouselStrings', $localize_strings );
253
			if( is_rtl() ) {
254
				wp_enqueue_style( 'jetpack-carousel', plugins_url( '/rtl/jetpack-carousel-rtl.css', __FILE__ ), array(), $this->asset_version( '20120629' ) );
255
			} else {
256
				wp_enqueue_style( 'jetpack-carousel', plugins_url( 'jetpack-carousel.css', __FILE__ ), array(), $this->asset_version( '20120629' ) );
257
			}
258
259
			wp_register_style( 'jetpack-carousel-ie8fix', plugins_url( 'jetpack-carousel-ie8fix.css', __FILE__ ), array(), $this->asset_version( '20121024' ) );
260
			$GLOBALS['wp_styles']->add_data( 'jetpack-carousel-ie8fix', 'conditional', 'lte IE 8' );
261
			wp_enqueue_style( 'jetpack-carousel-ie8fix' );
262
263
			/**
264
			 * Fires after carousel assets are enqueued for the first time.
265
			 * Allows for adding additional assets to the carousel page.
266
			 *
267
			 * @module carousel
268
			 *
269
			 * @since 1.6.0
270
			 *
271
			 * @param bool $first_run First load if Carousel on the page.
272
			 * @param array $localized_strings Array of strings passed to the Jetpack js file.
273
			 */
274
			do_action( 'jp_carousel_enqueue_assets', $this->first_run, $localize_strings );
275
276
			$this->first_run = false;
277
		}
278
279
		return $output;
280
	}
281
282
	function set_in_gallery( $output ) {
283
		$this->in_gallery = true;
284
		return $output;
285
	}
286
287
	function add_data_to_images( $attr, $attachment = null ) {
288
289
		// not in a gallery?
290
		if ( ! $this->in_gallery ) {
291
			return $attr;
292
		}
293
294
		$attachment_id   = intval( $attachment->ID );
295
		$orig_file       = wp_get_attachment_image_src( $attachment_id, 'full' );
296
		$orig_file       = isset( $orig_file[0] ) ? $orig_file[0] : wp_get_attachment_url( $attachment_id );
297
		$meta            = wp_get_attachment_metadata( $attachment_id );
298
		$size            = isset( $meta['width'] ) ? intval( $meta['width'] ) . ',' . intval( $meta['height'] ) : '';
299
		$img_meta        = ( ! empty( $meta['image_meta'] ) ) ? (array) $meta['image_meta'] : array();
300
		$comments_opened = intval( comments_open( $attachment_id ) );
301
302
		 /*
303
		 * Note: Cannot generate a filename from the width and height wp_get_attachment_image_src() returns because
304
		 * it takes the $content_width global variable themes can set in consideration, therefore returning sizes
305
		 * which when used to generate a filename will likely result in a 404 on the image.
306
		 * $content_width has no filter we could temporarily de-register, run wp_get_attachment_image_src(), then
307
		 * re-register. So using returned file URL instead, which we can define the sizes from through filename
308
		 * parsing in the JS, as this is a failsafe file reference.
309
		 *
310
		 * EG with Twenty Eleven activated:
311
		 * 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) }
312
		 *
313
		 * EG with Twenty Ten activated:
314
		 * 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) }
315
		 */
316
317
		$medium_file_info = wp_get_attachment_image_src( $attachment_id, 'medium' );
318
		$medium_file      = isset( $medium_file_info[0] ) ? $medium_file_info[0] : '';
319
320
		$large_file_info  = wp_get_attachment_image_src( $attachment_id, 'large' );
321
		$large_file       = isset( $large_file_info[0] ) ? $large_file_info[0] : '';
322
323
		$attachment       = get_post( $attachment_id );
324
		$attachment_title = wptexturize( $attachment->post_title );
325
		$attachment_desc  = wpautop( wptexturize( $attachment->post_content ) );
326
327
		// Not yet providing geo-data, need to "fuzzify" for privacy
328 View Code Duplication
		if ( ! empty( $img_meta ) ) {
329
			foreach ( $img_meta as $k => $v ) {
330
				if ( 'latitude' == $k || 'longitude' == $k )
331
					unset( $img_meta[$k] );
332
			}
333
		}
334
335
		// See https://github.com/Automattic/jetpack/issues/2765
336
		if ( isset( $img_meta['keywords'] ) ) {
337
			unset( $img_meta['keywords'] );
338
		}
339
340
		$img_meta = json_encode( array_map( 'strval', $img_meta ) );
341
342
		$attr['data-attachment-id']     = $attachment_id;
343
		$attr['data-orig-file']         = esc_attr( $orig_file );
344
		$attr['data-orig-size']         = $size;
345
		$attr['data-comments-opened']   = $comments_opened;
346
		$attr['data-image-meta']        = esc_attr( $img_meta );
347
		$attr['data-image-title']       = esc_attr( $attachment_title );
348
		$attr['data-image-description'] = esc_attr( $attachment_desc );
349
		$attr['data-medium-file']       = esc_attr( $medium_file );
350
		$attr['data-large-file']        = esc_attr( $large_file );
351
352
		return $attr;
353
	}
354
355
	function add_data_to_container( $html ) {
356
		global $post;
357
358
		if ( isset( $post ) ) {
359
			$blog_id = (int) get_current_blog_id();
360
361
			$extra_data = array(
362
				'data-carousel-extra' => array(
363
					'blog_id' => $blog_id,
364
					'permalink' => get_permalink( $post->ID ),
365
					)
366
				);
367
368
			/**
369
			 * Filter the data added to the Gallery container.
370
			 *
371
			 * @module carousel
372
			 *
373
			 * @since 1.6.0
374
			 *
375
			 * @param array $extra_data Array of data about the site and the post.
376
			 */
377
			$extra_data = apply_filters( 'jp_carousel_add_data_to_container', $extra_data );
378
			foreach ( (array) $extra_data as $data_key => $data_values ) {
379
				$html = str_replace( '<div ', '<div ' . esc_attr( $data_key ) . "='" . json_encode( $data_values ) . "' ", $html );
380
			}
381
		}
382
383
		return $html;
384
	}
385
386
	function get_attachment_comments() {
387
		if ( ! headers_sent() )
388
			header('Content-type: text/javascript');
389
390
		/**
391
		 * Allows for the checking of privileges of the blog user before comments
392
		 * are packaged as JSON and sent back from the get_attachment_comments
393
		 * AJAX endpoint
394
		 *
395
		 * @module carousel
396
		 *
397
		 * @since 1.6.0
398
		 */
399
		do_action('jp_carousel_check_blog_user_privileges');
400
401
		$attachment_id = ( isset( $_REQUEST['id'] ) ) ? (int) $_REQUEST['id'] : 0;
402
		$offset        = ( isset( $_REQUEST['offset'] ) ) ? (int) $_REQUEST['offset'] : 0;
403
404
		if ( ! $attachment_id ) {
405
			echo json_encode( __( 'Missing attachment ID.', 'jetpack' ) );
406
			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...
407
		}
408
409
		if ( $offset < 1 )
410
			$offset = 0;
411
412
		$comments = get_comments( array(
413
			'status'  => 'approve',
414
			'order'   => ( 'asc' == get_option('comment_order') ) ? 'ASC' : 'DESC',
415
			'number'  => 10,
416
			'offset'  => $offset,
417
			'post_id' => $attachment_id,
418
		) );
419
420
		$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...
421
422
		// Can't just send the results, they contain the commenter's email address.
423
		foreach ( $comments as $comment ) {
424
			$avatar = get_avatar( $comment->comment_author_email, 64 );
425
			if( ! $avatar )
426
				$avatar = '';
427
			$out[] = array(
428
				'id'              => $comment->comment_ID,
429
				'parent_id'       => $comment->comment_parent,
430
				'author_markup'   => get_comment_author_link( $comment->comment_ID ),
431
				'gravatar_markup' => $avatar,
432
				'date_gmt'        => $comment->comment_date_gmt,
433
				'content'         => wpautop($comment->comment_content),
434
			);
435
		}
436
437
		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...
438
	}
439
440
	function post_attachment_comment() {
441
		if ( ! headers_sent() )
442
			header('Content-type: text/javascript');
443
444
		if ( empty( $_POST['nonce'] ) || ! wp_verify_nonce($_POST['nonce'], 'carousel_nonce') )
445
			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...
446
447
		$_blog_id = (int) $_POST['blog_id'];
448
		$_post_id = (int) $_POST['id'];
449
		$comment = $_POST['comment'];
450
451
		if ( empty( $_blog_id ) )
452
			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...
453
454
		if ( empty( $_post_id ) )
455
			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...
456
457
		if ( empty( $comment ) )
458
			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...
459
460
		// Used in context like NewDash
461
		$switched = false;
462
		if ( is_multisite() && $_blog_id != get_current_blog_id() ) {
463
			switch_to_blog( $_blog_id );
464
			$switched = true;
465
		}
466
467
		/** This action is documented in modules/carousel/jetpack-carousel.php */
468
		do_action('jp_carousel_check_blog_user_privileges');
469
470
		if ( ! comments_open( $_post_id ) )
471
			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...
472
473
		if ( is_user_logged_in() ) {
474
			$user         = wp_get_current_user();
475
			$user_id      = $user->ID;
476
			$display_name = $user->display_name;
477
			$email        = $user->user_email;
478
			$url          = $user->user_url;
479
480
			if ( empty( $user_id ) )
481
				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...
482
		} else {
483
			$user_id      = 0;
484
			$display_name = $_POST['author'];
485
			$email        = $_POST['email'];
486
			$url          = $_POST['url'];
487
488
			if ( get_option( 'require_name_email' ) ) {
489
				if ( empty( $display_name ) )
490
					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...
491
492
				if ( empty( $email ) )
493
					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...
494
495
				if ( ! is_email( $email ) )
496
					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...
497
			}
498
		}
499
500
		$comment_data =  array(
501
			'comment_content'      => $comment,
502
			'comment_post_ID'      => $_post_id,
503
			'comment_author'       => $display_name,
504
			'comment_author_email' => $email,
505
			'comment_author_url'   => $url,
506
			'comment_approved'     => 0,
507
			'comment_type'         => '',
508
		);
509
510
		if ( ! empty( $user_id ) )
511
			$comment_data['user_id'] = $user_id;
512
513
		// Note: wp_new_comment() sanitizes and validates the values (too).
514
		$comment_id = wp_new_comment( $comment_data );
515
516
		/**
517
		 * Fires before adding a new comment to the database via the get_attachment_comments ajax endpoint.
518
		 *
519
		 * @module carousel
520
		 *
521
		 * @since 1.6.0
522
		 */
523
		do_action( 'jp_carousel_post_attachment_comment' );
524
		$comment_status = wp_get_comment_status( $comment_id );
525
526
		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...
527
			restore_current_blog();
528
529
		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...
530
	}
531
532
	function register_settings() {
533
		add_settings_section('carousel_section', __( 'Image Gallery Carousel', 'jetpack' ), array( $this, 'carousel_section_callback' ), 'media');
534
535
		if ( ! $this->in_jetpack ) {
536
			add_settings_field('carousel_enable_it', __( 'Enable carousel', 'jetpack' ), array( $this, 'carousel_enable_it_callback' ), 'media', 'carousel_section' );
537
			register_setting( 'media', 'carousel_enable_it', array( $this, 'carousel_enable_it_sanitize' ) );
538
		}
539
540
		add_settings_field('carousel_background_color', __( 'Background color', 'jetpack' ), array( $this, 'carousel_background_color_callback' ), 'media', 'carousel_section' );
541
		register_setting( 'media', 'carousel_background_color', array( $this, 'carousel_background_color_sanitize' ) );
542
543
		add_settings_field('carousel_display_exif', __( 'Metadata', 'jetpack'), array( $this, 'carousel_display_exif_callback' ), 'media', 'carousel_section' );
544
		register_setting( 'media', 'carousel_display_exif', array( $this, 'carousel_display_exif_sanitize' ) );
545
546
		// No geo setting yet, need to "fuzzify" data first, for privacy
547
		// add_settings_field('carousel_display_geo', __( 'Geolocation', 'jetpack' ), array( $this, 'carousel_display_geo_callback' ), 'media', 'carousel_section' );
548
		// register_setting( 'media', 'carousel_display_geo', array( $this, 'carousel_display_geo_sanitize' ) );
549
	}
550
551
	// Fulfill the settings section callback requirement by returning nothing
552
	function carousel_section_callback() {
553
		return;
554
	}
555
556
	function test_1or0_option( $value, $default_to_1 = true ) {
557
		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...
558
			// Binary false (===) of $value means it has not yet been set, in which case we do want to default sites to 1
559
			if ( false === $value )
560
				$value = 1;
561
		}
562
		return ( 1 == $value ) ? 1 : 0;
563
	}
564
565
	function sanitize_1or0_option( $value ) {
566
		return ( 1 == $value ) ? 1 : 0;
567
	}
568
569
	function settings_checkbox($name, $label_text, $extra_text = '', $default_to_checked = true) {
570
		if ( empty( $name ) )
571
			return;
572
		$option = $this->test_1or0_option( get_option( $name ), $default_to_checked );
573
		echo '<fieldset>';
574
		echo '<input type="checkbox" name="'.esc_attr($name).'" id="'.esc_attr($name).'" value="1" ';
575
		checked( '1', $option );
576
		echo '/> <label for="'.esc_attr($name).'">'.$label_text.'</label>';
577
		if ( ! empty( $extra_text ) )
578
			echo '<p class="description">'.$extra_text.'</p>';
579
		echo '</fieldset>';
580
	}
581
582
	function settings_select($name, $values, $extra_text = '') {
583
		if ( empty( $name ) || ! is_array( $values ) || empty( $values ) )
584
			return;
585
		$option = get_option( $name );
586
		echo '<fieldset>';
587
		echo '<select name="'.esc_attr($name).'" id="'.esc_attr($name).'">';
588
		foreach( $values as $key => $value ) {
589
			echo '<option value="'.esc_attr($key).'" ';
590
			selected( $key, $option );
591
			echo '>'.esc_html($value).'</option>';
592
		}
593
		echo '</select>';
594
		if ( ! empty( $extra_text ) )
595
			echo '<p class="description">'.$extra_text.'</p>';
596
		echo '</fieldset>';
597
	}
598
599
	function carousel_display_exif_callback() {
600
		$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' ) );
601
	}
602
603
	function carousel_display_exif_sanitize( $value ) {
604
		return $this->sanitize_1or0_option( $value );
605
	}
606
607
	function carousel_display_geo_callback() {
608
		$this->settings_checkbox( 'carousel_display_geo', __( 'Show map of photo location in carousel, when available.', 'jetpack' ) );
609
	}
610
611
	function carousel_display_geo_sanitize( $value ) {
612
		return $this->sanitize_1or0_option( $value );
613
	}
614
615
	function carousel_background_color_callback() {
616
		$this->settings_select( 'carousel_background_color', array( 'black' => __( 'Black', 'jetpack' ), 'white' => __( 'White', 'jetpack', 'jetpack' ) ) );
617
	}
618
619
	function carousel_background_color_sanitize( $value ) {
620
		return ( 'white' == $value ) ? 'white' : 'black';
621
	}
622
623
	function carousel_enable_it_callback() {
624
		$this->settings_checkbox( 'carousel_enable_it', __( 'Display images in full-size carousel slideshow.', 'jetpack' ) );
625
	}
626
627
	function carousel_enable_it_sanitize( $value ) {
628
		return $this->sanitize_1or0_option( $value );
629
	}
630
}
631
632
new Jetpack_Carousel;
633