Completed
Push — add/carousel-for-single-image ( 8186b5...2974b5 )
by
unknown
15:30
created

maybe_disable_jp_carousel_single_images()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 10
rs 9.4285
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
	public $single_image_gallery_enabled = false;
28
29
	function __construct() {
30
		add_action( 'init', array( $this, 'init' ) );
31
	}
32
33
	function init() {
34
		if ( $this->maybe_disable_jp_carousel() )
35
			return;
36
37
		$this->in_jetpack = ( class_exists( 'Jetpack' ) && method_exists( 'Jetpack', 'enable_module_configurable' ) ) ? true : false;
38
39
		$this->single_image_gallery_enabled = !$this->maybe_disable_jp_carousel_single_images();
40
41
		if ( is_admin() ) {
42
			// Register the Carousel-related related settings
43
			add_action( 'admin_init', array( $this, 'register_settings' ), 5 );
44
			if ( ! $this->in_jetpack ) {
45
				if ( 0 == $this->test_1or0_option( get_option( 'carousel_enable_it' ), true ) )
46
					return; // Carousel disabled, abort early, but still register setting so user can switch it back on
47
			}
48
			// If in admin, register the ajax endpoints.
49
			add_action( 'wp_ajax_get_attachment_comments', array( $this, 'get_attachment_comments' ) );
50
			add_action( 'wp_ajax_nopriv_get_attachment_comments', array( $this, 'get_attachment_comments' ) );
51
			add_action( 'wp_ajax_post_attachment_comment', array( $this, 'post_attachment_comment' ) );
52
			add_action( 'wp_ajax_nopriv_post_attachment_comment', array( $this, 'post_attachment_comment' ) );
53
		} else {
54
			if ( ! $this->in_jetpack ) {
55
				if ( 0 == $this->test_1or0_option( get_option( 'carousel_enable_it' ), true ) )
56
					return; // Carousel disabled, abort early
57
			}
58
			// If on front-end, do the Carousel thang.
59
			/**
60
			 * Filter the array of default prebuilt widths used in Carousel.
61
			 *
62
			 * @module carousel
63
			 *
64
			 * @since 1.6.0
65
			 *
66
			 * @param array $this->prebuilt_widths Array of default widths.
67
			 */
68
			$this->prebuilt_widths = apply_filters( 'jp_carousel_widths', $this->prebuilt_widths );
69
			add_filter( 'post_gallery', array( $this, 'check_and_enqueue_assets' ), 1000, 2 ); // load later than other callbacks hooked it
70
			add_filter( 'post_gallery', array( $this, 'set_in_gallery' ), -1000 );
71
			add_filter( 'gallery_style', array( $this, 'add_data_to_container' ) );
72
			add_filter( 'wp_get_attachment_image_attributes', array( $this, 'add_data_to_images' ), 10, 2 );
73
			if ( $this->single_image_gallery_enabled ) {
74
				add_filter( 'the_content', array( $this, 'add_data_to_single_images' ) );
75
				$this->enqueue_assets();
76
			}
77
		}
78
79
		if ( $this->in_jetpack && method_exists( 'Jetpack', 'module_configuration_load' ) ) {
80
			Jetpack::enable_module_configurable( dirname( dirname( __FILE__ ) ) . '/carousel.php' );
81
			Jetpack::module_configuration_load( dirname( dirname( __FILE__ ) ) . '/carousel.php', array( $this, 'jetpack_configuration_load' ) );
82
		}
83
	}
84
85
	function maybe_disable_jp_carousel() {
86
		/**
87
		 * Allow third-party plugins or themes to disable Carousel.
88
		 *
89
		 * @module carousel
90
		 *
91
		 * @since 1.6.0
92
		 *
93
		 * @param bool false Should Carousel be disabled? Default to false.
94
		 */
95
		return apply_filters( 'jp_carousel_maybe_disable', false );
96
	}
97
98
	function maybe_disable_jp_carousel_single_images() {
99
		/**
100
		 * Allow third-party plugins or themes to disable Carousel for single images.
101
		 *
102
		 * @module carousel
103
		 *
104
		 * @param bool false Should Carousel be disabled for single images? Default to false.
105
		 */
106
		return apply_filters( 'jp_carousel_maybe_disable_single_images', false );
107
	}
