PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 15.9-a.7
Jetpack – WP Security, Backup, Speed, & Growth v15.9-a.7
15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / modules / shortcodes / presentations.php
jetpack / modules / shortcodes Last commit date
css 2 weeks ago images 1 year ago img 4 weeks ago js 6 months ago archiveorg-book.php 6 months ago archiveorg.php 6 months ago archives.php 2 weeks ago bandcamp.php 6 months ago brightcove.php 5 months ago cartodb.php 6 months ago class.filter-embedded-html-objects.php 6 months ago codepen.php 6 months ago crowdsignal.php 5 months ago dailymotion.php 6 months ago descript.php 6 months ago facebook.php 6 months ago flatio.php 6 months ago flickr.php 5 months ago getty.php 6 months ago gist.php 6 months ago googleapps.php 6 months ago googlemaps.php 3 weeks ago googleplus.php 6 months ago gravatar.php 6 months ago houzz.php 6 months ago inline-pdfs.php 6 months ago instagram.php 6 months ago kickstarter.php 6 months ago mailchimp.php 5 months ago medium.php 6 months ago mixcloud.php 6 months ago others.php 6 months ago pinterest.php 6 months ago presentations.php 6 months ago quiz.php 6 months ago recipe.php 6 months ago scribd.php 6 months ago shortcode-utils.php 6 months ago sitemap.php 6 months ago slideshare.php 6 months ago slideshow.php 4 weeks ago smartframe.php 6 months ago soundcloud.php 6 months ago spotify.php 6 months ago ted.php 6 months ago tweet.php 6 months ago twitchtv.php 6 months ago twitter-timeline.php 6 months ago twitter.php 6 months ago unavailable.php 6 months ago untappd-menu.php 6 months ago upcoming-events.php 6 months ago ustream.php 6 months ago videopress.php 6 months ago vimeo.php 1 week ago vine.php 6 months ago vr.php 1 week ago wufoo.php 6 months ago youtube.php 3 months ago
presentations.php
493 lines
1 <?php //phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 /**
3 * Presentations
4 * Presentations plugin based on the work done by <a href="http://darylkoop.com/">Daryl Koopersmith</a>. Powered by jmpress.js
5 *
6 * HOW TO: How the plugin settings are organized and which features are supported.
7 *
8 * The entire presentation should be wrapped with a [presentation] shortcode, and every
9 * individual slide should be wrapped with a [slide] shortcode. Any settings supported
10 * by [slide] can be set into [presentation], which will apply that setting for the entire
11 * presentation unless overridden by individual slides.
12 *
13 * - [presentation] only settings:
14 * - duration: transition durations, default is one second.
15 * - height: content height, default is 400px
16 * - width: content width, default is 550px
17 * - autoplay: delay between transitions in seconds, default 3s
18 * when set the presentation will automatically transition between slides
19 * as long as the presentation remains in focus
20 *
21 * - [slide] settings:
22 * - transition: specifies where the next slide will be placed relative
23 * to the last one before it. Supported values are "up", "down"
24 * "left", "right", or "none". Default value is "down".
25 *
26 * - scale: scales the content relative to other slides, default value is one
27 *
28 * - rotate: rotates the content by the specified degrees, default is zero
29 *
30 * - fade: slides will fade in and out during transition. Values of "on" or
31 * "true" will enable fading, while values of "no" or "false" will
32 * disable it. Default value is "on"
33 *
34 * - bgcolor: specifies a background color for the slides. Any CSS valid value
35 * is permitted. Default color is transparent.
36 *
37 * - bgimg: specifies an image url which will fill the background. Image is
38 * set to fill the background 100% width and height
39 *
40 * - fadebullets: any html <li> tags will start out with an opacity of 0 and any
41 * subsequent slide transitions will show the bullets one by one
42 *
43 * Known issues:
44 *
45 * - IE 7/8 are not supported by jmpress and presentations will not work
46 * - IE 9 will not animate transitions at all, though it's possible to at least
47 * switch between slides.
48 * - Infinite Scroll themes will not load presentations properly unless the post
49 * happens to be on the first loaded page. The permalink page will function
50 * properly, however.
51 * - Exiting fullscreen mode will not properly reset the scroll locations in Safari
52 *
53 * @package automattic/jetpack
54 */
55
56 use Automattic\Jetpack\Assets;
57
58 if ( ! defined( 'ABSPATH' ) ) {
59 exit( 0 );
60 }
61
62 if ( ! class_exists( 'Presentations' ) ) :
63 /**
64 * Create a shortcode to display Presentations and slides.
65 */
66 class Presentations {
67
68 /**
69 * Presentation settings.
70 *
71 * @var array
72 */
73 private $presentation_settings;
74 /**
75 * Do we have a Presentation shortcode to be displayed.
76 *
77 * @var bool
78 */
79 private $presentation_initialized;
80 /**
81 * Were scripts and styles enqueued already.
82 *
83 * @var bool
84 */
85 private $scripts_and_style_included;
86
87 /**
88 * Constructor
89 */
90 public function __construct() {
91 $this->presentation_initialized = false;
92 $this->scripts_and_style_included = false;
93
94 // Registers shortcodes.
95 add_action( 'wp_head', array( $this, 'add_scripts' ), 1 );
96
97 add_shortcode( 'presentation', array( $this, 'presentation_shortcode' ) );
98 add_shortcode( 'slide', array( $this, 'slide_shortcode' ) );
99 }
100
101 /**
102 * Enqueue all scripts and styles.
103 */
104 public function add_scripts() {
105 $this->scripts_and_style_included = false;
106
107 if ( empty( $GLOBALS['posts'] ) || ! is_array( $GLOBALS['posts'] ) ) {
108 return;
109 }
110
111 foreach ( $GLOBALS['posts'] as $p ) {
112 if ( isset( $p->post_content ) && has_shortcode( $p->post_content, 'presentation' ) ) {
113 $this->scripts_and_style_included = true;
114 break;
115 }
116 }
117
118 if ( ! $this->scripts_and_style_included ) {
119 return;
120 }
121
122 $plugin = plugin_dir_url( __FILE__ );
123 // Add CSS.
124 wp_enqueue_style( 'presentations', $plugin . 'css/style.css', array(), JETPACK__VERSION );
125 // Add JavaScript.
126 wp_enqueue_script( 'jquery' );
127 wp_register_script(
128 'jetpack-shortcode-deps',
129 plugins_url( '_inc/build/shortcodes/js/dependencies.min.js', JETPACK__PLUGIN_FILE ),
130 array( 'jquery' ),
131 '20251030',
132 true
133 );
134 wp_enqueue_script(
135 'presentations',
136 Assets::get_file_url_for_environment( '_inc/build/shortcodes/js/main.min.js', 'modules/shortcodes/js/main.js' ),
137 array( 'jquery', 'jetpack-shortcode-deps' ),
138 JETPACK__VERSION,
139 true
140 );
141 }
142
143 /**
144 * Main Presentation shortcode.
145 *
146 * @param array $atts Shortcode attributes.
147 * @param string $content Post content.
148 */
149 public function presentation_shortcode( $atts, $content = '' ) {
150 // Mark that we've found a valid [presentation] shortcode.
151 $this->presentation_initialized = true;
152
153 $atts = shortcode_atts(
154 array(
155 'duration' => '',
156 'height' => '',
157 'width' => '',
158 'bgcolor' => '',
159 'bgimg' => '',
160 'autoplay' => '',
161
162 // Settings.
163 'transition' => '',
164 'scale' => '',
165 'rotate' => '',
166 'fade' => '',
167 'fadebullets' => '',
168 ),
169 $atts,
170 'presentation'
171 );
172
173 $this->presentation_settings = array(
174 'transition' => 'down',
175 'scale' => 1,
176 'rotate' => 0,
177 'fade' => 'on',
178 'fadebullets' => 0,
179 'last' => array(
180 'x' => 0,
181 'y' => 0,
182 'scale' => 1,
183 'rotate' => 0,
184 ),
185 );
186
187 // Set the presentation-wide settings.
188 if ( '' !== trim( $atts['transition'] ) ) {
189 $this->presentation_settings['transition'] = $atts['transition'];
190 }
191
192 if ( '' !== trim( $atts['scale'] ) ) {
193 $this->presentation_settings['scale'] = (float) $atts['scale'];
194 }
195
196 if ( '' !== trim( $atts['rotate'] ) ) {
197 $this->presentation_settings['rotate'] = (float) $atts['rotate'];
198 }
199
200 if ( '' !== trim( $atts['fade'] ) ) {
201 $this->presentation_settings['fade'] = $atts['fade'];
202 }
203
204 if ( '' !== trim( $atts['fadebullets'] ) ) {
205 $this->presentation_settings['fadebullets'] = $atts['fadebullets'];
206 }
207
208 // Set any settings the slides don't care about.
209 if ( '' !== trim( $atts['duration'] ) ) {
210 $duration = (float) $atts['duration'] . 's';
211 } else {
212 $duration = '1s';
213 }
214
215 // Autoplay durations are set in milliseconds.
216 if ( '' !== trim( $atts['autoplay'] ) ) {
217 $autoplay = (float) $atts['autoplay'] * 1000;
218 } else {
219 $autoplay = 0;
220 } // No autoplay
221
222 // Set the presentation size as specified or with some nicely sized dimensions.
223 if ( '' !== trim( $atts['width'] ) ) {
224 $this->presentation_settings['width'] = (int) $atts['width'];
225 } else {
226 $this->presentation_settings['width'] = 480;
227 }
228
229 if ( '' !== trim( $atts['height'] ) ) {
230 $this->presentation_settings['height'] = (int) $atts['height'];
231 } else {
232 $this->presentation_settings['height'] = 370;
233 }
234
235 // Hide the content by default in case the scripts fail.
236 $style = 'display: none; width: ' . $this->presentation_settings['width'] . 'px; height: ' . $this->presentation_settings['height'] . 'px;';
237
238 /*
239 * Check for background color XOR background image
240 * Use a white background if nothing specified
241 */
242 if ( preg_match( '/https?\:\/\/[^\'"\s]*/', $atts['bgimg'], $matches ) ) {
243 $style .= ' background-image: url("' . esc_url( $matches[0] ) . '");';
244 } elseif ( '' !== trim( $atts['bgcolor'] ) ) {
245 $style .= ' background-color: ' . esc_attr( $atts['bgcolor'] ) . ';';
246 } else {
247 $style .= ' background-color: #fff;';
248 }
249
250 // Not supported message style is inlined incase the style sheet doesn't get included.
251 $out = "<section class='presentation-wrapper'>";
252 $out .= "<p class='not-supported-msg' style='display: inherit; padding: 25%; text-align: center;'>";
253 $out .= __( 'This slideshow could not be started. Try refreshing the page or viewing it in another browser.', 'jetpack' ) . '</p>';
254
255 $out .= sprintf(
256 '<div class="presentation" duration="%s" data-autoplay="%s" style="%s">',
257 esc_attr( $duration ),
258 esc_attr( $autoplay ),
259 esc_attr( $style )
260 );
261 $out .= "<div class='nav-arrow-left'></div>";
262 $out .= "<div class='nav-arrow-right'></div>";
263 $out .= "<div class='nav-fullscreen-button'></div>";
264
265 if ( $autoplay ) {
266 $out .= '<div class="autoplay-overlay" style="display: none;"><p class="overlay-msg">';
267 $out .= __( 'Click to autoplay the presentation!', 'jetpack' );
268 $out .= '</p></div>';
269 }
270
271 $out .= do_shortcode( $content );
272
273 $out .= '</section>';
274
275 $this->presentation_initialized = false;
276
277 return $out;
278 }
279
280 /**
281 * Slide shortcode.
282 *
283 * @param array $atts Shortcode attributes.
284 * @param string $content Post content.
285 */
286 public function slide_shortcode( $atts, $content = '' ) {
287 // Bail out unless wrapped by a [presentation] shortcode.
288 if ( ! $this->presentation_initialized ) {
289 return $content;
290 }
291
292 $atts = shortcode_atts(
293 array(
294 'transition' => '',
295 'scale' => '',
296 'rotate' => '',
297 'fade' => '',
298 'fadebullets' => '',
299 'bgcolor' => '',
300 'bgimg' => '',
301 ),
302 $atts,
303 'slide'
304 );
305
306 // Determine positioning based on transition.
307 if ( '' === trim( $atts['transition'] ) ) {
308 $atts['transition'] = $this->presentation_settings['transition'];
309 }
310
311 // Setting the content scale.
312 if ( '' === trim( $atts['scale'] ) ) {
313 $atts['scale'] = $this->presentation_settings['scale'];
314 }
315
316 if ( '' === trim( $atts['scale'] ) ) {
317 $scale = 1;
318 } else {
319 $scale = (float) $atts['scale'];
320 }
321
322 if ( $scale < 0 ) {
323 $scale *= -1;
324 }
325
326 // Setting the content rotation.
327 if ( '' === trim( $atts['rotate'] ) ) {
328 $atts['rotate'] = $this->presentation_settings['rotate'];
329 }
330
331 if ( '' === trim( $atts['rotate'] ) ) {
332 $rotate = 0;
333 } else {
334 $rotate = (float) $atts['rotate'];
335 }
336
337 // Setting if the content should fade.
338 if ( '' === trim( $atts['fade'] ) ) {
339 $atts['fade'] = $this->presentation_settings['fade'];
340 }
341
342 if ( 'on' === $atts['fade'] || 'true' === $atts['fade'] ) {
343 $fade = 'fade';
344 } else {
345 $fade = '';
346 }
347
348 // Setting if bullets should fade on step changes.
349 if ( '' === trim( $atts['fadebullets'] ) ) {
350 $atts['fadebullets'] = $this->presentation_settings['fadebullets'];
351 }
352
353 if ( 'on' === $atts['fadebullets'] || 'true' === $atts['fadebullets'] ) {
354 $fadebullets = 'fadebullets';
355 } else {
356 $fadebullets = '';
357 }
358
359 $coords = $this->get_coords(
360 array(
361 'transition' => $atts['transition'],
362 'scale' => $scale,
363 'rotate' => $rotate,
364 )
365 );
366
367 $x = $coords['x'];
368 $y = $coords['y'];
369
370 /*
371 * Check for background color XOR background image
372 * Use a white background if nothing specified
373 */
374 if ( preg_match( '/https?\:\/\/[^\'"\s]*/', $atts['bgimg'], $matches ) ) {
375 $style = 'background-image: url("' . esc_url( $matches[0] ) . '");';
376 } elseif ( '' !== trim( $atts['bgcolor'] ) ) {
377 $style = 'background-color: ' . esc_attr( $atts['bgcolor'] ) . ';';
378 } else {
379 $style = '';
380 }
381
382 // Put everything together and let jmpress do the magic!
383 $out = sprintf(
384 '<div class="step %s %s" data-x="%s" data-y="%s" data-scale="%s" data-rotate="%s" style="%s">',
385 esc_attr( $fade ),
386 esc_attr( $fadebullets ),
387 esc_attr( $x ),
388 esc_attr( $y ),
389 esc_attr( $scale ),
390 esc_attr( $rotate ),
391 esc_attr( $style )
392 );
393
394 $out .= '<div class="slide-content">';
395 $out .= do_shortcode( $content );
396 $out .= '</div></div>';
397
398 return $out;
399 }
400
401 /**
402 * Determines the position of the next slide based on the position and scaling of the previous slide.
403 *
404 * @param array $args {
405 * Array of key-value pairs.
406 *
407 * @type string $transition: the transition name, "up", "down", "left", or "right".
408 * @type float $scale: the scale of the next slide (used to determine the position of the slide after that).
409 * }
410 *
411 * @return array with the 'x' and 'y' coordinates of the slide.
412 */
413 private function get_coords( $args ) {
414 if ( 0 === $args['scale'] ) {
415 $args['scale'] = 1;
416 }
417
418 $width = $this->presentation_settings['width'];
419 $height = $this->presentation_settings['height'];
420 $last = $this->presentation_settings['last'];
421 $scale = $last['scale'];
422
423 $next = array(
424 'x' => $last['x'],
425 'y' => $last['y'],
426 'scale' => $args['scale'],
427 'rotate' => $args['rotate'],
428 );
429
430 // All angles are measured from the vertical axis, so everything is backwards!
431 $diag_angle = atan2( $width, $height );
432 $diagonal = sqrt( pow( $width, 2 ) + pow( $height, 2 ) );
433
434 /*
435 * We offset the angles by the angle formed by the diagonal so that
436 * we can multiply the sines directly against the diagonal length
437 */
438 $theta = deg2rad( $last['rotate'] ) - $diag_angle;
439 $phi = deg2rad( $next['rotate'] ) - $diag_angle;
440
441 // We start by displacing by the slide dimensions.
442 $total_horiz_disp = $width * $scale;
443 $total_vert_disp = $height * $scale;
444
445 /*
446 * If the previous slide was rotated, we add the incremental offset from the rotation
447 * Namely the difference between the regular dimension (no rotation) and the component
448 * of the diagonal for that angle
449 */
450 $total_horiz_disp += ( ( ( abs( sin( $theta ) ) * $diagonal ) - $width ) / 2 ) * $scale;
451 $total_vert_disp += ( ( ( abs( cos( $theta ) ) * $diagonal ) - $height ) / 2 ) * $scale;
452
453 /*
454 * Similarly, we check if the current slide has been rotated and add whatever additional
455 * offset has been added. This is so that two rotated corners don't clash with each other.
456 * Note: we are checking the raw angle relative to the vertical axis, NOT the diagonal angle.
457 */
458 if ( 0 !== $next['rotate'] % 180 ) {
459 $total_horiz_disp += ( abs( ( sin( $phi ) * $diagonal ) - $width ) / 2 ) * $next['scale'];
460 $total_vert_disp += ( abs( ( cos( $phi ) * $diagonal ) - $height ) / 2 ) * $next['scale'];
461 }
462
463 switch ( trim( $args['transition'] ) ) {
464 case 'none':
465 break;
466
467 case 'left':
468 $next['x'] -= $total_horiz_disp;
469 break;
470
471 case 'right':
472 $next['x'] += $total_horiz_disp;
473 break;
474
475 case 'up':
476 $next['y'] -= $total_vert_disp;
477 break;
478
479 case 'down':
480 default:
481 $next['y'] += $total_vert_disp;
482 break;
483 }
484
485 $this->presentation_settings['last'] = $next;
486
487 return $next;
488 }
489 }
490
491 $GLOBALS['presentations'] = new Presentations();
492 endif;
493