Completed
Push — add/86-changelog ( 142a60...d9a8fc )
by Jeremy
19:49 queued 12:19
created

Jetpack_Slideshow_Shortcode::shortcode_callback()   F

Complexity

Conditions 13
Paths 528

Size

Total Lines 119

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
nc 528
nop 1
dl 0
loc 119
rs 2.4844
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php //phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
3
use Automattic\Jetpack\Assets;
4
use Automattic\Jetpack\Extensions\Slideshow;
5
6
/**
7
 * Slideshow shortcode.
8
 * Adds a new "slideshow" gallery type when adding a gallery using the classic editor.
9
 *
10
 * @package Jetpack
11
 */
12
13
/**
14
 * Slideshow shortcode usage: [gallery type="slideshow"] or the older [slideshow]
15
 */
16
class Jetpack_Slideshow_Shortcode {
17
	/**
18
	 * Number of slideshows on a page.
19
	 *
20
	 * @var int
21
	 */
22
	public $instance_count = 0;
23
24
	/**
25
	 * Constructor
26
	 */
27
	public function __construct() {
28
		global $shortcode_tags;
29
30
		// Only if the slideshow shortcode has not already been defined.
31
		if ( ! array_key_exists( 'slideshow', $shortcode_tags ) ) {
32
			add_shortcode( 'slideshow', array( $this, 'shortcode_callback' ) );
33
		}
34
35
		// Only if the gallery shortcode has not been redefined.
36
		if ( isset( $shortcode_tags['gallery'] ) && 'gallery_shortcode' === $shortcode_tags['gallery'] ) {
37
			add_filter( 'post_gallery', array( $this, 'post_gallery' ), 1002, 2 );
38
			add_filter( 'jetpack_gallery_types', array( $this, 'add_gallery_type' ), 10 );
39
		}
40
	}
41
42
	/**
43
	 * Responds to the [gallery] shortcode, but not an actual shortcode callback.
44
	 *
45
	 * @param string $value An empty string if nothing has modified the gallery output, the output html otherwise.
46
	 * @param array  $attr  The shortcode attributes array.
47
	 *
48
	 * @return string The (un)modified $value
49
	 */
50
	public function post_gallery( $value, $attr ) {
51
		// Bail if somebody else has done something.
52
		if ( ! empty( $value ) ) {
53
			return $value;
54
		}
55
56
		// If [gallery type="slideshow"] have it behave just like [slideshow].
57
		if ( ! empty( $attr['type'] ) && 'slideshow' === $attr['type'] ) {
58
			return $this->shortcode_callback( $attr );
59
		}
60
61
		return $value;
62
	}
63
64
	/**
65
	 * Add the Slideshow type to gallery settings
66
	 *
67
	 * @see Jetpack_Tiled_Gallery::media_ui_print_templates
68
	 *
69
	 * @param array $types An array of types where the key is the value, and the value is the caption.
70
	 *
71
	 * @return array
72
	 */
73
	public function add_gallery_type( $types = array() ) {
74
		$types['slideshow'] = esc_html__( 'Slideshow', 'jetpack' );
75
76
		return $types;
77
	}
78
79
	/**
80
	 * Display shortcode.
81
	 *
82
	 * @param array $attr Shortcode attributes.
83
	 */
84
	public function shortcode_callback( $attr ) {
85
		$post_id = get_the_ID();
86
87
		$attr = shortcode_atts(
88
			array(
89
				'trans'     => 'fade',
90
				'order'     => 'ASC',
91
				'orderby'   => 'menu_order ID',
92
				'id'        => $post_id,
93
				'include'   => '',
94
				'exclude'   => '',
95
				'autostart' => true,
96
				'size'      => '',
97
			),
98
			$attr,
99
			'slideshow'
100
		);
101
102
		if ( 'rand' === strtolower( $attr['order'] ) ) {
103
			$attr['orderby'] = 'none';
104
		}
105
106
		$attr['orderby'] = sanitize_sql_orderby( $attr['orderby'] );
107
		if ( ! $attr['orderby'] ) {
108
			$attr['orderby'] = 'menu_order ID';
109
		}
110
111
		if ( ! $attr['size'] ) {
112
			$attr['size'] = 'full';
113
		}
114
115
		// Don't restrict to the current post if include.
116
		$post_parent = ( empty( $attr['include'] ) ) ? intval( $attr['id'] ) : null;
117
118
		$attachments = get_posts(
119
			array(
120
				'post_status'      => 'inherit',
121
				'post_type'        => 'attachment',
122
				'post_mime_type'   => 'image',
123
				'posts_per_page'   => - 1,
124
				'post_parent'      => $post_parent,
125
				'order'            => $attr['order'],
126
				'orderby'          => $attr['orderby'],
127
				'include'          => $attr['include'],
128
				'exclude'          => $attr['exclude'],
129
				'suppress_filters' => false,
130
			)
131
		);
132
133
		if ( count( $attachments ) < 1 ) {
134
			return false;
135
		}
136
137
		$gallery_instance = sprintf( 'gallery-%d-%d', $attr['id'], ++$this->instance_count );
138
139
		$gallery = array();
140
		foreach ( $attachments as $attachment ) {
141
			$attachment_image_src   = wp_get_attachment_image_src( $attachment->ID, $attr['size'] );
142
			$attachment_image_src   = $attachment_image_src[0]; // [url, width, height].
143
			$attachment_image_title = get_the_title( $attachment->ID );
144
			$attachment_image_alt   = get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true );
145
			/**
146
			 * Filters the Slideshow slide caption.
147
			 *
148
			 * @module shortcodes
149
			 *
150
			 * @since 2.3.0
151
			 *
152
			 * @param string wptexturize( strip_tags( $attachment->post_excerpt ) ) Post excerpt.
153
			 * @param string $attachment ->ID Attachment ID.
154
			 */
155
			$caption = apply_filters( 'jetpack_slideshow_slide_caption', wptexturize( wp_strip_all_tags( $attachment->post_excerpt ) ), $attachment->ID );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $attachment->ID.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
156
157
			$gallery[] = (object) array(
158
				'src'      => (string) esc_url_raw( $attachment_image_src ),
159
				'id'       => (string) $attachment->ID,
160
				'title'    => (string) esc_attr( $attachment_image_title ),
161
				'alt'      => (string) esc_attr( $attachment_image_alt ),
162
				'caption'  => (string) $caption,
163
				'itemprop' => 'image',
164
			);
165
		}
166
167
		$color     = Jetpack_Options::get_option( 'slideshow_background_color', 'black' );
168
		$autostart = $attr['autostart'] ? $attr['autostart'] : 'true';
169
		$js_attr   = array(
170
			'gallery'   => $gallery,
171
			'selector'  => $gallery_instance,
172
			'trans'     => $attr['trans'] ? $attr['trans'] : 'fade',
173
			'autostart' => $autostart,
174
			'color'     => $color,
175
		);
176
177
		// Show a link to the gallery in feeds.
178
		if ( is_feed() ) {
179
			return sprintf(
180
				'<a href="%s">%s</a>',
181
				esc_url( get_permalink( $post_id ) . '#' . $gallery_instance . '-slideshow' ),
182
				esc_html__( 'Click to view slideshow.', 'jetpack' )
183
			);
184
		}
185
186
		if ( class_exists( 'Jetpack_AMP_Support' ) && Jetpack_AMP_Support::is_amp_request() ) {
187
			// Load the styles and use the rendering method from the Slideshow block.
188
			Jetpack_Gutenberg::load_styles_as_required( 'slideshow' );
189
190
			$amp_args = array(
191
				'ids' => wp_list_pluck( $gallery, 'id' ),
192
			);
193
194
			if ( 'true' == $autostart ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison -- attribute can be stored as boolean or string.
195
				$amp_args['autoplay'] = true;
196
			}
197
198
			return Slideshow\render_amp( $amp_args );
199
		}
200
201
		return $this->slideshow_js( $js_attr );
202
	}
