PluginProbe
FV Player 8 / trunk
FV Player 8 vtrunk
trunk 8.0.18 8.0.19 8.0.20 8.0.21 8.0.25 8.0.27 8.1 8.1.3
fv-player / includes / fp-api-private.php

fp-api-private.php in FV Player 8 trunk, at includes/fp-api-private.php

979 lines 36.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class FV_Wordpress_Flowplayer_Plugin_Private
4 {
5
6 var $_wp_using_ext_object_cache_prev;
7
8 var $class_name;
9
10 var $license_key;
11
12 var $pointer_boxes;
13
14 var $readme_URL;
15
16 var $strPluginName;
17
18 var $strPluginPath;
19
20 var $strPluginSlug;
21
22 var $strPrivateAPI;
23
24 var $log_file = false;
25 var $log_file_url = false;
26 var $log_is_writable = false;
27
28 function __construct(){
29 $this->class_name = sanitize_title( get_class($this) );
30
31 // get plugin slug based on directory
32 if( empty( $this->strPluginSlug ) ) {
33 $this->strPluginSlug = basename( dirname( __FILE__ ) );
34 }
35
36 if( empty( $this->strPluginName ) ) {
37 $this->strPluginName = $this->strPluginSlug;
38 }
39
40 if( empty( $this->strPluginPath ) ) {
41 $this->strPluginPath = basename(dirname(__FILE__)).'/plugin.php';
42 if( !file_exists( WP_PLUGIN_DIR.'/'.$this->strPluginPath ) ) {
43 $this->strPluginPath = basename(dirname(__FILE__)).'/'.$this->strPluginSlug.'.php';
44 }
45 }
46
47 add_action( 'admin_enqueue_scripts', array( $this, 'pointers_enqueue' ) );
48
49 // store cookie for each dimissed notice first
50 add_action( 'wp_ajax_fv_foliopress_ajax_pointers', array( $this, 'pointers_ajax_cookie' ), 0 );
51 // TODO: What about the actual processing of the Ajax? Does it have to be in the plugin for real?
52 add_action( 'wp_ajax_fv_foliopress_ajax_pointers', array( $this, 'pointers_ajax' ), 999 );
53
54 add_filter( 'plugins_api_result', array( $this, 'changelog_filter' ), 5, 3 );
55
56 add_filter( 'pre_set_transient_'.$this->strPluginSlug . '_license', array( $this, 'object_cache_disable' ) );
57 add_filter( 'pre_transient_'.$this->strPluginSlug . '_license', array( $this, 'object_cache_disable' ) );
58 add_action( 'delete_transient_'.$this->strPluginSlug . '_license', array( $this, 'object_cache_disable' ) );
59 add_action( 'set_transient_'.$this->strPluginSlug . '_license', array( $this, 'object_cache_disable' ) );
60 add_filter( 'transient_'.$this->strPluginSlug . '_license', array( $this, 'object_cache_enable' ) );
61 add_action( 'deleted_transient_'.$this->strPluginSlug . '_license', array( $this, 'object_cache_disable' ) );
62
63 //add_action('admin_head', array($this, 'welcome_screen_remove_menus'));
64 }
65
66 public function get_filesystem() {
67 if ( ! class_exists( 'WP_Filesystem_Direct' ) ) {
68 require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
69 require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';
70 }
71
72 return new WP_Filesystem_Direct( new StdClass() );
73 }
74
75 public function log( $message = '' ) {
76 if ( $this->log_file && $this->log_is_writable ) {
77 $fs = $this->get_filesystem();
78
79 $message = gmdate( 'Y-n-d H:i:s' ) . ' - ' . $message . "\r\n";
80
81 $content = $this->log_file_get_content();
82 $content .= $message;
83 $fs->put_contents( $this->log_file, $content, FILE_APPEND );
84 $fs->chmod( $this->log_file, 0664 );
85 }
86 }
87
88 public function log_file_delete() {
89 $fs = $this->get_filesystem();
90
91 if ( $this->log_file && $this->log_is_writable ) {
92 return $fs->delete( $this->log_file );
93 }
94 return false;
95 }
96
97 public function log_file_get_content() {
98 $fs = $this->get_filesystem();
99
100 if ( $this->log_file && $this->log_is_writable ) {
101 return $fs->get_contents( $this->log_file );
102 }
103 return false;
104 }
105
106 public function log_file_settings_field() {
107 if ( ! empty( $this->log_file ) && $this->log_is_writable ) : ?>
108 Logging into <a href="<?php echo $this->log_file_url; ?>" target="_blank"><?php echo basename( $this->log_file ); ?></a>. Disabling Debug will delete the log file.
109 <?php elseif ( ! empty( $this->log_file ) && ! $this->log_is_writable ) : ?>
110 Unable to write the log file.
111 <?php else : ?>
112 Log file failed to create for unknown reasons.
113 <?php endif;
114 }
115
116 public function log_file_setup() {
117 $fs = $this->get_filesystem();
118
119 if ( ! empty( $fs ) ) {
120 $upload_dir = wp_upload_dir();
121 $filename = $this->strPluginSlug . '-debug-' . wp_hash( home_url( '/' ) ) . '.log';
122 $this->log_file = trailingslashit( $upload_dir['basedir'] ) . $filename;
123 $this->log_file_url = trailingslashit( $upload_dir['baseurl'] ) . $filename;
124
125 if ( $fs->is_writable( $upload_dir['basedir'] ) ) {
126 $this->log_is_writable = true;
127
128 $content = $this->log_file_get_content();
129 if ( empty( $content ) ) {
130 $this->log( "Log file created." );
131 }
132 }
133
134 }
135 }
136
137 function object_cache_disable($value=null){
138 global $_wp_using_ext_object_cache;
139 $this->_wp_using_ext_object_cache_prev = $_wp_using_ext_object_cache;
140 $_wp_using_ext_object_cache = false;
141 return $value;
142 }
143
144 function object_cache_enable($value=null){
145 global $_wp_using_ext_object_cache;
146 $_wp_using_ext_object_cache = $this->_wp_using_ext_object_cache_prev;
147 return $value;
148 }
149
150 function http_request_args( $params ) {
151 $aArgs = func_get_args();
152 $url = $aArgs[1];
153
154 if( stripos($url,'foliovision.com') === false ) {
155 return $params;
156 }
157
158 add_filter( 'https_ssl_verify', '__return_false' );
159 return $params;
160 }
161
162 function is_min_wp( $version ) {
163 return version_compare( $GLOBALS['wp_version'], $version. 'alpha', '>=' );
164 }
165
166
167 public static function get_plugin_path( $slug ){
168 $aPluginSlugs = get_transient('plugin_slugs');
169 $aPluginSlugs = is_array($aPluginSlugs) ? $aPluginSlugs : array( $slug.'/'.$slug.'.php');
170 $aActivePlugins = get_option('active_plugins');
171 $aInactivePlugins = array_diff($aPluginSlugs,$aActivePlugins);
172
173 if( !$aPluginSlugs )
174 return false;
175
176 foreach( $aActivePlugins as $item ){
177 if( stripos($item,$slug.'.php') !== false && !is_wp_error(validate_plugin($item)) )
178 return $item;
179 }
180
181 $sPluginFolder = plugin_dir_path( dirname( dirname(__FILE__) ) );
182 foreach( $aInactivePlugins as $item ){
183 if( stripos($item,$slug.'.php') !== false && file_exists($sPluginFolder.$item) )
184 return $item;
185 }
186
187 return false;
188 }
189
190
191 private function check_license_remote( $args = array() ) {
192
193 if( !isset($this->strPluginSlug) || empty($this->strPluginSlug)
194 || !isset($this->version) || empty($this->version)
195 || !isset($this->license_key) || $this->license_key === FALSE ) {
196 return false;
197 }
198
199 $defaults = array(
200 'action' => 'check',
201 'core_ver' => false,
202 'key' => !empty( $this->license_key) ? $this->license_key : false,
203 'plugin' => $this->strPluginSlug,
204 'type' => home_url(),
205 'version' => $this->version,
206 );
207 $body_args = wp_parse_args( $args, $defaults );
208
209 $post = array(
210 'body' => $body_args,
211 'timeout' => 20,
212 'user-agent' => $this->strPluginSlug.'-'.$this->version
213 );
214 $resp = wp_remote_post( 'https://license.foliovision.com/?fv_remote=true', $post );
215 if( !is_wp_error($resp) && isset($resp['body']) && $resp['body'] && $data = json_decode( preg_replace( '~[\s\s]*?<FVFLOWPLAYER>(.*?)</FVFLOWPLAYER>[\s\s]*?~', '$1', $resp['body'] ) ) ) {
216 return $data;
217
218 } else if( is_wp_error($resp) ) {
219 $post['sslverify'] = false;
220 $resp = wp_remote_post( 'https://license.foliovision.com/?fv_remote=true', $post );
221
222 if( !is_wp_error($resp) && isset($resp['body']) && $resp['body'] && $data = json_decode( preg_replace( '~[\s\S]*?<FVFLOWPLAYER>(.*?)</FVFLOWPLAYER>[\s\S]*?~', '$1', $resp['body'] ) ) ) {
223 return $data;
224 }
225
226 }
227
228 return false;
229 }
230
231 // set force = true to delete transient and recheck license
232 function setLicenseTransient( $force = false ){
233 $strTransient = $this->strPluginSlug . '_license';
234
235 if( $force )
236 delete_transient( $strTransient );
237
238 //is transiet set?
239 if ( false !== ( $aCheck = get_transient( $strTransient ) ) )
240 return;
241
242 $aCheck = $this->check_license_remote( );
243 if( $aCheck ) {
244 set_transient( $strTransient, $aCheck, 60*60*24 );
245 } else {
246 set_transient( $strTransient, json_decode( wp_json_encode( array('error' => 'Error checking license') ), FALSE ), 60*10 );
247 }
248 }
249
250
251 function checkLicenseTransient(){
252 $aCheck = get_transient( $this->strPluginSlug . '_license' );
253 return isset($aCheck->valid) && $aCheck->valid;
254 }
255
256 function getUpgradeUrl(){
257 $aCheck = get_transient( $this->strPluginSlug . '_license' );
258 if( isset($aCheck->upgrade) && !empty($aCheck->upgrade) ) {
259 return $aCheck->upgrade;
260 } else {
261 return false;
262 }
263 }
264
265
266 /// ================================================================================================
267 /// Custom plugin repository
268 /// ================================================================================================
269
270 /*
271 Uses:
272 $this->strPluginSlug - this has to be in plugin object
273 $this->strPrivateAPI - also
274
275 */
276
277 private function PrepareRequest( $action, $args ){
278 global $wp_version;
279
280 return array(
281 'body' => array(
282 'action' => $action,
283 'request' => serialize($args),
284 'api-key' => md5(get_bloginfo('url'))
285 ),
286 'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo('url')
287 );
288 }
289
290 public function CheckPluginUpdate( $checked_data ){
291 $plugin_path = $this->strPluginPath;
292 $request_args = array( 'slug' => $this->strPluginSlug );
293 if( !empty( $checked_data->checked ) && empty($this->version) ){
294 $request_args['version'] = isset($checked_data->checked[$plugin_path]) ? $checked_data->checked[$plugin_path] : '0.1';
295 }
296 else{
297 if( !function_exists('get_plugins') ) return $checked_data;
298
299 $cache_plugins = get_plugins();
300
301 if( empty($cache_plugins[$plugin_path]['Version']) ){
302 return $checked_data;
303 }
304 $request_args['version'] = $this->version ? $this->version : $cache_plugins[$plugin_path]['Version'];
305 }
306
307 $request = $this->PrepareRequest( 'basic_check', $request_args );
308
309 $sTransient = $this->strPluginSlug.'_fp-private-updates-api-'.sanitize_title($request_args['version']);
310 $response = get_transient( $sTransient );
311
312 if( !$response ){
313 if( stripos($this->strPrivateAPI,'plugins.trac.wordpress.org') === false ) {
314 $raw_response = wp_remote_post( $this->strPrivateAPI, $request );
315 if( is_wp_error($raw_response) ) {
316 $request['sslverify'] = false;
317 $raw_response = wp_remote_post( $this->strPrivateAPI, $request );
318 }
319 } else {
320 $raw_response = wp_remote_get( $this->strPrivateAPI );
321 }
322
323 if( !is_wp_error( $raw_response ) && ( $raw_response['response']['code'] == 200 ) ) {
324 $response = @unserialize( preg_replace( '~^/\*[\s\S]*?\*/\s+~', '', $raw_response['body'] ) );
325 if( !$response ) $response = $raw_response['body'];
326 }
327
328 set_transient( $sTransient, $response, 3600 );
329 }
330
331 if( isset($response->version) && version_compare( $response->version, $request_args['version'] ) == 1 ){
332 if( is_object( $response ) && !empty( $response ) ) // Feed the update data into WP updater
333 $checked_data->response[ $plugin_path ] = $response;
334 }
335
336 return $checked_data;
337 }
338
339 public function CheckPluginUpdateOld( $aData = null ){
340 $aData = get_transient( "update_plugins" );
341 $aData = $this->CheckPluginUpdate( $aData );
342 set_transient( "update_plugins", $aData );
343
344 if( function_exists( "set_site_transient" ) ) set_site_transient( "update_plugins", $aData );
345 }
346
347 public function PluginAPICall( $def, $action, $args ){
348 if( !isset($args->slug) || $args->slug != $this->strPluginSlug ) return $def;
349
350 // Get the current version
351 $plugin_info = get_site_transient( 'update_plugins' );
352 $current_version = ( isset($plugin_info->response[$this->strPluginPath]) ) ? $plugin_info->response[$this->strPluginPath] : false;
353 $args->version = $current_version;
354
355 $request_string = $this->PrepareRequest( $action, $args );
356
357 $request = wp_remote_post( $this->strPrivateAPI, $request_string );
358
359 if( is_wp_error( $request ) ) {
360 $res = new WP_Error( 'plugins_api_failed', __( 'An Unexpected HTTP Error occurred during the API request.</p> <p><a href="?" onclick="document.location.reload(); return false;">Try again</a>' ), $request->get_error_message() );
361 }else{
362 $res = unserialize( preg_replace( '~^/\*[\s\S]*?\*/\s+~', '', $request['body'] ) );
363 if( $res === false ) $res = new WP_Error( 'plugins_api_failed', __( 'An unknown error occurred' ), $request['body'] );
364 }
365
366 return $res;
367 }
368
369
370 public function plugin_update_message() {
371 if( $this->readme_URL ) {
372 $data = $this->get_readme_url_remote( $this->readme_URL );
373 if( $data ) {
374 $matches = null; /// not sure if this works for more than one last changelog
375 //if (preg_match('~==\s*Changelog\s*==\s*=\s*[0-9.]+\s*=(.*)(=\s*[0-9.]+\s*=|$)~Uis', $data, $matches)) {
376 if (preg_match('~==\s*Upgrade Notice\s*==\s*=\s*[0-9.]+\s*=(.*)(=\s*[0-9.]+\s*=|$)~Uis', $data, $matches)) {
377 $changelog = (array) preg_split('~[\r\n]+~', trim($matches[1]));
378
379 $ul = false;
380 foreach ($changelog as $index => $line) {
381 if (preg_match('~^\s*\*\s*~', $line) && 1<0 ) {
382 if (!$ul) {
383 //echo '<ul style="list-style: disc; margin-left: 20px;">';
384 $ul = true;
385 }
386 $line = preg_replace('~^\s*\*\s*~', '', htmlspecialchars($line));
387 echo '<li style="width: 50%; margin: 0; float: left; ' . ($index % 2 == 0 ? 'clear: left;' : '') . '">' . $line . '</li>';
388 } else {
389 if ($ul) {
390 //echo '</ul><div style="clear: left;"></div>';
391 $ul = false;
392 }
393 $line = preg_replace('~^\s*\*\s*~', '', htmlspecialchars($line));
394 echo '<br /><br />' . htmlspecialchars($line)."\n";
395 }
396 }
397
398 if ($ul) {
399 //echo '</ul><div style="clear: left;"></div>';
400 }
401 }
402 }
403 }
404 }
405
406
407 function pointers_ajax() {
408 if( $this->pointer_boxes ) {
409 foreach( $this->pointer_boxes AS $sKey => $aPopup ) {
410 if( sanitize_key( $_POST['key'] ) == $sKey ) {
411 check_ajax_referer($sKey);
412 }
413 }
414 }
415 }
416
417
418 function pointers_ajax_cookie() {
419 $cookie = $this->pointers_get_cookie();
420
421 $cookie[ sanitize_key( $_POST['key'] ) ] = !empty($_POST['value']) ? sanitize_text_field( $_POST['value'] ) : true;
422
423 $secure = ( 'https' === wp_parse_url( home_url(), PHP_URL_SCHEME ) );
424 setcookie( $this->class_name.'_store_answer', wp_json_encode($cookie), time() + YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN, $secure );
425 }
426
427
428 function pointers_enqueue() {
429 global $wp_version;
430 if( ! current_user_can( 'manage_options' ) || ( isset($this->pointer_boxes) && count( $this->pointer_boxes ) == 0 ) || version_compare( $wp_version, '3.4', '<' ) ) {
431 return;
432 }
433
434 wp_enqueue_style( 'wp-pointer' );
435 wp_enqueue_script( 'jquery-ui' );
436 wp_enqueue_script( 'wp-pointer' );
437 wp_enqueue_script( 'utils' );
438
439 add_action( 'admin_print_footer_scripts', array( $this, 'pointers_init_scripts' ) );
440 }
441
442
443 /**
444 * Get a cookie storing which pointers were already dimissed
445 * The cookie uses JSON so we decode it too
446 *
447 * @return array
448 */
449 function pointers_get_cookie() {
450 $cookie_name = $this->class_name.'_store_answer';
451
452 $cookie = false;
453 if( !empty($_COOKIE[$cookie_name]) ) {
454 $cookie = sanitize_text_field( $_COOKIE[$cookie_name] );
455 }
456
457 $cookie = (array) json_decode( stripslashes($cookie) );
458
459 $json_error = json_last_error();
460 if( $json_error !== JSON_ERROR_NONE ) {
461 $cookie = array();
462 }
463
464 return $cookie;
465 }
466
467
468 private function get_readme_url_remote( $url = false ) { // todo: caching
469 $output = false;
470
471 if( $url ) {
472 $response = wp_remote_get( $url );
473 if( !is_wp_error($response) ) {
474 $output = $response['body'];
475 }
476 } else {
477 if( !isset($this->strPluginSlug) || empty($this->strPluginSlug) || !isset($this->version) || empty($this->version) )
478 return false;
479
480 $args = array(
481 'body' => array( 'plugin' => $this->strPluginSlug, 'version' => $this->version, 'type' => home_url() ),
482 'timeout' => 20,
483 'user-agent' => $this->strPluginSlug.'-'.$this->version
484 );
485 $resp = wp_remote_post( 'https://license.foliovision.com/?fv_remote=true&readme=1', $args );
486
487 if( !is_wp_error($resp) && isset($resp['body']) && $resp['body'] ) {
488 $output = $resp['body'];
489
490 } else if( is_wp_error($resp) ) {
491 $args['sslverify'] = false;
492 $resp = wp_remote_post( 'https://license.foliovision.com/?fv_remote=true', $args );
493
494 if( !is_wp_error($resp) && isset($resp['body']) && $resp['body'] ) {
495 $output = $resp['body'];
496 }
497
498 }
499 }
500
501 return $output;
502 }
503
504
505 function changelog_filter( $res, $action, $args ){
506
507 if( !isset( $args->slug ) || $args->slug != $this->strPluginSlug )
508 return $res;
509
510 if(isset($args->fv_readme_file)){
511 global $wp_filesystem;
512 $data = $wp_filesystem->get_contents( $args->fv_readme_file );
513 } else if( $this->readme_URL ) {
514 $data = $this->get_readme_url_remote( $this->readme_URL );
515 } else {
516 $data = $this->get_readme_url_remote();
517 }
518 if( !$data )
519 return $res;
520
521 /**
522 * Some users run into issue that the function was not defined.
523 * Did some other plugin run plugins_api_result in front end? Seems like security-malware-firewall.
524 * Let's just give up in such case.
525 */
526 if ( ! function_exists( 'get_plugin_data' ) ) {
527 return $res;
528 }
529
530 $plugin_data = get_plugin_data($this->strPluginPath);
531
532 $pluginReq = preg_match( '~Requires at least:\s*([0-9.]*)~', $data, $reqMatch ) ? $reqMatch[1] : false;
533 $pluginUpto = preg_match( '~Tested up to:\s*([0-9.]*)~', $data, $uptoMatch ) ? $uptoMatch[1] : false;
534
535 $changelogOut = '';
536 if( preg_match('~==\s*Changelog\s*==(.*)~si', $data, $match) ){
537 $changelogPart = preg_replace('~==.*~','',$match[1]);
538 $version = preg_match('~=\s*([0-9.]+).*=~', $changelogPart, $verMatch ) ? $verMatch[1] : false;
539
540 $changelog = (array) preg_split('~[\r\n]+~', trim($changelogPart));
541 $ul = false;
542 $changelogFinish = false;
543 $changelogCounter = 0;
544 foreach ($changelog as $index => $line) {
545 if (preg_match('~^\s*\*\s*~', $line)) {
546 if (!$ul) {
547 $changelogOut .= '<ul style="list-style: disc; margin-left: 20px;">';
548 $ul = true;
549 }
550 $line = preg_replace('~^\s*\*\s*~', '', htmlspecialchars($line));
551 $changelogOut .= '<li style="width: 50%; margin: 0; float: left; ' . ($index % 2 == 0 ? 'clear: left;' : '') . '">' . $line . '</li>';
552 } else {
553 if ($ul) {
554 $changelogOut .= '</ul><div style="clear: left;"></div>';
555 $ul = false;
556 }
557
558 $strong = $strongEnd = '';
559 if( preg_match('~^=(.*)=$~', $line ) ){
560 $strong = '<strong>';
561 $strongEnd = '</strong>';
562 $line = preg_replace('~^=(.*)=$~', '$1', $line );
563 if(isset($args->fv_prev_ver)){
564 if(($args->fv_prev_ver == false || $args->fv_prev_ver === $this->version ) ){
565 if(++$changelogCounter > 3){
566 $changelogFinish = true;
567 }
568 }elseif(strpos($line,str_replace('.beta','',$args->fv_prev_ver . ' ')) !== false){
569 $changelogFinish = true;
570 }
571 }
572 }
573 if ($changelogFinish) {
574 break;
575 }
576 $changelogOut .= '<p style="margin: 5px 0;">' .$strong. htmlspecialchars($line) .$strongEnd. '</p>';
577
578 }
579
580 }
581 if ($ul) {
582 $changelogOut .= '</ul><div style="clear: left;"></div>';
583 }
584 $changelogOut .= '</div>';
585 }
586
587 $res = (object) array(
588 'name' => $plugin_data['Name'],
589 'slug' => false,
590 'version' => $version,
591 'author' => $plugin_data['Author'],
592 'requires' => $pluginReq,
593 'tested' => $pluginUpto,
594 'homepage' => $plugin_data['PluginURI'],
595 'sections' =>
596 array (
597 'support' => 'Use support forum at <a href="https://foliovision.com/support/">foliovison.com/support</a>',
598 'changelog' => $changelogOut,
599 ),
600 'donate_link' => NULL
601 );
602
603 return $res;
604
605 }
606
607
608 //notification boxes
609 function pointers_init_scripts() {
610 if( !isset($this->pointer_boxes) || !$this->pointer_boxes ) {
611 return;
612 }
613
614 ?>
615 <script type="text/javascript">
616 //<![CDATA[
617 function <?php echo esc_attr( $this->class_name ); ?>_store_answer(key, input, nonce) {
618 jQuery.post(ajaxurl, { action : 'fv_foliopress_ajax_pointers', key : key, value : input, _ajax_nonce : nonce }, function () {
619 jQuery('#wp-pointer-0').remove(); // there must only be a single pointer at once. Or perhaps it removes them all, but the ones which were not dismissed by Ajax by storing the option will turn up again?
620 });
621 }
622
623 /*! js-cookie v3.0.1 | MIT */
624 !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self,function(){var n=e.Cookies,o=e.Cookies=t();o.noConflict=function(){return e.Cookies=n,o}}())}(this,(function(){"use strict";function e(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)e[o]=n[o]}return e}return function t(n,o){function r(t,r,i){if("undefined"!=typeof document){"number"==typeof(i=e({},o,i)).expires&&(i.expires=new Date(Date.now()+864e5*i.expires)),i.expires&&(i.expires=i.expires.toUTCString()),t=encodeURIComponent(t).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape);var c="";for(var u in i)i[u]&&(c+="; "+u,!0!==i[u]&&(c+="="+i[u].split(";")[0]));return document.cookie=t+"="+n.write(r,t)+c}}return Object.create({set:r,get:function(e){if("undefined"!=typeof document&&(!arguments.length||e)){for(var t=document.cookie?document.cookie.split("; "):[],o={},r=0;r<t.length;r++){var i=t[r].split("="),c=i.slice(1).join("=");try{var u=decodeURIComponent(i[0]);if(o[u]=n.read(c,u),e===u)break}catch(e){}}return e?o[e]:o}},remove:function(t,n){r(t,"",e({},n,{expires:-1}))},withAttributes:function(n){return t(this.converter,e({},this.attributes,n))},withConverter:function(n){return t(e({},this.converter,n),this.attributes)}},{attributes:{value:Object.freeze(o)},converter:{value:Object.freeze(n)}})}({read:function(e){return'"'===e[0]&&(e=e.slice(1,-1)),e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent)},write:function(e){return encodeURIComponent(e).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,decodeURIComponent)}},{path:"/"})}));
625
626 //]]>
627 </script>
628 <?php
629 $cookie = $this->pointers_get_cookie();
630
631 foreach( $this->pointer_boxes AS $key => $args ) {
632 // Some users are experiencing issues when dismissing the notices
633 // So we use cookies as a backup to not show the same notice twice
634 if( !empty($cookie[$key]) ) {
635 continue;
636 }
637
638 $nonce = wp_create_nonce( $key );
639
640 $args = wp_parse_args( $args, array(
641 'button1' => false, // req
642 'button2' => false,
643 'function1' => $this->class_name.'_store_answer("'.$key.'", "' . ( ! empty( $args['value1'] ) ? esc_js( $args['value1'] ) : 'true' ) . '","' . $nonce . '")',
644 'function2' => $this->class_name.'_store_answer("'.$key.'", "false","' . $nonce . '")',
645 'heading' => false, // req
646 'id' => false, // req
647 'content' => false, // req
648 'position' => array( 'edge' => 'top', 'align' => 'center' ),
649 ) );
650
651 extract($args);
652
653 $html = '<h3>'.$heading.'</h3>';
654 if( stripos( $content, '</p>' ) !== false ) {
655 $html .= $content;
656 } else {
657 $html .= '<p>'.$content.'</p>';
658 }
659
660 ?>
661 <script type="text/javascript">
662 //<![CDATA[
663 (function ($) {
664 store_cookie_js = function(value , key) {
665 var cookie_name = '<?php echo esc_attr( $this->class_name ) . '_store_answer'; ?>';
666 var pointer_cookies = JSON.parse( Cookies.get(cookie_name) );
667 pointer_cookies[key] = value;
668 Cookies.set(cookie_name, JSON.stringify(pointer_cookies) , { secure: location.protocol == 'https:', expires: 365 } )
669 jQuery('#wp-pointer-0').remove();
670 }
671
672 var pointer_options = <?php echo wp_json_encode( array( 'pointerClass' => $key, 'content' => $html, 'position' => $position ) ); ?>,
673 key = '<?php echo esc_attr( $key ); ?>',
674
675 setup = function () {
676 $('<?php echo esc_attr( $id ); ?>').pointer(pointer_options).pointer('open');
677 var buttons = $('.<?php echo esc_attr( $key ); ?> .wp-pointer-buttons').html('');
678 buttons.append( $('<a style="margin-left:5px" class="button-primary">' + '<?php echo addslashes($button1); ?>' + '</a>').on('click.pointer', function () { <?php echo wp_kses_post( $function1 ); ?>; store_cookie_js('true' , key); }));
679 <?php if ( $button2 ) { ?>
680 buttons.append( $('<a class="button-secondary">' + '<?php echo addslashes($button2); ?>' + '</a>').on('click.pointer', function () { <?php echo wp_kses_post( $function2 ); ?>; store_cookie_js('false', key); }));
681 <?php } ?>
682 };
683
684 if(pointer_options.position && pointer_options.position.defer_loading)
685 $(window).bind('load.wp-pointers', setup);
686 else
687 $(document).ready(setup);
688 })(jQuery);
689 //]]>
690 </script>
691 <?php
692 }
693 }
694
695 function change_transient_expiration( $transient_name, $time ){
696 $transient_val = get_transient($transient_name);
697 if( $transient_val ){
698 set_transient($transient_name,$transient_val,$time);
699 return true;
700 }
701 return false;
702 }
703
704
705 function domain_key_update() {
706
707 $data = $this->check_license_remote( array('action' => 'key_update') );
708
709 if( isset($data->domain) ) { // todo: test
710 if( $data->domain && $data->key && stripos( home_url(), $data->domain ) !== false ) {
711 $this->license_key = $data->key;
712 do_action( $this->strPluginSlug.'_admin_key_update', $this->license_key );
713
714 $this->change_transient_expiration( $this->strPluginSlug."_license", 1 );
715 // change the expiration to license renew by: $this->setLicenseTransient( true );
716
717 //fv_wp_flowplayer_delete_extensions_transients(5);
718 return $data->key;
719 }
720 } else if( isset($data->expired) && $data->expired && isset($data->message) ){
721
722 update_option( 'fv_'.$this->strPluginSlug.'_deferred_notices', $data->message );
723 return false;
724 } else {
725 $message = 'FV Player License upgrade failed - please check if you are running the plugin on your licensed domain.';
726 update_option( 'fv_'.$this->strPluginSlug.'_deferred_notices', $message );
727 return false;
728 }
729 }
730
731 function pro_install_talk( $content, $url ) {
732 $content = preg_replace( '~<h3.*?</h3>~', '<h3>'.$this->strPluginName.' auto-installation</h3><p>As a license holder, we would like to automatically install our Pro extension for you.</p>', $content );
733 $content = preg_replace( '~(<input[^>]*?type="submit"[^>]*?>)~', '$1 <a href="'.$url.'">Skip the Pro addon install</a>', $content );
734 return $content;
735 }
736
737 //search for plugin path with {slug}.php
738 function get_extension_path( $slug ){
739 $aPluginSlugs = get_transient('plugin_slugs');
740 $aPluginSlugs = is_array($aPluginSlugs) ? $aPluginSlugs : array( 'fv-player-pro/fv-player-pro.php');
741 $aActivePlugins = get_option('active_plugins');
742 $aInactivePlugins = array_diff($aPluginSlugs,$aActivePlugins);
743
744 if( !$aPluginSlugs )
745 return false;
746 foreach( $aActivePlugins as $item ){
747 if( stripos($item,$slug.'.php') !== false )
748 return $item;
749 }
750
751 foreach( $aInactivePlugins as $item ){
752 if( stripos($item,$slug.'.php') !== false )
753 return $item;
754 }
755
756 return false;
757 }
758
759
760 public static function install_form_text( $html, $name ) {
761 $tag = stripos($html,'</h3>') !== false ? 'h3' : 'h2';
762 $html = preg_replace( '~<'.$tag.'.*?</'.$tag.'>~', '<'.$tag.'>'.$name.' auto-installation</'.$tag.'>', $html );
763 $html = preg_replace( '~(<input[^>]*?type="submit"[^>]*?>)~', '$1 <a href="'.admin_url('admin.php?page=fvplayer').'">Skip the '.$name.' install</a>', $html );
764 return $html;
765 }
766
767
768 public static function install_plugin( $name, $plugin_package, $plugin_basename, $download_url, $settings_url, $option, $nonce ) { // 'FV Player Pro', 'fv-player-pro', '/wp-admin/admin.php?page=fvplayer', download URL (perhaps from the license), settings URL (use admin_url(...), should also contain some GET which will make it install the extension if present) and option where result message should be stored and a nonce which should be passed
769 global $hook_suffix;
770
771 $plugin_path = self::get_plugin_path( str_replace( '_', '-', $plugin_package ) );
772 if( !defined('PHPUnitTestMode') && $plugin_path ) {
773 $result = activate_plugin( $plugin_path, $settings_url );
774 if ( is_wp_error( $result ) ) {
775 update_option( $option, $name.' extension activation error: '.$result->get_error_message() );
776 return false;
777 } else {
778 update_option( $option, $name.' extension activated' );
779 return true; // already installed
780 }
781 }
782
783 $plugin_basename = $plugin_path ? $plugin_path : $plugin_basename;
784
785 $url = wp_nonce_url( $settings_url, $nonce, 'nonce_'.$nonce );
786
787 set_current_screen();
788
789 ob_start();
790 if ( false === ( $creds = request_filesystem_credentials( $url, '', false, false, false ) ) ) {
791 $form = ob_get_clean();
792 include( ABSPATH . 'wp-admin/admin-header.php' );
793 echo self::install_form_text($form, $name);
794 include( ABSPATH . 'wp-admin/admin-footer.php' );
795 die;
796 }
797
798 if ( ! WP_Filesystem( $creds ) ) {
799 ob_start();
800 request_filesystem_credentials( $url, $method, true, false, false );
801 $form = ob_get_clean();
802 include( ABSPATH . 'wp-admin/admin-header.php' );
803 echo self::install_form_text($form, $name);
804 include( ABSPATH . 'wp-admin/admin-footer.php' );
805 die;
806 }
807
808 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
809
810 $result = true;
811
812 if( !$plugin_path || is_wp_error(validate_plugin($plugin_basename)) ) {
813 $sTaskDone = $name.__( ' extension installed successfully!', 'fv-player' );
814
815 echo '<div style="display: none;">';
816 $objInstaller = new Plugin_Upgrader();
817 $objInstaller->install( $download_url );
818 echo '</div>';
819 wp_cache_flush();
820
821 if ( is_wp_error( $objInstaller->skin->result ) ) {
822 update_option( $option, $name.__( ' extension install failed - ', 'fv-player' ) . $objInstaller->skin->result->get_error_message() );
823 $result = false;
824 } else {
825 if ( $objInstaller->plugin_info() ) {
826 $plugin_basename = $objInstaller->plugin_info();
827 }
828
829 $activate = activate_plugin( $plugin_basename );
830 if ( is_wp_error( $activate ) ) {
831 update_option( $option, $name.__( ' extension install failed - ', 'fv-player' ) . $activate->get_error_message());
832 $result = false;
833 }
834 }
835
836 } else if( $plugin_path ) {
837 $sTaskDone = $name.__( ' extension upgraded successfully!', 'fv-player' );
838
839 echo '<div style="display: none;">';
840 $objInstaller = new Plugin_Upgrader();
841 $objInstaller->upgrade( $plugin_path );
842 echo '</div></div>'; // explanation: extra closing tag just to be safe (in case of "The plugin is at the latest version.")
843 wp_cache_flush();
844
845 if ( is_wp_error( $objInstaller->skin->result ) ) {
846 update_option( $option, $name.' extension upgrade failed - '.$objInstaller->skin->result->get_error_message() );
847 $result = false;
848 } else {
849 if ( $objInstaller->plugin_info() ) {
850 $plugin_basename = $objInstaller->plugin_info();
851 }
852
853 $activate = activate_plugin( $plugin_basename );
854 if ( is_wp_error( $activate ) ) {
855 update_option( $option, $name.' Pro extension upgrade failed - '.$activate->get_error_message() );
856 $result = false;
857 }
858 }
859
860 }
861
862 if( $result ) {
863 update_option( $option, $sTaskDone );
864 echo "<script>location.href='" . esc_html( sanitize_url( $settings_url ) ) . "';</script>";
865 }
866
867 return $result;
868 }
869
870
871 function install_pro_version( $plugin_package = false, $target_url = false ) {
872
873 $aPluginInfo = get_transient( $this->strPluginSlug.'_license' );
874 if( $plugin_package && isset( $aPluginInfo->{$plugin_package} ) ) {
875 $plugin_basename = $aPluginInfo->{$plugin_package}->slug;
876 $download_url = $aPluginInfo->{$plugin_package}->url;
877 }
878 else {
879 $plugin_basename = file_exists( WP_PLUGIN_DIR.'/'.$this->strPluginSlug.'/plugin.php' ) ? $this->strPluginSlug.'/plugin.php' : $this->strPluginSlug.'/'.$this->strPluginSlug.'.php';
880 $download_url = $aPluginInfo->url;
881 $plugin_package = $this->strPluginSlug;
882 }
883
884 $aInstalled = get_option( $this->strPluginSlug.'_extension_install', array() );
885 $aInstalled = array_merge( $aInstalled, array( $plugin_package => false ) );
886 update_option( $this->strPluginSlug.'_extension_install', $aInstalled );
887
888 $sPluginBasenameReal = $this->get_extension_path( str_replace( '_', '-', $plugin_package ) );
889 $plugin_basename = $sPluginBasenameReal ? $sPluginBasenameReal : $plugin_basename;
890
891 $url = ( $target_url ) ? $target_url : site_url().'/wp-admin/plugins.php';
892 $url = wp_nonce_url( $url );
893
894 set_current_screen();
895
896 ob_start();
897 if ( false === ( $creds = request_filesystem_credentials( $url, '', false, false, false ) ) ) {
898 $form = ob_get_clean();
899 include( ABSPATH . 'wp-admin/admin-header.php' );
900 echo wp_kses_post( $this->pro_install_talk( $form, $target_url ) );
901 include( ABSPATH . 'wp-admin/admin-footer.php' );
902 die;
903 }
904
905 if ( ! WP_Filesystem( $creds ) ) {
906 ob_start();
907 request_filesystem_credentials( $url, $method, true, false, false );
908 $form = ob_get_clean();
909 include( ABSPATH . 'wp-admin/admin-header.php' );
910 echo wp_kses_post( $this->pro_install_talk( $form, $target_url ) );
911 include( ABSPATH . 'wp-admin/admin-footer.php' );
912 die;
913 }
914
915 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
916
917 if( !$sPluginBasenameReal || is_wp_error(validate_plugin($plugin_basename)) ) {
918 $sTaskDone = $this->strPluginName.' has been installed!';
919 echo '<div style="display: none;">';
920 $objInstaller = new Plugin_Upgrader();
921 $objInstaller->install( $download_url );
922 echo '</div>';
923 wp_cache_flush();
924
925 if ( is_wp_error( $objInstaller->skin->result ) ) {
926
927 update_option( $this->strPluginSlug.'_deferred_notices', $this->strPluginName.' install failed - '. $objInstaller->skin->result->get_error_message() );
928 $bResult = false;
929 }
930 else {
931 if ( $objInstaller->plugin_info() ) {
932 $plugin_basename = $objInstaller->plugin_info();
933 }
934
935 $activate = activate_plugin( $plugin_basename );
936 if ( is_wp_error( $activate ) ) {
937 update_option( $this->strPluginSlug.'_deferred_notices', $this->strPluginName.' install failed - '. $activate->get_error_message() );
938 $bResult = false;
939 }
940 }
941 }
942 else if( $sPluginBasenameReal ) {
943 $sTaskDone = $this->strPluginName.' upgraded successfully!';
944 echo '<div style="display: none;">';
945 $objInstaller = new Plugin_Upgrader();
946 $objInstaller->upgrade( $sPluginBasenameReal );
947 echo '</div></div>'; // explanation: extra closing tag just to be safe (in case of "The plugin is at the latest version.")
948 wp_cache_flush();
949
950 if ( is_wp_error( $objInstaller->skin->result ) ) {
951 update_option( $this->strPluginSlug.'_deferred_notices', $this->strPluginName.' extension upgrade failed - '.$objInstaller->skin->result->get_error_message() );
952 $bResult = false;
953 }
954 else {
955 if ( $objInstaller->plugin_info() ) {
956 $plugin_basename = $objInstaller->plugin_info();
957 }
958
959 $activate = activate_plugin( $plugin_basename );
960 if ( is_wp_error( $activate ) ) {
961 update_option( $this->strPluginSlug.'_deferred_notices', $this->strPluginName.' extension upgrade failed - '.$activate->get_error_message() );
962 $bResult = false;
963 }
964 }
965 }
966
967 if( empty( $bResult ) ) {
968 update_option( $this->strPluginSlug.'_deferred_notices', $sTaskDone );
969 $bResult = true;
970 }
971
972 $aInstalled = array_merge( $aInstalled, array( $plugin_package => $bResult ) );
973 update_option( $this->strPluginSlug.'_extension_install', $aInstalled );
974
975 return $bResult;
976 }
977
978 }
979