FV Flowplayer Video Player - Version 6.5.1

Version Description

  • 2018/04/04 =

  • Amazon S3 - Adding URL signature for subtitles

  • CSS - Responsive sizing of subtitles in fullscreen mode for large retina displays

  • Bugfix - Google Analytics - fixing label of "Unknown" to say "Unknown engine" which occurs when the video fails to play before engines are initialized

  • Bugfix - Lightbox - when used for playlist the first item was appearing twice in the lightbox view

  • Bugfix - Lightbox - when using the "text" lightbox with playlist it was rendering the playlist items as thumbnails

  • Bugfix - Lightbox - stopping the playlist styles from interfering - forcing horizontal playlist style for lightboxed playlist

Download this release

Release Info

Developer FolioVision
Plugin Icon 128x128 FV Flowplayer Video Player
Version 6.5.1
Comparing to
See all releases

Code changes from version 6.5 to 6.5.1

css/flowplayer-beta.css CHANGED
@@ -1106,7 +1106,7 @@
1106
 
1107
  .flowplayer.is-mouseout .fp-captions{-webkit-transition:bottom 0.15s ease 0.3s;-moz-transition:bottom 0.15s ease 0.3s;transition:bottom 0.15s ease 0.3s}
1108
  .flowplayer .fp-captions p{display:inline-block;background-color:#000;color:#eee;padding:0 .4em;font-size:16px;border-radius: 5px; margin: 0}
1109
- .flowplayer.is-fullscreen .fp-captions p{font-size:175%;line-height:1.2}
1110
  .flowplayer .fp-captions.is-wide br{display:none}
1111
  .flowplayer .fp-captions p:after{content:'';clear:both}
1112
  .flowplayer .fp-captions p:first-of-type{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}
@@ -1127,7 +1127,23 @@
1127
  }