203
204
	/**
205
	 * Render the slideshow js
206
	 *
207
	 * Returns the necessary markup and js to fire a slideshow.
208
	 *
209
	 * @param array $attr Attributes for the slideshow.
210
	 *
211
	 * @uses $this->enqueue_scripts()
212
	 *
213
	 * @return string HTML output.
214
	 */
215
	public function slideshow_js( $attr ) {
216
		// Enqueue scripts.
217
		$this->enqueue_scripts();
218
219
		$output = '';
220
221
		if ( defined( 'JSON_HEX_AMP' ) ) {
222
			// This is nice to have, but not strictly necessary since we use _wp_specialchars() below.
223
			$gallery = wp_json_encode( $attr['gallery'], JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT ); // phpcs:ignore PHPCompatibility
224
		} else {
225
			$gallery = wp_json_encode( $attr['gallery'] );
226
		}
227
228
		$output .= '<p class="jetpack-slideshow-noscript robots-nocontent">' . esc_html__( 'This slideshow requires JavaScript.', 'jetpack' ) . '</p>';
229
230
		/*
231
		 * The input to json_encode() above can contain '&quot;'.
232
		 *
233
		 * For calls to json_encode() lacking the JSON_HEX_AMP option,
234
		 * that '&quot;' is left unaltered.  Running '&quot;' through esc_attr()
235
		 * also leaves it unaltered since esc_attr() does not double-encode.
236
		 *
237
		 * This means we end up with an attribute like
238
		 * `data-gallery="{&quot;foo&quot;:&quot;&quot;&quot;}"`,
239
		 * which is interpreted by the browser as `{"foo":"""}`,
240
		 * which cannot be JSON decoded.
241
		 *
242
		 * The preferred workaround is to include the JSON_HEX_AMP (and friends)
243
		 * options, but these are not available until 5.3.0.
244
		 * Alternatively, we can use _wp_specialchars( , , , true ) instead of
245
		 * esc_attr(), which will double-encode.
246
		 *
247
		 * Since we can't rely on JSON_HEX_AMP, we do both.
248
		 *
249
		 * @todo Update when minimum is PHP 5.3+
250
		 */
251
		$gallery_attributes = _wp_specialchars( wp_check_invalid_utf8( $gallery ), ENT_QUOTES, false, true );
252
253
		$output .= sprintf(
254
			'<div id="%s" class="slideshow-window jetpack-slideshow slideshow-%s" data-trans="%s" data-autostart="%s" data-gallery="%s" itemscope itemtype="https://schema.org/ImageGallery"></div>',
255
			esc_attr( $attr['selector'] . '-slideshow' ),
256
			esc_attr( $attr['color'] ),
257
			esc_attr( $attr['trans'] ),
258
			esc_attr( $attr['autostart'] ),
259
			$gallery_attributes
260
		);
261
262
		return $output;
263
	}