108
109
	function jetpack_configuration_load() {
110
		wp_safe_redirect( admin_url( 'options-media.php#carousel_background_color' ) );
111
		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...
112
	}
113
114
	function asset_version( $version ) {
115
		/**
116
		 * Filter the version string used when enqueuing Carousel assets.
117
		 *
118
		 * @module carousel
119
		 *
120
		 * @since 1.6.0
121
		 *
122
		 * @param string $version Asset version.
123
		 */
124
		return apply_filters( 'jp_carousel_asset_version', $version );
125
	}
126
127
	function display_bail_message( $output= '' ) {
128
		// Displays a message on top of gallery if carousel has bailed
129
		$message = '<div class="jp-carousel-msg"><p>';
130
		$message .= __( 'Jetpack\'s Carousel has been disabled, because another plugin or your theme is overriding the [gallery] shortcode.', 'jetpack' );
131
		$message .= '</p></div>';
132
		// put before gallery output
133
		$output = $message . $output;
134
		return $output;
135
	}
136
137
	function check_and_enqueue_assets( $output ) {
138
		if (
139
			! empty( $output ) &&
140
			/**
141
			 * Allow third-party plugins or themes to force-enable Carousel.
142
			 *
143
			 * @module carousel
144
			 *
145
			 * @since 1.9.0
146
			 *
147
			 * @param bool false Should we force enable Carousel? Default to false.
148
			 */
149
			! apply_filters( 'jp_carousel_force_enable', false )
150
		) {
151
			// Bail because someone is overriding the [gallery] shortcode.
152
			remove_filter( 'gallery_style', array( $this, 'add_data_to_container' ) );
153
			remove_filter( 'wp_get_attachment_image_attributes', array( $this, 'add_data_to_images' ) );
154
			// Display message that carousel has bailed, if user is super_admin, and if we're not on WordPress.com.
155
			if (
156
				is_super_admin() &&
157
				! ( defined( 'IS_WPCOM' ) && IS_WPCOM )
158
			) {
159
				add_filter( 'post_gallery', array( $this, 'display_bail_message' ) );
160
			}
161
			return $output;
162
		}
163
164
		/**
165
		 * Fires when thumbnails are shown in Carousel.
166
		 *
167
		 * @module carousel
168
		 *
169
		 * @since 1.6.0
170
		 **/
171
		do_action( 'jp_carousel_thumbnails_shown' );
172
173
		$this->enqueue_assets();
174
175
		return $output;
176
	}
