PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 2.4.7
Jetpack – WP Security, Backup, Speed, & Growth v2.4.7
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 / presentations.php

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

383 lines 12.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Presentations
4 Plugin URI: http://automattic.com/wordpress-plugins/
5 Description: Presentations plugin based on the work done by <a href="http://darylkoop.com/">Daryl Koopersmith</a>. Powered by jmpress.js
6 Version: 0.2
7 Author: Automattic
8 Author URI: http://automattic.com/wordpress-plugins/
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25
26 /**
27 * Known issues:
28 *
29 * - IE 7/8 are not supported by jmpress and presentations will not work
30 * - IE 9 will not animate transitions at all, though it's possible to at least
31 * switch between slides.
32 * - Infinite Scroll themes will not load presentations properly unless the post
33 * happens to be on the first loaded page. The permalink page will function
34 * properly, however.
35 * - Exiting fullscreen mode will not properly reset the scroll locations in Safari
36 */
37
38
39 /*
40 HOW TO: How the plugin settings are organized and which features are supported.
41
42 The entire presentation should be wrapped with a [presentation] shortcode, and every
43 individual slide should be wrapped with a [slide] shortcode. Any settings supported
44 by [slide] can be set into [presentation], which will apply that setting for the entire
45 presentation unless overridden by individual slides.
46
47 - [presentation] only settings:
48 - duration: transition durations, default is one second.
49 - height: content height, default is 400px
50 - width: content width, default is 550px
51
52 - [slide] settings:
53 - transition: specifies where the next slide will be placed relative
54 to the last one before it. Supported values are "up", "down"
55 "left", "right", or "none". Default value is "down".
56
57 - scale: scales the content relative to other slides, default value is one
58
59 - rotate: rotates the content by the specified degrees, default is zero
60
61 - fade: slides will fade in and out during transition. Values of "on" or
62 "true" will enable fading, while values of "no" or "false" will
63 disable it. Default value is "on"
64
65 - bgcolor: specifies a background color for the slides. Any CSS valid value
66 is permitted. Default color is transparent.
67
68 - bgimg: specifies an image url which will fill the background. Image is
69 set to fill the background 100% width and height
70 */
71
72 if ( ! class_exists( 'Presentations' ) ) :
73
74 class Presentations {
75
76 private $presentation_settings;
77 private $presentation_initialized;
78 private $scripts_and_style_included;
79
80 /**
81 * Constructor
82 */
83 function __construct() {
84 // Bail without 3.0.
85 if ( ! function_exists( '__return_false' ) )
86 return;
87
88 $this->presentation_initialized = false;
89 $this->scripts_and_style_included = false;
90
91 // Registers shortcodes
92 add_action( 'wp_head', array( &$this, 'add_scripts' ), 1 );
93
94 add_shortcode( 'presentation', array( &$this, 'presentation_shortcode' ) );
95 add_shortcode( 'slide', array( &$this, 'slide_shortcode' ) );
96 }
97
98 function add_scripts() {
99 $this->scripts_and_style_included = false;
100
101 if ( empty( $GLOBALS['posts'] ) || !is_array( $GLOBALS['posts'] ) ) {
102 return;
103 }
104
105 foreach ( $GLOBALS['posts'] as $p ) {
106 if ( false !== strpos( $p->post_content, '[presentation' ) ) {
107 $this->scripts_and_style_included = true;
108 break;
109 }
110 }
111
112 if ( ! $this->scripts_and_style_included )
113 return;
114
115 $plugin = plugin_dir_url( __FILE__ );
116 // Add CSS
117 wp_enqueue_style('presentations', $plugin . 'css/style.css');
118 // Add JavaScript
119 wp_enqueue_script('jquery');
120 wp_enqueue_script('jmpress',
121 $plugin . 'js/jmpress.min.js',
122 array('jquery'),
123 '0.4.5',
124 true);
125 wp_enqueue_script('presentations',
126 $plugin . 'js/main.js',
127 array('jquery', 'jmpress'),
128 false,
129 true);
130 }
131
132 function presentation_shortcode( $atts, $content='' ) {
133 // Mark that we've found a valid [presentation] shortcode
134 $this->presentation_initialized = true;
135
136 $atts = shortcode_atts( array(
137 'duration' => '',
138 'height' => '',
139 'width' => '',
140 'bgcolor' => '',
141 'bgimg' => '',
142
143 // Settings
144 'transition' => '',
145 'scale' => '',
146 'rotate' => '',
147 'fade' => '',
148 ), $atts );
149
150 $this->presentation_settings = array(
151 'transition' => 'down',
152 'scale' => 1,
153 'rotate' => 0,
154 'fade' => 'on',
155 'last' => array(
156 'x' => 0,
157 'y' => 0,
158 'scale' => 1,
159 'rotate' => 0,
160 ),
161 );
162
163 // Set the presentation-wide settings
164 if ( '' != trim( $atts['transition'] ) )
165 $this->presentation_settings['transition'] = $atts['transition'];
166
167 if ( '' != trim( $atts['scale'] ) )
168 $this->presentation_settings['scale'] = floatval( $atts['scale'] );
169
170 if ( '' != trim( $atts['rotate'] ) )
171 $this->presentation_settings['rotate'] = floatval( $atts['rotate'] );
172
173 if ( '' != trim( $atts['fade'] ) )
174 $this->presentation_settings['fade'] = $atts['fade'];
175
176 // Set any settings the slides don't care about
177 if ( '' != trim( $atts['duration'] ) )
178 $duration = floatval( $atts['duration'] ) . 's';
179 else
180 $duration = '1s';
181
182 // Set the presentation size as specified or with some nicely sized dimensions
183 if ( '' != trim( $atts['width'] ) )
184 $this->presentation_settings['width'] = intval( $atts['width'] );
185 else
186 $this->presentation_settings['width'] = 480;
187
188 if ( '' != trim( $atts['height'] ) )
189 $this->presentation_settings['height'] = intval( $atts['height'] );
190 else
191 $this->presentation_settings['height'] = 370;
192
193 // Hide the content by default in case the scripts fail
194 $style = 'display: none; width: ' . $this->presentation_settings['width'] . 'px; height: ' . $this->presentation_settings['height'] . 'px;';
195
196 // Check for background color XOR background image
197 // Use a white background if nothing specified
198 if ( preg_match( '/https?\:\/\/[^\'"\s]*/', $atts['bgimg'], $matches ) ) {
199 $style .= ' background-image: url("' . esc_url( $matches[0] ) . '");';
200 } else if ( '' != trim( $atts['bgcolor'] ) ) {
201 $style .= ' background-color: ' . esc_attr( $atts['bgcolor'] ) . ';';
202 } else {
203 $style .= ' background-color: #fff;';
204 }
205
206 // Not supported message style is inlined incase the style sheet doesn't get included
207 $out = "<section class='presentation-wrapper'>";
208 $out.= "<p class='not-supported-msg' style='display: inherit; padding: 25%; text-align: center;'>";
209 $out.= __( 'This slideshow could not be started. Try refreshing the page or viewing it in another browser.', 'jetpack' ) . '</p>';
210
211 // Bail out unless the scripts were added
212 if ( $this->scripts_and_style_included ) {
213 $out.= "<div class='presentation' duration='$duration' style='$style'>";
214 $out.= "<div class='nav-arrow-left'></div>";
215 $out.= "<div class='nav-arrow-right'></div>";
216 $out.= "<div class='nav-fullscreen-button'></div>";
217 $out.= do_shortcode( $content );
218 $out.= "</section>";
219 }
220
221 $out.= "</section>";
222
223 $this->presentation_initialized = false;
224 return $out;
225 }
226
227 function slide_shortcode( $atts, $content = '' ) {
228 // Bail out unless wrapped by a [presentation] shortcode
229 if ( ! $this->presentation_initialized )
230 return $content;
231
232 $atts = shortcode_atts( array(
233 'transition' => '',
234 'scale' => '',
235 'rotate' => '',
236 'fade' => '',
237 'bgcolor' => '',
238 'bgimg' => '',
239 ), $atts );
240
241 // Determine positioning based on transition
242 if ( '' == trim( $atts['transition'] ) )
243 $atts['transition'] = $this->presentation_settings['transition'];
244
245 // Setting the content scale
246 if ( '' == trim( $atts['scale'] ) )
247 $atts['scale'] = $this->presentation_settings['scale'];
248
249 if( '' == trim( $atts['scale'] ) )
250 $scale = 1;
251 else
252 $scale = floatval( $atts['scale'] );
253
254 if ( $scale < 0 )
255 $scale *= -1;
256
257 // Setting the content rotation
258 if ( '' == trim( $atts['rotate'] ) )
259 $atts['rotate'] = $this->presentation_settings['rotate'];
260
261 if( '' == trim( $atts['rotate'] ) )
262 $rotate = 0;
263 else
264 $rotate = floatval( $atts['rotate'] );
265
266 // Setting if the content should fade
267 if ( '' == trim( $atts['fade'] ) )
268 $atts['fade'] = $this->presentation_settings['fade'];
269
270 if ( 'on' == $atts['fade'] || 'true' == $atts['fade'] )
271 $fade = 'fade';
272 else
273 $fade = '';
274
275 $coords = $this->get_coords( array(
276 'transition' => $atts['transition'],
277 'scale' => $scale,
278 'rotate' => $rotate,
279 ));
280
281 $x = $coords['x'];
282 $y = $coords['y'];
283
284 // Check for background color XOR background image
285 // Use a white background if nothing specified
286 if ( preg_match( '/https?\:\/\/[^\'"\s]*/', $atts['bgimg'], $matches ) ) {
287 $style = 'background-image: url("' . esc_url( $matches[0] ) . '");';
288 } else if ( '' != trim( $atts['bgcolor'] ) ) {
289 $style = 'background-color: ' . esc_attr( $atts['bgcolor'] ) . ';';
290 } else {
291 $style = '';
292 }
293
294 // Put everything together and let jmpress do the magic!
295 $out = "<div class='step $fade' data-x='$x' data-y='$y' data-scale='$scale' data-rotate='$rotate' style='$style'>";
296 $out.= "<div class='slide-content'>";
297 $out.= do_shortcode( $content );
298 $out.= "</div></div>";
299 return $out;
300 }
301
302 /**
303 * Determines the position of the next slide based on the position and scaling of the previous slide.
304 *
305 * @param array $args: an array with the following key-value pairs
306 * string $transition: the transition name, "up", "down", "left", or "right"
307 * float $scale: the scale of the next slide (used to determine the position of the slide after that)
308 *
309 * @return array with the 'x' and 'y' coordinates of the slide
310 */
311 function get_coords( $args ) {
312 if ( 0 == $args['scale'] )
313 $args['scale'] = 1;
314
315 $width = $this->presentation_settings['width'];
316 $height = $this->presentation_settings['height'];
317 $last = $this->presentation_settings['last'];
318 $scale = $last['scale'];
319
320 $next = array(
321 'x' => $last['x'],
322 'y' => $last['y'],
323 'scale' => $args['scale'],
324 'rotate' => $args['rotate'],
325 );
326
327 // All angles are measured from the vertical axis, so everything is backwards!
328 $diagAngle = atan2( $width, $height );
329 $diagonal = sqrt( pow( $width, 2 ) + pow( $height, 2 ) );
330
331 // We offset the angles by the angle formed by the diagonal so that
332 // we can multiply the sines directly against the diagonal length
333 $theta = deg2rad( $last['rotate'] ) - $diagAngle;
334 $phi = deg2rad( $next['rotate'] ) - $diagAngle;
335
336 // We start by displacing by the slide dimensions
337 $totalHorizDisp = $width * $scale;
338 $totalVertDisp = $height * $scale;
339
340 // If the previous slide was rotated, we add the incremental offset from the rotation
341 // Namely the difference between the regular dimension (no rotation) and the component
342 // of the diagonal for that angle
343 $totalHorizDisp += ( ( ( abs( sin( $theta ) ) * $diagonal) - $width ) / 2) * $scale;
344 $totalVertDisp += ( ( ( abs( cos( $theta ) ) * $diagonal) - $height) / 2) * $scale;
345
346 // Similarly, we check if the current slide has been rotated and add whatever additional
347 // offset has been added. This is so that two rotated corners don't clash with each other.
348 // Note: we are checking the raw angle relative to the vertical axis, NOT the diagonal angle.
349 if ( $next['rotate'] % 180 != 0 ){
350 $totalHorizDisp += ( abs( ( sin( $phi ) * $diagonal ) - $width ) / 2) * $next['scale'];
351 $totalVertDisp += ( abs( ( cos( $phi ) * $diagonal ) - $height ) / 2) * $next['scale'];
352 }
353
354 switch ( trim( $args['transition'] ) ) {
355 case 'none':
356 break;
357
358 case 'left':
359 $next['x'] -= $totalHorizDisp;
360 break;
361
362 case 'right':
363 $next['x'] += $totalHorizDisp;
364 break;
365
366 case 'up':
367 $next['y'] -= $totalVertDisp;
368 break;
369
370 case 'down':
371 default:
372 $next['y'] += $totalVertDisp;
373 break;
374 }
375
376 $this->presentation_settings['last'] = $next;
377 return $next;
378 }
379 }
380
381 $GLOBALS['presentations'] = new Presentations();
382 endif;
383