PluginProbe
Bubble Menu – Floating Button Menu with Sticky Navigation / 1.3
Bubble Menu – Floating Button Menu with Sticky Navigation v1.3
trunk 1.3 2.0 2.2 2.2.1 3.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1 3.1.1 4.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.1 4.1.1
bubble-menu / include / class / update.php

update.php in Bubble Menu – Floating Button Menu with Sticky Navigation 1.3, at include/class/update.php

253 lines 9.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // uncomment this line for testing
3 //set_site_transient( 'update_plugins', null );
4 // Exit if accessed directly
5 if ( ! defined( 'ABSPATH' ) ) exit;
6 /**
7 * Allows plugins to use their own update API.
8 *
9 * @author Pippin Williamson
10 * @version 1.6.2
11 */
12 class WOW_PLUGIN_UPDATE {
13 private $api_url = '';
14 private $api_data = array();
15 private $name = '';
16 private $slug = '';
17 private $version = '';
18 /**
19 * Class constructor.
20 *
21 * @uses plugin_basename()
22 * @uses hook()
23 *
24 * @param string $_api_url The URL pointing to the custom API endpoint.
25 * @param string $_plugin_file Path to the plugin file.
26 * @param array $_api_data Optional data to send with API calls.
27 */
28 function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
29 $this->api_url = trailingslashit( $_api_url );
30 $this->api_data = $_api_data;
31 $this->name = plugin_basename( $_plugin_file );
32 $this->slug = basename( $_plugin_file, '.php' );
33 $this->version = $_api_data['version'];
34 // Set up hooks.
35 $this->init();
36 add_action( 'admin_init', array( $this, 'show_changelog' ) );
37 }
38 /**
39 * Set up WordPress filters to hook into WP's update process.
40 *
41 * @uses add_filter()
42 *
43 * @return void
44 */
45 public function init() {
46 add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
47 add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
48 remove_action( 'after_plugin_row_' . $this->name, 'wp_plugin_update_row', 10, 2 );
49 add_action( 'after_plugin_row_' . $this->name, array( $this, 'show_update_notification' ), 10, 2 );
50 }
51 /**
52 * Check for Updates at the defined API endpoint and modify the update array.
53 *
54 * This function dives into the update API just when WordPress creates its update array,
55 * then adds a custom API call and injects the custom plugin data retrieved from the API.
56 * It is reassembled from parts of the native WordPress plugin update code.
57 * See wp-includes/update.php line 121 for the original wp_update_plugins() function.
58 *
59 * @uses api_request()
60 *
61 * @param array $_transient_data Update array build by WordPress.
62 * @return array Modified update array with custom plugin data.
63 */
64 function check_update( $_transient_data ) {
65 global $pagenow;
66 if( ! is_object( $_transient_data ) ) {
67 $_transient_data = new stdClass;
68 }
69 if( 'plugins.php' == $pagenow && is_multisite() ) {
70 return $_transient_data;
71 }
72 if ( empty( $_transient_data->response ) || empty( $_transient_data->response[ $this->name ] ) ) {
73 $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug ) );
74 if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
75 if( version_compare( $this->version, $version_info->new_version, '<' ) ) {
76 $_transient_data->response[ $this->name ] = $version_info;
77 }
78 $_transient_data->last_checked = time();
79 $_transient_data->checked[ $this->name ] = $this->version;
80 }
81 }
82 return $_transient_data;
83 }
84 /**
85 * show update nofication row -- needed for multisite subsites, because WP won't tell you otherwise!
86 *
87 * @param string $file
88 * @param array $plugin
89 */
90 public function show_update_notification( $file, $plugin ) {
91 if( ! current_user_can( 'update_plugins' ) ) {
92 return;
93 }
94 if( ! is_multisite() ) {
95 return;
96 }
97 if ( $this->name != $file ) {
98 return;
99 }
100 // Remove our filter on the site transient
101 remove_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ), 10 );
102 $update_cache = get_site_transient( 'update_plugins' );
103 $update_cache = is_object( $update_cache ) ? $update_cache : new stdClass();
104 if ( empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] ) ) {
105 $cache_key = md5( 'edd_plugin_' .sanitize_key( $this->name ) . '_version_info' );
106 $version_info = get_transient( $cache_key );
107 if( false === $version_info ) {
108 $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug ) );
109 set_transient( $cache_key, $version_info, 3600 );
110 }
111 if( ! is_object( $version_info ) ) {
112 return;
113 }
114 if( version_compare( $this->version, $version_info->new_version, '<' ) ) {
115 $update_cache->response[ $this->name ] = $version_info;
116 }
117 $update_cache->last_checked = time();
118 $update_cache->checked[ $this->name ] = $this->version;
119 set_site_transient( 'update_plugins', $update_cache );
120 } else {
121 $version_info = $update_cache->response[ $this->name ];
122 }
123 // Restore our filter
124 add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
125 if ( ! empty( $update_cache->response[ $this->name ] ) && version_compare( $this->version, $version_info->new_version, '<' ) ) {
126 // build a plugin list row, with update notification
127 $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
128 echo '<tr class="plugin-update-tr"><td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange"><div class="update-message">';
129 $changelog_link = self_admin_url( 'index.php?edd_sl_action=view_plugin_changelog&plugin=' . $this->name . '&slug=' . $this->slug . '&TB_iframe=true&width=772&height=911' );
130 if ( empty( $version_info->download_link ) ) {
131 printf(
132 __( 'There is a new version of %1$s available. <a target="_blank" class="thickbox" href="%2$s">View version %3$s details</a>.', 'edd' ),
133 esc_html( $version_info->name ),
134 esc_url( $changelog_link ),
135 esc_html( $version_info->new_version )
136 );
137 } else {
138 printf(
139 __( 'There is a new version of %1$s available. <a target="_blank" class="thickbox" href="%2$s">View version %3$s details</a> or <a href="%4$s">update now</a>.', 'edd' ),
140 esc_html( $version_info->name ),
141 esc_url( $changelog_link ),
142 esc_html( $version_info->new_version ),
143 esc_url( wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $this->name, 'upgrade-plugin_' . $this->name ) )
144 );
145 }
146 echo '</div></td></tr>';
147 }
148 }
149 /**
150 * Updates information on the "View version x.x details" page with custom data.
151 *
152 * @uses api_request()
153 *
154 * @param mixed $_data
155 * @param string $_action
156 * @param object $_args
157 * @return object $_data
158 */
159 function plugins_api_filter( $_data, $_action = '', $_args = null ) {
160 if ( $_action != 'plugin_information' ) {
161 return $_data;
162 }
163 if ( ! isset( $_args->slug ) || ( $_args->slug != $this->slug ) ) {
164 return $_data;
165 }
166 $to_send = array(
167 'slug' => $this->slug,
168 'is_ssl' => is_ssl(),
169 'fields' => array(
170 'banners' => false, // These will be supported soon hopefully
171 'reviews' => false
172 )
173 );
174 $api_response = $this->api_request( 'plugin_information', $to_send );
175 if ( false !== $api_response ) {
176 $_data = $api_response;
177 }
178 return $_data;
179 }
180 /**
181 * Disable SSL verification in order to prevent download update failures
182 *
183 * @param array $args
184 * @param string $url
185 * @return object $array
186 */
187 function http_request_args( $args, $url ) {
188 // If it is an https request and we are performing a package download, disable ssl verification
189 if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
190 $args['sslverify'] = false;
191 }
192 return $args;
193 }
194 /**
195 * Calls the API and, if successfull, returns the object delivered by the API.
196 *
197 * @uses get_bloginfo()
198 * @uses wp_remote_post()
199 * @uses is_wp_error()
200 *
201 * @param string $_action The requested action.
202 * @param array $_data Parameters for the API action.
203 * @return false|object
204 */
205 private function api_request( $_action, $_data ) {
206 global $wp_version;
207 $data = array_merge( $this->api_data, $_data );
208 if ( $data['slug'] != $this->slug ) {
209 return;
210 }
211 if( $this->api_url == home_url() ) {
212 return false; // Don't allow a plugin to ping itself
213 }
214 $api_params = array(
215 'edd_action' => 'get_version',
216 'license' => ! empty( $data['license'] ) ? $data['license'] : '',
217 'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
218 'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
219 'slug' => $data['slug'],
220 'author' => $data['author'],
221 'url' => home_url()
222 );
223 $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
224 if ( ! is_wp_error( $request ) ) {
225 $request = json_decode( wp_remote_retrieve_body( $request ) );
226 }
227 if ( $request && isset( $request->sections ) ) {
228 $request->sections = maybe_unserialize( $request->sections );
229 } else {
230 $request = false;
231 }
232 return $request;
233 }
234 public function show_changelog() {
235 if( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' != $_REQUEST['edd_sl_action'] ) {
236 return;
237 }
238 if( empty( $_REQUEST['plugin'] ) ) {
239 return;
240 }
241 if( empty( $_REQUEST['slug'] ) ) {
242 return;
243 }
244 if( ! current_user_can( 'update_plugins' ) ) {
245 wp_die( __( 'You do not have permission to install plugin updates', 'edd' ), __( 'Error', 'edd' ), array( 'response' => 403 ) );
246 }
247 $response = $this->api_request( 'plugin_latest_version', array( 'slug' => $_REQUEST['slug'] ) );
248 if( $response && isset( $response->sections['changelog'] ) ) {
249 echo '<div style="background:#fff;padding:10px;">' . $response->sections['changelog'] . '</div>';
250 }
251 exit;
252 }
253 }