177
178
	function enqueue_assets() {
179
		if ( $this->first_run ) {
180
			wp_enqueue_script( 'jetpack-carousel', plugins_url( 'jetpack-carousel.js', __FILE__ ), array( 'jquery.spin' ), $this->asset_version( '20160325' ), true );
181
182
			// 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)
183
			// Also: not hardcoding path since there is no guarantee site is running on site root in self-hosted context.
184
			$is_logged_in = is_user_logged_in();
185
			$current_user = wp_get_current_user();
186
			$comment_registration = intval( get_option( 'comment_registration' ) );
187
			$require_name_email   = intval( get_option( 'require_name_email' ) );
188
			$localize_strings = array(
189
				'widths'               => $this->prebuilt_widths,
190
				'is_logged_in'         => $is_logged_in,
191
				'lang'                 => strtolower( substr( get_locale(), 0, 2 ) ),
192
				'ajaxurl'              => set_url_scheme( admin_url( 'admin-ajax.php' ) ),
193
				'nonce'                => wp_create_nonce( 'carousel_nonce' ),
194
				'display_exif'         => $this->test_1or0_option( Jetpack_Options::get_option_and_ensure_autoload( 'carousel_display_exif', true ) ),
195
				'display_geo'          => $this->test_1or0_option( Jetpack_Options::get_option_and_ensure_autoload( 'carousel_display_geo', true ) ),
196
				'single_image_gallery' => $this->single_image_gallery_enabled,
197
				'background_color'     => $this->carousel_background_color_sanitize( Jetpack_Options::get_option_and_ensure_autoload( 'carousel_background_color', '' ) ),
198
				'comment'              => __( 'Comment', 'jetpack' ),
199
				'post_comment'         => __( 'Post Comment', 'jetpack' ),
200
				'write_comment'        => __( 'Write a Comment...', 'jetpack' ),
201
				'loading_comments'     => __( 'Loading Comments...', 'jetpack' ),
202
				'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}' ),
203
				'no_comment_text'      => __( 'Please be sure to submit some text with your comment.', 'jetpack' ),
204
				'no_comment_email'     => __( 'Please provide an email address to comment.', 'jetpack' ),
205
				'no_comment_author'    => __( 'Please provide your name to comment.', 'jetpack' ),
206
				'comment_post_error'   => __( 'Sorry, but there was an error posting your comment. Please try again later.', 'jetpack' ),
207
				'comment_approved'     => __( 'Your comment was approved.', 'jetpack' ),
208
				'comment_unapproved'   => __( 'Your comment is in moderation.', 'jetpack' ),
209
				'camera'               => __( 'Camera', 'jetpack' ),
210
				'aperture'             => __( 'Aperture', 'jetpack' ),
211
				'shutter_speed'        => __( 'Shutter Speed', 'jetpack' ),
212
				'focal_length'         => __( 'Focal Length', 'jetpack' ),
213
				'comment_registration' => $comment_registration,
214
				'require_name_email'   => $require_name_email,
215
				/** This action is documented in core/src/wp-includes/link-template.php */
216
				'login_url'            => wp_login_url( apply_filters( 'the_permalink', get_permalink() ) ),
217
			);
218
219
			if ( ! isset( $localize_strings['jetpack_comments_iframe_src'] ) || empty( $localize_strings['jetpack_comments_iframe_src'] ) ) {
220
				// We're not using Comments after all, so fallback to standard local comments.
221
222
				if ( $is_logged_in ) {
223
					$localize_strings['local_comments_commenting_as'] = '<p id="jp-carousel-commenting-as">' . sprintf( __( 'Commenting as %s', 'jetpack' ), $current_user->data->display_name ) . '</p>';
224
				} else {
225
					if ( $comment_registration ) {
226
						$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>';
227
					} else {
228
						$required = ( $require_name_email ) ? __( '%s (Required)', 'jetpack' ) : '%s';
229
						$localize_strings['local_comments_commenting_as'] = ''
230
							. '<fieldset><label for="email">' . sprintf( $required, __( 'Email', 'jetpack' ) ) . '</label> '
231
							. '<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>'
232
							. '<fieldset><label for="author">' . sprintf( $required, __( 'Name', 'jetpack' ) ) . '</label> '
233
							. '<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>'
234
							. '<fieldset><label for="url">' . __( 'Website', 'jetpack' ) . '</label> '
235
							. '<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>';
236
						}
237
				}
238
			}
239
240
			/**
241
			 * Handle WP stats for images in full-screen.
242
			 * Build string with tracking info.
243
			 */
244
245
			/**
246
			 * Filter if Jetpack should enable stats collection on carousel views
247
			 *
248
			 * @module carousel
249
			 *
250
			 * @since 4.3.2
251
			 *
252
			 * @param bool Enable Jetpack Carousel stat collection. Default false.
253
			 */
254
			if ( apply_filters( 'jetpack_enable_carousel_stats', false ) && in_array( 'stats', Jetpack::get_active_modules() ) && ! Jetpack::is_development_mode() ) {
255
				$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;
256
257
				// Set the stats as empty if user is logged in but logged-in users shouldn't be tracked.
258 View Code Duplication
				if ( is_user_logged_in() && function_exists( 'stats_get_options' ) ) {
259
					$stats_options = stats_get_options();
260
					$track_loggedin_users = isset( $stats_options['reg_users'] ) ? (bool) $stats_options['reg_users'] : false;
261
262
					if ( ! $track_loggedin_users ) {
263
						$localize_strings['stats'] = '';
264
					}
265
				}
266
			}
267
268
			/**
269
			 * Filter the strings passed to the Carousel's js file.
270
			 *
271
			 * @module carousel
272
			 *
273
			 * @since 1.6.0
274
			 *
275
			 * @param array $localize_strings Array of strings passed to the Jetpack js file.
276
			 */
277
			$localize_strings = apply_filters( 'jp_carousel_localize_strings', $localize_strings );
278
			wp_localize_script( 'jetpack-carousel', 'jetpackCarouselStrings', $localize_strings );
279
			if( is_rtl() ) {
280
				wp_enqueue_style( 'jetpack-carousel', plugins_url( '/rtl/jetpack-carousel-rtl.css', __FILE__ ), array(), $this->asset_version( '20120629' ) );
281
			} else {
282
				wp_enqueue_style( 'jetpack-carousel', plugins_url( 'jetpack-carousel.css', __FILE__ ), array(), $this->asset_version( '20120629' ) );
283
			}
284
285
			wp_register_style( 'jetpack-carousel-ie8fix', plugins_url( 'jetpack-carousel-ie8fix.css', __FILE__ ), array(), $this->asset_version( '20121024' ) );
286
			$GLOBALS['wp_styles']->add_data( 'jetpack-carousel-ie8fix', 'conditional', 'lte IE 8' );
287
			wp_enqueue_style( 'jetpack-carousel-ie8fix' );
288
289
			/**
290
			 * Fires after carousel assets are enqueued for the first time.
291
			 * Allows for adding additional assets to the carousel page.
292
			 *
293
			 * @module carousel
294
			 *
295
			 * @since 1.6.0
296
			 *
297
			 * @param bool $first_run First load if Carousel on the page.
298
			 * @param array $localized_strings Array of strings passed to the Jetpack js file.
299
			 */
300
			do_action( 'jp_carousel_enqueue_assets', $this->first_run, $localize_strings );
301
302
			$this->first_run = false;
303
		}
