PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 4.3.5
Jetpack – WP Security, Backup, Speed, & Growth v4.3.5
16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 All 501 releases
jetpack / modules / shortcodes / slideshow.php

slideshow.php in Jetpack – WP Security, Backup, Speed, & Growth 4.3.5, at modules/shortcodes/slideshow.php

331 lines 10.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Slideshow shortcode usage: [gallery type="slideshow"] or the older [slideshow]
5 */
6 class Jetpack_Slideshow_Shortcode {
7 public $instance_count = 0;
8
9 function __construct() {
10 global $shortcode_tags;
11
12 $needs_scripts = false;
13
14 // Only if the slideshow shortcode has not already been defined.
15 if ( ! array_key_exists( 'slideshow', $shortcode_tags ) ) {
16 add_shortcode( 'slideshow', array( $this, 'shortcode_callback' ) );
17 $needs_scripts = true;
18 }
19
20 // Only if the gallery shortcode has not been redefined.
21 if ( isset( $shortcode_tags['gallery'] ) && 'gallery_shortcode' === $shortcode_tags['gallery'] ) {
22 add_filter( 'post_gallery', array( $this, 'post_gallery' ), 1002, 2 );
23 add_filter( 'jetpack_gallery_types', array( $this, 'add_gallery_type' ), 10 );
24 $needs_scripts = true;
25 }
26
27 if ( $needs_scripts ) {
28 add_action( 'wp_enqueue_scripts', array( $this, 'maybe_enqueue_scripts' ), 1 );
29 }
30
31 /**
32 * For the moment, comment out the setting for v2.8.
33 * The remainder should work as it always has.
34 * See: https://github.com/Automattic/jetpack/pull/85/files
35 */
36 // add_action( 'admin_init', array( $this, 'register_settings' ), 5 );
37 }
38
39 /**
40 * Responds to the [gallery] shortcode, but not an actual shortcode callback.
41 *
42 * @param $value string An empty string if nothing has modified the gallery output, the output html otherwise
43 * @param $attr array The shortcode attributes array
44 *
45 * @return string The (un)modified $value
46 */
47 function post_gallery( $value, $attr ) {
48 // Bail if somebody else has done something
49 if ( ! empty( $value ) ) {
50 return $value;
51 }
52
53 // If [gallery type="slideshow"] have it behave just like [slideshow]
54 if ( ! empty( $attr['type'] ) && 'slideshow' == $attr['type'] ) {
55 return $this->shortcode_callback( $attr );
56 }
57
58 return $value;
59 }
60
61 /**
62 * Add the Slideshow type to gallery settings
63 *
64 * @see Jetpack_Tiled_Gallery::media_ui_print_templates
65 *
66 * @param $types array An array of types where the key is the value, and the value is the caption.
67 *
68 * @return array
69 */
70 function add_gallery_type( $types = array() ) {
71 $types['slideshow'] = esc_html__( 'Slideshow', 'jetpack' );
72
73 return $types;
74 }
75
76 function register_settings() {
77 add_settings_section( 'slideshow_section', __( 'Image Gallery Slideshow', 'jetpack' ), '__return_empty_string', 'media' );
78
79 add_settings_field( 'jetpack_slideshow_background_color', __( 'Background color', 'jetpack' ), array( $this, 'slideshow_background_color_callback' ), 'media', 'slideshow_section' );
80
81 register_setting( 'media', 'jetpack_slideshow_background_color', array( $this, 'slideshow_background_color_sanitize' ) );
82 }
83
84 function slideshow_background_color_callback() {
85 $options = array(
86 'black' => __( 'Black', 'jetpack' ),
87 'white' => __( 'White', 'jetpack' ),
88 );
89 $this->settings_select( 'jetpack_slideshow_background_color', $options );
90 }
91
92 function settings_select( $name, $values, $extra_text = '' ) {
93 if ( empty( $name ) || empty( $values ) || ! is_array( $values ) ) {
94 return;
95 }
96 $option = get_option( $name );
97 ?>
98 <fieldset>
99 <select name="<?php echo esc_attr( $name ); ?>" id="<?php echo esc_attr( $name ); ?>">
100 <?php foreach ( $values as $key => $value ) : ?>
101 <option value="<?php echo esc_attr( $key ); ?>" <?php selected( $key, $option ); ?>>
102 <?php echo esc_html( $value ); ?>
103 </option>
104 <?php endforeach; ?>
105 </select>
106 <?php if ( ! empty( $extra_text ) ) : ?>
107 <p class="description"><?php echo esc_html( $extra_text ); ?></p>
108 <?php endif; ?>
109 </fieldset>
110 <?php
111 }
112
113 function slideshow_background_color_sanitize( $value ) {
114 return ( 'white' == $value ) ? 'white' : 'black';
115 }
116
117 function shortcode_callback( $attr ) {
118 global $post;
119
120 $attr = shortcode_atts(
121 array(
122 'trans' => 'fade',
123 'order' => 'ASC',
124 'orderby' => 'menu_order ID',
125 'id' => $post->ID,
126 'include' => '',
127 'exclude' => '',
128 'autostart' => true,
129 'size' => '',
130 ), $attr, 'slideshow'
131 );
132
133 if ( 'rand' == strtolower( $attr['order'] ) ) {
134 $attr['orderby'] = 'none';
135 }
136
137 $attr['orderby'] = sanitize_sql_orderby( $attr['orderby'] );
138 if ( ! $attr['orderby'] ) {
139 $attr['orderby'] = 'menu_order ID';
140 }
141
142 if ( ! $attr['size'] ) {
143 $attr['size'] = 'full';
144 }
145
146 // Don't restrict to the current post if include
147 $post_parent = ( empty( $attr['include'] ) ) ? intval( $attr['id'] ) : null;
148
149 $attachments = get_posts(
150 array(
151 'post_status' => 'inherit',
152 'post_type' => 'attachment',
153 'post_mime_type' => 'image',
154 'posts_per_page' => - 1,
155 'post_parent' => $post_parent,
156 'order' => $attr['order'],
157 'orderby' => $attr['orderby'],
158 'include' => $attr['include'],
159 'exclude' => $attr['exclude'],
160 )
161 );
162
163 if ( count( $attachments ) < 1 ) {
164 return false;
165 }
166
167 $gallery_instance = sprintf( 'gallery-%d-%d', $attr['id'], ++$this->instance_count );
168
169 $gallery = array();
170 foreach ( $attachments as $attachment ) {
171 $attachment_image_src = wp_get_attachment_image_src( $attachment->ID, $attr['size'] );
172 $attachment_image_src = $attachment_image_src[0]; // [url, width, height]
173 $attachment_image_title = get_the_title( $attachment->ID );
174 $attachment_image_alt = get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true );
175 /**
176 * Filters the Slideshow slide caption.
177 *
178 * @module shortcodes
179 *
180 * @since 2.3.0
181 *
182 * @param string wptexturize( strip_tags( $attachment->post_excerpt ) ) Post excerpt.
183 * @param string $attachment ->ID Attachment ID.
184 */
185 $caption = apply_filters( 'jetpack_slideshow_slide_caption', wptexturize( strip_tags( $attachment->post_excerpt ) ), $attachment->ID );
186
187 $gallery[] = (object) array(
188 'src' => (string) esc_url_raw( $attachment_image_src ),
189 'id' => (string) $attachment->ID,
190 'title' => (string) esc_attr( $attachment_image_title ),
191 'alt' => (string) esc_attr( $attachment_image_alt ),
192 'caption' => (string) $caption,
193 'itemprop' => 'image',
194 );
195 }
196
197 $color = Jetpack_Options::get_option( 'slideshow_background_color', 'black' );
198
199 $js_attr = array(
200 'gallery' => $gallery,
201 'selector' => $gallery_instance,
202 'trans' => $attr['trans'] ? $attr['trans'] : 'fade',
203 'autostart' => $attr['autostart'] ? $attr['autostart'] : 'true',
204 'color' => $color,
205 );
206
207 // Show a link to the gallery in feeds.
208 if ( is_feed() ) {
209 return sprintf(
210 '<a href="%s">%s</a>',
211 esc_url( get_permalink( $post->ID ) . '#' . $gallery_instance . '-slideshow' ),
212 esc_html__( 'Click to view slideshow.', 'jetpack' )
213 );
214 }
215
216 return $this->slideshow_js( $js_attr );
217 }
218
219 /**
220 * Render the slideshow js
221 *
222 * Returns the necessary markup and js to fire a slideshow.
223 *
224 * @param $attr array Attributes for the slideshow.
225 *
226 * @uses $this->enqueue_scripts()
227 *
228 * @return string HTML output.
229 */
230 function slideshow_js( $attr ) {
231 // Enqueue scripts
232 $this->enqueue_scripts();
233
234 $output = '';
235
236 if ( defined( 'JSON_HEX_AMP' ) ) {
237 // This is nice to have, but not strictly necessary since we use _wp_specialchars() below
238 $gallery = json_encode( $attr['gallery'], JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT );
239 } else {
240 $gallery = json_encode( $attr['gallery'] );
241 }
242
243 $output .= '<p class="jetpack-slideshow-noscript robots-nocontent">' . esc_html__( 'This slideshow requires JavaScript.', 'jetpack' ) . '</p>';
244 $output .= sprintf(
245 '<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>',
246 esc_attr( $attr['selector'] . '-slideshow' ),
247 esc_attr( $attr['color'] ),
248 esc_attr( $attr['trans'] ),
249 esc_attr( $attr['autostart'] ),
250 /*
251 * The input to json_encode() above can contain '&quot;'.
252 *
253 * For calls to json_encode() lacking the JSON_HEX_AMP option,
254 * that '&quot;' is left unaltered. Running '&quot;' through esc_attr()
255 * also leaves it unaltered since esc_attr() does not double-encode.
256 *
257 * This means we end up with an attribute like
258 * `data-gallery="{&quot;foo&quot;:&quot;&quot;&quot;}"`,
259 * which is interpreted by the browser as `{"foo":"""}`,
260 * which cannot be JSON decoded.
261 *
262 * The preferred workaround is to include the JSON_HEX_AMP (and friends)
263 * options, but these are not available until 5.3.0.
264 * Alternatively, we can use _wp_specialchars( , , , true ) instead of
265 * esc_attr(), which will double-encode.
266 *
267 * Since we can't rely on JSON_HEX_AMP, we do both.
268 */
269 _wp_specialchars( wp_check_invalid_utf8( $gallery ), ENT_QUOTES, false, true )
270 );
271
272 return $output;
273 }
274
275 /**
276 * Infinite Scroll needs the scripts to be present at all times
277 */
278 function maybe_enqueue_scripts() {
279 if ( is_home() && current_theme_supports( 'infinite-scroll' ) ) {
280 $this->enqueue_scripts();
281 }
282 }
283
284 /**
285 * Actually enqueues the scripts and styles.
286 */
287 function enqueue_scripts() {
288 static $enqueued = false;
289
290 if ( $enqueued ) {
291 return;
292 }
293
294 wp_enqueue_script( 'jquery-cycle', plugins_url( '/js/jquery.cycle.js', __FILE__ ), array( 'jquery' ), '2.9999.8', true );
295 wp_enqueue_script( 'jetpack-slideshow', plugins_url( '/js/slideshow-shortcode.js', __FILE__ ), array( 'jquery-cycle' ), '20121214.1', true );
296 if ( is_rtl() ) {
297 wp_enqueue_style( 'jetpack-slideshow', plugins_url( '/css/rtl/slideshow-shortcode-rtl.css', __FILE__ ) );
298 } else {
299 wp_enqueue_style( 'jetpack-slideshow', plugins_url( '/css/slideshow-shortcode.css', __FILE__ ) );
300 }
301
302 wp_localize_script(
303 'jetpack-slideshow',
304 'jetpackSlideshowSettings',
305 /**
306 * Filters the slideshow JavaScript spinner.
307 *
308 * @module shortcodes
309 *
310 * @since 2.1.0
311 *
312 * @param array $args
313 * - string - spinner - URL of the spinner image.
314 */
315 apply_filters(
316 'jetpack_js_slideshow_settings', array(
317 'spinner' => plugins_url( '/img/slideshow-loader.gif', __FILE__ ),
318 )
319 )
320 );
321
322 $enqueued = true;
323 }
324
325 public static function init() {
326 $gallery = new Jetpack_Slideshow_Shortcode;
327 }
328 }
329
330 add_action( 'init', array( 'Jetpack_Slideshow_Shortcode', 'init' ) );
331