Completed
Push — master-stable ( e17c57...c646dd )
by
unknown
276:05 queued 265:38
created

Jetpack_Carousel::settings_checkbox()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 11
nc 3
nop 4
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/*
3
Plugin Name: Jetpack Carousel
4
Plugin URL: https://wordpress.com/
5
Description: Transform your standard image galleries into an immersive full-screen experience.
6
Version: 0.1
7
Author: Automattic
8
Released under the GPL v.2 license.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
GNU General Public License for more details.
13
*/
14
15
/**
16
 * Jetpack_Carousel class.
17
 */
18
class Jetpack_Carousel {
19
20
	/**
21
	 * Prebuilt Widths.
22
	 *
23
	 * (default value: array( 370, 700, 1000, 1200, 1400, 2000 ))
24
	 *
25
	 * @var array
26
	 * @access public
27
	 */
28
	public $prebuilt_widths = array( 370, 700, 1000, 1200, 1400, 2000 );
29
30
	/**
31
	 * First Run.
32
	 *
33
	 * (default value: true)
34
	 *
35
	 * @var bool
36
	 * @access public
37
	 */
38
	public $first_run = true;
39
40
	/**
41
	 * In Gallery.
42
	 *
43
	 * (default value: false)
44
	 *
45
	 * @var bool
46
	 * @access public
47
	 */
48
	public $in_gallery = false;
49
50
	/**
51
	 * In Jetpack.
52
	 *
53
	 * (default value: true)
54
	 *
55
	 * @var bool
56
	 * @access public
57
	 */
58
	public $in_jetpack = true;
59
60
	/**
61
	 * __construct function.
62
	 *
63
	 * @access public
64
	 * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
65
	 */
66
	function __construct() {
67
		add_action( 'init', array( $this, 'init' ) );
68
	}
69
70
	/**
71
	 * The init function.
72
	 *
73
	 * @access public
74
	 * @return void
75
	 */
76
	function init() {
77
		if ( $this->maybe_disable_jp_carousel() ) {
78
			return;
79
		}
80
		$this->in_jetpack = ( class_exists( 'Jetpack' ) && method_exists( 'Jetpack', 'enable_module_configurable' ) ) ? true : false;
81
		if ( is_admin() ) {
82
			// Register the Carousel-related related settings.
83
			add_action( 'admin_init', array( $this, 'register_settings' ), 5 );
84
			if ( ! $this->in_jetpack ) {
85
				if ( 0 === $this->test_1or0_option( get_option( 'carousel_enable_it' ), true ) ) {
86
					return; // Carousel disabled, abort early, but still register setting so user can switch it back on.
87
				}
88
			}
89
			// If in admin, register the ajax endpoints.
90
			add_action( 'wp_ajax_get_attachment_comments', array( $this, 'get_attachment_comments' ) );
91
			add_action( 'wp_ajax_nopriv_get_attachment_comments', array( $this, 'get_attachment_comments' ) );
92
			add_action( 'wp_ajax_post_attachment_comment', array( $this, 'post_attachment_comment' ) );
93
			add_action( 'wp_ajax_nopriv_post_attachment_comment', array( $this, 'post_attachment_comment' ) );
94
		} else {
95
			if ( ! $this->in_jetpack ) {
96
				if ( 0 === $this->test_1or0_option( get_option( 'carousel_enable_it' ), true ) ) {
97
					return; // Carousel disabled, abort early.
98
				}
99
			}
100
			// If on front-end, do the Carousel thang.
101
			/**
102
			 * Filter the array of default prebuilt widths used in Carousel.
103
			 *
104
			 * @module carousel
105
			 *
106
			 * @since 1.6.0
107
			 *
108
			 * @param array $this->prebuilt_widths Array of default widths.
109
			 */
110
			$this->prebuilt_widths = apply_filters( 'jp_carousel_widths', $this->prebuilt_widths );
111
			add_filter( 'post_gallery', array( $this, 'enqueue_assets' ), 1000, 2 ); // Load later than other callbacks hooked it.
112
			add_filter( 'post_gallery', array( $this, 'set_in_gallery' ), -1000 );
113
			add_filter( 'gallery_style', array( $this, 'add_data_to_container' ) );
114
			add_filter( 'wp_get_attachment_image_attributes', array( $this, 'add_data_to_images' ), 10, 2 );
115
		}
116
		if ( $this->in_jetpack && method_exists( 'Jetpack', 'module_configuration_load' ) ) {
117
			Jetpack::enable_module_configurable( dirname( dirname( __FILE__ ) ) . '/carousel.php' );
118
			Jetpack::module_configuration_load( dirname( dirname( __FILE__ ) ) . '/carousel.php', array( $this, 'jetpack_configuration_load' ) );
119
		}
120
	}
121
122
123
	/**
124
	 * Maybe Disable JP Carousel.
125
	 *
126
	 * @access public
127
	 * @return value.
0 ignored issues
show
Documentation introduced by
The doc-type value. could not be parsed: Unknown type name "value." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
128
	 */
129
	function maybe_disable_jp_carousel() {
130
		/**
131
		 * Allow third-party plugins or themes to disable Carousel.
132
		 *
133
		 * @module carousel
134
		 *
135
		 * @since 1.6.0
136
		 *
137
		 * @param bool false Should Carousel be disabled? Default to false.
138
		 */
139
		return apply_filters( 'jp_carousel_maybe_disable', false );
140
	}
141
142
143
	/**
144
	 * Jetpack Config Load.
145
	 *
146
	 * @access public
147
	 * @return void
148
	 */
149
	function jetpack_configuration_load() {
150
		wp_safe_redirect( admin_url( 'options-media.php#carousel_background_color' ) );
151
		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...
152
	}
153
154
	/**
155
	 * Asset Version.
156
	 *
157
	 * @access public
158
	 * @param mixed $version Version.
159
	 * @return $version Version.
0 ignored issues
show
Documentation introduced by
The doc-type $version could not be parsed: Unknown type name "$version" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
160
	 */
161
	function asset_version( $version ) {
162
		/**
163
		 * Filter the version string used when enqueuing Carousel assets.
164
		 *
165
		 * @module carousel
166
		 *
167
		 * @since 1.6.0
168
		 *
169
		 * @param string $version Asset version.
170
		 */
171
		return apply_filters( 'jp_carousel_asset_version', $version );
172
	}
173
174
	/**
175
	 * Display Bail Message.
176
	 *
177
	 * @access public
178
	 * @param string $output (default: '') Output.
179
	 * @return $output Output.
0 ignored issues
show
Documentation introduced by
The doc-type $output could not be parsed: Unknown type name "$output" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
180
	 */
181
	function display_bail_message( $output = '' ) {
182
		// Displays a message on top of gallery if carousel has bailed.
183
		$message = '<div class="jp-carousel-msg"><p>';
184
		$message .= __( 'Jetpack\'s Carousel has been disabled, because another plugin or your theme is overriding the [gallery] shortcode.', 'jetpack' );
185
		$message .= '</p></div>';
186
		// Put before gallery output.
187
		$output = $message . $output;
188
		return $output;
189
	}
190
191
192
	/**
193
	 * Enqueue Assets.
194
	 *
195
	 * @access public
196
	 * @param mixed $output Output.
197
	 * @return $output Output.
0 ignored issues
show
Documentation introduced by
The doc-type $output could not be parsed: Unknown type name "$output" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
198
	 */
199
	function enqueue_assets( $output ) {
200
		if (
201
			! empty( $output ) &&
202
			/**
203
			 * Allow third-party plugins or themes to force-enable Carousel.
204
			 *
205
			 * @module carousel
206
			 *
207
			 * @since 1.9.0
208
			 *
209
			 * @param bool false Should we force enable Carousel? Default to false.
210
			 */
211
			! apply_filters( 'jp_carousel_force_enable', false )
212
		) {
213
			// Bail because someone is overriding the [gallery] shortcode.
214
			remove_filter( 'gallery_style', array( $this, 'add_data_to_container' ) );
215
			remove_filter( 'wp_get_attachment_image_attributes', array( $this, 'add_data_to_images' ) );
216
			// Display message that carousel has bailed, if user is super_admin, and if we're not on WordPress.com.
217
			if (
218
				is_super_admin() &&
219
				! ( defined( 'IS_WPCOM' ) && IS_WPCOM )
220
			) {
221
				add_filter( 'post_gallery', array( $this, 'display_bail_message' ) );
222
			}
223
			return $output;
224
		}
225
		/**
226
		 * Fires when thumbnails are shown in Carousel.
227
		 *
228
		 * @module carousel
229
		 *
230
		 * @since 1.6.0
231
		 */
232
		do_action( 'jp_carousel_thumbnails_shown' );
233
		if ( $this->first_run ) {
234
			wp_enqueue_script( 'jetpack-carousel', plugins_url( 'jetpack-carousel.js', __FILE__ ), array( 'jquery.spin' ), $this->asset_version( '20160325' ), true );
235
			// 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)
236
			// Also: not hardcoding path since there is no guarantee site is running on site root in self-hosted context.
237
			$is_logged_in = is_user_logged_in();
238
			$current_user = wp_get_current_user();
239
			$comment_registration = intval( get_option( 'comment_registration' ) );
240
			$require_name_email   = intval( get_option( 'require_name_email' ) );
241
			$localize_strings = array(
242
				'widths'               => $this->prebuilt_widths,
243
				'is_logged_in'         => $is_logged_in,
244
				'lang'                 => strtolower( substr( get_locale(), 0, 2 ) ),
245
				'ajaxurl'              => set_url_scheme( admin_url( 'admin-ajax.php' ) ),
246
				'nonce'                => wp_create_nonce( 'carousel_nonce' ),
247
				'display_exif'         => $this->test_1or0_option( Jetpack_Options::get_option_and_ensure_autoload( 'carousel_display_exif', true ) ),
248
				'display_geo'          => $this->test_1or0_option( Jetpack_Options::get_option_and_ensure_autoload( 'carousel_display_geo', true ) ),
249
				'background_color'     => $this->carousel_background_color_sanitize( Jetpack_Options::get_option_and_ensure_autoload( 'carousel_background_color', '' ) ),
250
				'comment'              => __( 'Comment', 'jetpack' ),
251
				'post_comment'         => __( 'Post Comment', 'jetpack' ),
252
				'write_comment'        => __( 'Write a Comment...', 'jetpack' ),
253
				'loading_comments'     => __( 'Loading Comments...', 'jetpack' ),
254
				'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}' ),
255
				'no_comment_text'      => __( 'Please be sure to submit some text with your comment.', 'jetpack' ),
256
				'no_comment_email'     => __( 'Please provide an email address to comment.', 'jetpack' ),
257
				'no_comment_author'    => __( 'Please provide your name to comment.', 'jetpack' ),
258
				'comment_post_error'   => __( 'Sorry, but there was an error posting your comment. Please try again later.', 'jetpack' ),
259
				'comment_approved'     => __( 'Your comment was approved.', 'jetpack' ),
260
				'comment_unapproved'   => __( 'Your comment is in moderation.', 'jetpack' ),
261
				'camera'               => __( 'Camera', 'jetpack' ),
262
				'aperture'             => __( 'Aperture', 'jetpack' ),
263
				'shutter_speed'        => __( 'Shutter Speed', 'jetpack' ),
264
				'focal_length'         => __( 'Focal Length', 'jetpack' ),
265
				'comment_registration' => $comment_registration,
266
				'require_name_email'   => $require_name_email,
267
				/** This action is documented in core/src/wp-includes/link-template.php */
268
				'login_url'            => wp_login_url( apply_filters( 'the_permalink', get_permalink() ) ),
269
			);
270
			if ( ! isset( $localize_strings['jetpack_comments_iframe_src'] ) || empty( $localize_strings['jetpack_comments_iframe_src'] ) ) {
271
				// We're not using Comments after all, so fallback to standard local comments.
272
				if ( $is_logged_in ) {
273
					$localize_strings['local_comments_commenting_as'] = '<p id="jp-carousel-commenting-as">' . sprintf( __( 'Commenting as %s', 'jetpack' ), $current_user->data->display_name ) . '</p>';
274
				} else {
275
					if ( $comment_registration ) {
276
						$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>';
277
					} else {
278
						$required = ( $require_name_email ) ? __( '%s (Required)', 'jetpack' ) : '%s';
279
						$localize_strings['local_comments_commenting_as'] = '<fieldset><label for="email">' . sprintf( $required, __( 'Email', 'jetpack' ) ) . '</label>
280
							<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>
281
							<fieldset><label for="author">' . sprintf( $required, __( 'Name', 'jetpack' ) ) . '</label>
282
							<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>
283
							<fieldset><label for="url">' . __( 'Website', 'jetpack' ) . '</label>
284
							<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>';
285
					}
286
				}
287
			}
288
			/**
289
			 * Handle WP stats for images in full-screen.
290
			 * Build string with tracking info.
291
			 */
292
			/**
293
			 * Filter if Jetpack should enable stats collection on carousel views
294
			 *
295
			 * @module carousel
296
			 *
297
			 * @since 4.3.2
298
			 *
299
			 * @param bool Enable Jetpack Carousel stat collection. Default false.
300
			 */
301
			if ( apply_filters( 'jetpack_enable_carousel_stats', false ) && in_array( 'stats', Jetpack::get_active_modules() ) && ! Jetpack::is_development_mode() ) {
302
				$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;
303
				// Set the stats as empty if user is logged in but logged-in users shouldn't be tracked.
304 View Code Duplication
				if ( is_user_logged_in() && function_exists( 'stats_get_options' ) ) {
305
					$stats_options = stats_get_options();
306
					$track_loggedin_users = isset( $stats_options['reg_users'] ) ? (bool) $stats_options['reg_users'] : false;
307
					if ( ! $track_loggedin_users ) {
308
						$localize_strings['stats'] = '';
309
					}
310
				}
311
			}
312
			/**
313
			 * Filter the strings passed to the Carousel's js file.
314
			 *
315
			 * @module carousel
316
			 *
317
			 * @since 1.6.0
318
			 *
319
			 * @param array $localize_strings Array of strings passed to the Jetpack js file.
320
			 */
321
			$localize_strings = apply_filters( 'jp_carousel_localize_strings', $localize_strings );
322
			wp_localize_script( 'jetpack-carousel', 'jetpackCarouselStrings', $localize_strings );
323
			if ( is_rtl() ) {
324
				wp_enqueue_style( 'jetpack-carousel', plugins_url( '/rtl/jetpack-carousel-rtl.css', __FILE__ ), array(), $this->asset_version( '20120629' ) );
325
			} else {
326
				wp_enqueue_style( 'jetpack-carousel', plugins_url( 'jetpack-carousel.css', __FILE__ ), array(), $this->asset_version( '20120629' ) );
327
			}
328
			wp_register_style( 'jetpack-carousel-ie8fix', plugins_url( 'jetpack-carousel-ie8fix.css', __FILE__ ), array(), $this->asset_version( '20121024' ) );
329
			$GLOBALS['wp_styles']->add_data( 'jetpack-carousel-ie8fix', 'conditional', 'lte IE 8' );
330
			wp_enqueue_style( 'jetpack-carousel-ie8fix' );
331
			/**
332
			 * Fires after carousel assets are enqueued for the first time.
333
			 * Allows for adding additional assets to the carousel page.
334
			 *
335
			 * @module carousel
336
			 *
337
			 * @since 1.6.0
338
			 *
339
			 * @param bool $first_run First load if Carousel on the page.
340
			 * @param array $localized_strings Array of strings passed to the Jetpack js file.
341
			 */
342
			do_action( 'jp_carousel_enqueue_assets', $this->first_run, $localize_strings );
343
			$this->first_run = false;
344
		}
345
		return $output;
346
	}