304
	}
305
306
	function set_in_gallery( $output ) {
307
		$this->in_gallery = true;
308
		return $output;
309
	}
310
311
	/**
312
	 * Adds data-* attributes required by carousel to img tags in post HTML
313
	 * content. To be used by 'the_content' filter.
314
	 *
315
	 * @see add_data_to_images()
316
	 * @see wp_make_content_images_responsive() in wp-includes/media.php
317
	 *
318
	 * @param string $content HTML content of the post
319
	 * @return string Modified HTML content of the post
320
	 */
321
	function add_data_to_single_images( $content ) {
322
		if ( ! preg_match_all( '/<img [^>]+>/', $content, $matches ) ) {
323
			return $content;
324
		}
325
		$selected_images = array();
326
327
		foreach( $matches[0] as $image_html ) {
328
			if ( preg_match( '/wp-image-([0-9]+)/i', $image_html, $class_id ) &&
329
				( $attachment_id = absint( $class_id[1] ) ) ) {
330
331
				/*
332
				 * If exactly the same image tag is used more than once, overwrite it.
333
				 * All identical tags will be replaced later with 'str_replace()'.
334
				 */
335
				$selected_images[ $attachment_id  ] = $image_html;
336
			}
337
		}
338
339
		foreach ( $selected_images as $attachment_id => $image_html ) {
340
			$attachment = WP_Post::get_instance( $attachment_id );
341
			$attributes = $this->add_data_to_images( array(), $attachment );
342
			$attributes_html = '';
343
			foreach( $attributes as $k => $v ) {
344
				$attributes_html .= esc_attr( $k ) . '="' . esc_attr( $v ) . '"';
345
			}
346
			$image_html_with_data = str_replace( '<img ', "<img $attributes_html", $image_html );
347
			$content = str_replace( $image_html, $image_html_with_data, $content );
348
		}
349
350
		return $content;
351
	}
