2017-09-11 18:05:42 +03:00
< ? php
namespace um\core ;
2019-10-09 12:47:43 +03:00
2017-09-11 18:05:42 +03:00
if ( ! defined ( 'ABSPATH' ) ) exit ;
2019-10-09 12:47:43 +03:00
2018-03-26 01:27:46 +03:00
if ( ! class_exists ( 'um\core\Plugin_Updater' ) ) {
2017-09-11 18:05:42 +03:00
2018-03-20 13:24:38 +02:00
/**
* Class Plugin_Updater
* @package um\core
*/
class Plugin_Updater {
/**
* Plugin_Updater constructor.
*/
function __construct () {
//create cron event
if ( ! wp_next_scheduled ( 'um_check_extensions_licenses' ) ) {
wp_schedule_event ( time () + ( 24 * 60 * 60 ), 'daily' , 'um_check_extensions_licenses' );
}
register_deactivation_hook ( um_plugin , array ( & $this , 'um_plugin_updater_deactivation_hook' ) );
2019-05-10 15:43:14 +03:00
//cron request to UM()->store_url;
2018-03-20 13:24:38 +02:00
add_action ( 'um_check_extensions_licenses' , array ( & $this , 'um_checklicenses' ) );
2019-11-15 18:31:17 +02:00
// clean update plugin cache
add_action ( 'upgrader_process_complete' , array ( & $this , 'clean_update_plugins_cache' ), 20 , 2 );
2018-03-20 13:24:38 +02:00
//update plugin info
2019-05-10 15:43:14 +03:00
add_filter ( 'pre_set_site_transient_update_plugins' , array ( & $this , 'check_update' ) );
2018-03-20 13:24:38 +02:00
//plugin information info
2019-05-10 15:43:14 +03:00
add_filter ( 'plugins_api' , array ( & $this , 'plugin_information' ), 9999 , 3 );
2018-03-20 13:24:38 +02:00
}
2019-11-15 18:31:17 +02:00
/**
* This action is documented in wp-admin/includes/class-wp-upgrader.php
*
* @see file /wp-admin/includes/class-plugin-upgrader.php method bulk_upgrade()
* @since 2.1.1 [2019-11-15]
*
2019-11-19 13:45:02 +02:00
* @param \Plugin_Upgrader $updater
2019-11-15 18:31:17 +02:00
* @param array $action
*/
2019-11-19 13:45:02 +02:00
public function clean_update_plugins_cache ( $updater , $action = array () ) {
if ( is_a ( $updater , 'Plugin_Upgrader' ) && isset ( $updater -> result ) && isset ( $updater -> result [ 'destination_name' ] ) && strpos ( $updater -> result [ 'destination_name' ], 'um-' ) === 0 && $action [ 'action' ] === 'update' && $action [ 'action' ] === 'plugin' ) {
2019-11-15 18:31:17 +02:00
wp_clean_plugins_cache ( true );
}
}
2018-03-20 13:24:38 +02:00
/**
* Get all paid UM extensions
*
* @return array
*/
2019-05-10 15:43:14 +03:00
function get_active_plugins () {
2018-03-20 13:24:38 +02:00
$paid_extensions = array (
'um-bbpress/um-bbpress.php' => array (
'key' => 'bbpress' ,
'title' => 'bbPress' ,
),
'um-followers/um-followers.php' => array (
'key' => 'followers' ,
'title' => 'Followers' ,
),
'um-friends/um-friends.php' => array (
'key' => 'friends' ,
'title' => 'Friends' ,
),
'um-groups/um-groups.php' => array (
'key' => 'groups' ,
'title' => 'Groups' ,
),
'um-instagram/um-instagram.php' => array (
'key' => 'instagram' ,
'title' => 'Instagram' ,
),
'um-mailchimp/um-mailchimp.php' => array (
'key' => 'mailchimp' ,
'title' => 'MailChimp' ,
),
'um-messaging/um-messaging.php' => array (
'key' => 'messaging' ,
2019-04-16 17:28:13 +03:00
'title' => 'Private Messages' ,
2018-03-20 13:24:38 +02:00
),
'um-mycred/um-mycred.php' => array (
'key' => 'mycred' ,
'title' => 'myCRED' ,
),
'um-notices/um-notices.php' => array (
'key' => 'notices' ,
'title' => 'Notices' ,
),
'um-notifications/um-notifications.php' => array (
'key' => 'notifications' ,
2019-04-16 17:28:13 +03:00
'title' => 'Real-time Notifications' ,
2018-03-20 13:24:38 +02:00
),
'um-profile-completeness/um-profile-completeness.php' => array (
'key' => 'profile_completeness' ,
'title' => 'Profile Completeness' ,
),
'um-reviews/um-reviews.php' => array (
'key' => 'reviews' ,
2019-04-16 17:28:13 +03:00
'title' => 'User Reviews' ,
2018-03-20 13:24:38 +02:00
),
'um-social-activity/um-social-activity.php' => array (
'key' => 'activity' ,
'title' => 'Social Activity' ,
),
'um-social-login/um-social-login.php' => array (
'key' => 'social_login' ,
'title' => 'Social Login' ,
),
'um-user-tags/um-user-tags.php' => array (
'key' => 'user_tags' ,
'title' => 'User Tags' ,
),
'um-verified-users/um-verified-users.php' => array (
2019-11-18 17:01:40 +02:00
'key' => 'verified' ,
2018-03-20 13:24:38 +02:00
'title' => 'Verified Users' ,
),
'um-woocommerce/um-woocommerce.php' => array (
'key' => 'woocommerce' ,
2019-04-16 17:28:13 +03:00
'title' => 'WooCommerce' ,
2018-03-20 13:24:38 +02:00
),
2018-07-04 18:20:30 +03:00
'um-user-photos/um-user-photos.php' => array (
'key' => 'user_photos' ,
'title' => 'User Photos' ,
),
'um-private-content/um-private-content.php' => array (
'key' => 'private_content' ,
'title' => 'Private Content' ,
),
2019-04-16 17:28:13 +03:00
'um-user-bookmarks/um-user-bookmarks.php' => array (
'key' => 'user_bookmarks' ,
'title' => 'User Bookmarks' ,
),
2019-05-07 11:26:12 +03:00
'um-unsplash/um-unsplash.php' => array (
'key' => 'unsplash' ,
'title' => 'Unsplash' ,
),
2019-04-16 17:28:13 +03:00
'um-user-notes/um-user-notes.php' => array (
'key' => 'user_notes' ,
'title' => 'User Notes' ,
),
2019-04-23 11:39:19 +03:00
'um-frontend-posting/um-frontend-posting.php' => array (
'key' => 'frontend_posting' ,
'title' => 'Frontend Posting' ,
),
'um-filesharing/um-filesharing.php' => array (
'key' => 'filesharing' ,
'title' => 'File Sharing' ,
),
2019-09-06 11:53:04 +03:00
'um-user-location/um-user-location.php' => array (
'key' => 'user-location' ,
'title' => 'User Location' ,
),
2018-03-20 13:24:38 +02:00
);
$active_um_plugins = array ();
2018-12-06 15:57:29 +02:00
if ( is_multisite () ) {
// Per site activated
$sites = get_sites ();
2018-12-07 10:29:05 +02:00
$sitewide_plugins = get_site_option ( 'active_sitewide_plugins' );
$sitewide_plugins = array_keys ( $sitewide_plugins );
2018-12-06 15:57:29 +02:00
foreach ( $sites as $site ) {
switch_to_blog ( $site -> blog_id );
$the_plugs = get_option ( 'active_plugins' );
2019-11-04 21:18:34 +02:00
if ( ! $the_plugs ) {
2019-10-28 13:28:14 +02:00
$the_plugs = array ();
}
2018-12-07 10:29:05 +02:00
$the_plugs = array_merge ( $the_plugs , $sitewide_plugins );
2018-12-06 15:57:29 +02:00
foreach ( $the_plugs as $key => $value ) {
if ( in_array ( $value , array_keys ( $paid_extensions ) ) ) {
$license = UM () -> options () -> get ( " um_ { $paid_extensions [ $value ][ 'key' ] } _license_key " );
if ( empty ( $license ) ) {
continue ;
}
$active_um_plugins [ $value ] = $paid_extensions [ $value ];
$active_um_plugins [ $value ][ 'license' ] = $license ;
}
}
restore_current_blog ();
}
} else {
$the_plugs = get_option ( 'active_plugins' );
foreach ( $the_plugs as $key => $value ) {
2018-03-20 13:24:38 +02:00
2018-12-06 15:57:29 +02:00
if ( in_array ( $value , array_keys ( $paid_extensions ) ) ) {
$license = UM () -> options () -> get ( " um_ { $paid_extensions [ $value ][ 'key' ] } _license_key " );
2018-03-20 13:24:38 +02:00
2019-05-10 15:43:14 +03:00
if ( empty ( $license ) ) {
2018-12-06 15:57:29 +02:00
continue ;
2019-05-10 15:43:14 +03:00
}
2018-03-20 13:24:38 +02:00
2018-12-06 15:57:29 +02:00
$active_um_plugins [ $value ] = $paid_extensions [ $value ];
$active_um_plugins [ $value ][ 'license' ] = $license ;
}
2018-03-20 13:24:38 +02:00
}
}
return $active_um_plugins ;
}
/**
* Remove CRON events on deactivation hook
*/
function um_plugin_updater_deactivation_hook () {
wp_clear_scheduled_hook ( 'um_check_extensions_licenses' );
}
/**
* Check license function
*/
function um_checklicenses () {
2019-05-10 15:43:14 +03:00
$exts = $this -> get_active_plugins ();
2018-03-20 13:24:38 +02:00
2019-04-16 17:28:13 +03:00
if ( 0 == count ( $exts ) ) {
2018-03-20 13:24:38 +02:00
return ;
2019-04-16 17:28:13 +03:00
}
2018-03-20 13:24:38 +02:00
require_once ( ABSPATH . 'wp-admin/includes/plugin.php' );
$api_params = array (
'edd_action' => 'check_licenses' ,
'author' => 'Ultimate Member' ,
'url' => home_url (),
);
$api_params [ 'active_extensions' ] = array ();
2019-04-16 17:28:13 +03:00
2018-03-20 13:24:38 +02:00
foreach ( $exts as $slug => $data ) {
2018-07-03 14:12:45 +03:00
$plugin_data = get_plugin_data ( WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $slug );
2018-03-20 13:24:38 +02:00
2019-04-16 17:28:13 +03:00
$api_params [ 'active_extensions' ][ $slug ] = array (
2018-03-20 13:24:38 +02:00
'slug' => $slug ,
'license' => $data [ 'license' ],
2019-04-16 17:28:13 +03:00
'item_name' => $data [ 'title' ],
2018-03-20 13:24:38 +02:00
'version' => $plugin_data [ 'Version' ]
);
}
$request = wp_remote_post (
2019-05-10 15:43:14 +03:00
UM () -> store_url ,
2018-03-20 13:24:38 +02:00
array (
2019-05-10 15:43:14 +03:00
'timeout' => UM () -> request_timeout ,
2018-03-20 13:24:38 +02:00
'sslverify' => false ,
'body' => $api_params
)
);
2019-05-10 15:43:14 +03:00
if ( ! is_wp_error ( $request ) ) {
2018-03-20 13:24:38 +02:00
$request = json_decode ( wp_remote_retrieve_body ( $request ) );
2019-05-10 15:43:14 +03:00
}
2018-03-20 13:24:38 +02:00
$request = ( $request ) ? maybe_unserialize ( $request ) : false ;
if ( $request ) {
foreach ( $exts as $slug => $data ) {
2019-05-10 15:43:14 +03:00
if ( ! empty ( $request -> $slug -> license_check ) ) {
2018-03-20 13:24:38 +02:00
update_option ( " { $data [ 'key' ] } _edd_answer " , $request -> $slug -> license_check );
2019-05-10 15:43:14 +03:00
}
2018-03-20 13:24:38 +02:00
if ( ! empty ( $request -> $slug -> get_version_check ) ) {
$request -> $slug -> get_version_check = json_decode ( $request -> $slug -> get_version_check );
2019-05-10 15:43:14 +03:00
if ( ! empty ( $request -> $slug -> get_version_check -> package ) ) {
2018-03-20 13:24:38 +02:00
$request -> $slug -> get_version_check -> package = $this -> extend_download_url ( $request -> $slug -> get_version_check -> package , $slug , $data );
2019-05-10 15:43:14 +03:00
}
2018-03-20 13:24:38 +02:00
2019-05-10 15:43:14 +03:00
if ( ! empty ( $request -> $slug -> get_version_check -> download_link ) ) {
2018-03-20 13:24:38 +02:00
$request -> $slug -> get_version_check -> download_link = $this -> extend_download_url ( $request -> $slug -> get_version_check -> download_link , $slug , $data );
2019-05-10 15:43:14 +03:00
}
2018-03-20 13:24:38 +02:00
if ( isset ( $request -> $slug -> get_version_check -> sections ) ) {
$request -> $slug -> get_version_check -> sections = maybe_unserialize ( $request -> $slug -> get_version_check -> sections );
2019-05-10 15:43:14 +03:00
$request -> $slug -> get_version_check -> sections = ( array ) $request -> $slug -> get_version_check -> sections ;
2018-03-20 13:24:38 +02:00
} else {
$request -> $slug -> get_version_check = new \WP_Error ( 'plugins_api_failed' ,
sprintf (
/* translators: %s: support forums URL */
2019-05-10 15:43:14 +03:00
__ ( 'An unexpected error occurred. Something may be wrong with %s or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
UM () -> store_url ,
2018-03-20 13:24:38 +02:00
__ ( 'https://wordpress.org/support/' )
),
wp_remote_retrieve_body ( $request -> $slug -> get_version_check )
);
}
2019-05-10 15:43:14 +03:00
if ( isset ( $request -> $slug -> get_version_check -> banners ) ) {
$request -> $slug -> get_version_check -> banners = maybe_unserialize ( $request -> $slug -> get_version_check -> banners );
}
if ( isset ( $request -> $slug -> get_version_check -> icons ) ) {
$request -> $slug -> get_version_check -> icons = maybe_unserialize ( $request -> $slug -> get_version_check -> icons );
}
if ( ! empty ( $request -> $slug -> get_version_check -> sections ) ) {
foreach ( $request -> $slug -> get_version_check -> sections as $key => $section ) {
$request -> $slug -> get_version_check -> $key = ( array ) $section ;
}
}
$this -> set_version_info_cache ( $slug , $request -> $slug -> get_version_check );
2018-03-20 13:24:38 +02:00
}
}
}
return ;
}
/**
* Check for Updates by request to the marketplace
* and modify the update array.
*
* @param array $_transient_data plugin update array build by WordPress.
* @return \stdClass modified plugin update array.
*/
2019-05-10 15:43:14 +03:00
function check_update ( $_transient_data ) {
2018-03-20 13:24:38 +02:00
global $pagenow ;
2019-05-10 15:43:14 +03:00
if ( ! is_object ( $_transient_data ) ) {
2018-03-20 13:24:38 +02:00
$_transient_data = new \stdClass ;
2019-05-10 15:43:14 +03:00
}
2018-03-20 13:24:38 +02:00
2019-05-10 15:43:14 +03:00
if ( 'plugins.php' == $pagenow && is_multisite () ) {
2018-03-20 13:24:38 +02:00
return $_transient_data ;
2019-05-10 15:43:14 +03:00
}
$exts = $this -> get_active_plugins ();
2018-03-20 13:24:38 +02:00
foreach ( $exts as $slug => $data ) {
2019-05-10 15:43:14 +03:00
//if response for current product isn't empty check for override
if ( ! empty ( $_transient_data -> response ) && ! empty ( $_transient_data -> response [ $slug ] ) && $_transient_data -> last_checked > time () - DAY_IN_SECONDS ) {
continue ;
}
2018-03-20 13:24:38 +02:00
2019-11-15 18:31:17 +02:00
$path = wp_normalize_path ( WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $slug );
2019-11-19 13:45:02 +02:00
if ( ! file_exists ( $path ) ) {
2019-11-15 18:31:17 +02:00
continue ;
}
$plugin_data = get_plugin_data ( $path );
2018-03-20 13:24:38 +02:00
2019-05-10 15:43:14 +03:00
$version_info = $this -> get_cached_version_info ( $slug );
if ( false === $version_info ) {
$version_info = $this -> single_request ( 'plugin_latest_version' , array (
'slug' => $slug ,
'license' => $data [ 'license' ],
'item_name' => $data [ 'title' ],
'version' => $plugin_data [ 'Version' ]
) );
2018-03-20 13:24:38 +02:00
2019-05-10 15:43:14 +03:00
$this -> set_version_info_cache ( $slug , $version_info );
}
2018-03-20 13:24:38 +02:00
if ( false !== $version_info && is_object ( $version_info ) && isset ( $version_info -> new_version ) ) {
//show update version block if new version > then current
2019-05-10 15:43:14 +03:00
if ( version_compare ( $plugin_data [ 'Version' ], $version_info -> new_version , '<' ) ) {
2018-03-20 13:24:38 +02:00
$_transient_data -> response [ $slug ] = $version_info ;
2019-05-10 15:43:14 +03:00
$_transient_data -> response [ $slug ] -> plugin = $slug ;
}
2018-03-20 13:24:38 +02:00
$_transient_data -> last_checked = time ();
$_transient_data -> checked [ $slug ] = $plugin_data [ 'Version' ];
}
}
return $_transient_data ;
}
2019-05-10 15:43:14 +03:00
/**
* Calls the API and, if successfull, returns the object delivered by the API.
*
* @uses get_bloginfo()
* @uses wp_remote_post()
* @uses is_wp_error()
*
* @param string $_action The requested action.
* @param array $_data Parameters for the API action.
* @return false|object
*/
private function single_request ( $_action , $_data ) {
$api_params = array (
'edd_action' => 'get_version' ,
'author' => 'Ultimate Member' ,
'url' => home_url (),
'beta' => false ,
);
$api_params = array_merge ( $api_params , $_data );
$request = wp_remote_post (
UM () -> store_url ,
array (
'timeout' => UM () -> request_timeout ,
'sslverify' => false ,
'body' => $api_params
)
);
if ( ! is_wp_error ( $request ) ) {
$request = json_decode ( wp_remote_retrieve_body ( $request ) );
}
if ( $request && isset ( $request -> sections ) ) {
$request -> sections = maybe_unserialize ( $request -> sections );
$request -> sections = ( array ) $request -> sections ;
} else {
$request = false ;
}
if ( $request && isset ( $request -> banners ) ) {
$request -> banners = maybe_unserialize ( $request -> banners );
}
if ( $request && isset ( $request -> icons ) ) {
$request -> icons = maybe_unserialize ( $request -> icons );
}
if ( ! empty ( $request -> sections ) ) {
foreach ( $request -> sections as $key => $section ) {
$request -> $key = ( array ) $section ;
}
}
if ( ! empty ( $request -> package ) ) {
$request -> package = $this -> extend_download_url ( $request -> package , $_data [ 'slug' ], $_data );
}
if ( ! empty ( $request -> download_link ) ) {
$request -> download_link = $this -> extend_download_url ( $request -> download_link , $_data [ 'slug' ], $_data );
}
return $request ;
}
2018-03-20 13:24:38 +02:00
/**
* Updates information on the "View version x.x details" popup with custom data.
*
* @param mixed $_data
* @param string $_action
* @param object $_args
* @return object $_data
*/
2019-05-10 15:43:14 +03:00
function plugin_information ( $_data , $_action = '' , $_args = null ) {
2018-03-20 13:24:38 +02:00
//by default $data = false (from Wordpress)
2019-05-10 15:43:14 +03:00
if ( $_action != 'plugin_information' ) {
2018-03-20 13:24:38 +02:00
return $_data ;
2019-05-10 15:43:14 +03:00
}
2018-03-20 13:24:38 +02:00
2019-05-10 15:43:14 +03:00
$exts = $this -> get_active_plugins ();
2018-03-20 13:24:38 +02:00
foreach ( $exts as $slug => $data ) {
2019-05-10 15:43:14 +03:00
if ( isset ( $_args -> slug ) && $_args -> slug == $slug ) {
$api_request_transient = $this -> get_cached_version_info ( $slug );
if ( false === $api_request_transient ) {
$plugin_data = get_plugin_data ( WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $slug );
$api_request_transient = $this -> single_request ( 'plugin_latest_version' , array (
'slug' => $slug ,
'license' => $data [ 'license' ],
'item_name' => $data [ 'title' ],
'version' => $plugin_data [ 'Version' ]
) );
$this -> set_version_info_cache ( $slug , $api_request_transient );
}
break ;
}
2018-03-20 13:24:38 +02:00
}
//If we have no transient-saved value, run the API, set a fresh transient with the API value, and return that value too right now.
2019-05-10 15:43:14 +03:00
if ( isset ( $api_request_transient ) ) {
$_data = $api_request_transient ;
2018-03-20 13:24:38 +02:00
}
return $_data ;
}
/**
* Disable SSL verification in order to prevent download update failures
*
* @param array $args
* @param string $url
* @return array $array
*/
function http_request_args ( $args , $url ) {
// If it is an https request and we are performing a package download, disable ssl verification
if ( strpos ( $url , 'https://' ) !== false && strpos ( $url , 'action=package_download' ) ) {
$args [ 'sslverify' ] = false ;
}
return $args ;
}
/**
* Download extension URL
*
* @param $download_url
* @param $slug
* @param $data
*
* @return string
*/
function extend_download_url ( $download_url , $slug , $data ) {
$url = get_site_url ( get_current_blog_id () );
$domain = strtolower ( urlencode ( rtrim ( $url , '/' ) ) );
2018-07-03 14:12:45 +03:00
$plugin_data = get_plugin_data ( WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $slug );
2018-03-20 13:24:38 +02:00
$api_params = array (
'action' => 'get_last_version' ,
'license' => ! empty ( $data [ 'license' ] ) ? $data [ 'license' ] : '' ,
'item_name' => str_replace ( 'Ultimate Member - ' , '' , $plugin_data [ 'Name' ] ),
'blog_id' => get_current_blog_id (),
'site_url' => urlencode ( $url ),
'domain' => urlencode ( $domain ),
'slug' => urlencode ( $slug ),
);
$download_url = add_query_arg ( $api_params , $download_url );
return $download_url ;
}
2019-05-10 15:43:14 +03:00
/**
* @param $slug
*
* @return bool|string
*/
function get_cache_key ( $slug ) {
$exts = $this -> get_active_plugins ();
if ( empty ( $exts [ $slug ] ) ) {
return false ;
}
return 'edd_sl_' . md5 ( serialize ( $slug . $exts [ $slug ][ 'license' ] ) );
}
/**
* @param $slug
*
* @return array|bool|mixed|object
*/
function get_cached_version_info ( $slug ) {
$cache_key = $this -> get_cache_key ( $slug );
if ( empty ( $cache_key ) ) {
return false ;
}
$cache = get_option ( $cache_key );
if ( empty ( $cache [ 'timeout' ] ) || time () > $cache [ 'timeout' ] ) {
return false ; // Cache is expired
}
// We need to turn the icons into an array, thanks to WP Core forcing these into an object at some point.
$cache [ 'value' ] = json_decode ( $cache [ 'value' ] );
if ( ! empty ( $cache [ 'value' ] -> icons ) ) {
$cache [ 'value' ] -> icons = ( array ) $cache [ 'value' ] -> icons ;
}
if ( ! empty ( $cache [ 'value' ] -> sections ) ) {
$cache [ 'value' ] -> sections = ( array ) $cache [ 'value' ] -> sections ;
}
if ( ! empty ( $cache [ 'value' ] -> banners ) ) {
$cache [ 'value' ] -> banners = ( array ) $cache [ 'value' ] -> banners ;
}
return $cache [ 'value' ];
}
/**
* @param $slug
* @param string $value
*/
function set_version_info_cache ( $slug , $value = '' ) {
$cache_key = $this -> get_cache_key ( $slug );
if ( empty ( $cache_key ) ) {
return ;
}
$data = array (
'timeout' => strtotime ( '+6 hours' , time () ),
'value' => json_encode ( $value )
);
update_option ( $cache_key , $data , 'no' );
}
2018-03-20 13:24:38 +02:00
}
2017-09-11 18:05:42 +03:00
}