347
348
349
	/**
350
	 * Set in Gallery.
351
	 *
352
	 * @access public
353
	 * @param mixed $output Output.
354
	 * @return $output Output.
0 ignored issues
show
Documentation introduced by
The doc-type $output could not be parsed: Unknown type name "$output" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
355
	 */
356
	function set_in_gallery( $output ) {
357
		$this->in_gallery = true;
358
		return $output;
359
	}
360
361
362
	/**
363
	 * Add data to Images.
364
	 *
365
	 * @access public
366
	 * @param mixed $attr Attribute.
367
	 * @param mixed $attachment (default: null) Attachment.
368
	 * @return $attr Image Attributes.
0 ignored issues
show
Documentation introduced by
The doc-type $attr could not be parsed: Unknown type name "$attr" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
369
	 */
370
	function add_data_to_images( $attr, $attachment = null ) {
371
		// Not in a gallery?
372
		if ( ! $this->in_gallery ) {
373
			return $attr;
374
		}
375
		$attachment_id   = intval( $attachment->ID );
376
		$orig_file       = wp_get_attachment_image_src( $attachment_id, 'full' );
377
		$orig_file       = isset( $orig_file[0] ) ? $orig_file[0] : wp_get_attachment_url( $attachment_id );
378
		$meta            = wp_get_attachment_metadata( $attachment_id );
379
		$size            = isset( $meta['width'] ) ? intval( $meta['width'] ) . ',' . intval( $meta['height'] ) : '';
380
		$img_meta        = ( ! empty( $meta['image_meta'] ) ) ? (array) $meta['image_meta'] : array();
381
		$comments_opened = intval( comments_open( $attachment_id ) );
382
383
		 /*
384
		 * Note: Cannot generate a filename from the width and height wp_get_attachment_image_src() returns because
385
		 * it takes the $content_width global variable themes can set in consideration, therefore returning sizes
386
		 * which when used to generate a filename will likely result in a 404 on the image.
387
		 * $content_width has no filter we could temporarily de-register, run wp_get_attachment_image_src(), then
388
		 * re-register. So using returned file URL instead, which we can define the sizes from through filename
389
		 * parsing in the JS, as this is a failsafe file reference.
390
		 *
391
		 * EG with Twenty Eleven activated:
392
		 * 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) }
393
		 *
394
		 * EG with Twenty Ten activated:
395
		 * 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) }
396
		 */
397
		$medium_file_info = wp_get_attachment_image_src( $attachment_id, 'medium' );
398
		$medium_file      = isset( $medium_file_info[0] ) ? $medium_file_info[0] : '';
399
		$large_file_info  = wp_get_attachment_image_src( $attachment_id, 'large' );
400
		$large_file       = isset( $large_file_info[0] ) ? $large_file_info[0] : '';
401
		$attachment       = get_post( $attachment_id );
402
		$attachment_title = wptexturize( $attachment->post_title );
403
		$attachment_desc  = wpautop( wptexturize( $attachment->post_content ) );
404
		// Not yet providing geo-data, need to "fuzzify" for privacy.
405 View Code Duplication
		if ( ! empty( $img_meta ) ) {
406
			foreach ( $img_meta as $k => $v ) {
407
				if ( 'latitude' === $k || 'longitude' === $k ) {
408
					unset( $img_meta[ $k ] );
409
				}
410
			}
411
		}
412
		// See https://github.com/Automattic/jetpack/issues/2765 .
413
		if ( isset( $img_meta['keywords'] ) ) {
414
			unset( $img_meta['keywords'] );
415
		}
416
		$img_meta = wp_json_encode( array_map( 'strval', $img_meta ) );
417
		$attr['data-attachment-id']     = $attachment_id;
418
		$attr['data-orig-file']         = esc_attr( $orig_file );
419
		$attr['data-orig-size']         = $size;
420
		$attr['data-comments-opened']   = $comments_opened;
421
		$attr['data-image-meta']        = esc_attr( $img_meta );
422
		$attr['data-image-title']       = esc_attr( $attachment_title );
423
		$attr['data-image-description'] = esc_attr( $attachment_desc );
424
		$attr['data-medium-file']       = esc_attr( $medium_file );
425
		$attr['data-large-file']        = esc_attr( $large_file );
426
		return $attr;
427
	}