352
353
	function add_data_to_images( $attr, $attachment = null ) {
354
		$attachment_id   = intval( $attachment->ID );
355
		$orig_file       = wp_get_attachment_image_src( $attachment_id, 'full' );
356
		$orig_file       = isset( $orig_file[0] ) ? $orig_file[0] : wp_get_attachment_url( $attachment_id );
357
		$meta            = wp_get_attachment_metadata( $attachment_id );
358
		$size            = isset( $meta['width'] ) ? intval( $meta['width'] ) . ',' . intval( $meta['height'] ) : '';
359
		$img_meta        = ( ! empty( $meta['image_meta'] ) ) ? (array) $meta['image_meta'] : array();
360
		$comments_opened = intval( comments_open( $attachment_id ) );
361
362
		 /*
363
		 * Note: Cannot generate a filename from the width and height wp_get_attachment_image_src() returns because
364
		 * it takes the $content_width global variable themes can set in consideration, therefore returning sizes
365
		 * which when used to generate a filename will likely result in a 404 on the image.
366
		 * $content_width has no filter we could temporarily de-register, run wp_get_attachment_image_src(), then
367
		 * re-register. So using returned file URL instead, which we can define the sizes from through filename
368
		 * parsing in the JS, as this is a failsafe file reference.
369
		 *
370
		 * EG with Twenty Eleven activated:
371
		 * 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) }
372
		 *
373
		 * EG with Twenty Ten activated:
374
		 * 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) }
375
		 */
376
377
		$medium_file_info = wp_get_attachment_image_src( $attachment_id, 'medium' );
378
		$medium_file      = isset( $medium_file_info[0] ) ? $medium_file_info[0] : '';
379
380
		$large_file_info  = wp_get_attachment_image_src( $attachment_id, 'large' );
381
		$large_file       = isset( $large_file_info[0] ) ? $large_file_info[0] : '';
382
383
		$attachment       = get_post( $attachment_id );
384
		$attachment_title = wptexturize( $attachment->post_title );
385
		$attachment_desc  = wpautop( wptexturize( $attachment->post_content ) );
386
387
		// Not yet providing geo-data, need to "fuzzify" for privacy
388 View Code Duplication
		if ( ! empty( $img_meta ) ) {
389
			foreach ( $img_meta as $k => $v ) {
390
				if ( 'latitude' == $k || 'longitude' == $k )
391
					unset( $img_meta[$k] );
392
			}
393
		}
394
395
		// See https://github.com/Automattic/jetpack/issues/2765
396
		if ( isset( $img_meta['keywords'] ) ) {
397
			unset( $img_meta['keywords'] );
398
		}
399
400
		$img_meta = json_encode( array_map( 'strval', $img_meta ) );
401
402
		$attr['data-attachment-id']     = $attachment_id;
403
		$attr['data-orig-file']         = esc_attr( $orig_file );
404
		$attr['data-orig-size']         = $size;
405
		$attr['data-comments-opened']   = $comments_opened;
406
		$attr['data-image-meta']        = esc_attr( $img_meta );
407
		$attr['data-image-title']       = esc_attr( $attachment_title );
408
		$attr['data-image-description'] = esc_attr( $attachment_desc );
409
		$attr['data-medium-file']       = esc_attr( $medium_file );
410
		$attr['data-large-file']        = esc_attr( $large_file );
411
412
		return $attr;
413
	}
414
415
	function add_data_to_container( $html ) {
416
		global $post;
417
418
		if ( isset( $post ) ) {
419
			$blog_id = (int) get_current_blog_id();
420
421
			$extra_data = array(
422
				'data-carousel-extra' => array(
423
					'blog_id' => $blog_id,
424
					'permalink' => get_permalink( $post->ID ),
425
					)
426
				);
427
428
			/**
429
			 * Filter the data added to the Gallery container.
430
			 *
431
			 * @module carousel
432
			 *
433
			 * @since 1.6.0
434
			 *
435
			 * @param array $extra_data Array of data about the site and the post.
436
			 */
437
			$extra_data = apply_filters( 'jp_carousel_add_data_to_container', $extra_data );
438
			foreach ( (array) $extra_data as $data_key => $data_values ) {
439
				$html = str_replace( '<div ', '<div ' . esc_attr( $data_key ) . "='" . json_encode( $data_values ) . "' ", $html );
440
			}
441
		}
442
443
		return $html;
444
	}
445
446
	function get_attachment_comments() {
447
		if ( ! headers_sent() )
448
			header('Content-type: text/javascript');
449
450
		/**
451
		 * Allows for the checking of privileges of the blog user before comments
452
		 * are packaged as JSON and sent back from the get_attachment_comments
453
		 * AJAX endpoint
454
		 *
455
		 * @module carousel
456
		 *
457
		 * @since 1.6.0
458
		 */
459
		do_action('jp_carousel_check_blog_user_privileges');
460
461
		$attachment_id = ( isset( $_REQUEST['id'] ) ) ? (int) $_REQUEST['id'] : 0;
462
		$offset        = ( isset( $_REQUEST['offset'] ) ) ? (int) $_REQUEST['offset'] : 0;
463
464
		if ( ! $attachment_id ) {
465
			echo json_encode( __( 'Missing attachment ID.', 'jetpack' ) );
466
			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...
467
		}
468
469
		if ( $offset < 1 )
470
			$offset = 0;
471
472
		$comments = get_comments( array(
473
			'status'  => 'approve',
474
			'order'   => ( 'asc' == get_option('comment_order') ) ? 'ASC' : 'DESC',
475
			'number'  => 10,
476
			'offset'  => $offset,
477
			'post_id' => $attachment_id,
478
		) );
479
480
		$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...
481
482
		// Can't just send the results, they contain the commenter's email address.
483
		foreach ( $comments as $comment ) {
484
			$avatar = get_avatar( $comment->comment_author_email, 64 );
485
			if( ! $avatar )
486
				$avatar = '';
487
			$out[] = array(
488
				'id'              => $comment->comment_ID,
489
				'parent_id'       => $comment->comment_parent,
490
				'author_markup'   => get_comment_author_link( $comment->comment_ID ),
491
				'gravatar_markup' => $avatar,
492
				'date_gmt'        => $comment->comment_date_gmt,
493
				'content'         => wpautop($comment->comment_content),
494
			);
495
		}
496
497
		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...
498
	}