1128
  @media (max-width: 30em) {
1129
  .flowplayer .fp-captions{bottom:4px;line-height:12px !important}
1130
- .flowplayer .fp-captions p{font-size:12px !important;line-height:18px !important;-webkit-text-shadow:0 0 2px #666;-moz-text-shadow:0 0 2px #666;text-shadow:0 0 2px #666}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1131
  }
1132
 
1133
 
1106
 
1107
  .flowplayer.is-mouseout .fp-captions{-webkit-transition:bottom 0.15s ease 0.3s;-moz-transition:bottom 0.15s ease 0.3s;transition:bottom 0.15s ease 0.3s}
1108
  .flowplayer .fp-captions p{display:inline-block;background-color:#000;color:#eee;padding:0 .4em;font-size:16px;border-radius: 5px; margin: 0}
1109
+ .flowplayer.is-fullscreen .fp-captions p{font-size:125%;line-height:1.2}
1110
  .flowplayer .fp-captions.is-wide br{display:none}
1111
  .flowplayer .fp-captions p:after{content:'';clear:both}
1112
  .flowplayer .fp-captions p:first-of-type{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}
1127
  }
1128
  @media (max-width: 30em) {
1129
  .flowplayer .fp-captions{bottom:4px;line-height:12px !important}
1130
+ .flowplayer .fp-captions p{font-size:11px !important;line-height:18px !important;-webkit-text-shadow:0 0 2px #666;-moz-text-shadow:0 0 2px #666;text-shadow:0 0 2px #666}
1131
+ }
1132
+ /* Fullscreen captions on large screens */
1133
+ @media (min-width: 64.063em) {
1134
+ .flowplayer.is-fullscreen .fp-captions p{font-size:135%}
1135
+ }
1136
+ @media (min-width: 90.063em) {
1137
+ .flowplayer.is-fullscreen .fp-captions p{font-size:175%}
1138
+ }
1139
+ @media (min-width: 120.063em) {
1140
+ .flowplayer.is-fullscreen .fp-captions p{font-size:225%}
1141
+ }
1142
+ @media (min-width: 128em) {
1143
+ .flowplayer.is-fullscreen .fp-captions p{font-size:300%}
1144
+ }
1145
+ @media (min-width: 160em) {
1146
+ .flowplayer.is-fullscreen .fp-captions p{font-size:350%}
1147
  }
1148
 
1149
 
css/flowplayer.css CHANGED
@@ -82,7 +82,7 @@
82
  .flowplayer.is-mouseover .fp-subtitle{bottom:34px;}
83
  .flowplayer.is-mouseout .fp-subtitle{-webkit-transition:bottom 0.15s ease 0.3s;-moz-transition:bottom 0.15s ease 0.3s;transition:bottom 0.15s ease 0.3s}
84
  .flowplayer .fp-subtitle .fp-subtitle-line{display:inline-block;background-color:#000;color:#eee;padding:0 .4em;font-size:16px;border-radius: 5px;}
85
- .flowplayer.is-fullscreen .fp-subtitle .fp-subtitle-line{font-size:175%;line-height:1.2}
86
  .flowplayer .fp-subtitle.is-wide br{display:none}
87
  .flowplayer .fp-subtitle .fp-subtitle-line:after{content:'';clear:both}
88
  .flowplayer .fp-subtitle .fp-subtitle-line:first-of-type{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}
@@ -331,7 +331,7 @@
331
  }
332
  @media (max-width: 30em) {
333
  .flowplayer .fp-subtitle{bottom:4px;line-height:12px !important}
334
- .flowplayer .fp-subtitle .fp-subtitle-line{font-size:12px !important;line-height:18px !important;-webkit-text-shadow:0 0 2px #666;-moz-text-shadow:0 0 2px #666;text-shadow:0 0 2px #666}
335
  .flowplayer .fv_player_popup {width:99%;font-size:14px;top:0;}
336
  .flowplayer.is-fv-narrow .fv_player_popup{font-size:0.8em}
337
  }
@@ -340,6 +340,23 @@
340
  .flowplayer.is-fv-narrow .mailchimp-form{padding:10px 1.5%}
341
  .flowplayer.is-fv-narrow .fv_player_popup{font-size:0.7em}
342
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343
  @media (-webkit-min-device-pixel-ratio: 2),(min-resolution: 2dppx){.flowplayer .fp-context-menu li.copyright{background-image:url("img/flowplayer-2x.png")}
344
  }@-moz-keyframes pulse{0%{opacity:0}
345
  100%{opacity:1}
82
  .flowplayer.is-mouseover .fp-subtitle{bottom:34px;}
83
  .flowplayer.is-mouseout .fp-subtitle{-webkit-transition:bottom 0.15s ease 0.3s;-moz-transition:bottom 0.15s ease 0.3s;transition:bottom 0.15s ease 0.3s}
84
  .flowplayer .fp-subtitle .fp-subtitle-line{display:inline-block;background-color:#000;color:#eee;padding:0 .4em;font-size:16px;border-radius: 5px;}
85
+ .flowplayer.is-fullscreen .fp-subtitle .fp-subtitle-line{font-size:125%;line-height:1.2}
86
  .flowplayer .fp-subtitle.is-wide br{display:none}
87
  .flowplayer .fp-subtitle .fp-subtitle-line:after{content:'';clear:both}
88
  .flowplayer .fp-subtitle .fp-subtitle-line:first-of-type{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}
331
  }
332
  @media (max-width: 30em) {
333
  .flowplayer .fp-subtitle{bottom:4px;line-height:12px !important}
334
+ .flowplayer .fp-subtitle .fp-subtitle-line{font-size:11px !important;line-height:18px !important;-webkit-text-shadow:0 0 2px #666;-moz-text-shadow:0 0 2px #666;text-shadow:0 0 2px #666}
335
  .flowplayer .fv_player_popup {width:99%;font-size:14px;top:0;}
336
  .flowplayer.is-fv-narrow .fv_player_popup{font-size:0.8em}
337
  }
340
  .flowplayer.is-fv-narrow .mailchimp-form{padding:10px 1.5%}
341
  .flowplayer.is-fv-narrow .fv_player_popup{font-size:0.7em}
342
  }
343
+ /* Fullscreen captions on large screens */
344
+ @media (min-width: 64.063em) {
345
+ .flowplayer.is-fullscreen .fp-captions p{font-size:135%}
346
+ }
347
+ @media (min-width: 90.063em) {
348
+ .flowplayer.is-fullscreen .fp-captions p{font-size:175%}
349
+ }
350
+ @media (min-width: 120.063em) {
351
+ .flowplayer.is-fullscreen .fp-captions p{font-size:225%}
352
+ }
353
+ @media (min-width: 128em) {
354
+ .flowplayer.is-fullscreen .fp-captions p{font-size:300%}
355
+ }
356
+ @media (min-width: 160em) {
357
+ .flowplayer.is-fullscreen .fp-captions p{font-size:350%}
358
+ }
359
+
360
  @media (-webkit-min-device-pixel-ratio: 2),(min-resolution: 2dppx){.flowplayer .fp-context-menu li.copyright{background-image:url("img/flowplayer-2x.png")}
361
  }@-moz-keyframes pulse{0%{opacity:0}
362
  100%{opacity:1}
flowplayer-beta/fv-flowplayer.min.js CHANGED
@@ -476,7 +476,7 @@ jQuery(document).ready( function() {
476
 
477
  // failsafe is Flowplayer is loaded outside of fv_player_load()
478
  var playlist = jQuery('.fp-playlist-external[rel='+root.attr('id')+']');
479
- if( !api.conf.playlist && playlist.length && playlist.find('a[data-item]').length > 0 ) {
480
  var items = [];
481
  playlist.find('a[data-item]').each( function() {
482
  items.push( fv_player_videos_parse(jQuery(this).attr('data-item'), root) );
@@ -1085,7 +1085,7 @@ function fv_player_track( ga_id, event, engineType, name){
1085
  return;
1086
  }
1087
 
1088
- if( typeof(engineType) == "undefined" ) engineType = 'Unknown';
1089
 
1090
  if( /fv_ga_debug/.test(window.location.href) ) console.log('FV GA: ' + event + ' - ' + engineType + " '" + name + "'")
1091
  tracker._setAllowLinker(true);
476
 
477
  // failsafe is Flowplayer is loaded outside of fv_player_load()
478
  var playlist = jQuery('.fp-playlist-external[rel='+root.attr('id')+']');
479
+ if( ( !api.conf.playlist || api.conf.playlist.length == 0 ) && playlist.length && playlist.find('a[data-item]').length > 0 ) { // api.conf.playlist.length necessary for iOS 9 in some setups
480
  var items = [];
481
  playlist.find('a[data-item]').each( function() {
482
  items.push( fv_player_videos_parse(jQuery(this).attr('data-item'), root) );
1085
  return;
1086
  }
1087
 
1088
+ if( typeof(engineType) == "undefined" ) engineType = 'Unknown engine';
1089
 
1090
  if( /fv_ga_debug/.test(window.location.href) ) console.log('FV GA: ' + event + ' - ' + engineType + " '" + name + "'")
1091
  tracker._setAllowLinker(true);
flowplayer.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: FV Player
4
  Plugin URI: http://foliovision.com/wordpress/plugins/fv-wordpress-flowplayer
5
  Description: Formerly FV WordPress Flowplayer. Embed videos (MP4, WEBM, OGV, FLV) into posts or pages. Uses Flowplayer 6.
6
- Version: 6.5
7
  Author URI: http://foliovision.com/
8
  License: GPL-3.0
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.txt
@@ -26,7 +26,7 @@ License URI: http://www.gnu.org/licenses/gpl-3.0.txt
26
  along with this program. If not, see <http://www.gnu.org/licenses/>.
27
  */
28
 
29
- $fv_wp_flowplayer_ver = '6.5';
30
  $fv_wp_flowplayer_core_ver = '6.0.5';
31
  $fv_wp_flowplayer_core_ver_beta = '7.2.4';
32
 
3
  Plugin Name: FV Player
4
  Plugin URI: http://foliovision.com/wordpress/plugins/fv-wordpress-flowplayer
5
  Description: Formerly FV WordPress Flowplayer. Embed videos (MP4, WEBM, OGV, FLV) into posts or pages. Uses Flowplayer 6.
6
+ Version: 6.5.1
7
  Author URI: http://foliovision.com/
8
  License: GPL-3.0
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.txt
26
  along with this program. If not, see <http://www.gnu.org/licenses/>.
27
  */
28
 
29
+ $fv_wp_flowplayer_ver = '6.5.1';
30
  $fv_wp_flowplayer_core_ver = '6.0.5';
31
  $fv_wp_flowplayer_core_ver_beta = '7.2.4';
32
 
flowplayer/fv-flowplayer.min.js CHANGED
@@ -1069,7 +1069,7 @@ function fv_player_track( ga_id, event, engineType, name){
1069
  return;
1070
  }
1071
 
1072
- if( typeof(engineType) == "undefined" ) engineType = 'Unknown';
1073
 
1074
  if( /fv_ga_debug/.test(window.location.href) ) console.log('FV GA: ' + event + ' - ' + engineType + " '" + name + "'")
1075
  tracker._setAllowLinker(true);
1069
  return;
1070
  }
1071
 
1072
+ if( typeof(engineType) == "undefined" ) engineType = 'Unknown engine';
1073
 
1074
  if( /fv_ga_debug/.test(window.location.href) ) console.log('FV GA: ' + event + ' - ' + engineType + " '" + name + "'")
1075
  tracker._setAllowLinker(true);
models/checker.php CHANGED
@@ -161,146 +161,141 @@ class FV_Player_Checker {
161
  if( function_exists('is_utf8') && is_utf8($remotefilename) ) {
162
  $video_errors[] = '<p><strong>UTF-8 error</strong>: Your file name is using non-latin characters, the file might not play in browsers using Flash for the video!</p>';
163
  }
 
 
 
 
 
164
 
165
- if( version_compare(phpversion(), '5.3.0', '<') && @ini_get('safe_mode') ) {
166
- $video_warnings[] = 'Detailed video check is not available with PHP Safe Mode On. Please contact your webhost support.';
167
  } else {
168
-
169
- if ( ! class_exists( 'getID3' ) ) {
170
- require( ABSPATH . WPINC . '/ID3/getid3.php' );
171
- }
172
- $getID3 = new getID3;
173
-
174
- if( !function_exists('curl_init') ) {
175
- $video_errors[] = 'cURL for PHP not found, please contact your server administrator.';
176
- } else {
177
- $message = '<p>Analysis of <a class="bluelink" target="_blank" href="'.esc_attr($remotefilename_encoded).'">'.$remotefilename_encoded.'</a></p>';
178
-
179
- // taken from: http://www.getid3.org/phpBB3/viewtopic.php?f=3&t=1141
180
- $upload_dir = wp_upload_dir();
181
- $localtempfilename = trailingslashit( $upload_dir['basedir'] ).'fv_flowlayer_tmp_'.md5(rand(1,999)).'_'.basename( substr($remotefilename_encoded,0,32) );
182
 
183
- $out = @fopen( $localtempfilename,'wb' );
184
-
185
- if( $out ) {
186
- $aArgs = array( 'file' => $out );
187
- if( !$this->is_cron ) {
188
- $aArgs['quick_check'] = apply_filters( 'fv_flowplayer_checker_timeout_quick', 2 );
189
- }
190
- list( $header, $sHTTPError ) = $this->http_request( $remotefilename_encoded, $aArgs );
191
 
192
- $video_errors = array();
193
- if( $sHTTPError ) {
194
- $video_errors[] = $sHTTPError;
 
 
 
 
 
 
 
 
 
195
  $bValidFile = false;
196
  }
197
- fclose($out);
198
-
199
- if( !$headers ) {
200
- $headers = WP_Http::processHeaders( $header );
201
-
202
- list( $aVideoErrors, $sContentType, $bFatal ) = $this->check_headers( $headers, $remotefilename, $random );
203
- if( $bFatal ) {
204
- $bValidFile = false;
205
- }
206
-
207
- if( $aVideoErrors ) {
208
- $video_errors = array_merge( $video_errors, $aVideoErrors );
209
- }
210
-
211
- if( isset($hearders['headers']['server']) && $hearders['headers']['server'] == 'AmazonS3' && $headers['response']['code'] == '403' ) {
212
- $error = new SimpleXMLElement($body);
213
-
214
- if( stripos( $error->Message, 'Request has expired' ) !== false ) {
215
- $video_errors[] = '<p><strong>Amazon S3</strong>: Your secure link is expired, there might be problem with your Amazon S3 plugin. Please test if the above URL opens in your browser.</p>';
216
- } else {
217
- $video_errors[] = '<p><strong>Amazon S3</strong>: '.$error->Message.'</p>';
218
- }
219
-
220
  }
 
221
  }
 
222
 
223
- if( $bValidFile ) {
224
- $ThisFileInfo = $getID3->analyze( $localtempfilename );
225
- }
226
- if( !@unlink($localtempfilename) ) {
227
- $video_errors[] = 'Can\'t remove temporary file for video analysis in <tt>'.$localtempfilename.'</tt>!';
228
- }
229
- } else {
230
- $video_errors[] = 'Can\'t create temporary file for video analysis in <tt>'.$localtempfilename.'</tt>!';
231
- }
 
 
 
 
 
 
 
 
 
 
 
232
  }
233
-
234
 
235
- /*
236
- Only check file length
237
- */
238
-
239
- if( isset($meta_action) && $meta_action == 'check_time' ) {
240
- $time = false;
241
- if( isset($ThisFileInfo) && isset($ThisFileInfo['playtime_seconds']) ) {
242
- $time = $ThisFileInfo['playtime_seconds'];
243
- }
244
-
245
 
246
-
247
- if(preg_match('/.m3u8(\?.*)?$/i', $meta_original)){
248
-
249
- remove_action( 'http_api_curl', array( 'FV_Player_Checker', 'http_api_curl' ) );
250
-
251
- $request = wp_remote_get($meta_original);
252
- $response = wp_remote_retrieve_body( $request );
253
 
254
- $playlist = false;
255
- $duration = 0;
256
- $segments = false;
257
 
258
- if(!preg_match_all('/^[^#].*\.m3u8(\?.*)?$/im', $response,$playlist)){
259
- if(preg_match_all('/^#EXTINF:([0-9]+\.?[0-9]*)/im', $response,$segments)){
 
 
 
 
 
 
 
 
 
 
260
  foreach($segments[1] as $segment_item){
261
  $duration += $segment_item;
262
  }
263
  }
264
- }else{
265
- foreach($playlist[0] as $item){
266
- $item_url = preg_replace('/[^\/]*\.m3u8(\?.*)?/i', $item, $meta_original);
267
- $request = wp_remote_get($item_url);
268
- $playlist_item = wp_remote_retrieve_body( $request );
269
- if(preg_match_all('/^#EXTINF:([0-9]+\.?[0-9]*)/im', $playlist_item,$segments)){
270
- foreach($segments[1] as $segment_item){
271
- $duration += $segment_item;
272
- }
273
- }
274
- if($duration > 0)
275
- break;
276
- }
277
  }
278
-
279
- $time = $duration;
280
  }
281
-
282
- $time = apply_filters( 'fv_flowplayer_checker_time', $time, $meta_original );
283
-
284
- global $post;
285
- $fv_flowplayer_meta = get_post_meta( $post->ID, flowplayer::get_video_key($meta_original), true );
286
- $fv_flowplayer_meta = ($fv_flowplayer_meta) ? $fv_flowplayer_meta : array();
287
- $fv_flowplayer_meta['duration'] = $time;
288
- $fv_flowplayer_meta['etag'] = isset($headers['headers']['etag']) ? $headers['headers']['etag'] : false; // todo: check!
289
- $fv_flowplayer_meta['date'] = time();
290
- $fv_flowplayer_meta['check_time'] = microtime(true) - $tStart;
291
 
292
- if( $time > 0 || $this->is_cron ) {
293
- update_post_meta( $post->ID, flowplayer::get_video_key($meta_original), $fv_flowplayer_meta );
294
- return true;
295
- }
296
- //} else {
297
- //self::queue_add($post->ID);
298
- //return false;
299
- //}
300
-
301
- }
302
-
303
- }
 
 
 
 
 
 
 
 
 
 
 
 
304
  } // end is_wp_error check
305
 
306
  } // end isset($media)
161
  if( function_exists('is_utf8') && is_utf8($remotefilename) ) {
162
  $video_errors[] = '<p><strong>UTF-8 error</strong>: Your file name is using non-latin characters, the file might not play in browsers using Flash for the video!</p>';
163
  }
164
+
165
+ if ( ! class_exists( 'getID3' ) ) {
166
+ require( ABSPATH . WPINC . '/ID3/getid3.php' );
167
+ }
168
+ $getID3 = new getID3;
169
 
170
+ if( !function_exists('curl_init') ) {
171
+ $video_errors[] = 'cURL for PHP not found, please contact your server administrator.';
172
  } else {
173
+ $message = '<p>Analysis of <a class="bluelink" target="_blank" href="'.esc_attr($remotefilename_encoded).'">'.$remotefilename_encoded.'</a></p>';
174
+
175
+ // taken from: http://www.getid3.org/phpBB3/viewtopic.php?f=3&t=1141
176
+ $upload_dir = wp_upload_dir();
177
+ $localtempfilename = trailingslashit( $upload_dir['basedir'] ).'fv_flowlayer_tmp_'.md5(rand(1,999)).'_'.basename( substr($remotefilename_encoded,0,32) );
 
 
 
 
 
 
 
 
 
178
 
179
+ $out = @fopen( $localtempfilename,'wb' );
180
+
181
+ if( $out ) {
182
+ $aArgs = array( 'file' => $out );
183
+ if( !$this->is_cron ) {
184
+ $aArgs['quick_check'] = apply_filters( 'fv_flowplayer_checker_timeout_quick', 2 );
185
+ }
186
+ list( $header, $sHTTPError ) = $this->http_request( $remotefilename_encoded, $aArgs );
187
 
188
+ $video_errors = array();
189
+ if( $sHTTPError ) {
190
+ $video_errors[] = $sHTTPError;
191
+ $bValidFile = false;
192
+ }
193
+ fclose($out);
194
+
195
+ if( !$headers ) {
196
+ $headers = WP_Http::processHeaders( $header );
197
+
198
+ list( $aVideoErrors, $sContentType, $bFatal ) = $this->check_headers( $headers, $remotefilename, $random );
199
+ if( $bFatal ) {
200
  $bValidFile = false;
201
  }
202
+
203
+ if( $aVideoErrors ) {
204
+ $video_errors = array_merge( $video_errors, $aVideoErrors );
205
+ }
206
+
207
+ if( isset($hearders['headers']['server']) && $hearders['headers']['server'] == 'AmazonS3' && $headers['response']['code'] == '403' ) {
208
+ $error = new SimpleXMLElement($body);
209
+
210
+ if( stripos( $error->Message, 'Request has expired' ) !== false ) {
211
+ $video_errors[] = '<p><strong>Amazon S3</strong>: Your secure link is expired, there might be problem with your Amazon S3 plugin. Please test if the above URL opens in your browser.</p>';
212
+ } else {
213
+ $video_errors[] = '<p><strong>Amazon S3</strong>: '.$error->Message.'</p>';
 
 
 
 
 
 
 
 
 
 
 
214
  }
215
+
216
  }
217
+ }
218
 
219
+ if( $bValidFile ) {
220
+ $ThisFileInfo = $getID3->analyze( $localtempfilename );
221
+ }
222
+ if( !@unlink($localtempfilename) ) {
223
+ $video_errors[] = 'Can\'t remove temporary file for video analysis in <tt>'.$localtempfilename.'</tt>!';
224
+ }
225
+ } else {
226
+ $video_errors[] = 'Can\'t create temporary file for video analysis in <tt>'.$localtempfilename.'</tt>!';
227
+ }
228
+ }
229
+
230
+
231
+ /*
232
+ Only check file length
233
+ */
234
+
235
+ if( isset($meta_action) && $meta_action == 'check_time' ) {
236
+ $time = false;
237
+ if( isset($ThisFileInfo) && isset($ThisFileInfo['playtime_seconds']) ) {
238
+ $time = $ThisFileInfo['playtime_seconds'];
239
  }
240
+
241
 
242
+
243
+ if(preg_match('/.m3u8(\?.*)?$/i', $meta_original)){
 
 
 
 
 
 
 
 
244
 
245
+ remove_action( 'http_api_curl', array( 'FV_Player_Checker', 'http_api_curl' ) );
246
+
247
+ $request = wp_remote_get($meta_original);
248
+ $response = wp_remote_retrieve_body( $request );
 
 
 
249
 
250
+ $playlist = false;
251
+ $duration = 0;
252
+ $segments = false;
253
 
254
+ if(!preg_match_all('/^[^#].*\.m3u8(\?.*)?$/im', $response,$playlist)){
255
+ if(preg_match_all('/^#EXTINF:([0-9]+\.?[0-9]*)/im', $response,$segments)){
256
+ foreach($segments[1] as $segment_item){
257
+ $duration += $segment_item;
258
+ }
259
+ }
260
+ }else{
261
+ foreach($playlist[0] as $item){
262
+ $item_url = preg_replace('/[^\/]*\.m3u8(\?.*)?/i', $item, $meta_original);
263
+ $request = wp_remote_get($item_url);
264
+ $playlist_item = wp_remote_retrieve_body( $request );
265
+ if(preg_match_all('/^#EXTINF:([0-9]+\.?[0-9]*)/im', $playlist_item,$segments)){
266
  foreach($segments[1] as $segment_item){
267
  $duration += $segment_item;
268
  }
269
  }
270
+ if($duration > 0)
271
+ break;
 
 
 
 
 
 
 
 
 
 
 
272
  }
 
 
273
  }
 
 
 
 
 
 
 
 
 
 
274
 
275
+ $time = $duration;
276
+ }
277
+
278
+ $time = apply_filters( 'fv_flowplayer_checker_time', $time, $meta_original );
279
+
280
+ global $post;
281
+ $fv_flowplayer_meta = get_post_meta( $post->ID, flowplayer::get_video_key($meta_original), true );
282
+ $fv_flowplayer_meta = ($fv_flowplayer_meta) ? $fv_flowplayer_meta : array();
283
+ $fv_flowplayer_meta['duration'] = $time;
284
+ $fv_flowplayer_meta['etag'] = isset($headers['headers']['etag']) ? $headers['headers']['etag'] : false; // todo: check!
285
+ $fv_flowplayer_meta['date'] = time();
286
+ $fv_flowplayer_meta['check_time'] = microtime(true) - $tStart;
287
+
288
+ if( $time > 0 || $this->is_cron ) {
289
+ update_post_meta( $post->ID, flowplayer::get_video_key($meta_original), $fv_flowplayer_meta );
290
+ return true;
291
+ }
292
+ //} else {
293
+ //self::queue_add($post->ID);
294
+ //return false;
295
+ //}
296
+
297
+ }
298
+
299
  } // end is_wp_error check
300
 
301
  } // end isset($media)
models/flowplayer-frontend.php CHANGED
@@ -1004,7 +1004,7 @@ class flowplayer_frontend extends flowplayer
1004
  $subtitles = trim($subtitles);
1005
  }
1006
 
1007
- $aSubtitles[str_replace( 'subtitles_', '', $key )] = $subtitles;
1008
 
1009
  }
1010
  }
1004
  $subtitles = trim($subtitles);
1005
  }
1006
 
1007
+ $aSubtitles[str_replace( 'subtitles_', '', $key )] = apply_filters( 'fv_flowplayer_resource', $subtitles );
1008
 
1009
  }
1010
  }
models/flowplayer.php CHANGED
@@ -972,35 +972,19 @@ class flowplayer extends FV_Wordpress_Flowplayer_Plugin {
972
 
973
  }
974
 
975
- $sPlaylistClass = 'fv-playlist-design-'.$this->_get_option('playlist-design');
976
 
977
- if( isset($aArgs['liststyle']) && in_array($this->aCurArgs['liststyle'], array('horizontal','slider') ) ) {
978
- $sPlaylistClass .= ' fp-playlist-horizontal';
979
- } else if( isset($aArgs['liststyle']) && $aArgs['liststyle'] == 'vertical' ){
980
- $sPlaylistClass .= ' fp-playlist-vertical';
981
- } else if( isset($aArgs['liststyle']) && $aArgs['liststyle'] == 'text' ){
982
- $sPlaylistClass = 'fp-playlist-vertical';
983
- }
984
- //var_dump($aCaptions);
985
- if( isset($aArgs['liststyle']) && $aArgs['liststyle'] == 'text' ){
986
- $sPlaylistClass .= ' fp-playlist-only-captions';
987
- } else if( isset($aArgs['liststyle']) && sizeof($aCaptions) > 0 && strlen(implode($aCaptions)) > 0 ){
988
- $sPlaylistClass .= ' fp-playlist-has-captions';
989
- }
990
-
991
- if(isset($aArgs['liststyle']) && $aArgs['liststyle'] != 'tabs'){
992
  $aPlaylistItems = apply_filters('fv_flowplayer_playlist_items',$aPlaylistItems,$this);
993
- }
994
-
995
 
996
 
997
  $sHTML = apply_filters( 'fv_flowplayer_playlist_item_html', $sHTML );
998
 
999
  $attributes = array();
1000
  $attributes_html = '';
1001
- $attributes['class'] = 'fp-playlist-external '.$sPlaylistClass;
1002
  $attributes['rel'] = 'wpfp_'.$this->hash;
1003
- if( isset($aArgs['liststyle']) && $this->aCurArgs['liststyle'] == 'slider' ) {
1004
  $attributes['style'] = "width: ".(count($aPlaylistItems)*201)."px";
1005
  }
1006
 
@@ -1844,6 +1828,27 @@ class flowplayer extends FV_Wordpress_Flowplayer_Plugin {
1844
  }
1845
 
1846
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1847
  public static function get_core_version() {
1848
  global $fv_wp_flowplayer_core_ver, $fv_wp_flowplayer_core_ver_beta;
1849
  return self::is_beta() ? $fv_wp_flowplayer_core_ver_beta : $fv_wp_flowplayer_core_ver;
972
 
973
  }
974
 
 
975
 
976
+ if(isset($this->aCurArgs['liststyle']) && $this->aCurArgs['liststyle'] != 'tabs'){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
977
  $aPlaylistItems = apply_filters('fv_flowplayer_playlist_items',$aPlaylistItems,$this);
978
+ }
 
979
 
980
 
981
  $sHTML = apply_filters( 'fv_flowplayer_playlist_item_html', $sHTML );
982
 
983
  $attributes = array();
984
  $attributes_html = '';
985
+ $attributes['class'] = 'fp-playlist-external '.$this->get_playlist_class($aCaptions);
986
  $attributes['rel'] = 'wpfp_'.$this->hash;
987
+ if( isset($this->aCurArgs['liststyle']) && $this->aCurArgs['liststyle'] == 'slider' ) {
988
  $attributes['style'] = "width: ".(count($aPlaylistItems)*201)."px";
989
  }
990
 
1828
  }
1829
 
1830
 
1831
+ public function get_playlist_class($aCaptions) {
1832
+ $sPlaylistClass = 'fv-playlist-design-'.$this->_get_option('playlist-design');
1833
+
1834
+ if( isset($this->aCurArgs['liststyle']) && in_array($this->aCurArgs['liststyle'], array('horizontal','slider') ) ) {
1835
+ $sPlaylistClass .= ' fp-playlist-horizontal';
1836
+ } else if( isset($this->aCurArgs['liststyle']) && $this->aCurArgs['liststyle'] == 'vertical' ){
1837
+ $sPlaylistClass .= ' fp-playlist-vertical';
1838
+ } else if( isset($this->aCurArgs['liststyle']) && $this->aCurArgs['liststyle'] == 'text' ){
1839
+ $sPlaylistClass = 'fp-playlist-vertical';
1840
+ }
1841
+ //var_dump($aCaptions);
1842
+ if( isset($this->aCurArgs['liststyle']) && $this->aCurArgs['liststyle'] == 'text' ){
1843
+ $sPlaylistClass .= ' fp-playlist-only-captions';
1844
+ } else if( isset($this->aCurArgs['liststyle']) && sizeof($aCaptions) > 0 && strlen(implode($aCaptions)) > 0 ){
1845
+ $sPlaylistClass .= ' fp-playlist-has-captions';
1846
+ }
1847
+
1848
+ return $sPlaylistClass;
1849
+ }
1850
+
1851
+
1852
  public static function get_core_version() {
1853
  global $fv_wp_flowplayer_core_ver, $fv_wp_flowplayer_core_ver_beta;
1854
  return self::is_beta() ? $fv_wp_flowplayer_core_ver_beta : $fv_wp_flowplayer_core_ver;
models/lightbox.php CHANGED
@@ -113,6 +113,17 @@ class FV_Player_lightbox {
113
  }
114
  }
115
 
 
 
 
 
 
 
 
 
 
 
 
116
  function lightbox_html($html) {
117
  $aArgs = func_get_args();
118
 
@@ -126,18 +137,10 @@ class FV_Player_lightbox {
126
 
127
  $iPlayerWidth = ( isset($aArgs[1]->aCurArgs['width']) && intval($aArgs[1]->aCurArgs['width']) > 0 ) ? intval($aArgs[1]->aCurArgs['width']) : $iConfWidth;
128
  $iPlayerHeight = ( isset($aArgs[1]->aCurArgs['height']) && intval($aArgs[1]->aCurArgs['height']) > 0 ) ? intval($aArgs[1]->aCurArgs['height']) : $iConfHeight;
 
 
129
 
130
- $aLightbox = preg_split('~[;]~', $aArgs[1]->aCurArgs['lightbox']);
131
-
132
- $bUseAnchor = false;
133
- foreach ($aLightbox AS $k => $i) {
134
- if ($i == 'text') {
135
- unset($aLightbox[$k]);
136
- $bUseAnchor = true;
137
- }
138
- }
139
-
140
- if ($bUseAnchor) {
141
  $html = str_replace(array('class="flowplayer ', "class='flowplayer "), array('class="flowplayer lightboxed ', "class='flowplayer lightboxed "), $html);
142
  $this->lightboxHtml .= "<div style='display: none'>\n" . $html . "</div>\n";
143
  $html = "<a id='fv_flowplayer_" . $aArgs[1]->hash . "_lightbox_starter' href=\"#\" data-fv-lightbox='#wpfp_" . $aArgs[1]->hash . "'>" . $aArgs[1]->aCurArgs['caption'] . "</a>";
@@ -181,14 +184,14 @@ class FV_Player_lightbox {
181
  return $html;
182
  }
183
 
184
- function lightbox_playlist($output, $aCurArgs, $aPlaylistItems, $aSplashScreens, $aCaptions) {
185
-
186
  if ($output || empty($aCurArgs['lightbox']) || !count($aPlaylistItems) || count($aPlaylistItems) == 1 ) {
187
  return $output;
188
  }
189
-
190
  global $FV_Player_Pro;
191
- if( count($FV_Player_Pro->bVideoAdsStatus) ) return $output;
192
 
193
  global $fv_fp;
194
  $output = array();
@@ -203,20 +206,37 @@ class FV_Player_lightbox {
203
  $aCurArgs['src'] = $aSrc['sources'][0]['src']; // todo: remaining sources!
204
  $aCurArgs['splash'] = isset($aSplashScreens[$key]) ? $aSplashScreens[$key] : false;
205
  $aCurArgs['caption'] = isset($aCaptions[$key]) ? $aCaptions[$key] : false;
 
 
206
 
207
  $aPlayer = $fv_fp->build_min_player($aCurArgs['src'], $aCurArgs);
208
 
209
- if ($i == 1) {
210
- $output['html'] .= $aPlayer['html'];
211
- $output['html'] .= "<div class='fp-playlist-external'>";
212
- }
213
-
214
- $aPlayerParts = explode("<div class='fv_player_lightbox_hidden'", $aPlayer['html']);
215
- $id = $i == 1 ? "_2_lightbox_starter" : "_lightbox_starter";
216
- $output['html'] .= "<a id='fv_flowplayer_" . $fv_fp->hash. $id . "' href='#' data-fv-lightbox='#wpfp_" . $fv_fp->hash . "'><span style=\"background-image: url('" . $fv_fp->aCurArgs['splash'] . "')\"></span>" . $fv_fp->aCurArgs['caption'] . "</a>";
217
-
218
- if ($i > 1) {
219
- $after .= "<div class='fv_player_lightbox_hidden'" . $aPlayerParts[1];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  }
221
 
222
  if ($i == count($aPlaylistItems)) {
@@ -227,9 +247,13 @@ class FV_Player_lightbox {
227
  $output['script'][$key2] = array_merge(isset($output['script'][$key2]) ? $output['script'][$key2] : array(), $aPlayer['script'][$key2]);
228
  }
229
  }
 
 
 
 
230
 
231
  $output['html'] .= $after;
232
-
233
  return $output;
234
  }
235
 
@@ -347,6 +371,16 @@ class FV_Player_lightbox {
347
  }
348
  return $aArgs;
349
  }
 
 
 
 
 
 
 
 
 
 
350
 
351
  function parse_html_caption( $aArgs ) {
352
  if( isset($aArgs['caption_html']) && $aArgs['caption_html'] ) {
@@ -479,4 +513,5 @@ class FV_Player_lightbox {
479
 
480
  }
481
 
 
482
  $FV_Player_lightbox = new FV_Player_lightbox();
113
  }
114
  }
115
 
116
+ function is_text_lightbox($aArgs) {
117
+ $aLightbox = preg_split('~[;]~', $aArgs['lightbox']);
118
+
119
+ foreach ($aLightbox AS $k => $i) {
120
+ if ($i == 'text') {
121
+ return true;
122
+ }
123
+ }
124
+ return false;
125
+ }
126
+
127
  function lightbox_html($html) {
128
  $aArgs = func_get_args();
129
 
137
 
138
  $iPlayerWidth = ( isset($aArgs[1]->aCurArgs['width']) && intval($aArgs[1]->aCurArgs['width']) > 0 ) ? intval($aArgs[1]->aCurArgs['width']) : $iConfWidth;
139
  $iPlayerHeight = ( isset($aArgs[1]->aCurArgs['height']) && intval($aArgs[1]->aCurArgs['height']) > 0 ) ? intval($aArgs[1]->aCurArgs['height']) : $iConfHeight;
140
+
141
+ $aLightbox = $this->parse_args($aArgs[1]->aCurArgs);
142
 
143
+ if ( $this->is_text_lightbox($aArgs[1]->aCurArgs) ) {
 
 
 
 
 
 
 
 
 
 
144
  $html = str_replace(array('class="flowplayer ', "class='flowplayer "), array('class="flowplayer lightboxed ', "class='flowplayer lightboxed "), $html);
145
  $this->lightboxHtml .= "<div style='display: none'>\n" . $html . "</div>\n";
146
  $html = "<a id='fv_flowplayer_" . $aArgs[1]->hash . "_lightbox_starter' href=\"#\" data-fv-lightbox='#wpfp_" . $aArgs[1]->hash . "'>" . $aArgs[1]->aCurArgs['caption'] . "</a>";
184
  return $html;
185
  }
186
 
187
+ function lightbox_playlist($output, $aCurArgs, $aPlaylistItems, $aSplashScreens, $aCaptions) {
188
+
189
  if ($output || empty($aCurArgs['lightbox']) || !count($aPlaylistItems) || count($aPlaylistItems) == 1 ) {
190
  return $output;
191
  }
192
+
193
  global $FV_Player_Pro;
194
+ if( !empty($FV_Player_Pro) && count($FV_Player_Pro->bVideoAdsStatus) ) return $output;
195
 
196
  global $fv_fp;
197
  $output = array();
206
  $aCurArgs['src'] = $aSrc['sources'][0]['src']; // todo: remaining sources!
207
  $aCurArgs['splash'] = isset($aSplashScreens[$key]) ? $aSplashScreens[$key] : false;
208
  $aCurArgs['caption'] = isset($aCaptions[$key]) ? $aCaptions[$key] : false;
209
+
210
+ $aCurArgs['liststyle'] = 'horizontal'; // it's the only safe choice!
211
 
212
  $aPlayer = $fv_fp->build_min_player($aCurArgs['src'], $aCurArgs);
213
 
214
+ if ( $this->is_text_lightbox($aCurArgs) ) {
215
+ if ($i == 1) {
216
+ $output['html'] .= "<li>".$aPlayer['html']."</li>";
217
+ }
218
+
219
+ if( $i > 1 ) {
220
+ $output['html'] .= "<li><a id='fv_flowplayer_lightbox_starter' href='#' data-fv-lightbox='#wpfp_" . $fv_fp->hash . "'>" . $fv_fp->aCurArgs['caption'] . "</a></li>";
221
+ }
222
+
223
+ } else {
224
+ if ($i == 1) {
225
+ $output['html'] .= $aPlayer['html'];
226
+ $output['html'] .= "<div class='fp-playlist-external ".$fv_fp->get_playlist_class($aCaptions)."'>";
227
+ }
228
+
229
+ $aPlayerParts = explode("<div class='fv_player_lightbox_hidden'", $aPlayer['html']);
230
+ if( $i == 1 ) {
231
+ $output['html'] .= "<a id='fv_flowplayer_lightbox_placeholder' href='#' onclick='document.getElementById(\"fv_flowplayer_" . $fv_fp->hash . "_lightbox_starter\").click(); return false'><div style=\"background-image: url('" . $fv_fp->aCurArgs['splash'] . "')\"></div><h4><span>" . $fv_fp->aCurArgs['caption'] . "</span></h4></a>";
232
+ } else {
233
+ $output['html'] .= "<a id='fv_flowplayer_lightbox_starter' href='#' data-fv-lightbox='#wpfp_" . $fv_fp->hash . "'><div style=\"background-image: url('" . $fv_fp->aCurArgs['splash'] . "')\"></div><h4><span>" . $fv_fp->aCurArgs['caption'] . "</span></h4></a>";
234
+ }
235
+
236
+ if ($i > 1) {
237
+ $after .= "<div class='fv_player_lightbox_hidden'" . $aPlayerParts[1];
238
+ }
239
+
240
  }
241
 
242
  if ($i == count($aPlaylistItems)) {
247
  $output['script'][$key2] = array_merge(isset($output['script'][$key2]) ? $output['script'][$key2] : array(), $aPlayer['script'][$key2]);
248
  }
249
  }
250
+
251
+ if ( $this->is_text_lightbox($aCurArgs) ) {
252
+ $output['html'] = "<ul>".$output['html']."</ul>";
253
+ }
254
 
255
  $output['html'] .= $after;
256
+
257
  return $output;
258
  }
259
 
371
  }
372
  return $aArgs;
373
  }
374
+
375
+ function parse_args( $aArgs ) {
376
+ foreach ($aArgs AS $k => $i) {
377
+ if ($i == 'text') {
378
+ unset($aArgs[$k]);
379
+ $bUseAnchor = true;
380
+ }
381
+ }
382
+ return $aArgs;
383
+ }
384
 
385
  function parse_html_caption( $aArgs ) {
386
  if( isset($aArgs['caption_html']) && $aArgs['caption_html'] ) {
513
 
514
  }
515
 
516
+ global $FV_Player_lightbox;
517
  $FV_Player_lightbox = new FV_Player_lightbox();
readme.txt CHANGED
@@ -356,6 +356,15 @@ Thank you for being part of the HMTL 5 mobile video revolution!
356
 
357
  == Changelog ==
358
 
 
 
 
 
 
 
 
 
 
359
  = 6.5 - 2018/03/14 =
360
 
361
  * New feature - Video position saving for both guest and logged in users - see Settings -> FV Player -> Sidewide Flowplayer Defaults -> Remember video position
356
 
357
  == Changelog ==
358
 
359
+ = 6.5.1 - 2018/04/04 =
360
+
361
+ * Amazon S3 - Adding URL signature for subtitles
362
+ * CSS - Responsive sizing of subtitles in fullscreen mode for large retina displays
363
+ * Bugfix - Google Analytics - fixing label of "Unknown" to say "Unknown engine" which occurs when the video fails to play before engines are initialized
364
+ * Bugfix - Lightbox - when used for playlist the first item was appearing twice in the lightbox view
365
+ * Bugfix - Lightbox - when using the "text" lightbox with playlist it was rendering the playlist items as thumbnails
366
+ * Bugfix - Lightbox - stopping the playlist styles from interfering - forcing horizontal playlist style for lightboxed playlist
367
+
368
  = 6.5 - 2018/03/14 =
369
 
370
  * New feature - Video position saving for both guest and logged in users - see Settings -> FV Player -> Sidewide Flowplayer Defaults -> Remember video position
test/integration/frontend/{shortcodesTest.php → 1-shortcodesTest.php} RENAMED
File without changes
test/integration/frontend/shortcodesLightboxTest.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once( dirname(__FILE__).'/../fv-player-unittest-case.php');
4
+
5
+ /**
6
+ * Tests WordPress integration of playlists without any advertisements present
7
+ * in the HTML markup.
8
+ */
9
+ final class FV_Player_ShortcodeLightboxTestCase extends FV_Player_UnitTestCase {
10
+
11
+ public function setUp() {
12
+ parent::setUp();
13
+
14
+ $shortcode_body = 'src="https://cdn.site.com/video1.mp4" splash="https://cdn.site.com/video1.jpg" playlist="https://cdn.site.com/video2.mp4,https://cdn.site.com/video2.jpg;https://cdn.site.com/video3.mp4,https://cdn.site.com/video3.jpg" caption="Video 1;Video 2; Video 3" share="no" embed="false"';
15
+
16
+ $this->playlist_lightbox = $this->factory->post->create( array(
17
+ 'post_content' => '[fvplayer '.$shortcode_body.' lightbox="true"]'
18
+ ) );
19
+
20
+ $this->playlist_lightbox_with_style = $this->factory->post->create( array(
21
+ 'post_content' => '[fvplayer '.$shortcode_body.' lightbox="true" liststyle="slider"]' // should make no difference!
22
+ ) );
23
+
24
+ $this->playlist_lightbox_text = $this->factory->post->create( array(
25
+ 'post_content' => '[fvplayer '.$shortcode_body.' lightbox="true;text"]'
26
+ ) );
27
+
28
+ }
29
+
30
+ public function testPlaylistLightboxShortcode() {
31
+ global $post;
32
+
33
+ $post = get_post( $this->playlist_lightbox );
34
+ $output = apply_filters( 'the_content', $post->post_content );
35
+
36
+ $sample = <<< HTML
37
+ <div id='fv_flowplayer_5d2ac904592b20b5bf87a2a85df7ace7_lightbox_starter' href='#wpfp_5d2ac904592b20b5bf87a2a85df7ace7' class='flowplayer lightbox-starter is-splash' style="max-width: 640px; max-height: 360px; background-image: url('https://cdn.site.com/video1.jpg')" data-ratio="0.5625"><div class='fp-ui'></div><div class="fp-ratio" style="padding-top: 56.25%"></div></div>
38
+ <div class='fv_player_lightbox_hidden' style='display: none'>
39
+ <div id="wpfp_5d2ac904592b20b5bf87a2a85df7ace7" data-item="{&quot;sources&quot;:[{&quot;src&quot;:&quot;https:\/\/cdn.site.com\/video1.mp4&quot;,&quot;type&quot;:&quot;video\/mp4&quot;}]}" class="flowplayer lightboxed no-brand is-splash fvp-play-button has-caption" data-embed="false" style="max-width: 640px; max-height: 360px; background-image: url(https://cdn.site.com/video1.jpg);" data-ratio="0.5625">
40
+ <div class="fp-ratio" style="padding-top: 56.25%"></div>
41
+
42
+ </div>
43
+ <p class='fp-caption'>Video 1</p></div><div class='fp-playlist-external fv-playlist-design-2017 fp-playlist-horizontal fp-playlist-has-captions'><a id='fv_flowplayer_lightbox_placeholder' href='#' onclick='document.getElementById("fv_flowplayer_5d2ac904592b20b5bf87a2a85df7ace7_lightbox_starter").click(); return false'><div style="background-image: url('https://cdn.site.com/video1.jpg')"></div><h4><span>Video 1</span></h4></a><a id='fv_flowplayer_lightbox_starter' href='#' data-fv-lightbox='#wpfp_e802b17ebbace952275cd50709bf549b'><div style="background-image: url('https://cdn.site.com/video2.jpg')"></div><h4><span>Video 2</span></h4></a><a id='fv_flowplayer_lightbox_starter' href='#' data-fv-lightbox='#wpfp_2ffbd4e84c1ecf2e00db5edf98996de3'><div style="background-image: url('https://cdn.site.com/video3.jpg')"></div><h4><span> Video 3</span></h4></a></div><div class='fv_player_lightbox_hidden' style='display: none'>
44
+ <div id="wpfp_e802b17ebbace952275cd50709bf549b" data-item="{&quot;sources&quot;:[{&quot;src&quot;:&quot;https:\/\/cdn.site.com\/video2.mp4&quot;,&quot;type&quot;:&quot;video\/mp4&quot;}]}" class="flowplayer lightboxed no-brand is-splash fvp-play-button has-caption" data-embed="false" style="max-width: 640px; max-height: 360px; background-image: url(https://cdn.site.com/video2.jpg);" data-ratio="0.5625">
45
+ <div class="fp-ratio" style="padding-top: 56.25%"></div>
46
+
47
+ </div>
48
+ <p class='fp-caption'>Video 2</p></div><div class='fv_player_lightbox_hidden' style='display: none'>
49
+ <div id="wpfp_2ffbd4e84c1ecf2e00db5edf98996de3" data-item="{&quot;sources&quot;:[{&quot;src&quot;:&quot;https:\/\/cdn.site.com\/video3.mp4&quot;,&quot;type&quot;:&quot;video\/mp4&quot;}]}" class="flowplayer lightboxed no-brand is-splash fvp-play-button has-caption" data-embed="false" style="max-width: 640px; max-height: 360px; background-image: url(https://cdn.site.com/video3.jpg);" data-ratio="0.5625">
50
+ <div class="fp-ratio" style="padding-top: 56.25%"></div>
51
+
52
+ </div>
53
+ <p class='fp-caption'> Video 3</p></div>
54
+ HTML;
55
+
56
+ $this->assertEquals( $this->fix_newlines($sample), $this->fix_newlines($output) );
57
+
58
+
59
+ $post = get_post( $this->playlist_lightbox_with_style );
60
+ $output = apply_filters( 'the_content', $post->post_content );
61
+ $this->assertEquals( $this->fix_newlines($sample), $this->fix_newlines($output) );
62
+
63
+
64
+ $post = get_post( $this->playlist_lightbox_text );
65
+ $output = apply_filters( 'the_content', $post->post_content );
66
+ $sample = <<< HTML
67
+ <ul><li><a id='fv_flowplayer_b721d6e309a0b856f27cc5ffe3f64c19_lightbox_starter' href="#" data-fv-lightbox='#wpfp_b721d6e309a0b856f27cc5ffe3f64c19'>Video 1</a></li><li><a id='fv_flowplayer_lightbox_starter' href='#' data-fv-lightbox='#wpfp_f7e1bf7ee8d12a2bf3bc4f148cdd718c'>Video 2</a></li><li><a id='fv_flowplayer_lightbox_starter' href='#' data-fv-lightbox='#wpfp_d0ecb746d43cfeca15296bd46c0dee3c'> Video 3</a></li></div></ul>
68
+ HTML;
69
+ $this->assertEquals( $this->fix_newlines($sample), $this->fix_newlines($output) );
70
+
71
+
72
+ ob_start();
73
+ do_action('wp_footer');
74
+ $footer = ob_get_clean();
75
+
76
+ global $FV_Player_lightbox;
77
+ ob_start();
78
+ $FV_Player_lightbox->disp__lightboxed_players();
79
+ $find = ob_get_clean();
80
+
81
+ $this->assertTrue( stripos($footer,$find) !== false ); // are the lightboxed players in the footer?
82
+ $this->assertTrue( $FV_Player_lightbox->bLoad ); // is the flag to load lightbox JS set?
83
+ }
84
+
85
+ public function tearDown() {
86
+ global $FV_Player_lightbox;
87
+ $FV_Player_lightbox = false;
88
+ $FV_Player_lightbox = new FV_Player_lightbox(); // reset the lightbox loading flag and footer lightboxed players HTML
89
+
90
+ parent::tearDown();
91
+ }
92
+
93
+ }
test/integration/frontend/shortcodesPlaylistTest.php ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once( dirname(__FILE__).'/../fv-player-unittest-case.php');
4
+
5
+ /**
6
+ * Tests WordPress integration of playlists without any advertisements present
7
+ * in the HTML markup.
8
+ */
9
+ final class FV_Player_ShortcodePlaylistTestCase extends FV_Player_UnitTestCase {
10
+
11
+ public function setUp() {
12
+ parent::setUp();
13
+
14
+ $shortcode_body = 'src="https://cdn.site.com/video1.mp4" splash="https://cdn.site.com/video1.jpg" playlist="https://cdn.site.com/video2.mp4,https://cdn.site.com/video2.jpg;https://cdn.site.com/video3.mp4,https://cdn.site.com/video3.jpg" caption="Video 1;Video 2; Video 3" share="no" embed="false"';
15
+
16
+ // create a post with playlist shortcode
17
+ $this->playlist_default = $this->factory->post->create( array(
18
+ 'post_content' => '[fvplayer '.$shortcode_body.']'
19
+ ) );
20
+
21
+ $this->playlist_vertical = $this->factory->post->create( array(
22
+ 'post_content' => '[fvplayer '.$shortcode_body.' liststyle="vertical"]'
23
+ ) );
24
+
25
+ $this->playlist_tabs = $this->factory->post->create( array(
26
+ 'post_content' => '[fvplayer '.$shortcode_body.' liststyle="tabs"]'
27
+ ) );
28
+
29
+ $this->playlist_prevnext = $this->factory->post->create( array(
30
+ 'post_content' => '[fvplayer '.$shortcode_body.' liststyle="prevnext"]'
31
+ ) );
32
+
33
+ $this->playlist_slider = $this->factory->post->create( array(
34
+ 'post_content' => '[fvplayer '.$shortcode_body.' liststyle="slider"]'
35
+ ) );
36
+
37
+ }
38
+
39
+ public function testPlaylistStyleShortcode() {
40
+ global $post;
41
+
42
+ $post = get_post( $this->playlist_default );
43
+ $output = apply_filters( 'the_content', $post->post_content );
44
+
45
+ $sample = <<< HTML
46
+ <div id="wpfp_10ecd1d835d0db002906d6666d27a916" class="flowplayer no-brand is-splash fvp-play-button" data-embed="false" style="background-image: url(https://cdn.site.com/video1.jpg);" data-ratio="0.5625">
47
+ <div class="fp-ratio" style="padding-top: 56.25%"></div>
48
+ </div>
49
+ <div class="fp-playlist-external fv-playlist-design-2017 fp-playlist-horizontal fp-playlist-has-captions" rel="wpfp_10ecd1d835d0db002906d6666d27a916">
50
+ <a href='#' onclick='return false' data-item='{"sources":[{"src":"https:\/\/cdn.site.com\/video1.mp4","type":"video\/mp4"}]}'><div style='background-image: url("https://cdn.site.com/video1.jpg")'></div><h4><span>Video 1</span></h4></a>
51
+ <a href='#' onclick='return false' data-item='{"sources":[{"src":"https:\/\/cdn.site.com\/video2.mp4","type":"video\/mp4"}]}'><div style='background-image: url("https://cdn.site.com/video2.jpg")'></div><h4><span>Video 2</span></h4></a>
52
+ <a href='#' onclick='return false' data-item='{"sources":[{"src":"https:\/\/cdn.site.com\/video3.mp4","type":"video\/mp4"}]}'><div style='background-image: url("https://cdn.site.com/video3.jpg")'></div><h4><span> Video 3</span></h4></a>
53
+ </div>
54
+ HTML;
55
+
56
+ $this->assertEquals( $this->fix_newlines($sample), $this->fix_newlines($output) );
57
+
58
+
59
+ $post = get_post( $this->playlist_vertical );
60
+ $output = apply_filters( 'the_content', $post->post_content );
61
+
62
+ $sample = <<< HTML
63
+ <div class="fp-playlist-vertical-wrapper"><div id="wpfp_10ecd1d835d0db002906d6666d27a916" class="flowplayer no-brand is-splash fvp-play-button" data-embed="false" style="background-image: url(https://cdn.site.com/video1.jpg);" data-ratio="0.5625">
64
+ <div class="fp-ratio" style="padding-top: 56.25%"></div>
65
+ </div>
66
+ <div class="fp-playlist-external fv-playlist-design-2017 fp-playlist-vertical fp-playlist-has-captions" rel="wpfp_10ecd1d835d0db002906d6666d27a916">
67
+ <a href='#' onclick='return false' data-item='{"sources":[{"src":"https:\/\/cdn.site.com\/video1.mp4","type":"video\/mp4"}]}'><div style='background-image: url("https://cdn.site.com/video1.jpg")'></div><h4><span>Video 1</span></h4></a>
68
+ <a href='#' onclick='return false' data-item='{"sources":[{"src":"https:\/\/cdn.site.com\/video2.mp4","type":"video\/mp4"}]}'><div style='background-image: url("https://cdn.site.com/video2.jpg")'></div><h4><span>Video 2</span></h4></a>
69
+ <a href='#' onclick='return false' data-item='{"sources":[{"src":"https:\/\/cdn.site.com\/video3.mp4","type":"video\/mp4"}]}'><div style='background-image: url("https://cdn.site.com/video3.jpg")'></div><h4><span> Video 3</span></h4></a>
70
+ </div>
71
+ </div>
72
+ HTML;
73
+
74
+ $this->assertEquals( $this->fix_newlines($sample), $this->fix_newlines($output) );
75
+
76
+
77
+ $post = get_post( $this->playlist_prevnext );
78
+ $output = apply_filters( 'the_content', $post->post_content );
79
+
80
+ $sample = <<< HTML
81
+ <div id="wpfp_10ecd1d835d0db002906d6666d27a916" class="flowplayer no-brand is-splash fvp-play-button" data-embed="false" style="background-image: url(https://cdn.site.com/video1.jpg);" data-ratio="0.5625">
82
+ <div class="fp-ratio" style="padding-top: 56.25%"></div>
83
+ <a class="fp-prev" title="prev">&lt;</a><a class="fp-next" title="next">&gt;</a></div>
84
+ <div style="display: none" class="fp-playlist-external fv-playlist-design-2017 fp-playlist-has-captions" rel="wpfp_10ecd1d835d0db002906d6666d27a916">
85
+ <a href='#' onclick='return false' data-item='{"sources":[{"src":"https:\/\/cdn.site.com\/video1.mp4","type":"video\/mp4"}]}'><div style='background-image: url("https://cdn.site.com/video1.jpg")'></div><h4><span>Video 1</span></h4></a>
86
+ <a href='#' onclick='return false' data-item='{"sources":[{"src":"https:\/\/cdn.site.com\/video2.mp4","type":"video\/mp4"}]}'><div style='background-image: url("https://cdn.site.com/video2.jpg")'></div><h4><span>Video 2</span></h4></a>
87
+ <a href='#' onclick='return false' data-item='{"sources":[{"src":"https:\/\/cdn.site.com\/video3.mp4","type":"video\/mp4"}]}'><div style='background-image: url("https://cdn.site.com/video3.jpg")'></div><h4><span> Video 3</span></h4></a>
88
+ </div>
89
+ HTML;
90
+
91
+ $this->assertEquals( $this->fix_newlines($sample), $this->fix_newlines($output) );
92
+
93
+
94
+ $post = get_post( $this->playlist_slider );
95
+ $output = apply_filters( 'the_content', $post->post_content );
96
+
97
+ $sample = <<< HTML
98
+ <div id="wpfp_10ecd1d835d0db002906d6666d27a916" class="flowplayer no-brand is-splash fvp-play-button" data-embed="false" style="background-image: url(https://cdn.site.com/video1.jpg);" data-ratio="0.5625">
99
+ <div class="fp-ratio" style="padding-top: 56.25%"></div>
100
+ </div>
101
+ <div class='fv-playlist-slider-wrapper'><div class="fp-playlist-external fv-playlist-design-2017 fp-playlist-horizontal fp-playlist-has-captions" rel="wpfp_10ecd1d835d0db002906d6666d27a916" style="width: 603px">
102
+ <a href='#' onclick='return false' data-item='{"sources":[{"src":"https:\/\/cdn.site.com\/video1.mp4","type":"video\/mp4"}]}'><div style='background-image: url("https://cdn.site.com/video1.jpg")'></div><h4><span>Video 1</span></h4></a>
103
+ <a href='#' onclick='return false' data-item='{"sources":[{"src":"https:\/\/cdn.site.com\/video2.mp4","type":"video\/mp4"}]}'><div style='background-image: url("https://cdn.site.com/video2.jpg")'></div><h4><span>Video 2</span></h4></a>
104
+ <a href='#' onclick='return false' data-item='{"sources":[{"src":"https:\/\/cdn.site.com\/video3.mp4","type":"video\/mp4"}]}'><div style='background-image: url("https://cdn.site.com/video3.jpg")'></div><h4><span> Video 3</span></h4></a>
105
+ </div>
106
+ </div>
107
+ HTML;
108
+
109
+ $this->assertEquals( $this->fix_newlines($sample), $this->fix_newlines($output) );
110
+ }
111
+
112
+ public function testPlaylistTabsShortcode() {
113
+ global $post;
114
+
115
+ $post = get_post( $this->playlist_tabs );
116
+ $output = apply_filters( 'the_content', $post->post_content );
117
+
118
+ $sample = <<< HTML
119
+ <script>document.body.className += " fv_flowplayer_tabs_hide";</script><div class="fv_flowplayer_tabs tabs woocommerce-tabs" style="max-width: 640px"><div id="tabs-10-1" class="fv_flowplayer_tabs_content"><ul><li><a href="#tabs-10-1-0">Video 1</a></li><li><a href="#tabs-10-1-1">Video 2</a></li><li><a href="#tabs-10-1-2"> Video 3</a></li></ul><div class="fv_flowplayer_tabs_cl"></div><div id="tabs-10-1-0" class="fv_flowplayer_tabs_first"><div id="wpfp_5d697f461a6a69e41882ec0212d63d1f" data-item="{&quot;sources&quot;:[{&quot;src&quot;:&quot;https:\/\/cdn.site.com\/video1.mp4&quot;,&quot;type&quot;:&quot;video\/mp4&quot;}]}" class="flowplayer no-brand is-splash fvp-play-button" data-embed="false" style="max-width: 640px; max-height: 360px; background-image: url(https://cdn.site.com/video1.jpg);" data-ratio="0.5625">
120
+ <div class="fp-ratio" style="padding-top: 56.25%"></div>
121
+
122
+ </div>
123
+ </div><div id="tabs-10-1-1"><div id="wpfp_f31738e686c3bdae67dfd7e57dec3d8c" data-item="{&quot;sources&quot;:[{&quot;src&quot;:&quot;https:\/\/cdn.site.com\/video2.mp4&quot;,&quot;type&quot;:&quot;video\/mp4&quot;}]}" class="flowplayer no-brand is-splash fvp-play-button" data-embed="false" style="max-width: 640px; max-height: 360px; background-image: url(https://cdn.site.com/video2.jpg);" data-ratio="0.5625">
124
+ <div class="fp-ratio" style="padding-top: 56.25%"></div>
125
+
126
+ </div>
127
+ </div><div id="tabs-10-1-2"><div id="wpfp_0dfbb08c099beb557be57907b1c01eb2" data-item="{&quot;sources&quot;:[{&quot;src&quot;:&quot;https:\/\/cdn.site.com\/video3.mp4&quot;,&quot;type&quot;:&quot;video\/mp4&quot;}]}" class="flowplayer no-brand is-splash fvp-play-button" data-embed="false" style="max-width: 640px; max-height: 360px; background-image: url(https://cdn.site.com/video3.jpg);" data-ratio="0.5625">
128
+ <div class="fp-ratio" style="padding-top: 56.25%"></div>
129
+
130
+ </div>
131
+ </div><div class="fv_flowplayer_tabs_cl"></div><div class="fv_flowplayer_tabs_cr"></div></div></div>
132
+ HTML;
133
+
134
+ $this->assertEquals( $this->fix_newlines($sample), $this->fix_newlines($output) );
135
+
136
+
137
+ global $fv_fp;
138
+ $this->assertTrue( $fv_fp->load_tabs );
139
+ }
140
+
141
+ public function tearDown() {
142
+ global $fv_fp, $FV_Player_lightbox;
143
+ $fv_fp->load_tabs = false;
144
+ $FV_Player_lightbox = new FV_Player_lightbox(); // reset the lightbox loading flag and footer lightboxed players HTML
145
+
146
+ parent::tearDown();
147
+ }
148
+
149
+ }
test/integration/fv-player-ajax-unittest-case.php CHANGED
@@ -9,6 +9,11 @@ abstract class FV_Player_Ajax_UnitTestCase extends WP_Ajax_UnitTestCase {
9
 
10
  global $fv_fp;
11
  $this->restore = $fv_fp->conf;
 
 
 
 
 
12
  }
13
 
14
  public function fix_newlines( $html ) {
@@ -21,8 +26,16 @@ abstract class FV_Player_Ajax_UnitTestCase extends WP_Ajax_UnitTestCase {
21
  $html = preg_replace( '~fv_vimeo_[a-z0-9]+~', 'fv_vimeo_XYZ', $html);
22
  $html = preg_replace( '~<input type="hidden" id="fv-player-custom-videos-_fv_player_user_video-0" name="fv-player-custom-videos-_fv_player_user_video-0" value="[^"]*?" />~', '<input type="hidden" id="fv-player-custom-videos-_fv_player_user_video-0" name="fv-player-custom-videos-_fv_player_user_video-0" value="XYZ" />', $html);
23
 
 
 
 
24
  $html = explode("\n",$html);
 
 
 
25
  $html = implode( "\n", array_map('trim',$html) );
 
 
26
  return $html;
27
  }
28
 
9
 
10
  global $fv_fp;
11
  $this->restore = $fv_fp->conf;
12
+
13
+ // somehow this got hooked in again after being removed in WP_Ajax_UnitTestCase::setUpBeforeClass() already
14
+ remove_action( 'admin_init', '_maybe_update_core' );
15
+ remove_action( 'admin_init', '_maybe_update_plugins' );
16
+ remove_action( 'admin_init', '_maybe_update_themes' );
17
  }
18
 
19
  public function fix_newlines( $html ) {
26
  $html = preg_replace( '~fv_vimeo_[a-z0-9]+~', 'fv_vimeo_XYZ', $html);
27
  $html = preg_replace( '~<input type="hidden" id="fv-player-custom-videos-_fv_player_user_video-0" name="fv-player-custom-videos-_fv_player_user_video-0" value="[^"]*?" />~', '<input type="hidden" id="fv-player-custom-videos-_fv_player_user_video-0" name="fv-player-custom-videos-_fv_player_user_video-0" value="XYZ" />', $html);
28
 
29
+ $html = preg_replace( '~convert_jwplayer=[a-z0-9]+~', 'convert_jwplayer=XYZ', $html);
30
+ $html = preg_replace( '~_wpnonce=[a-z0-9]+~', '_wpnonce=XYZ', $html);
31
+
32
  $html = explode("\n",$html);
33
+ foreach( $html AS $k => $v ) {
34
+ if( trim($v) == '' ) unset($html[$k]);
35
+ }
36
  $html = implode( "\n", array_map('trim',$html) );
37
+
38
+ $html = preg_replace( '~\t~', '', $html );
39
  return $html;
40
  }
41
 
test/integration/fv-player-unittest-case.php CHANGED
@@ -25,7 +25,20 @@ abstract class FV_Player_UnitTestCase extends WP_UnitTestCase {
25
  $html = preg_replace( '~_wpnonce=[a-z0-9]+~', '_wpnonce=XYZ', $html);
26
 
27
  $html = explode("\n",$html);
 
 
 
28
  $html = implode( "\n", array_map('trim',$html) );
 
 
 
 
 
 
 
 
 
 
29
  return $html;
30
  }
31
 
25
  $html = preg_replace( '~_wpnonce=[a-z0-9]+~', '_wpnonce=XYZ', $html);
26
 
27
  $html = explode("\n",$html);
28
+ foreach( $html AS $k => $v ) {
29
+ if( trim($v) == '' ) unset($html[$k]);
30
+ }
31
  $html = implode( "\n", array_map('trim',$html) );
32
+
33
+ $html = preg_replace( '~\t~', '', $html );
34
+
35
+ // playlist in lightbox test
36
+ $html = preg_replace( "/(href|data-fv-lightbox)='#wpfp_[^']+'/", "$1='#some-test-hash'", $html);
37
+ $html = preg_replace( '~fv_flowplayer_[a-z0-9]+_lightbox_starter~', 'fv_flowplayer_XYZ_lightbox_starter', $html);
38
+
39
+ // tabbed playlist test
40
+ $html = preg_replace( '~tabs-\d+~', 'tabs-1', $html);
41
+
42
  return $html;
43
  }
44