264
265
	/**
266
	 * Actually enqueues the scripts and styles.
267
	 */
268
	public function enqueue_scripts() {
269
270
		wp_enqueue_script( 'jquery-cycle', plugins_url( '/js/jquery.cycle.min.js', __FILE__ ), array( 'jquery' ), '20161231', true );
271
		wp_enqueue_script(
272
			'jetpack-slideshow',
273
			Assets::get_file_url_for_environment( '_inc/build/shortcodes/js/slideshow-shortcode.min.js', 'modules/shortcodes/js/slideshow-shortcode.js' ),
274
			array( 'jquery-cycle' ),
275
			'20160119.1',
276
			true
277
		);
278
		wp_enqueue_style(
279
			'jetpack-slideshow',
280
			plugins_url( '/css/slideshow-shortcode.css', __FILE__ ),
281
			array(),
282
			JETPACK__VERSION
283
		);
284
		wp_style_add_data( 'jetpack-slideshow', 'rtl', 'replace' );
285
286
		wp_localize_script(
287
			'jetpack-slideshow',
288
			'jetpackSlideshowSettings',
289
			/**
290
			 * Filters the slideshow JavaScript spinner.
291
			 *
292
			 * @module shortcodes
293
			 *
294
			 * @since 2.1.0
295
			 * @since 4.7.0 Added the `speed` option to the array of options.
296
			 *
297
			 * @param array $args
298
			 * - string - spinner        - URL of the spinner image.
299
			 * - string - speed          - Speed of the slideshow. Defaults to 4000.
300
			 * - string - label_prev     - Aria label for slideshow's previous button
301
			 * - string - label_stop    - Aria label for slideshow's pause button
302
			 * - string - label_next     - Aria label for slideshow's next button
303
			 */
304
			apply_filters(
305
				'jetpack_js_slideshow_settings',
306
				array(
307
					'spinner'    => plugins_url( '/img/slideshow-loader.gif', __FILE__ ),
308
					'speed'      => '4000',
309
					'label_prev' => __( 'Previous Slide', 'jetpack' ),
310
					'label_stop' => __( 'Pause Slideshow', 'jetpack' ),
311
					'label_next' => __( 'Next Slide', 'jetpack' ),
312
				)
313
			)
314
		);
315
	}
316
317
	/**
318
	 * Instantiate shortcode.
319
	 */
320
	public static function init() {
321
		new Jetpack_Slideshow_Shortcode();
322
	}
323
}
324
325
Jetpack_Slideshow_Shortcode::init();
326