499
500
	function post_attachment_comment() {
501
		if ( ! headers_sent() )
502
			header('Content-type: text/javascript');
503
504
		if ( empty( $_POST['nonce'] ) || ! wp_verify_nonce($_POST['nonce'], 'carousel_nonce') )
505
			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...
506
507
		$_blog_id = (int) $_POST['blog_id'];
508
		$_post_id = (int) $_POST['id'];
509
		$comment = $_POST['comment'];
510
511
		if ( empty( $_blog_id ) )
512
			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...
513
514
		if ( empty( $_post_id ) )
515
			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...
516
517
		if ( empty( $comment ) )
518
			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...
519
520
		// Used in context like NewDash
521
		$switched = false;
522
		if ( is_multisite() && $_blog_id != get_current_blog_id() ) {
523
			switch_to_blog( $_blog_id );
524
			$switched = true;
525
		}
526
527
		/** This action is documented in modules/carousel/jetpack-carousel.php */
528
		do_action('jp_carousel_check_blog_user_privileges');
529
530
		if ( ! comments_open( $_post_id ) )
531
			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...
532
533
		if ( is_user_logged_in() ) {
534
			$user         = wp_get_current_user();
535
			$user_id      = $user->ID;
536
			$display_name = $user->display_name;
537
			$email        = $user->user_email;
538
			$url          = $user->user_url;
539
540
			if ( empty( $user_id ) )
541
				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...
542
		} else {
543
			$user_id      = 0;
544
			$display_name = $_POST['author'];
545
			$email        = $_POST['email'];
546
			$url          = $_POST['url'];
547
548
			if ( get_option( 'require_name_email' ) ) {
549
				if ( empty( $display_name ) )
550
					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...
551
552
				if ( empty( $email ) )
553
					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...
554
555
				if ( ! is_email( $email ) )
556
					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...
557
			}
558
		}
559
560
		$comment_data =  array(
561
			'comment_content'      => $comment,
562
			'comment_post_ID'      => $_post_id,
563
			'comment_author'       => $display_name,
564
			'comment_author_email' => $email,
565
			'comment_author_url'   => $url,
566
			'comment_approved'     => 0,
567
			'comment_type'         => '',
568
		);
569
570
		if ( ! empty( $user_id ) )
571
			$comment_data['user_id'] = $user_id;
572
573
		// Note: wp_new_comment() sanitizes and validates the values (too).
574
		$comment_id = wp_new_comment( $comment_data );
575
576
		/**
577
		 * Fires before adding a new comment to the database via the get_attachment_comments ajax endpoint.
578
		 *
579
		 * @module carousel
580
		 *
581
		 * @since 1.6.0
582
		 */
583
		do_action( 'jp_carousel_post_attachment_comment' );
584
		$comment_status = wp_get_comment_status( $comment_id );
585
586
		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...
587
			restore_current_blog();
588
589
		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...
590
	}
