FV Flowplayer Video Player - Version 7.3.9.727

Version Description

  • 2019/02/05 =

  • FV Player wp-admin menu - sorting by player date, latest first

  • S3 Bucket browser - improving to work well with large quantities of files. The search function was removed gone as AWS S3 doesn't have that, unfortunately.

  • Quality Switching - improving the label for qualities in range of 540-720p (HD if there is no higher quality, otherwise SD)

  • Bugfix - iOS video recovery issues in playlists

Download this release

Release Info

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

Code changes from version 7.3.7.727 to 7.3.9.727

Files changed (49) hide show
  1. controller/backend.php +0 -0
  2. controller/frontend.php +0 -0
  3. css/colorbox.css +0 -0
  4. css/fonts/fpicons.eot +0 -0
  5. css/fonts/fpicons.svg +0 -0
  6. css/fonts/fpicons.ttf +0 -0
  7. css/fonts/fpicons.woff +0 -0
  8. css/img/exit_btn.png +0 -0
  9. css/img/flowplayer.png +0 -0
  10. css/img/no_play_white-x2.png +0 -0
  11. css/img/no_play_white.png +0 -0
  12. css/img/techinfo.png +0 -0
  13. css/s3-browser.css +0 -3
  14. flowplayer.php +2 -2
  15. flowplayer/embed.min.js +0 -0
  16. flowplayer/flowplayer.swf +0 -0
  17. flowplayer/flowplayerhls.swf +0 -0
  18. flowplayer/fv-flowplayer.min.js +19 -17
  19. js/s3-browser.js +50 -245
  20. js/shortcode-editor.js +1 -0
  21. models/checker.php +0 -0
  22. models/custom-videos.php +9 -3
  23. models/flowplayer-frontend.php +0 -0
  24. models/flowplayer.php +0 -0
  25. models/list-table.php +1 -1
  26. models/media-browser-s3.php +84 -96
  27. readme.txt +7 -0
  28. test/integration/backend/profileVideosTest.php +47 -0
  29. test/integration/backend/s3BrowserAjaxTest.php +61 -0
  30. test/integration/backend/settingsTest.php +45 -0
  31. test/integration/backend/testProfileScreen.html +54 -0
  32. test/integration/backend/testSettingsScreen.html +2073 -0
  33. test/integration/backend/videointelligenceInstallTest.php +80 -0
  34. test/integration/bootstrap.php +38 -0
  35. test/integration/frontend/1-shortcodesTest.php +52 -0
  36. test/integration/frontend/dbTest.php +121 -0
  37. test/integration/frontend/endActionsTest.php +164 -0
  38. test/integration/frontend/player-data.json +1 -0
  39. test/integration/frontend/shortcodesLightboxTest.php +168 -0
  40. test/integration/frontend/shortcodesPlaylistTest.php +156 -0
  41. test/integration/frontend/testSimpleShortcode.html +83 -0
  42. test/integration/frontend/videoPositionSavingTest.php +151 -0
  43. test/integration/fv-player-ajax-unittest-case.php +67 -0
  44. test/integration/fv-player-unittest-case.php +76 -0
  45. test/integration/phpunit.xml +8 -0
  46. test/unit/bootstrap.php +3 -0
  47. test/unit/controller/frontendTest.php +209 -0
  48. test/unit/phpunit.xml +7 -0
  49. test/wp-global-empty-mocks.php +225 -0