428
429
430
	/**
431
	 * Add Data to Container.
432
	 *
433
	 * @access public
434
	 * @param mixed $html HTML.
435
	 * @return $html HTML.
0 ignored issues
show
Documentation introduced by
The doc-type $html could not be parsed: Unknown type name "$html" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
436
	 */
437
	function add_data_to_container( $html ) {
438
		global $post;
439
		if ( isset( $post ) ) {
440
			$blog_id = (int) get_current_blog_id();
441
			$extra_data = array(
442
				'data-carousel-extra' => array(
443
					'blog_id' => $blog_id,
444
					'permalink' => get_permalink( $post->ID ),
445
					),
446
				);
447
			/**
448
			 * Filter the data added to the Gallery container.
449
			 *
450
			 * @module carousel
451
			 *
452
			 * @since 1.6.0
453
			 *
454
			 * @param array $extra_data Array of data about the site and the post.
455
			 */
456
			$extra_data = apply_filters( 'jp_carousel_add_data_to_container', $extra_data );
457
			foreach ( (array) $extra_data as $data_key => $data_values ) {
458
				$html = str_replace( '<div ', '<div ' . esc_attr( $data_key ) . "='" . wp_json_encode( $data_values ) . "' ", $html );
459
			}
460
		}
461
		return $html;
462
	}