591
592
	function register_settings() {
593
		add_settings_section('carousel_section', __( 'Image Gallery Carousel', 'jetpack' ), array( $this, 'carousel_section_callback' ), 'media');
594
595
		if ( ! $this->in_jetpack ) {
596
			add_settings_field('carousel_enable_it', __( 'Enable carousel', 'jetpack' ), array( $this, 'carousel_enable_it_callback' ), 'media', 'carousel_section' );
597
			register_setting( 'media', 'carousel_enable_it', array( $this, 'carousel_enable_it_sanitize' ) );
598
		}
599
600
		add_settings_field('carousel_background_color', __( 'Background color', 'jetpack' ), array( $this, 'carousel_background_color_callback' ), 'media', 'carousel_section' );
601
		register_setting( 'media', 'carousel_background_color', array( $this, 'carousel_background_color_sanitize' ) );
602
603
		add_settings_field('carousel_display_exif', __( 'Metadata', 'jetpack'), array( $this, 'carousel_display_exif_callback' ), 'media', 'carousel_section' );
604
		register_setting( 'media', 'carousel_display_exif', array( $this, 'carousel_display_exif_sanitize' ) );
605
606
		// No geo setting yet, need to "fuzzify" data first, for privacy
607
		// add_settings_field('carousel_display_geo', __( 'Geolocation', 'jetpack' ), array( $this, 'carousel_display_geo_callback' ), 'media', 'carousel_section' );
608
		// register_setting( 'media', 'carousel_display_geo', array( $this, 'carousel_display_geo_sanitize' ) );
609
	}
610
611
	// Fulfill the settings section callback requirement by returning nothing
612
	function carousel_section_callback() {
613
		return;
614
	}
615
616
	function test_1or0_option( $value, $default_to_1 = true ) {
617
		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...
618
			// Binary false (===) of $value means it has not yet been set, in which case we do want to default sites to 1
619
			if ( false === $value )
620
				$value = 1;
621
		}
622
		return ( 1 == $value ) ? 1 : 0;
623
	}
624
625
	function sanitize_1or0_option( $value ) {
626
		return ( 1 == $value ) ? 1 : 0;
627
	}
628
629
	function settings_checkbox($name, $label_text, $extra_text = '', $default_to_checked = true) {
630
		if ( empty( $name ) )
631
			return;
632
		$option = $this->test_1or0_option( get_option( $name ), $default_to_checked );
633
		echo '<fieldset>';
634
		echo '<input type="checkbox" name="'.esc_attr($name).'" id="'.esc_attr($name).'" value="1" ';
635
		checked( '1', $option );
636
		echo '/> <label for="'.esc_attr($name).'">'.$label_text.'</label>';
637
		if ( ! empty( $extra_text ) )
638
			echo '<p class="description">'.$extra_text.'</p>';
639
		echo '</fieldset>';
640
	}
641
642
	function settings_select($name, $values, $extra_text = '') {
643
		if ( empty( $name ) || ! is_array( $values ) || empty( $values ) )
644
			return;
645
		$option = get_option( $name );
646
		echo '<fieldset>';
647
		echo '<select name="'.esc_attr($name).'" id="'.esc_attr($name).'">';
648
		foreach( $values as $key => $value ) {
649
			echo '<option value="'.esc_attr($key).'" ';
650
			selected( $key, $option );
651
			echo '>'.esc_html($value).'</option>';
652
		}
653
		echo '</select>';
654
		if ( ! empty( $extra_text ) )
655
			echo '<p class="description">'.$extra_text.'</p>';
656
		echo '</fieldset>';
657
	}
658
659
	function carousel_display_exif_callback() {
660
		$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' ) );
661
	}
662
663
	function carousel_display_exif_sanitize( $value ) {
664
		return $this->sanitize_1or0_option( $value );
665
	}
666
667
	function carousel_display_geo_callback() {
668
		$this->settings_checkbox( 'carousel_display_geo', __( 'Show map of photo location in carousel, when available.', 'jetpack' ) );
669
	}
670
671
	function carousel_display_geo_sanitize( $value ) {
672
		return $this->sanitize_1or0_option( $value );
673
	}
674
675
	function carousel_background_color_callback() {
676
		$this->settings_select( 'carousel_background_color', array( 'black' => __( 'Black', 'jetpack' ), 'white' => __( 'White', 'jetpack', 'jetpack' ) ) );
677
	}
678
679
	function carousel_background_color_sanitize( $value ) {
680
		return ( 'white' == $value ) ? 'white' : 'black';
681
	}
682
683
	function carousel_enable_it_callback() {
684
		$this->settings_checkbox( 'carousel_enable_it', __( 'Display images in full-size carousel slideshow.', 'jetpack' ) );
685
	}
686
687
	function carousel_enable_it_sanitize( $value ) {
688
		return $this->sanitize_1or0_option( $value );
689
	}
690
}
691
692
new Jetpack_Carousel;
693