controller/backend.php CHANGED
File without changes
controller/frontend.php CHANGED
File without changes
css/colorbox.css CHANGED
File without changes
css/fonts/fpicons.eot CHANGED
File without changes
css/fonts/fpicons.svg CHANGED
File without changes
css/fonts/fpicons.ttf CHANGED
File without changes
css/fonts/fpicons.woff CHANGED
File without changes
css/img/exit_btn.png CHANGED
File without changes
css/img/flowplayer.png CHANGED
File without changes
css/img/no_play_white-x2.png CHANGED
File without changes
css/img/no_play_white.png CHANGED
File without changes
css/img/techinfo.png CHANGED
File without changes
css/s3-browser.css CHANGED
@@ -70,7 +70,6 @@
70
right: 0 !important;
71
font-size: 17px;
72
color: #ffffff !important;
73
- display: block !important;
74
width: 40px !important;
75
height: 40px !important;
76
}
@@ -132,7 +131,6 @@
132
/* Content area */
133
134
.filemanager .data {
135
- margin-top: 60px;
136
z-index: -3;
137
}
138
.filemanager .data.animated {
@@ -151,7 +149,6 @@
151
overflow: hidden;
152
padding: 0.3em;
153
z-index: 1;
154
- cursor: pointer;
155
box-sizing: border-box;
156
border: 1px solid #ddd;
157
transition: 0.3s background-color;
70
right: 0 !important;
71
font-size: 17px;
72
color: #ffffff !important;
73
width: 40px !important;
74
height: 40px !important;
75
}
131
/* Content area */
132
133
.filemanager .data {
134
z-index: -3;
135
}
136
.filemanager .data.animated {
149
overflow: hidden;
150
padding: 0.3em;
151
z-index: 1;
152
box-sizing: border-box;
153
border: 1px solid #ddd;
154
transition: 0.3s background-color;
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. Supports MP4, HLS, MPEG-DASH, WebM and OGV. Advanced features such as overlay ads or popups. Uses Flowplayer 7.2.7.
6
- Version: 7.3.7.727
7
Author URI: http://foliovision.com/
8
License: GPL-3.0
9
License URI: http://www.gnu.org/licenses/gpl-3.0.txt
@@ -27,7 +27,7 @@ License URI: http://www.gnu.org/licenses/gpl-3.0.txt
27
*/
28
29
global $fv_wp_flowplayer_ver;
30
- $fv_wp_flowplayer_ver = '7.3.7.727.1';
31
$fv_wp_flowplayer_core_ver = '7.2.7.1';
32
33
include_once( dirname( __FILE__ ) . '/includes/extra-functions.php' );
3
Plugin Name: FV Player
4
Plugin URI: http://foliovision.com/wordpress/plugins/fv-wordpress-flowplayer
5
Description: Formerly FV WordPress Flowplayer. Supports MP4, HLS, MPEG-DASH, WebM and OGV. Advanced features such as overlay ads or popups. Uses Flowplayer 7.2.7.
6
+ Version: 7.3.9.727
7
Author URI: http://foliovision.com/
8
License: GPL-3.0
9
License URI: http://www.gnu.org/licenses/gpl-3.0.txt
27
*/
28
29
global $fv_wp_flowplayer_ver;
30
+ $fv_wp_flowplayer_ver = '7.3.9.727';
31
$fv_wp_flowplayer_core_ver = '7.2.7.1';
32
33
include_once( dirname( __FILE__ ) . '/includes/extra-functions.php' );
flowplayer/embed.min.js CHANGED
File without changes
flowplayer/flowplayer.swf CHANGED
File without changes
flowplayer/flowplayerhls.swf CHANGED
File without changes
flowplayer/fv-flowplayer.min.js CHANGED
@@ -38,9 +38,7 @@ if( typeof(fv_flowplayer_conf) != "undefined" ) {
38
this.nextAutoLevel = nextLevel;
39
}
40
41
- FVAbrController.prototype.destroy = function() {
42
- EventHandler.prototype.destroy.call(this);
43
- }
44
45
flowplayer.conf.hlsjs = {
46
startLevel: -1, // todo: doesn't seem to work, fix it to pick quality matching the player size
@@ -2150,22 +2148,14 @@ flowplayer( function(api,root) {
2150
var stream_info = bitrates[api.engine.dash.getQualityFor('video')];
2151
if( stream_info.qualityIndex != last_quality ) {
2152
last_quality = stream_info.qualityIndex;
2153
- var low = 100000;
2154
- for( var i in bitrates ) {
2155
- if( bitrates[i].height < low ) low = bitrates[i].height;
2156
- }
2157
- quality_label(stream_info.qualityIndex,stream_info.height,low);
2158
}
2159
if( search.match(/dash_debug/) ) quality_debug(stream_info.width,stream_info.height,stream_info.bitrate);
2160
2161
} else if( api.engine.engineName == 'hlsjs-lite' ) {
2162
if( hlsjs.currentLevel != last_quality ) {
2163
last_quality = hlsjs.currentLevel;
2164
- var low = 100000;
2165
- for( var i in hlsjs.levels ) {
2166
- if( hlsjs.levels[i].height < low ) low = hlsjs.levels[i].height;
2167
- }
2168
- quality_label( hlsjs.currentLevel, hlsjs.levels[hlsjs.currentLevel].height, low );
2169
}
2170
2171
if( search.match(/hls_debug/) ) {
@@ -2176,13 +2166,23 @@ flowplayer( function(api,root) {
2176
}
2177
}
2178
2179
- function quality_label(index,height,low) {
2180
root.find('a[data-quality]').removeClass('is-current');
2181
root.find('a[data-quality='+index+']').addClass('is-current');
2182
var label = 'M';
2183
- if( height >= 360 && low < height ) label = 'SD';
2184
- if( height > 540 ) label = 'HD';
2185
- if( height >= 1400 ) label = '4K';
2186
root.find('.fp-qsel').html(label);
2187
}
2188
@@ -2738,10 +2738,12 @@ flowplayer( function(api,root) {
2738
time_delay = 0;
2739
2740
api.on('load', function(e,api,video) {
2741
time_start = new Date().getTime();
2742
});
2743
2744
api.on('ready', function() {
2745
root.find('video').on( "stalled", function(e) {} ); // could be helpful, but just using this event alone is not enough: https://github.com/flowplayer/flowplayer/issues/1403
2746
2747
if( api.engine.engineName == 'html5' ) {
38
this.nextAutoLevel = nextLevel;
39
}
40
41
+ FVAbrController.prototype.destroy = function() {}
42
43
flowplayer.conf.hlsjs = {
44
startLevel: -1, // todo: doesn't seem to work, fix it to pick quality matching the player size
2148
var stream_info = bitrates[api.engine.dash.getQualityFor('video')];
2149
if( stream_info.qualityIndex != last_quality ) {
2150
last_quality = stream_info.qualityIndex;
2151
+ quality_label( stream_info.qualityIndex, bitrates );
2152
}
2153
if( search.match(/dash_debug/) ) quality_debug(stream_info.width,stream_info.height,stream_info.bitrate);
2154
2155
} else if( api.engine.engineName == 'hlsjs-lite' ) {
2156
if( hlsjs.currentLevel != last_quality ) {
2157
last_quality = hlsjs.currentLevel;
2158
+ quality_label( hlsjs.currentLevel, hlsjs.levels );
2159
}
2160
2161
if( search.match(/hls_debug/) ) {
2166
}
2167
}
2168
2169
+ function quality_label(index,qualities) {
2170
+ if( !qualities[index] ) return;
2171
+
2172
+ var height = qualities[index].height,
2173
+ hd_limit = 541,
2174
+ lowest = 100000;
2175
+ jQuery(qualities).each( function(k,v) {
2176
+ if( v.height >= 720 && v.height < 1400 ) hd_limit = 720;
2177
+ if( v.height < lowest ) lowest = v.height;
2178
+ });
2179
+
2180
root.find('a[data-quality]').removeClass('is-current');
2181
root.find('a[data-quality='+index+']').addClass('is-current');
2182
var label = 'M';
2183
+ if( height >= 360 && lowest < height ) label = 'SD';
2184
+ if( height >= hd_limit ) label = 'HD';
2185
+ if( height >= 1400 ) label = '4K';
2186
root.find('.fp-qsel').html(label);
2187
}
2188
2738
time_delay = 0;
2739
2740
api.on('load', function(e,api,video) {
2741
+ clearInterval(no_progress);
2742
time_start = new Date().getTime();
2743
});
2744
2745
api.on('ready', function() {
2746
+ clearInterval(no_progress);
2747
root.find('video').on( "stalled", function(e) {} ); // could be helpful, but just using this event alone is not enough: https://github.com/flowplayer/flowplayer/issues/1403
2748
2749
if( api.engine.engineName == 'html5' ) {
js/s3-browser.js CHANGED
@@ -1,7 +1,5 @@
1
jQuery( function($) {
2
3
- window.fv_player_browser = '';
4
-
5
function fv_flowplayer_media_browser_add_tab(tabId, tabText, tabOnClickCallback) {
6
if (!jQuery('#' + tabId).length) {
7
// add Vimeo browser tab
@@ -18,7 +16,7 @@ jQuery( function($) {
18
}
19
};
20
21
- function fv_flowplayer_s3_browser_load_assets(bucket) {
22
var
23
$this = jQuery(this),
24
$media_frame_content = jQuery('.media-frame-content:visible'),
@@ -27,7 +25,6 @@ jQuery( function($) {
27
}),
28
ajax_data = {
29
action: "load_s3_assets",
30
- cookie: encodeURIComponent(document.cookie)
31
};
32
33
$this.addClass('active').siblings().removeClass('active')
@@ -36,6 +33,9 @@ jQuery( function($) {
36
if (typeof bucket === 'string' && bucket) {
37
ajax_data['bucket'] = bucket;
38
}
39
40
jQuery.post(ajaxurl, ajax_data, function(ret) {
41
var
@@ -66,8 +66,7 @@ jQuery( function($) {
66
select_html = '<strong>You have no S3 buckets configured <a href="options-general.php?page=fvplayer#postbox-container-tab_hosting">in settings</a> or none of them has complete settings (region, key ID and secret key).</strong>';
67
}
68
69
- html += select_html + '</div>' +
70
- '<hr /><br />';
71
}
72
73
if (ret.err) {
@@ -117,6 +116,11 @@ jQuery( function($) {
117
$( document ).on( "mediaBrowserOpen", function(event) {
118
fv_flowplayer_media_browser_add_tab('fv_flowplayer_s3_browser_media_tab', 'Amazon S3', fv_flowplayer_s3_browser_load_assets);
119
});
120
});
121
122
@@ -128,34 +132,21 @@ fv_flowplayer_s3_browse = function(data, ajax_search_callback) {
128
breadcrumbs = jQuery('.breadcrumbs'),
129
fileList = filemanager.find('.data');
130
131
- // Start by fetching the file data from scan.php with an AJAX request
132
-
133
- // jQuery.get('scan.php', function(data) {
134
-
135
var response = [data],
136
currentPath = '',
137
breadcrumbsUrls = [];
138
139
- // console.log(response);
140
-
141
var folders = [],
142
files = [];
143
144
- // This event listener monitors changes on the URL. We use it to
145
- // capture back/forward navigation in the browser.
146
-
147
- jQuery(window).on('fv-player-browser-hashchange', function(){
148
-
149
- goto(window.fv_player_browser);
150
-
151
- // We are triggering the event. This will execute
152
- // this function on page load, so that we show the correct folder:
153
-
154
- }).trigger('fv-player-browser-hashchange');
155
-
156
157
// Hiding and showing the search box
158
-
159
filemanager.find('.search').click(function(){
160
161
var search = jQuery(this);
@@ -163,7 +154,7 @@ fv_flowplayer_s3_browse = function(data, ajax_search_callback) {
163
search.find('span').hide();
164
search.find('input[type=search]').show().focus();
165
166
- });
167
168
169
// Listening for keyboard input on the search field.
@@ -188,17 +179,13 @@ fv_flowplayer_s3_browse = function(data, ajax_search_callback) {
188
filemanager.addClass('searching');
189
190
// Update the hash on every key stroke
191
- window.fv_player_browser = 'search=' + value.trim();
192
- jQuery(window).trigger('fv-player-browser-hashchange');
193
-
194
}
195
196
else {
197
198
filemanager.removeClass('searching');
199
- window.fv_player_browser = encodeURIComponent(currentPath);
200
- jQuery(window).trigger('fv-player-browser-hashchange');
201
-
202
}
203
204
}).on('keyup', function(e){
@@ -225,121 +212,16 @@ fv_flowplayer_s3_browse = function(data, ajax_search_callback) {
225
var search = jQuery(this);
226
227
if(!search.val().trim().length) {
228
229
- window.fv_player_browser = encodeURIComponent(currentPath);
230
- jQuery(window).trigger('fv-player-browser-hashchange');
231
-
232
search.hide();
233
search.parent().find('span').show();
234
-
235
}
236
237
});
238
239
240
- // Clicking on folders
241
-
242
- fileList.on('click', 'li.folders', function(e){
243
- e.preventDefault();
244
-
245
- var nextDir = jQuery(this).find('a.folders').attr('href');
246
-
247
- if(filemanager.hasClass('searching')) {
248
-
249
- // Building the breadcrumbs
250
-
251
- breadcrumbsUrls = generateBreadcrumbs(nextDir);
252
-
253
- filemanager.removeClass('searching');
254
- filemanager.find('input[type=search]').val('').hide();
255
- filemanager.find('span').show();
256
- }
257
- else {
258
- breadcrumbsUrls.push(nextDir);
259
- }
260
-
261
- window.fv_player_browser = encodeURIComponent(nextDir);
262
- jQuery(window).trigger('fv-player-browser-hashchange');
263
-
264
- currentPath = nextDir;
265
- });
266
-
267
-
268
- // Clicking on breadcrumbs
269
-
270
- breadcrumbs.on('click', 'a', function(e){
271
- e.preventDefault();
272
-
273
- var index = breadcrumbs.find('a').index(jQuery(this)),
274
- nextDir = breadcrumbsUrls[index];
275
-
276
- breadcrumbsUrls.length = Number(index);
277
-
278
- window.fv_player_browser = encodeURIComponent(nextDir);
279
- jQuery(window).trigger('fv-player-browser-hashchange');
280
-
281
- });
282
-
283
-
284
- // Navigates to the given hash (path)
285
-
286
- function goto(hash) {
287
-
288
- hash = decodeURIComponent(hash).split('=');
289
-
290
- if (hash.length) {
291
- var rendered = '';
292
-
293
- // if hash has search in it
294
-
295
- if (hash[0] === 'search') {
296
-
297
- filemanager.addClass('searching');
298
- rendered = searchData(response, hash[1].toLowerCase());
299
-
300
- if (rendered.length) {
301
- currentPath = hash[0];
302
- render(rendered);
303
- }
304
- else {
305
- render(rendered);
306
- }
307
-
308
- }
309
-
310
- // if hash is some path
311
-
312
- else if (hash[0].trim().length) {
313
-
314
- rendered = searchByPath(hash[0]);
315
-
316
- if (rendered.length) {
317
-
318
- currentPath = hash[0];
319
- breadcrumbsUrls = generateBreadcrumbs(hash[0]);
320
- render(rendered);
321
-
322
- }
323
- else {
324
- currentPath = hash[0];
325
- breadcrumbsUrls = generateBreadcrumbs(hash[0]);
326
- render(rendered);
327
- }
328
-
329
- }
330
-
331
- // if there is no hash
332
-
333
- else if (typeof(data) !== 'undefined' && data && data.path) {
334
- currentPath = data.path;
335
- breadcrumbsUrls.push(data.path);
336
- render(searchByPath(data.path));
337
- }
338
- }
339
- }
340
-
341
// Splits a file path and turns it into clickable breadcrumbs
342
-
343
function generateBreadcrumbs(nextDir){
344
var path = nextDir.split('/').slice(0);
345
for(var i=1;i<path.length;i++){
@@ -348,54 +230,7 @@ fv_flowplayer_s3_browse = function(data, ajax_search_callback) {
348
return path;
349
}
350
351
-
352
- // Locates a file by path
353
-
354
- function searchByPath(dir) {
355
- var path = dir.split('/'),
356
- demo = response,
357
- flag = 0;
358
-
359
- for(var i=0;i<path.length;i++){
360
- for(var j=0;j<demo.length;j++){
361
- if(demo[j] && demo[j].name === path[i]){
362
- flag = 1;
363
- demo = demo[j].items;
364
- break;
365
- }
366
- }
367
- }
368
-
369
- demo = flag ? demo : [];
370
- return demo;
371
- }
372
-
373
-
374
- // Recursively search through the file tree
375
-
376
- function searchData(data, searchTerms) {
377
-
378
- data.forEach(function(d){
379
- if(d.type === 'folder') {
380
-
381
- searchData(d.items,searchTerms);
382
-
383
- if(d.name.toLowerCase().match(searchTerms)) {
384
- folders.push(d);
385
- }
386
- }
387
- else if(d.type === 'file') {
388
- if(d.name.toLowerCase().match(searchTerms)) {
389
- files.push(d);
390
- }
391
- }
392
- });
393
- return {folders: folders, files: files};
394
- }
395
-
396
-
397
// Render the HTML for the file manager
398
-
399
function render(data) {
400
401
var scannedFolders = [],
@@ -408,25 +243,21 @@ fv_flowplayer_s3_browse = function(data, ajax_search_callback) {
408
if (d.type === 'folder') {
409
scannedFolders.push(d);
410
}
411
- else if (d.type === 'file') {
412
scannedFiles.push(d);
413
}
414
415
});
416
417
- }
418
- else if(typeof data === 'object') {
419
-
420
scannedFolders = data.folders;
421
scannedFiles = data.files;
422
423
}
424
425
-
426
// Empty the old result and make the new one
427
-
428
fileList.empty().hide();
429
-
430
if(!scannedFolders.length && !scannedFiles.length) {
431
filemanager.find('.nothingfound').show();
432
}
@@ -437,27 +268,8 @@ fv_flowplayer_s3_browse = function(data, ajax_search_callback) {
437
if(scannedFolders.length) {
438
439
scannedFolders.forEach(function(f) {
440
-
441
- var itemsLength = f.items.length,
442
- name = escapeHTML(f.name),
443
- icon = '<span class="icon folder"></span>';
444
-
445
- if(itemsLength) {
446
- icon = '<span class="icon folder full"></span>';
447
- }
448
-
449
- if(itemsLength == 1) {
450
- itemsLength += ' item';
451
- }
452
- else if(itemsLength > 1) {
453
- itemsLength += ' items';
454
- }
455
- else {
456
- itemsLength = 'Empty';
457
- }
458
-
459
- var folder = jQuery('<li class="folders"><a href="'+ f.path +'" title="'+ name +'" class="folders">'+icon+'<span class="name">' + name + '</span> <span class="details">' + itemsLength + '</span></a></li>');
460
- fileList.append(folder);
461
});
462
463
}
@@ -498,7 +310,8 @@ fv_flowplayer_s3_browse = function(data, ajax_search_callback) {
498
$url_input
499
.val($this.attr('href'))
500
.removeClass('fv_flowplayer_target' )
501
- .trigger('keyup'); // this changes the HLS key field visibility in FV Player Pro
502
503
if( splash && $url_input.attr('id').match(/^fv_wp_flowplayer_field_src/) ) {
504
var splash_input = $url_input.parents('table').find('#fv_wp_flowplayer_field_splash');
@@ -514,20 +327,23 @@ fv_flowplayer_s3_browse = function(data, ajax_search_callback) {
514
515
scannedFiles.forEach(function(f) {
516
517
- var fileSize = bytesToSize(f.size),
518
name = escapeHTML(f.name),
519
fileType = name.split('.'),
520
- icon = '<span class="icon file"></span>';
521
-
522
- fileType = fileType[fileType.length-1];
523
-
524
- icon = '<span class="icon file f-'+fileType+'">.'+fileType+'</span>';
525
-
526
- var
527
- $href = jQuery('<a href="'+ f.link+'" title="'+ name +'" class="files">'+icon+'<span class="name">'+ name +'</span> <span class="details">'+fileSize+'</span></a>'),
528
file = jQuery('<li class="files"></li>');
529
530
- $href.on('click', fileUrlIntoShortcodeEditor);
531
532
file.append($href);
533
file.appendTo(fileList);
@@ -537,33 +353,26 @@ fv_flowplayer_s3_browse = function(data, ajax_search_callback) {
537
538
539
// Generate the breadcrumbs
540
-
541
var url = '';
542
-
543
if(filemanager.hasClass('searching')){
544
-
545
url = '<span>Search results: </span>';
546
fileList.removeClass('animated');
547
-
548
}
549
else {
550
-
551
fileList.addClass('animated');
552
553
var right_arrow = '<span class="arrow_sign">→</span> ';
554
breadcrumbsUrls.forEach(function (u, i) {
555
-
556
- var name = u.split('/');
557
- if (!name[name.length-1]) {
558
- url = url.substr(0, url.length - right_arrow.length - 1);
559
- return;
560
- }
561
-
562
- if (i !== breadcrumbsUrls.length - 1) {
563
- url += '<a href="'+u+'"><span class="folderName">' + name[name.length-1] + '</span></a>' + right_arrow;
564
- }
565
- else {
566
- url += '<span class="folderName">' + name[name.length-1] + '</span>';
567
}
568
569
});
@@ -572,11 +381,7 @@ fv_flowplayer_s3_browse = function(data, ajax_search_callback) {
572
573
breadcrumbs.text('').append(url);
574
575
-
576
- // Show the generated elements
577
-
578
fileList.fadeIn();
579
-
580
}
581
582
1
jQuery( function($) {
2
3
function fv_flowplayer_media_browser_add_tab(tabId, tabText, tabOnClickCallback) {
4
if (!jQuery('#' + tabId).length) {
5
// add Vimeo browser tab
16
}
17
};
18
19
+ function fv_flowplayer_s3_browser_load_assets(bucket,path) {
20
var
21
$this = jQuery(this),
22
$media_frame_content = jQuery('.media-frame-content:visible'),
25
}),
26
ajax_data = {
27
action: "load_s3_assets",
28
};
29
30
$this.addClass('active').siblings().removeClass('active')
33
if (typeof bucket === 'string' && bucket) {
34
ajax_data['bucket'] = bucket;
35
}
36
+ if (typeof path === 'string' && path) {
37
+ ajax_data['path'] = path;
38
+ }
39
40
jQuery.post(ajaxurl, ajax_data, function(ret) {
41
var
66
select_html = '<strong>You have no S3 buckets configured <a href="options-general.php?page=fvplayer#postbox-container-tab_hosting">in settings</a> or none of them has complete settings (region, key ID and secret key).</strong>';
67
}
68
69
+ html += select_html + '</div>';
70
}
71
72
if (ret.err) {
116
$( document ).on( "mediaBrowserOpen", function(event) {
117
fv_flowplayer_media_browser_add_tab('fv_flowplayer_s3_browser_media_tab', 'Amazon S3', fv_flowplayer_s3_browser_load_assets);
118
});
119
+
120
+ $( document ).on( "click", ".folders, .breadcrumbs a", function(event) {
121
+ fv_flowplayer_s3_browser_load_assets( jQuery('#bucket-dropdown').val(), jQuery(this).attr('href') );
122
+ return false;
123
+ });
124
});
125
126
132
breadcrumbs = jQuery('.breadcrumbs'),
133
fileList = filemanager.find('.data');
134
135
var response = [data],
136
currentPath = '',
137
breadcrumbsUrls = [];
138
139
var folders = [],
140
files = [];
141
142
+ jQuery(window).off('fv-player-browser-open-folder');
143
+ jQuery(window).on('fv-player-browser-open-folder', function(e, path){
144
+ currentPath = data.path;
145
+ breadcrumbsUrls.push(data.path);
146
+ render(data.items);
147
+ }).trigger('fv-player-browser-open-folder', [ '' ] );
148
149
// Hiding and showing the search box
150
filemanager.find('.search').click(function(){
151
152
var search = jQuery(this);
154
search.find('span').hide();
155
search.find('input[type=search]').show().focus();
156
157
+ }).hide(); // not implemented for S3
158
159
160
// Listening for keyboard input on the search field.
179
filemanager.addClass('searching');
180
181
// Update the hash on every key stroke
182
+ jQuery(window).trigger('fv-player-browser-open-folder', [ 'search=' + value.trim() ]);
183
}
184
185
else {
186
187
filemanager.removeClass('searching');
188
+ jQuery(window).trigger('fv-player-browser-open-folder', [ currentPath ] );
189
}
190
191
}).on('keyup', function(e){
212
var search = jQuery(this);
213
214
if(!search.val().trim().length) {
215
+ jQuery(window).trigger('fv-player-browser-open-folder', [ currentPath ] );
216
217
search.hide();
218
search.parent().find('span').show();
219
}
220
221
});
222
223
224
// Splits a file path and turns it into clickable breadcrumbs
225
function generateBreadcrumbs(nextDir){
226
var path = nextDir.split('/').slice(0);
227
for(var i=1;i<path.length;i++){
230
return path;
231
}
232
233
// Render the HTML for the file manager
234
function render(data) {
235
236
var scannedFolders = [],
243
if (d.type === 'folder') {
244
scannedFolders.push(d);
245
}
246
+ else {
247
scannedFiles.push(d);
248
}
249
250
});
251
252
+ } else if(typeof data === 'object') {
253
scannedFolders = data.folders;
254
scannedFiles = data.files;
255
256
}
257
258
// Empty the old result and make the new one
259
fileList.empty().hide();
260
+
261
if(!scannedFolders.length && !scannedFiles.length) {
262
filemanager.find('.nothingfound').show();
263
}
268
if(scannedFolders.length) {
269
270
scannedFolders.forEach(function(f) {
271
+ var name = escapeHTML(f.name).replace(/\/#x2F;,'');
272
+ fileList.append( jQuery('<li class="folders"><a href="'+f.path+'" title="'+name+'" class="folders"><span class="icon folder"></span><span class="name">'+name+'</span></a></li>'));
273
});
274
275
}
310
$url_input
311
.val($this.attr('href'))
312
.removeClass('fv_flowplayer_target' )
313
+ .trigger('keyup') // this changes the HLS key field visibility in FV Player Pro
314
+ .trigger('change'); // this check the video duration etc.
315
316
if( splash && $url_input.attr('id').match(/^fv_wp_flowplayer_field_src/) ) {
317
var splash_input = $url_input.parents('table').find('#fv_wp_flowplayer_field_splash');
327
328
scannedFiles.forEach(function(f) {
329
330
+ var fileSize = typeof(f.size) == "number" ? bytesToSize(f.size) : f.size, // just show the size for placeholders
331
name = escapeHTML(f.name),
332
fileType = name.split('.'),
333
+ icon = '<span class="icon file"></span>',
334
+ fileType = fileType[fileType.length-1],
335
+ icon = '<span class="icon file f-'+fileType+'">.'+fileType+'</span>',
336
+ link = f.link ? 'href="'+ f.link+'"' : '',
337
+ $href = jQuery('<a '+link+' title="'+ name +'" class="files">'+icon+'<span class="name">'+ name +'</span> <span class="details">'+fileSize+'</span></a>'),
338
file = jQuery('<li class="files"></li>');
339
340
+ if( f.link ) {
341
+ $href.on('click', fileUrlIntoShortcodeEditor);
342
+ } else { // click on placeholder
343
+ $href.on('click', function() {
344
+ return false;
345
+ });
346
+ }
347
348
file.append($href);
349
file.appendTo(fileList);
353
354
355
// Generate the breadcrumbs
356
var url = '';
357
if(filemanager.hasClass('searching')){
358
url = '<span>Search results: </span>';
359
fileList.removeClass('animated');
360
}
361
else {
362
fileList.addClass('animated');
363
364
var right_arrow = '<span class="arrow_sign">→</span> ';
365
breadcrumbsUrls.forEach(function (u, i) {
366
+ var name = u.replace(/\/#x2F;,'').split('/');
367
+ if( name.length > 1 ) {
368
+ name.forEach(function (n, k) {
369
+ var path = '';
370
+ for( var j=0; j<k+1; j++ ) {
371
+ path += name[j]+'/';
372
+ }
373
+ url += '<a href="'+path+'"><span class="folderName">'+n+'</span></a>';
374
+ if( k < name.length-1 ) url += right_arrow;
375
+ });
376
}
377
378
});
381
382
breadcrumbs.text('').append(url);
383
384
fileList.fadeIn();
385
}
386
387
js/shortcode-editor.js CHANGED
@@ -798,6 +798,7 @@ function fv_flowplayer_playlist_show() {
798
playlist_row.find('.fvp_item_video-thumbnail').html( video_preview.length ? '<img src="' + video_preview + '" />':'');
799
800
var video_name = decodeURIComponent(currentUrl).split("/").pop();
801
video_name = video_name.replace(/watch\?v=/,'YouTube: ');
802
803
playlist_row.find('.fvp_item_video-filename').html( video_name );
798
playlist_row.find('.fvp_item_video-thumbnail').html( video_preview.length ? '<img src="' + video_preview + '" />':'');
799
800
var video_name = decodeURIComponent(currentUrl).split("/").pop();
801
+ video_name = video_name.replace(/\+/g,' ');
802
video_name = video_name.replace(/watch\?v=/,'YouTube: ');
803
804
playlist_row.find('.fvp_item_video-filename').html( video_name );
models/checker.php CHANGED
File without changes
models/custom-videos.php CHANGED
@@ -90,8 +90,8 @@ class FV_Player_Custom_Videos {
90
<div class='fv-player-editor-preview'>".($video ? do_shortcode($video) : '')."</div>
91
<input class='attachement-shortcode fv-player-editor-field' name='fv_player_videos[".$this->meta."][]' type='hidden' value='".esc_attr($video)."' />
92
<div class='edit-video' ".(!$video ? 'style="display:none"' : '').">
93
- <button class='button fv-player-editor-button'>Edit Video</button>
94
- <button class='button fv-player-editor-remove'>Remove Video</button>
95
$add_another
96
</div>
97
@@ -444,7 +444,13 @@ class FV_Player_MetaBox {
444
);
445
}
446
447
- $args = wp_parse_args( $args, array( 'display' => false, 'multiple' => true ) );
448
449
global $FV_Player_Custom_Videos_Master;
450
$FV_Player_Custom_Videos_Master->register_metabox($args);
90
<div class='fv-player-editor-preview'>".($video ? do_shortcode($video) : '')."</div>
91
<input class='attachement-shortcode fv-player-editor-field' name='fv_player_videos[".$this->meta."][]' type='hidden' value='".esc_attr($video)."' />
92
<div class='edit-video' ".(!$video ? 'style="display:none"' : '').">
93
+ <button class='button fv-player-editor-button'>".$args['labels']['edit']."</button>
94
+ <button class='button fv-player-editor-remove'>".$args['labels']['remove']."</button>
95
$add_another
96
</div>
97
444
);
445
}
446
447
+ $args = wp_parse_args( $args, array(
448
+ 'display' => false,
449
+ 'multiple' => true,
450
+ 'labels' => array(
451
+ 'edit' => 'Edit Video',
452
+ 'remove' => 'Remove Video'
453
+ ) ) );
454
455
global $FV_Player_Custom_Videos_Master;
456
$FV_Player_Custom_Videos_Master->register_metabox($args);
models/flowplayer-frontend.php CHANGED
File without changes
models/flowplayer.php CHANGED
File without changes
models/list-table.php CHANGED
@@ -233,7 +233,7 @@ class FV_Player_List_Table extends WP_List_Table {
233
234
public function get_data() {
235
$current = !empty($_GET['paged']) ? intval($_GET['paged']) : 1;
236
- $order = !empty($_GET['order']) ? esc_sql($_GET['order']) : 'asc';
237
$order_by = !empty($_GET['orderby']) ? esc_sql($_GET['orderby']) : 'id';
238
$single_id = !empty($_GET['id']) ? esc_sql($_GET['id']) : null;
239
$search = !empty($_GET['s']) ? esc_sql($_GET['s']) : null;
233
234
public function get_data() {
235
$current = !empty($_GET['paged']) ? intval($_GET['paged']) : 1;
236
+ $order = !empty($_GET['order']) ? esc_sql($_GET['order']) : 'desc';
237
$order_by = !empty($_GET['orderby']) ? esc_sql($_GET['orderby']) : 'id';
238
$single_id = !empty($_GET['id']) ? esc_sql($_GET['id']) : null;
239
$search = !empty($_GET['s']) ? esc_sql($_GET['s']) : null;
models/media-browser-s3.php CHANGED
@@ -92,7 +92,12 @@ class FV_Player_Media_Browser_S3 extends FV_Player_Media_Browser {
92
93
if ($regioned_bucket_found) {
94
95
- $output = array();
96
97
$region = $regions[ $array_id ];
98
$secret = $secrets[ $array_id ];
@@ -102,14 +107,20 @@ class FV_Player_Media_Browser_S3 extends FV_Player_Media_Browser {
102
$credentials = new Aws\Credentials\Credentials( $key, $secret );
103
104
try {
105
-
106
- $cfClient = Aws\CloudFront\CloudFrontClient::factory( array(
107
- 'credentials' => $credentials,
108
- 'region' => 'us-east-1',
109
- 'version' => 'latest'
110
- ) );
111
-
112
- $cloudfronts = $cfClient->listDistributions();
113
foreach( $cloudfronts['DistributionList']['Items'] AS $item ) {
114
if( !$item['Enabled'] ) continue;
115
@@ -142,27 +153,56 @@ class FV_Player_Media_Browser_S3 extends FV_Player_Media_Browser {
142
) );
143
144
try {
145
- $objects = $s3Client->getIterator( 'ListObjects', array( 'Bucket' => $bucket ) );
146
-
147
- $path_array = array();
148
- $size_array = array();
149
- $link_array = array();
150
151
foreach ( $objects as $object ) {
152
if ( ! isset( $objectarray ) ) {
153
$objectarray = array();
154
}
155
- //print_r($object);
156
- $name = $object['Key'];
157
- $size = $object['Size'];
158
-
159
- if (strtolower(substr($name, strrpos($name, '.') + 1)) === 'ts') {
160
continue;
161
}
162
-
163
- if ( $object['Size'] != '0' ) {
164
-
165
- $link = (string) $s3Client->getObjectUrl( $bucket, $name );
166
$link = str_replace( '%20', '+', $link );
167
168
// replace link with CloudFront URL, if we have one
@@ -173,87 +213,35 @@ class FV_Player_Media_Browser_S3 extends FV_Player_Media_Browser {
173
// replace S3 URLs with bucket name as a subfolder
174
$link = preg_replace('/https?:\/\/[^\/]+\/' . $bucket . '\/(.*)/i', rtrim($domains[$array_id], '/').'/$1', $link);
175
}
176
-
177
- $path = 'Home/' . $name;
178
-
179
- $path_array[] = $path;
180
- $size_array[] = $size;
181
- $link_array[] = $link;
182
-
183
- }
184
-
185
- }
186
-
187
- function &placeInArray( array &$dest, array $path_array, $size, $pathorig, $link ) {
188
- // If we're at the leaf of the tree, just push it to the array and return
189
- //echo $pathorig;
190
- //echo $size."<br>";
191
-
192
- global $folders_added;
193
- if ( count( $path_array ) === 1 ) {
194
- if ( $path_array[0] !== '' ) {
195
- $file_array = array();
196
- $file_array['name'] = $path_array[0];
197
- $file_array['size'] = $size;
198
- $file_array['type'] = 'file';
199
- $file_array['path'] = $pathorig;
200
- $file_array['link'] = $link;
201
- array_push( $dest['items'], $file_array );
202
- }
203
-
204
- return $dest;
205
}
206
207
- // If not (if multiple elements exist in path_array) then shift off the next path-part...
208
- // (this removes $path_array's first element off, too)
209
- $path = array_shift( $path_array );
210
-
211
- if ( $path ) {
212
-
213
- $newpath_temp = explode( $path, $pathorig );
214
- $newpath = $newpath_temp[0] . $path . '/';
215
- // ...make a new sub-array for it...
216
-
217
-
218
- //if (!isset($dest['items'][$path])) {
219
- if ( ! in_array( $newpath, $folders_added, true ) ) {
220
- $dest['items'][] = array(
221
-
222
- 'name' => $path,
223
- 'type' => 'folder',
224
- 'path' => $newpath,
225
- 'items' => array()
226
-
227
- );
228
- $folders_added[] = $newpath;
229
- //print_r($folders_added);
230
- }
231
- $count = count( $dest['items'] );
232
- $count --;
233
- //echo $count.'<br>';
234
- //print_r($dest['items'][$path]);
235
-
236
- // ...and continue the process on the sub-array
237
- return placeInArray( $dest['items'][ $count ], $path_array, $size, $pathorig, $link );
238
}
239
240
- // This is just here to blow past multiple slashes (an empty path-part), like
241
- // /path///to///thing
242
- return placeInArray( $dest, $path_array, $size, $pathorig, $link );
243
}
244
-
245
- $folders_added = array();
246
- $i = 0;
247
- foreach ( $path_array as $path ) {
248
- $size = $size_array[ $i ];
249
- $link = $link_array[ $i ];
250
- placeInArray( $output, explode( '/', $path ), $size, $path, $link );
251
- $i ++;
252
}
253
} catch ( Aws\S3\Exception\S3Exception $e ) {
254
//echo $e->getMessage() . "\n";
255
$err = $e->getMessage();
256
- $output['items'] = array(
257
'items' => array(),
258
'name' => '/',
259
'path' => '/',
@@ -279,7 +267,7 @@ class FV_Player_Media_Browser_S3 extends FV_Player_Media_Browser {
279
'active_bucket_id' => $array_id,
280
'items' => (
281
$regioned_bucket_found ?
282
- $output['items'][0] :
283
array(
284
'items' => array(),
285
'name' => '/',
92
93
if ($regioned_bucket_found) {
94
95
+ $output = array(
96
+ 'name' => 'Home',
97
+ 'type' => 'folder',
98
+ 'path' => !empty($_POST['path']) ? $_POST['path'] : 'Home/',
99
+ 'items' => array()
100
+ );
101
102
$region = $regions[ $array_id ];
103
$secret = $secrets[ $array_id ];
107
$credentials = new Aws\Credentials\Credentials( $key, $secret );
108
109
try {
110
+ $cloudfronts = get_transient('fv_player_s3_browser_cf');
111
+ if( !$cloudfronts ) {
112
+ $cfClient = Aws\CloudFront\CloudFrontClient::factory( array(
113
+ 'credentials' => $credentials,
114
+ 'region' => 'us-east-1',
115
+ 'version' => 'latest'
116
+ ) );
117
+
118
+ $cloudfronts = $cfClient->listDistributions();
119
+ if( !empty($cloudfronts['DistributionList']['Items']) ) {
120
+ set_transient('fv_player_s3_browser_cf',$cloudfronts,60);
121
+ }
122
+ }
123
+
124
foreach( $cloudfronts['DistributionList']['Items'] AS $item ) {
125
if( !$item['Enabled'] ) continue;
126
153
) );
154
155
try {
156
+ $args = array(
157
+ 'Bucket' => $bucket,
158
+ 'Delimiter' => '/',
159
+ );
160
+
161
+ $request_path = !empty($_POST['path']) ? str_replace( 'Home/', '', stripslashes($_POST['path']) ) : false;
162
+
163
+ if( $request_path ) {
164
+ $args['Prefix'] = $request_path;
165
+ }
166
+
167
+ $res = $s3Client->ListObjects( $args );
168
+ $objects = array_merge( !empty($res['CommonPrefixes']) ? $res['CommonPrefixes'] : array(), $res->get('Contents') );
169
+
170
+ if( isset($_REQUEST['debug']) ) {
171
+ var_dump($args,$objects);
172
+ die();
173
+ }
174
175
+ $sum_up = array();
176
foreach ( $objects as $object ) {
177
if ( ! isset( $objectarray ) ) {
178
$objectarray = array();
179
}
180
+
181
+ $item = array();
182
+
183
+ $path = $object['Prefix'] ? $object['Prefix'] : $object['Key'];
184
+
185
+ if( !empty($object['Key']) && preg_match( '~\.ts$~', $object['Key'] ) ) {
186
+ if( empty($sum_up['ts']) ) $sum_up['ts'] = 0;
187
+ $sum_up['ts']++;
188
continue;
189
}
190
+
191
+ $item['path'] = 'Home/' . $path;
192
+
193
+ if( $request_path ) {
194
+ if( $request_path == $path ) continue; // sometimes the current folder is present in the response, weird
195
+
196
+ $item['name'] = str_replace( $request_path, '', $path );
197
+ } else {
198
+ $item['name'] = $path;
199
+ }
200
+
201
+ if( !empty($object['Size']) ) {
202
+ $item['type'] = 'file';
203
+ $item['size'] = $object['Size'];
204
+
205
+ $link = (string) $s3Client->getObjectUrl( $bucket, $path );
206
$link = str_replace( '%20', '+', $link );
207
208
// replace link with CloudFront URL, if we have one
213
// replace S3 URLs with bucket name as a subfolder
214
$link = preg_replace('/https?:\/\/[^\/]+\/' . $bucket . '\/(.*)/i', rtrim($domains[$array_id], '/').'/$1', $link);
215
}
216
+
217
+ $item['link'] = $link;
218
+
219
+ } else {
220
+ $item['type'] = 'folder';
221
+ $item['items'] = array();
222
}
223
+
224
+ $output['items'][] = $item;
225
226
+ if (strtolower(substr($name, strrpos($name, '.') + 1)) === 'ts') {
227
+ continue;
228
}
229
230
}
231
+
232
+ foreach( $sum_up AS $ext => $count ) {
233
+ $output['items'][] = array(
234
+ 'name' => '*.ts',
235
+ 'link' => '',
236
+ 'size' => $count.' .'.$ext.' files hidden',
237
+ 'type' => 'placeholder'
238
+ );
239
}
240
+
241
} catch ( Aws\S3\Exception\S3Exception $e ) {
242
//echo $e->getMessage() . "\n";
243
$err = $e->getMessage();
244
+ $output = array(
245
'items' => array(),
246
'name' => '/',
247
'path' => '/',
267
'active_bucket_id' => $array_id,
268
'items' => (
269
$regioned_bucket_found ?
270
+ $output :
271
array(
272
'items' => array(),
273
'name' => '/',
readme.txt CHANGED
@@ -357,6 +357,13 @@ Thank you for being part of the HMTL 5 mobile video revolution!
357
358
== Changelog ==
359
360
= 7.3.7.727 - 2019/01/24 =
361
362
* Database - performance fix
357
358
== Changelog ==
359
360
+ = 7.3.9.727 - 2019/02/05 =
361
+
362
+ * FV Player wp-admin menu - sorting by player date, latest first
363
+ * S3 Bucket browser - improving to work well with large quantities of files. The search function was removed gone as AWS S3 doesn't have that, unfortunately.
364
+ * Quality Switching - improving the label for qualities in range of 540-720p (HD if there is no higher quality, otherwise SD)
365
+ * Bugfix - iOS video recovery issues in playlists
366
+
367
= 7.3.7.727 - 2019/01/24 =
368
369
* Database - performance fix
test/integration/backend/profileVideosTest.php ADDED
@@ -0,0 +1,47 @@
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_ProfileVideosTestCase extends FV_Player_UnitTestCase {
10
+
11
+ public function testProfileScreen() {
12
+ global $fv_fp;
13
+ $fv_fp->conf['profile_videos_enable_bio'] = true;
14
+
15
+ // add new user and create last saved position metadata for this new user
16
+ $this->userID = $this->factory->user->create(array(
17
+ 'role' => 'admin'
18
+ ));
19
+
20
+ add_user_meta($this->userID, '_fv_player_user_video', '[fvplayer src="https://vimeo.com/255317467" playlist="https://vimeo.com/192934117" caption=";Talking about FV Player"]');
21
+ add_user_meta($this->userID, '_fv_player_user_video', '[fvplayer src="https://vimeo.com/255370388"]');
22
+ add_user_meta($this->userID, '_fv_player_user_video', '[fvplayer src="https://www.youtube.com/watch?v=6ZfuNTqbHE8"]]');
23
+
24
+ $profileuser = get_user_to_edit($this->userID);
25
+
26
+ ob_start();
27
+ apply_filters( 'show_password_fields', true, $profileuser );
28
+ $output = ob_get_clean();
29
+
30
+ $one = $this->fix_newlines(file_get_contents(dirname(__FILE__).'/testProfileScreen.html')); // this contains user ID of '4'
31
+ $two = explode("\n",$this->fix_newlines($output));
32
+ foreach( explode("\n",$one) as $k => $v ) {
33
+
34
+ /*if( $v != $two[$k]) {
35
+ for($i=0;$i<strlen($two[$k]);$i++) {
36
+ var_dump( $two[$k][$i].' '.ord($two[$k][$i]) );
37
+ }
38
+ }*/
39
+
40
+ //$this->assertEquals( $v, $two[$k] );
41
+ }
42
+
43
+ $this->assertEquals( $this->fix_newlines(file_get_contents(dirname(__FILE__).'/testProfileScreen.html')), $this->fix_newlines($output) );
44
+
45
+ }
46
+
47
+ }
test/integration/backend/s3BrowserAjaxTest.php ADDED
@@ -0,0 +1,61 @@
1
+ <?php
2
+
3
+ require_once( dirname(__FILE__).'/../fv-player-ajax-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_S3BrowserAjaxTestCase extends FV_Player_Ajax_UnitTestCase {
10
+
11
+ // we need to make sure FV Player loads as if it's wp-admin
12
+ public static function wpSetUpBeforeClass() {
13
+ global $fv_fp;
14
+
15
+ $_POST = array (
16
+ 'amazon_bucket' => array(FV_PLAYER_AMAZON_BUCKET),
17
+ 's3_browser' => 1,
18
+ 'fv-wp-flowplayer-submit' => 'Save All Changes'
19
+ );
20
+
21
+ set_current_screen( 'edit-post' );
22
+ // without this included, fv_wp_flowplayer_delete_extensions_transients() would not be found
23
+ include_once "../../../fv-wordpress-flowplayer/controller/backend.php";
24
+ parent::wpSetUpBeforeClass();
25
+
26
+ $fv_fp->_set_conf();
27
+ }
28
+
29
+ public function setUp() {
30
+ parent::setUp();
31
+ }
32
+
33
+ public function testNoSaveForNotLoggedInUsers() {
34
+ global $fv_fp;
35
+
36
+ //$fv_fp->conf['amazon_bucket'] = array(FV_PLAYER_AMAZON_BUCKET);
37
+ $fv_fp->conf['amazon_region'] = array(FV_PLAYER_AMAZON_REGION);
38
+ $fv_fp->conf['amazon_key'] = array(FV_PLAYER_AMAZON_ACCESS_KEY);
39
+ $fv_fp->conf['amazon_secret'] = array(FV_PLAYER_AMAZON_SECRET);
40
+
41
+ // is anybody listening out there?
42
+ $this->assertTrue( has_action('wp_ajax_load_s3_assets') );
43
+
44
+ // Spoof the nonce in the POST superglobal
45
+ //$_POST['_wpnonce'] = wp_create_nonce( 'anything-here-if-needed' );
46
+
47
+ // set up POST data for video resume times
48
+ // $_POST['action'] = 'fv_wp_flowplayer_video_position_save';
49
+
50
+ // call the AJAX which
51
+ try {
52
+ $this->_handleAjax( 'fv_wp_flowplayer_ajax_load_s3_assets' );
53
+ } catch ( WPAjaxDieContinueException $e ) {
54
+ $response = json_decode( $this->_last_response );
55
+ $this->assertInternalType( 'object', $response );
56
+ $this->assertObjectHasAttribute( 'success', $response );
57
+ $this->assertFalse( $response->success );
58
+ }
59
+ }
60
+
61
+ }
test/integration/backend/settingsTest.php ADDED
@@ -0,0 +1,45 @@
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_SettingsTestCase extends FV_Player_UnitTestCase {
10
+
11
+ // we need to convince it is showing the FV Player settings screen!
12
+ public static function wpSetUpBeforeClass() {
13
+ set_current_screen( 'settings_page_fvplayer' );
14
+
15
+ parent::wpSetUpBeforeClass();
16
+
17
+ remove_action( 'admin_init', 'wp_admin_headers' );
18
+ do_action( 'admin_init' );
19
+ }
20
+
21
+ public function testSettingsScreen() {
22
+
23
+ ob_start();
24
+ fv_player_admin_page();
25
+ $output = ob_get_clean();
26
+
27
+ $one = $this->fix_newlines(file_get_contents(dirname(__FILE__).'/testSettingsScreen.html'));
28
+ $two = explode("\n",$this->fix_newlines($output));
29
+ foreach( explode("\n",$one) as $k => $v ) {
30
+
31
+ /*if( $v != $two[$k]) {
32
+ for($i=0;$i<strlen($two[$k]);$i++) {
33
+ if( $v[$i] != $two[$k][$i]) {
34
+ var_dump( $v[$i].' vs '.$two[$k][$i].' '.ord($two[$k][$i]) );
35
+ }
36
+ }
37
+ }*/
38
+
39
+ $this->assertEquals( $v, $two[$k] );
40
+ }
41
+
42
+ $this->assertEquals( $this->fix_newlines(file_get_contents(dirname(__FILE__).'/testSettingsScreen.html')), $this->fix_newlines($output) );
43
+ }
44
+
45
+ }
test/integration/backend/testProfileScreen.html ADDED
@@ -0,0 +1,54 @@
1
+ <tr class="user-videos">
2
+ <th>Videos</th>
3
+ <td>
4
+ <div class="fv-player-custom-video-list"><form method='POST'><div class="fv-player-custom-video"><div class='fv-player-editor-wrapper' data-key='fv-player-editor-field-_fv_player_user_video'>
5
+ <div class='inside inside-child'>
6
+ <div class='fv-player-editor-preview'><iframe id='fv_vimeo_40a1ea9c2827d8afc50536475564effe' src='//player.vimeo.com/video/255317467' width='640' height='360' frameborder='0' webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
7
+ </div>
8
+ <input class='attachement-shortcode fv-player-editor-field' name='fv_player_videos[_fv_player_user_video][]' type='hidden' value='[fvplayer src=&quot;https://vimeo.com/255317467&quot; playlist=&quot;https://vimeo.com/192934117&quot; caption=&quot;;Talking about FV Player&quot;]' />
9
+ <div class='edit-video' >
10
+ <button class='button fv-player-editor-button'>Edit Video</button>
11
+ <button class='button fv-player-editor-remove'>Remove Video</button>
12
+ <button class='button fv-player-editor-more' style='display:none'>Add Another Video</button>
13
+ </div>
14
+
15
+ <div class='add-video' style="display:none">
16
+ <button class='button fv-player-editor-button'>Add Video</button>
17
+ </div>
18
+ </div>
19
+ </div><div class='fv-player-editor-wrapper' data-key='fv-player-editor-field-_fv_player_user_video'>
20
+ <div class='inside inside-child'>
21
+ <div class='fv-player-editor-preview'><iframe id='fv_vimeo_611247c19e9196fbf9433d589da255e1' src='//player.vimeo.com/video/255370388' width='640' height='360' frameborder='0' webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
22
+ </div>
23
+ <input class='attachement-shortcode fv-player-editor-field' name='fv_player_videos[_fv_player_user_video][]' type='hidden' value='[fvplayer src=&quot;https://vimeo.com/255370388&quot;]' />
24
+ <div class='edit-video' >
25
+ <button class='button fv-player-editor-button'>Edit Video</button>
26
+ <button class='button fv-player-editor-remove'>Remove Video</button>
27
+ <button class='button fv-player-editor-more' style='display:none'>Add Another Video</button>
28
+ </div>
29
+
30
+ <div class='add-video' style="display:none">
31
+ <button class='button fv-player-editor-button'>Add Video</button>
32
+ </div>
33
+ </div>
34
+ </div><div class='fv-player-editor-wrapper' data-key='fv-player-editor-field-_fv_player_user_video'>
35
+ <div class='inside inside-child'>
36
+ <div class='fv-player-editor-preview'><iframe id='fv_ytplayer_5fc2c295c1c8d43b356a8b8ee0c122ca' type='text/html' width='640' height='360'
37
+ src='//www.youtube.com/embed/6ZfuNTqbHE8?origin=' frameborder='0' webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
38
+ ]</div>
39
+ <input class='attachement-shortcode fv-player-editor-field' name='fv_player_videos[_fv_player_user_video][]' type='hidden' value='[fvplayer src=&quot;https://www.youtube.com/watch?v=6ZfuNTqbHE8&quot;]]' />
40
+ <div class='edit-video' >
41
+ <button class='button fv-player-editor-button'>Edit Video</button>
42
+ <button class='button fv-player-editor-remove'>Remove Video</button>
43
+ <button class='button fv-player-editor-more' style='display:none'>Add Another Video</button>
44
+ </div>
45
+
46
+ <div class='add-video' style="display:none">
47
+ <button class='button fv-player-editor-button'>Add Video</button>
48
+ </div>
49
+ </div>
50
+ </div><div style="clear: both"></div>
51
+ </div>
52
+ <input type='hidden' name='fv-player-custom-videos-entity-id[_fv_player_user_video]' value='4' /><input type='hidden' name='fv-player-custom-videos-entity-type[_fv_player_user_video]' value='user' /><input type="hidden" id="fv-player-custom-videos-_fv_player_user_video-0" name="fv-player-custom-videos-_fv_player_user_video-0" value="0926bc6617" /><input type="hidden" name="_wp_http_referer" value="" /><input type='hidden' name='action' value='fv-player-custom-videos-save' /><input type='submit' value='Save Videos' /></form></div> <p class="description">You can put your Vimeo or YouTube links here. <abbr title="These show up as a part of the user bio. Licensed users get FV Player Pro which embeds these video types in FV Player interface without Vimeo or YouTube interface showing up."><span class="dashicons dashicons-editor-help"></span></abbr></p>
53
+ </td>
54
+ </tr>
test/integration/backend/testSettingsScreen.html ADDED
@@ -0,0 +1,2073 @@
1
+ <div class="wrap">
2
+ <div style="position: absolute; margin-top: 10px; right: 10px;">
3
+ <a href="https://foliovision.com/wordpress/plugins/fv-wordpress-flowplayer" target="_blank" title="Documentation"><img alt="visit foliovision" src="//foliovision.com/shared/fv-logo.png" /></a>
4
+ </div>
5
+ <div>
6
+ <div id="icon-options-general" class="icon32"></div>
7
+ <h2>FV Player</h2>
8
+ </div>
9
+
10
+
11
+ <form id="wpfp_options" method="post" action="">
12
+
13
+ <p id="fv_flowplayer_admin_buttons">
14
+ <input type="button" class="button fv-license-inactive" onclick="fv_flowplayer_ajax_check('fv_wp_flowplayer_check_license'); return false" value="Apply Pro upgrade" />
15
+ <input type="button" class="button" onclick="fv_flowplayer_ajax_check('fv_wp_flowplayer_check_template'); return false" value="Check template" />
16
+ <input type="button" class="button" onclick="fv_flowplayer_ajax_check('fv_wp_flowplayer_check_files')" value="Check videos" />
17
+
18
+ <input type="text" name="key" id="key" placeholder="Commercial License Key" value="" /> <a title="Click here for license info" target="_blank" href="https://foliovision.com/player/download"><span class="dashicons dashicons-editor-help"></span></a>
19
+
20
+ <img class="fv_wp_flowplayer_check_license-spin" style="display: none; " src="http://example.org/wp-includes/images/wpspin.gif" width="16" height="16" />
21
+ <img class="fv_wp_flowplayer_check_template-spin" style="display: none; " src="http://example.org/wp-includes/images/wpspin.gif" width="16" height="16" />
22
+ <img class="fv_wp_flowplayer_check_files-spin" style="display: none; " src="http://example.org/wp-includes/images/wpspin.gif" width="16" height="16" />
23
+ </p>
24
+ <div id="fv_flowplayer_admin_notices">
25
+ </div>
26
+
27
+ <div id="fv_flowplayer_ad">
28
+ <div class="text-part">
29
+ <h2>FV Wordpress<strong>Flowplayer</strong></h2>
30
+ <span class="red-text">with your own branding</span>
31
+ <ul>
32
+ <li>Put up your own logo</li>
33
+ <li>Or remove the logo completely</li>
34
+ <li>The best video plugin for Wordpress</li>
35
+ </ul>
36
+ <a href="http://foliovision.com/wordpress/plugins/fv-wordpress-flowplayer/download" class="red-button"><strong>Easter sale!</strong><br />All Licenses 20% Off</a></p>
37
+ </div>
38
+ <div class="graphic-part">
39
+ <a href="http://foliovision.com/wordpress/plugins/fv-wordpress-flowplayer/buy">
40
+ <img width="297" height="239" border="0" src="http://example.org/wp-content/plugins/fv-wordpress-flowplayer/images/fv-wp-flowplayer-led-monitor.png"> </a>
41
+ </div>
42
+ </div>
43
+
44
+ <div id="fv_flowplayer_admin_tabs">
45
+ <h2 class="fv-nav-tab-wrapper nav-tab-wrapper">
46
+ <a href="#postbox-container-tab_basic" class="nav-tab nav-tab-active" style="outline: 0px;">Setup</a>
47
+ <a href="#postbox-container-tab_skin" class="nav-tab" style="outline: 0px;">Skin</a>