463
464
465
	/**
466
	 * Get Attachment Comments.
467
	 *
468
	 * @access public
469
	 * @return void
470
	 */
471
	function get_attachment_comments() {
472
		if ( ! headers_sent() ) {
473
			header( 'Content-type: text/javascript' );
474
		}
475
		/**
476
		 * Allows for the checking of privileges of the blog user before comments
477
		 * are packaged as JSON and sent back from the get_attachment_comments
478
		 * AJAX endpoint
479
		 *
480
		 * @module carousel
481
		 *
482
		 * @since 1.6.0
483
		 */
484
		do_action( 'jp_carousel_check_blog_user_privileges' );
485
		$attachment_id = ( isset( $_REQUEST['id'] ) ) ? (int) $_REQUEST['id'] : 0;
486
		$offset        = ( isset( $_REQUEST['offset'] ) ) ? (int) $_REQUEST['offset'] : 0;
487
		if ( ! $attachment_id ) {
488
			echo wp_json_encode( __( 'Missing attachment ID.', 'jetpack' ) );
489
			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...
490
		}
491
		if ( $offset < 1 ) {
492
			$offset = 0;
493
		}
494
		$comments = get_comments( array(
495
			'status'  => 'approve',
496
			'order'   => ( 'asc' === get_option( 'comment_order' ) ) ? 'ASC' : 'DESC',
497
			'number'  => 10,
498
			'offset'  => $offset,
499
			'post_id' => $attachment_id,
500
		) );
501
		$out      = array();
502
		// Can't just send the results, they contain the commenter's email address.
503
		foreach ( $comments as $comment ) {
504
			$avatar = get_avatar( $comment->comment_author_email, 64 );
505
			if ( ! $avatar ) {
506
				$avatar = '';
507
			}
508
			$out[] = array(
509
				'id'              => $comment->comment_ID,
510
				'parent_id'       => $comment->comment_parent,
511
				'author_markup'   => get_comment_author_link( $comment->comment_ID ),
512
				'gravatar_markup' => $avatar,
513
				'date_gmt'        => $comment->comment_date_gmt,
514
				'content'         => wpautop( $comment->comment_content ),
515
			);
516
		}
517
		die( wp_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...
518
	}
519
520
521
	/**
522
	 * Post Attachment Comment.
523
	 *
524
	 * @access public
525
	 * @return void
526
	 */
527
	function post_attachment_comment() {
528
		if ( ! headers_sent() ) {
529
			header( 'Content-type: text/javascript' );
530
		}
531
		if ( empty( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'carousel_nonce' ) ) {
532
			die( wp_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...
533
		}
534
		$_blog_id = (int) $_POST['blog_id'];
535
		$_post_id = (int) $_POST['id'];
536
		$comment = $_POST['comment'];
537
		if ( empty( $_blog_id ) ) {
538
			die( wp_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...
539
		}
540
		if ( empty( $_post_id ) ) {
541
			die( wp_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...
542
		}
543
		if ( empty( $comment ) ) {
544
			die( wp_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...
545
		}
546
		// Used in context like NewDash.
547
		$switched = false;
548
		if ( $_blog_id && is_multisite() !== get_current_blog_id() ) {
549
			switch_to_blog( $_blog_id );
550
			$switched = true;
551
		}
552
		/** This action is documented in modules/carousel/jetpack-carousel.php. */
553
		do_action( 'jp_carousel_check_blog_user_privileges' );
554
		if ( ! comments_open( $_post_id ) ) {
555
			die( wp_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...
556
		}
557
		if ( is_user_logged_in() ) {
558
			$user         = wp_get_current_user();
559
			$user_id      = $user->ID;
560
			$display_name = $user->display_name;
561
			$email        = $user->user_email;
562
			$url          = $user->user_url;
563
			if ( empty( $user_id ) ) {
564
				die( wp_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...
565
			}
566
		} else {
567
			$user_id      = 0;
568
			$display_name = $_POST['author'];
569
			$email        = $_POST['email'];
570
			$url          = $_POST['url'];
571
			if ( get_option( 'require_name_email' ) ) {
572
				if ( empty( $display_name ) ) {
573
					die( wp_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...
574
				}
575
				if ( empty( $email ) ) {
576
					die( wp_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...
577
				}
578
				if ( ! is_email( $email ) ) {
579
					die( wp_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...
580
				}
581
			}
582
		}
583
		$comment_data = array(
584
			'comment_content'      => $comment,
585
			'comment_post_ID'      => $_post_id,
586
			'comment_author'       => $display_name,
587
			'comment_author_email' => $email,
588
			'comment_author_url'   => $url,
589
			'comment_approved'     => 0,
590
			'comment_type'         => '',
591
		);
592
		if ( ! empty( $user_id ) ) {
593
			$comment_data['user_id'] = $user_id;
594
		}
595
		// Note: wp_new_comment() sanitizes and validates the values (too).
596
		$comment_id = wp_new_comment( $comment_data );
597
		/**
598
		 * Fires before adding a new comment to the database via the get_attachment_comments ajax endpoint.
599
		 *
600
		 * @module carousel
601
		 *
602
		 * @since 1.6.0
603
		 */
604
		do_action( 'jp_carousel_post_attachment_comment' );
605
		$comment_status = wp_get_comment_status( $comment_id );
606
		if ( true === $switched ) {
607
			restore_current_blog();
608
		}
609
		die( wp_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...
610
	}
611
612
613
	/**
614
	 * Register Settings.
615
	 *
616
	 * @access public
617
	 * @return void
618
	 */
619
	function register_settings() {
620
		add_settings_section( 'carousel_section', __( 'Image Gallery Carousel', 'jetpack' ), array( $this, 'carousel_section_callback' ), 'media' );
621
		if ( ! $this->in_jetpack ) {
622
			add_settings_field( 'carousel_enable_it', __( 'Enable carousel', 'jetpack' ), array( $this, 'carousel_enable_it_callback' ), 'media', 'carousel_section' );
623
			register_setting( 'media', 'carousel_enable_it', array( $this, 'carousel_enable_it_sanitize' ) );
624
		}
625
		add_settings_field( 'carousel_background_color', __( 'Background color', 'jetpack' ), array( $this, 'carousel_background_color_callback' ), 'media', 'carousel_section' );
626
		register_setting( 'media', 'carousel_background_color', array( $this, 'carousel_background_color_sanitize' ) );
627
		add_settings_field( 'carousel_display_exif', __( 'Metadata', 'jetpack' ), array( $this, 'carousel_display_exif_callback' ), 'media', 'carousel_section' );
628
		register_setting( 'media', 'carousel_display_exif', array( $this, 'carousel_display_exif_sanitize' ) );
629
630
	}
631
632
	/**
633
	 * Fulfill the settings section callback requirement by returning nothing.
634
	 *
635
	 * @access public
636
	 * @return void
637
	 */
638
	function carousel_section_callback() {
639
		return;
640
	}
641
642
643
	/**
644
	 * Test 1or0_option function.
645
	 *
646
	 * @access public
647
	 * @param mixed $value Value.
648
	 * @param bool  $default_to_1 (default: true) Default to 1.
649
	 * @return $value Value.
0 ignored issues
show
Documentation introduced by
The doc-type $value could not be parsed: Unknown type name "$value" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
650
	 */
651
	function test_1or0_option( $value, $default_to_1 = true ) {
652
		if ( true === $default_to_1 ) {
653
			// Binary false (===) of $value means it has not yet been set, in which case we do want to default sites to 1.
654
			if ( false === $value ) {
655
				$value = 1;
656
			}
657
		}
658
		return ( 1 === $value ) ? 1 : 0;
659
	}
660
661
	/**
662
	 * Sanitize 1or0_option function.
663
	 *
664
	 * @access public
665
	 * @param mixed $value Value.
666
	 * @return $value Value.
0 ignored issues
show
Documentation introduced by
The doc-type $value could not be parsed: Unknown type name "$value" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
667
	 */
668
	function sanitize_1or0_option( $value ) {
669
		return ( 1 === $value ) ? 1 : 0;
670
	}
671
672
	/**
673
	 * Settings Checkbox.
674
	 *
675
	 * @access public
676
	 * @param mixed  $name Name.
677
	 * @param mixed  $label_text Label Text.
678
	 * @param string $extra_text (default: '') Extra text.
679
	 * @param bool   $default_to_checked (default: true) Default Checked.
680
	 * @return void
681
	 */
682
	function settings_checkbox( $name, $label_text, $extra_text = '', $default_to_checked = true ) {
683
		if ( empty( $name ) ) {
684
			return;
685
		}
686
		$option = $this->test_1or0_option( get_option( $name ), $default_to_checked );
687
		echo '<fieldset>';
688
		echo '<input type="checkbox" name="'.esc_attr( $name ).'" id="'.esc_attr( $name ).'" value="1" ';
689
		checked( '1', $option );
690
		echo '/> <label for="'.esc_attr( $name ).'">'. esc_attr( $label_text ).'</label>';
691
		if ( ! empty( $extra_text ) ) {
692
			echo '<p class="description">'. esc_attr( $extra_text ).'</p>';
693
		}
694
		echo '</fieldset>';
695
	}
696
697
	/**
698
	 * Select Settings.
699
	 *
700
	 * @access public
701
	 * @param mixed  $name Name.
702
	 * @param mixed  $values Values.
703
	 * @param string $extra_text (default: '') Extra Text.
704
	 * @return void
705
	 */
706
	function settings_select( $name, $values, $extra_text = '' ) {
707
		if ( empty( $name ) || ! is_array( $values ) || empty( $values ) ) {
708
			return;
709
		}
710
		$option = get_option( $name );
711
		echo '<fieldset>';
712
		echo '<select name="'.esc_attr( $name ).'" id="'.esc_attr( $name ).'">';
713
		foreach ( $values as $key => $value ) {
714
			echo '<option value="'.esc_attr( $key ).'" ';
715
			selected( $key, $option );
716
			echo '>'.esc_html( $value ).'</option>';
717
		}
718
		echo '</select>';
719
		if ( ! empty( $extra_text ) ) {
720
			echo '<p class="description">'. esc_attr( $extra_text ) .'</p>';
721
		}
722
		echo '</fieldset>';
723
	}
724
725
	/**
726
	 * Callback to Display Carousel EXIF.
727
	 *
728
	 * @access public
729
	 * @return void
730
	 */
731
	function carousel_display_exif_callback() {
732
		$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' ) );
733
	}
734
735
	/**
736
	 * Sanitize Carousel EXIF.
737
	 *
738
	 * @access public
739
	 * @param mixed $value Value.
740
	 * @return $value Value.
0 ignored issues
show
Documentation introduced by
The doc-type $value could not be parsed: Unknown type name "$value" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
741
	 */
742
	function carousel_display_exif_sanitize( $value ) {
743
		return $this->sanitize_1or0_option( $value );
744
	}
745
746
	/**
747
	 * Display Geo Callback.
748
	 *
749
	 * @access public
750
	 * @return void
751
	 */
752
	function carousel_display_geo_callback() {
753
		$this->settings_checkbox( 'carousel_display_geo', __( 'Show map of photo location in carousel, when available.', 'jetpack' ) );
754
	}
755
756
	/**
757
	 * Sanitize Display Geo.
758
	 *
759
	 * @access public
760
	 * @param mixed $value Value.
761
	 * @return $value Value.
0 ignored issues
show
Documentation introduced by
The doc-type $value could not be parsed: Unknown type name "$value" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
762
	 */
763
	function carousel_display_geo_sanitize( $value ) {
764
		return $this->sanitize_1or0_option( $value );
765
	}
766
767
	/**
768
	 * Carousel Background Color Callback.
769
	 *
770
	 * @access public
771
	 * @return void
772
	 */
773
	function carousel_background_color_callback() {
774
		$this->settings_select( 'carousel_background_color', array( 'black' => __( 'Black', 'jetpack' ), 'white' => __( 'White', 'jetpack', 'jetpack' ) ) );
775
	}
776
777
	/**
778
	 * Sanatize Carousel Background Color.
779
	 *
780
	 * @access public
781
	 * @param mixed $value Value.
782
	 * @return $value Value.
0 ignored issues
show
Documentation introduced by
The doc-type $value could not be parsed: Unknown type name "$value" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
783
	 */
784
	function carousel_background_color_sanitize( $value ) {
785
		return ( 'white' === $value ) ? 'white' : 'black';
786
	}
787
788
	/**
789
	 * Carousel Enable It Callback.
790
	 *
791
	 * @access public
792
	 * @return void
793
	 */
794
	function carousel_enable_it_callback() {
795
		$this->settings_checkbox( 'carousel_enable_it', __( 'Display images in full-size carousel slideshow.', 'jetpack' ) );
796
	}
797
798
	/**
799
	 * Sanitize carousel Enable It.
800
	 *
801
	 * @access public
802
	 * @param mixed $value Value.
803
	 * @return $value Value.
0 ignored issues
show
Documentation introduced by
The doc-type $value could not be parsed: Unknown type name "$value" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
804
	 */
805
	function carousel_enable_it_sanitize( $value ) {
806
		return $this->sanitize_1or0_option( $value );
807
	}
808
}
809
new Jetpack_Carousel;
810