This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * A simple set of functions to check our version 1.0 update service. |
||
4 | * |
||
5 | * @package WordPress |
||
6 | * @since 2.3.0 |
||
7 | */ |
||
8 | |||
9 | /** |
||
10 | * Check WordPress version against the newest version. |
||
11 | * |
||
12 | * The WordPress version, PHP version, and Locale is sent. Checks against the |
||
13 | * WordPress server at api.wordpress.org server. Will only check if WordPress |
||
14 | * isn't installing. |
||
15 | * |
||
16 | * @since 2.3.0 |
||
17 | * @global string $wp_version Used to check against the newest WordPress version. |
||
18 | * @global wpdb $wpdb |
||
19 | * @global string $wp_local_package |
||
20 | * |
||
21 | * @param array $extra_stats Extra statistics to report to the WordPress.org API. |
||
22 | * @param bool $force_check Whether to bypass the transient cache and force a fresh update check. Defaults to false, true if $extra_stats is set. |
||
23 | */ |
||
24 | function wp_version_check( $extra_stats = array(), $force_check = false ) { |
||
25 | if ( wp_installing() ) { |
||
26 | return; |
||
27 | } |
||
28 | |||
29 | global $wpdb, $wp_local_package; |
||
30 | // include an unmodified $wp_version |
||
31 | include( ABSPATH . WPINC . '/version.php' ); |
||
32 | $php_version = phpversion(); |
||
33 | |||
34 | $current = get_site_transient( 'update_core' ); |
||
35 | $translations = wp_get_installed_translations( 'core' ); |
||
36 | |||
37 | // Invalidate the transient when $wp_version changes |
||
38 | if ( is_object( $current ) && $wp_version != $current->version_checked ) |
||
0 ignored issues
–
show
|
|||
39 | $current = false; |
||
40 | |||
41 | if ( ! is_object($current) ) { |
||
42 | $current = new stdClass; |
||
43 | $current->updates = array(); |
||
44 | $current->version_checked = $wp_version; |
||
45 | } |
||
46 | |||
47 | if ( ! empty( $extra_stats ) ) |
||
48 | $force_check = true; |
||
49 | |||
50 | // Wait 60 seconds between multiple version check requests |
||
51 | $timeout = 60; |
||
52 | $time_not_changed = isset( $current->last_checked ) && $timeout > ( time() - $current->last_checked ); |
||
53 | if ( ! $force_check && $time_not_changed ) { |
||
54 | return; |
||
55 | } |
||
56 | |||
57 | /** |
||
58 | * Filters the locale requested for WordPress core translations. |
||
59 | * |
||
60 | * @since 2.8.0 |
||
61 | * |
||
62 | * @param string $locale Current locale. |
||
63 | */ |
||
64 | $locale = apply_filters( 'core_version_check_locale', get_locale() ); |
||
65 | |||
66 | // Update last_checked for current to prevent multiple blocking requests if request hangs |
||
67 | $current->last_checked = time(); |
||
68 | set_site_transient( 'update_core', $current ); |
||
69 | |||
70 | if ( method_exists( $wpdb, 'db_version' ) ) |
||
71 | $mysql_version = preg_replace('/[^0-9.].*/', '', $wpdb->db_version()); |
||
72 | else |
||
73 | $mysql_version = 'N/A'; |
||
74 | |||
75 | if ( is_multisite() ) { |
||
76 | $user_count = get_user_count(); |
||
77 | $num_blogs = get_blog_count(); |
||
78 | $wp_install = network_site_url(); |
||
79 | $multisite_enabled = 1; |
||
80 | } else { |
||
81 | $user_count = count_users(); |
||
82 | $user_count = $user_count['total_users']; |
||
83 | $multisite_enabled = 0; |
||
84 | $num_blogs = 1; |
||
85 | $wp_install = home_url( '/' ); |
||
86 | } |
||
87 | |||
88 | $query = array( |
||
89 | 'version' => $wp_version, |
||
90 | 'php' => $php_version, |
||
91 | 'locale' => $locale, |
||
92 | 'mysql' => $mysql_version, |
||
93 | 'local_package' => isset( $wp_local_package ) ? $wp_local_package : '', |
||
94 | 'blogs' => $num_blogs, |
||
95 | 'users' => $user_count, |
||
96 | 'multisite_enabled' => $multisite_enabled, |
||
97 | 'initial_db_version' => get_site_option( 'initial_db_version' ), |
||
98 | ); |
||
99 | |||
100 | $post_body = array( |
||
101 | 'translations' => wp_json_encode( $translations ), |
||
102 | ); |
||
103 | |||
104 | if ( is_array( $extra_stats ) ) |
||
105 | $post_body = array_merge( $post_body, $extra_stats ); |
||
106 | |||
107 | $url = $http_url = 'http://api.wordpress.org/core/version-check/1.7/?' . http_build_query( $query, null, '&' ); |
||
108 | if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) |
||
109 | $url = set_url_scheme( $url, 'https' ); |
||
110 | |||
111 | $doing_cron = wp_doing_cron(); |
||
112 | |||
113 | $options = array( |
||
114 | 'timeout' => $doing_cron ? 30 : 3, |
||
115 | 'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url( '/' ), |
||
116 | 'headers' => array( |
||
117 | 'wp_install' => $wp_install, |
||
118 | 'wp_blog' => home_url( '/' ) |
||
119 | ), |
||
120 | 'body' => $post_body, |
||
121 | ); |
||
122 | |||
123 | $response = wp_remote_post( $url, $options ); |
||
124 | View Code Duplication | if ( $ssl && is_wp_error( $response ) ) { |
|
125 | trigger_error( |
||
126 | sprintf( |
||
127 | /* translators: %s: support forums URL */ |
||
128 | __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ), |
||
129 | __( 'https://wordpress.org/support/' ) |
||
130 | ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), |
||
131 | headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE |
||
132 | ); |
||
133 | $response = wp_remote_post( $http_url, $options ); |
||
134 | } |
||
135 | |||
136 | if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) { |
||
0 ignored issues
–
show
It seems like
$response can also be of type object<WP_Error> ; however, wp_remote_retrieve_response_code() does only seem to accept array , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
137 | return; |
||
138 | } |
||
139 | |||
140 | $body = trim( wp_remote_retrieve_body( $response ) ); |
||
0 ignored issues
–
show
It seems like
$response can also be of type object<WP_Error> ; however, wp_remote_retrieve_body() does only seem to accept array , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
141 | $body = json_decode( $body, true ); |
||
142 | |||
143 | if ( ! is_array( $body ) || ! isset( $body['offers'] ) ) { |
||
144 | return; |
||
145 | } |
||
146 | |||
147 | $offers = $body['offers']; |
||
148 | |||
149 | foreach ( $offers as &$offer ) { |
||
150 | foreach ( $offer as $offer_key => $value ) { |
||
151 | if ( 'packages' == $offer_key ) |
||
152 | $offer['packages'] = (object) array_intersect_key( array_map( 'esc_url', $offer['packages'] ), |
||
153 | array_fill_keys( array( 'full', 'no_content', 'new_bundled', 'partial', 'rollback' ), '' ) ); |
||
154 | elseif ( 'download' == $offer_key ) |
||
155 | $offer['download'] = esc_url( $value ); |
||
156 | else |
||
157 | $offer[ $offer_key ] = esc_html( $value ); |
||
158 | } |
||
159 | $offer = (object) array_intersect_key( $offer, array_fill_keys( array( 'response', 'download', 'locale', |
||
160 | 'packages', 'current', 'version', 'php_version', 'mysql_version', 'new_bundled', 'partial_version', 'notify_email', 'support_email', 'new_files' ), '' ) ); |
||
161 | } |
||
162 | |||
163 | $updates = new stdClass(); |
||
164 | $updates->updates = $offers; |
||
165 | $updates->last_checked = time(); |
||
166 | $updates->version_checked = $wp_version; |
||
167 | |||
168 | if ( isset( $body['translations'] ) ) |
||
169 | $updates->translations = $body['translations']; |
||
170 | |||
171 | set_site_transient( 'update_core', $updates ); |
||
172 | |||
173 | if ( ! empty( $body['ttl'] ) ) { |
||
174 | $ttl = (int) $body['ttl']; |
||
175 | if ( $ttl && ( time() + $ttl < wp_next_scheduled( 'wp_version_check' ) ) ) { |
||
176 | // Queue an event to re-run the update check in $ttl seconds. |
||
177 | wp_schedule_single_event( time() + $ttl, 'wp_version_check' ); |
||
178 | } |
||
179 | } |
||
180 | |||
181 | // Trigger background updates if running non-interactively, and we weren't called from the update handler. |
||
182 | if ( $doing_cron && ! doing_action( 'wp_maybe_auto_update' ) ) { |
||
183 | do_action( 'wp_maybe_auto_update' ); |
||
184 | } |
||
185 | } |
||
186 | |||
187 | /** |
||
188 | * Check plugin versions against the latest versions hosted on WordPress.org. |
||
189 | * |
||
190 | * The WordPress version, PHP version, and Locale is sent along with a list of |
||
191 | * all plugins installed. Checks against the WordPress server at |
||
192 | * api.wordpress.org. Will only check if WordPress isn't installing. |
||
193 | * |
||
194 | * @since 2.3.0 |
||
195 | * @global string $wp_version Used to notify the WordPress version. |
||
196 | * |
||
197 | * @param array $extra_stats Extra statistics to report to the WordPress.org API. |
||
198 | */ |
||
199 | function wp_update_plugins( $extra_stats = array() ) { |
||
200 | if ( wp_installing() ) { |
||
201 | return; |
||
202 | } |
||
203 | |||
204 | // include an unmodified $wp_version |
||
205 | include( ABSPATH . WPINC . '/version.php' ); |
||
206 | |||
207 | // If running blog-side, bail unless we've not checked in the last 12 hours |
||
208 | if ( !function_exists( 'get_plugins' ) ) |
||
209 | require_once( ABSPATH . 'wp-admin/includes/plugin.php' ); |
||
210 | |||
211 | $plugins = get_plugins(); |
||
212 | $translations = wp_get_installed_translations( 'plugins' ); |
||
213 | |||
214 | $active = get_option( 'active_plugins', array() ); |
||
215 | $current = get_site_transient( 'update_plugins' ); |
||
216 | if ( ! is_object($current) ) |
||
217 | $current = new stdClass; |
||
218 | |||
219 | $new_option = new stdClass; |
||
220 | $new_option->last_checked = time(); |
||
221 | |||
222 | $doing_cron = wp_doing_cron(); |
||
223 | |||
224 | // Check for update on a different schedule, depending on the page. |
||
225 | View Code Duplication | switch ( current_filter() ) { |
|
226 | case 'upgrader_process_complete' : |
||
227 | $timeout = 0; |
||
228 | break; |
||
229 | case 'load-update-core.php' : |
||
230 | $timeout = MINUTE_IN_SECONDS; |
||
231 | break; |
||
232 | case 'load-plugins.php' : |
||
233 | case 'load-update.php' : |
||
234 | $timeout = HOUR_IN_SECONDS; |
||
235 | break; |
||
236 | default : |
||
237 | if ( $doing_cron ) { |
||
238 | $timeout = 0; |
||
239 | } else { |
||
240 | $timeout = 12 * HOUR_IN_SECONDS; |
||
241 | } |
||
242 | } |
||
243 | |||
244 | $time_not_changed = isset( $current->last_checked ) && $timeout > ( time() - $current->last_checked ); |
||
245 | |||
246 | if ( $time_not_changed && ! $extra_stats ) { |
||
0 ignored issues
–
show
The expression
$extra_stats of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
247 | $plugin_changed = false; |
||
248 | foreach ( $plugins as $file => $p ) { |
||
249 | $new_option->checked[ $file ] = $p['Version']; |
||
250 | |||
251 | if ( !isset( $current->checked[ $file ] ) || strval($current->checked[ $file ]) !== strval($p['Version']) ) |
||
252 | $plugin_changed = true; |
||
253 | } |
||
254 | |||
255 | if ( isset ( $current->response ) && is_array( $current->response ) ) { |
||
256 | foreach ( $current->response as $plugin_file => $update_details ) { |
||
257 | if ( ! isset($plugins[ $plugin_file ]) ) { |
||
258 | $plugin_changed = true; |
||
259 | break; |
||
260 | } |
||
261 | } |
||
262 | } |
||
263 | |||
264 | // Bail if we've checked recently and if nothing has changed |
||
265 | if ( ! $plugin_changed ) { |
||
266 | return; |
||
267 | } |
||
268 | } |
||
269 | |||
270 | // Update last_checked for current to prevent multiple blocking requests if request hangs |
||
271 | $current->last_checked = time(); |
||
272 | set_site_transient( 'update_plugins', $current ); |
||
273 | |||
274 | $to_send = compact( 'plugins', 'active' ); |
||
275 | |||
276 | $locales = array_values( get_available_languages() ); |
||
277 | |||
278 | /** |
||
279 | * Filters the locales requested for plugin translations. |
||
280 | * |
||
281 | * @since 3.7.0 |
||
282 | * @since 4.5.0 The default value of the `$locales` parameter changed to include all locales. |
||
283 | * |
||
284 | * @param array $locales Plugin locales. Default is all available locales of the site. |
||
285 | */ |
||
286 | $locales = apply_filters( 'plugins_update_check_locales', $locales ); |
||
287 | $locales = array_unique( $locales ); |
||
288 | |||
289 | if ( $doing_cron ) { |
||
290 | $timeout = 30; |
||
291 | } else { |
||
292 | // Three seconds, plus one extra second for every 10 plugins |
||
293 | $timeout = 3 + (int) ( count( $plugins ) / 10 ); |
||
294 | } |
||
295 | |||
296 | $options = array( |
||
297 | 'timeout' => $timeout, |
||
298 | 'body' => array( |
||
299 | 'plugins' => wp_json_encode( $to_send ), |
||
300 | 'translations' => wp_json_encode( $translations ), |
||
301 | 'locale' => wp_json_encode( $locales ), |
||
302 | 'all' => wp_json_encode( true ), |
||
303 | ), |
||
304 | 'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ) |
||
0 ignored issues
–
show
|
|||
305 | ); |
||
306 | |||
307 | if ( $extra_stats ) { |
||
0 ignored issues
–
show
The expression
$extra_stats of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
308 | $options['body']['update_stats'] = wp_json_encode( $extra_stats ); |
||
309 | } |
||
310 | |||
311 | $url = $http_url = 'http://api.wordpress.org/plugins/update-check/1.1/'; |
||
312 | if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) |
||
313 | $url = set_url_scheme( $url, 'https' ); |
||
314 | |||
315 | $raw_response = wp_remote_post( $url, $options ); |
||
316 | View Code Duplication | if ( $ssl && is_wp_error( $raw_response ) ) { |
|
317 | trigger_error( |
||
318 | sprintf( |
||
319 | /* translators: %s: support forums URL */ |
||
320 | __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ), |
||
321 | __( 'https://wordpress.org/support/' ) |
||
322 | ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), |
||
323 | headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE |
||
324 | ); |
||
325 | $raw_response = wp_remote_post( $http_url, $options ); |
||
326 | } |
||
327 | |||
328 | if ( is_wp_error( $raw_response ) || 200 != wp_remote_retrieve_response_code( $raw_response ) ) { |
||
0 ignored issues
–
show
It seems like
$raw_response can also be of type object<WP_Error> ; however, wp_remote_retrieve_response_code() does only seem to accept array , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
329 | return; |
||
330 | } |
||
331 | |||
332 | $response = json_decode( wp_remote_retrieve_body( $raw_response ), true ); |
||
0 ignored issues
–
show
It seems like
$raw_response can also be of type object<WP_Error> ; however, wp_remote_retrieve_body() does only seem to accept array , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
333 | foreach ( $response['plugins'] as &$plugin ) { |
||
334 | $plugin = (object) $plugin; |
||
335 | if ( isset( $plugin->compatibility ) ) { |
||
336 | $plugin->compatibility = (object) $plugin->compatibility; |
||
337 | foreach ( $plugin->compatibility as &$data ) { |
||
338 | $data = (object) $data; |
||
339 | } |
||
340 | } |
||
341 | } |
||
342 | unset( $plugin, $data ); |
||
343 | foreach ( $response['no_update'] as &$plugin ) { |
||
344 | $plugin = (object) $plugin; |
||
345 | } |
||
346 | unset( $plugin ); |
||
347 | |||
348 | if ( is_array( $response ) ) { |
||
349 | $new_option->response = $response['plugins']; |
||
350 | $new_option->translations = $response['translations']; |
||
351 | // TODO: Perhaps better to store no_update in a separate transient with an expiry? |
||
352 | $new_option->no_update = $response['no_update']; |
||
353 | } else { |
||
354 | $new_option->response = array(); |
||
355 | $new_option->translations = array(); |
||
356 | $new_option->no_update = array(); |
||
357 | } |
||
358 | |||
359 | set_site_transient( 'update_plugins', $new_option ); |
||
360 | } |
||
361 | |||
362 | /** |
||
363 | * Check theme versions against the latest versions hosted on WordPress.org. |
||
364 | * |
||
365 | * A list of all themes installed in sent to WP. Checks against the |
||
366 | * WordPress server at api.wordpress.org. Will only check if WordPress isn't |
||
367 | * installing. |
||
368 | * |
||
369 | * @since 2.7.0 |
||
370 | * |
||
371 | * @param array $extra_stats Extra statistics to report to the WordPress.org API. |
||
372 | */ |
||
373 | function wp_update_themes( $extra_stats = array() ) { |
||
374 | if ( wp_installing() ) { |
||
375 | return; |
||
376 | } |
||
377 | |||
378 | // include an unmodified $wp_version |
||
379 | include( ABSPATH . WPINC . '/version.php' ); |
||
380 | |||
381 | $installed_themes = wp_get_themes(); |
||
382 | $translations = wp_get_installed_translations( 'themes' ); |
||
383 | |||
384 | $last_update = get_site_transient( 'update_themes' ); |
||
385 | if ( ! is_object($last_update) ) |
||
386 | $last_update = new stdClass; |
||
387 | |||
388 | $themes = $checked = $request = array(); |
||
389 | |||
390 | // Put slug of current theme into request. |
||
391 | $request['active'] = get_option( 'stylesheet' ); |
||
392 | |||
393 | foreach ( $installed_themes as $theme ) { |
||
394 | $checked[ $theme->get_stylesheet() ] = $theme->get('Version'); |
||
395 | |||
396 | $themes[ $theme->get_stylesheet() ] = array( |
||
397 | 'Name' => $theme->get('Name'), |
||
398 | 'Title' => $theme->get('Name'), |
||
399 | 'Version' => $theme->get('Version'), |
||
400 | 'Author' => $theme->get('Author'), |
||
401 | 'Author URI' => $theme->get('AuthorURI'), |
||
402 | 'Template' => $theme->get_template(), |
||
403 | 'Stylesheet' => $theme->get_stylesheet(), |
||
404 | ); |
||
405 | } |
||
406 | |||
407 | $doing_cron = wp_doing_cron(); |
||
408 | |||
409 | // Check for update on a different schedule, depending on the page. |
||
410 | View Code Duplication | switch ( current_filter() ) { |
|
411 | case 'upgrader_process_complete' : |
||
412 | $timeout = 0; |
||
413 | break; |
||
414 | case 'load-update-core.php' : |
||
415 | $timeout = MINUTE_IN_SECONDS; |
||
416 | break; |
||
417 | case 'load-themes.php' : |
||
418 | case 'load-update.php' : |
||
419 | $timeout = HOUR_IN_SECONDS; |
||
420 | break; |
||
421 | default : |
||
422 | $timeout = $doing_cron ? 0 : 12 * HOUR_IN_SECONDS; |
||
423 | } |
||
424 | |||
425 | $time_not_changed = isset( $last_update->last_checked ) && $timeout > ( time() - $last_update->last_checked ); |
||
426 | |||
427 | if ( $time_not_changed && ! $extra_stats ) { |
||
0 ignored issues
–
show
The expression
$extra_stats of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
428 | $theme_changed = false; |
||
429 | foreach ( $checked as $slug => $v ) { |
||
430 | if ( !isset( $last_update->checked[ $slug ] ) || strval($last_update->checked[ $slug ]) !== strval($v) ) |
||
431 | $theme_changed = true; |
||
432 | } |
||
433 | |||
434 | if ( isset ( $last_update->response ) && is_array( $last_update->response ) ) { |
||
435 | foreach ( $last_update->response as $slug => $update_details ) { |
||
436 | if ( ! isset($checked[ $slug ]) ) { |
||
437 | $theme_changed = true; |
||
438 | break; |
||
439 | } |
||
440 | } |
||
441 | } |
||
442 | |||
443 | // Bail if we've checked recently and if nothing has changed |
||
444 | if ( ! $theme_changed ) { |
||
445 | return; |
||
446 | } |
||
447 | } |
||
448 | |||
449 | // Update last_checked for current to prevent multiple blocking requests if request hangs |
||
450 | $last_update->last_checked = time(); |
||
451 | set_site_transient( 'update_themes', $last_update ); |
||
452 | |||
453 | $request['themes'] = $themes; |
||
454 | |||
455 | $locales = array_values( get_available_languages() ); |
||
456 | |||
457 | /** |
||
458 | * Filters the locales requested for theme translations. |
||
459 | * |
||
460 | * @since 3.7.0 |
||
461 | * @since 4.5.0 The default value of the `$locales` parameter changed to include all locales. |
||
462 | * |
||
463 | * @param array $locales Theme locales. Default is all available locales of the site. |
||
464 | */ |
||
465 | $locales = apply_filters( 'themes_update_check_locales', $locales ); |
||
466 | $locales = array_unique( $locales ); |
||
467 | |||
468 | if ( $doing_cron ) { |
||
469 | $timeout = 30; |
||
470 | } else { |
||
471 | // Three seconds, plus one extra second for every 10 themes |
||
472 | $timeout = 3 + (int) ( count( $themes ) / 10 ); |
||
473 | } |
||
474 | |||
475 | $options = array( |
||
476 | 'timeout' => $timeout, |
||
477 | 'body' => array( |
||
478 | 'themes' => wp_json_encode( $request ), |
||
479 | 'translations' => wp_json_encode( $translations ), |
||
480 | 'locale' => wp_json_encode( $locales ), |
||
481 | ), |
||
482 | 'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ) |
||
0 ignored issues
–
show
|
|||
483 | ); |
||
484 | |||
485 | if ( $extra_stats ) { |
||
0 ignored issues
–
show
The expression
$extra_stats of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
486 | $options['body']['update_stats'] = wp_json_encode( $extra_stats ); |
||
487 | } |
||
488 | |||
489 | $url = $http_url = 'http://api.wordpress.org/themes/update-check/1.1/'; |
||
490 | if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) |
||
491 | $url = set_url_scheme( $url, 'https' ); |
||
492 | |||
493 | $raw_response = wp_remote_post( $url, $options ); |
||
494 | View Code Duplication | if ( $ssl && is_wp_error( $raw_response ) ) { |
|
495 | trigger_error( |
||
496 | sprintf( |
||
497 | /* translators: %s: support forums URL */ |
||
498 | __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ), |
||
499 | __( 'https://wordpress.org/support/' ) |
||
500 | ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), |
||
501 | headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE |
||
502 | ); |
||
503 | $raw_response = wp_remote_post( $http_url, $options ); |
||
504 | } |
||
505 | |||
506 | if ( is_wp_error( $raw_response ) || 200 != wp_remote_retrieve_response_code( $raw_response ) ) { |
||
0 ignored issues
–
show
It seems like
$raw_response can also be of type object<WP_Error> ; however, wp_remote_retrieve_response_code() does only seem to accept array , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
507 | return; |
||
508 | } |
||
509 | |||
510 | $new_update = new stdClass; |
||
511 | $new_update->last_checked = time(); |
||
512 | $new_update->checked = $checked; |
||
513 | |||
514 | $response = json_decode( wp_remote_retrieve_body( $raw_response ), true ); |
||
0 ignored issues
–
show
It seems like
$raw_response can also be of type object<WP_Error> ; however, wp_remote_retrieve_body() does only seem to accept array , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
515 | |||
516 | if ( is_array( $response ) ) { |
||
517 | $new_update->response = $response['themes']; |
||
518 | $new_update->translations = $response['translations']; |
||
519 | } |
||
520 | |||
521 | set_site_transient( 'update_themes', $new_update ); |
||
522 | } |
||
523 | |||
524 | /** |
||
525 | * Performs WordPress automatic background updates. |
||
526 | * |
||
527 | * @since 3.7.0 |
||
528 | */ |
||
529 | function wp_maybe_auto_update() { |
||
530 | include_once( ABSPATH . '/wp-admin/includes/admin.php' ); |
||
531 | include_once( ABSPATH . '/wp-admin/includes/class-wp-upgrader.php' ); |
||
532 | |||
533 | $upgrader = new WP_Automatic_Updater; |
||
534 | $upgrader->run(); |
||
535 | } |
||
536 | |||
537 | /** |
||
538 | * Retrieves a list of all language updates available. |
||
539 | * |
||
540 | * @since 3.7.0 |
||
541 | * |
||
542 | * @return array |
||
543 | */ |
||
544 | function wp_get_translation_updates() { |
||
545 | $updates = array(); |
||
546 | $transients = array( 'update_core' => 'core', 'update_plugins' => 'plugin', 'update_themes' => 'theme' ); |
||
547 | foreach ( $transients as $transient => $type ) { |
||
548 | $transient = get_site_transient( $transient ); |
||
549 | if ( empty( $transient->translations ) ) |
||
550 | continue; |
||
551 | |||
552 | foreach ( $transient->translations as $translation ) { |
||
553 | $updates[] = (object) $translation; |
||
554 | } |
||
555 | } |
||
556 | return $updates; |
||
557 | } |
||
558 | |||
559 | /** |
||
560 | * Collect counts and UI strings for available updates |
||
561 | * |
||
562 | * @since 3.3.0 |
||
563 | * |
||
564 | * @return array |
||
565 | */ |
||
566 | function wp_get_update_data() { |
||
567 | $counts = array( 'plugins' => 0, 'themes' => 0, 'wordpress' => 0, 'translations' => 0 ); |
||
568 | |||
569 | View Code Duplication | if ( $plugins = current_user_can( 'update_plugins' ) ) { |
|
570 | $update_plugins = get_site_transient( 'update_plugins' ); |
||
571 | if ( ! empty( $update_plugins->response ) ) |
||
572 | $counts['plugins'] = count( $update_plugins->response ); |
||
573 | } |
||
574 | |||
575 | View Code Duplication | if ( $themes = current_user_can( 'update_themes' ) ) { |
|
576 | $update_themes = get_site_transient( 'update_themes' ); |
||
577 | if ( ! empty( $update_themes->response ) ) |
||
578 | $counts['themes'] = count( $update_themes->response ); |
||
579 | } |
||
580 | |||
581 | if ( ( $core = current_user_can( 'update_core' ) ) && function_exists( 'get_core_updates' ) ) { |
||
582 | $update_wordpress = get_core_updates( array('dismissed' => false) ); |
||
583 | if ( ! empty( $update_wordpress ) && ! in_array( $update_wordpress[0]->response, array('development', 'latest') ) && current_user_can('update_core') ) |
||
584 | $counts['wordpress'] = 1; |
||
585 | } |
||
586 | |||
587 | if ( ( $core || $plugins || $themes ) && wp_get_translation_updates() ) |
||
588 | $counts['translations'] = 1; |
||
589 | |||
590 | $counts['total'] = $counts['plugins'] + $counts['themes'] + $counts['wordpress'] + $counts['translations']; |
||
591 | $titles = array(); |
||
592 | if ( $counts['wordpress'] ) { |
||
593 | /* translators: 1: Number of updates available to WordPress */ |
||
594 | $titles['wordpress'] = sprintf( __( '%d WordPress Update'), $counts['wordpress'] ); |
||
595 | } |
||
596 | if ( $counts['plugins'] ) { |
||
597 | /* translators: 1: Number of updates available to plugins */ |
||
598 | $titles['plugins'] = sprintf( _n( '%d Plugin Update', '%d Plugin Updates', $counts['plugins'] ), $counts['plugins'] ); |
||
599 | } |
||
600 | if ( $counts['themes'] ) { |
||
601 | /* translators: 1: Number of updates available to themes */ |
||
602 | $titles['themes'] = sprintf( _n( '%d Theme Update', '%d Theme Updates', $counts['themes'] ), $counts['themes'] ); |
||
603 | } |
||
604 | if ( $counts['translations'] ) { |
||
605 | $titles['translations'] = __( 'Translation Updates' ); |
||
606 | } |
||
607 | |||
608 | $update_title = $titles ? esc_attr( implode( ', ', $titles ) ) : ''; |
||
609 | |||
610 | $update_data = array( 'counts' => $counts, 'title' => $update_title ); |
||
611 | /** |
||
612 | * Filters the returned array of update data for plugins, themes, and WordPress core. |
||
613 | * |
||
614 | * @since 3.5.0 |
||
615 | * |
||
616 | * @param array $update_data { |
||
617 | * Fetched update data. |
||
618 | * |
||
619 | * @type array $counts An array of counts for available plugin, theme, and WordPress updates. |
||
620 | * @type string $update_title Titles of available updates. |
||
621 | * } |
||
622 | * @param array $titles An array of update counts and UI strings for available updates. |
||
623 | */ |
||
624 | return apply_filters( 'wp_get_update_data', $update_data, $titles ); |
||
625 | } |
||
626 | |||
627 | /** |
||
628 | * Determines whether core should be updated. |
||
629 | * |
||
630 | * @since 2.8.0 |
||
631 | * |
||
632 | * @global string $wp_version |
||
633 | */ |
||
634 | function _maybe_update_core() { |
||
635 | // include an unmodified $wp_version |
||
636 | include( ABSPATH . WPINC . '/version.php' ); |
||
637 | |||
638 | $current = get_site_transient( 'update_core' ); |
||
639 | |||
640 | if ( isset( $current->last_checked, $current->version_checked ) && |
||
641 | 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) && |
||
642 | $current->version_checked == $wp_version ) { |
||
0 ignored issues
–
show
|
|||
643 | return; |
||
644 | } |
||
645 | wp_version_check(); |
||
646 | } |
||
647 | /** |
||
648 | * Check the last time plugins were run before checking plugin versions. |
||
649 | * |
||
650 | * This might have been backported to WordPress 2.6.1 for performance reasons. |
||
651 | * This is used for the wp-admin to check only so often instead of every page |
||
652 | * load. |
||
653 | * |
||
654 | * @since 2.7.0 |
||
655 | * @access private |
||
656 | */ |
||
657 | function _maybe_update_plugins() { |
||
658 | $current = get_site_transient( 'update_plugins' ); |
||
659 | View Code Duplication | if ( isset( $current->last_checked ) && 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) ) |
|
660 | return; |
||
661 | wp_update_plugins(); |
||
662 | } |
||
663 | |||
664 | /** |
||
665 | * Check themes versions only after a duration of time. |
||
666 | * |
||
667 | * This is for performance reasons to make sure that on the theme version |
||
668 | * checker is not run on every page load. |
||
669 | * |
||
670 | * @since 2.7.0 |
||
671 | * @access private |
||
672 | */ |
||
673 | function _maybe_update_themes() { |
||
674 | $current = get_site_transient( 'update_themes' ); |
||
675 | View Code Duplication | if ( isset( $current->last_checked ) && 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) ) |
|
676 | return; |
||
677 | wp_update_themes(); |
||
678 | } |
||
679 | |||
680 | /** |
||
681 | * Schedule core, theme, and plugin update checks. |
||
682 | * |
||
683 | * @since 3.1.0 |
||
684 | */ |
||
685 | function wp_schedule_update_checks() { |
||
686 | if ( ! wp_next_scheduled( 'wp_version_check' ) && ! wp_installing() ) |
||
687 | wp_schedule_event(time(), 'twicedaily', 'wp_version_check'); |
||
688 | |||
689 | if ( ! wp_next_scheduled( 'wp_update_plugins' ) && ! wp_installing() ) |
||
690 | wp_schedule_event(time(), 'twicedaily', 'wp_update_plugins'); |
||
691 | |||
692 | if ( ! wp_next_scheduled( 'wp_update_themes' ) && ! wp_installing() ) |
||
693 | wp_schedule_event(time(), 'twicedaily', 'wp_update_themes'); |
||
694 | } |
||
695 | |||
696 | /** |
||
697 | * Clear existing update caches for plugins, themes, and core. |
||
698 | * |
||
699 | * @since 4.1.0 |
||
700 | */ |
||
701 | function wp_clean_update_cache() { |
||
702 | if ( function_exists( 'wp_clean_plugins_cache' ) ) { |
||
703 | wp_clean_plugins_cache(); |
||
704 | } else { |
||
705 | delete_site_transient( 'update_plugins' ); |
||
706 | } |
||
707 | wp_clean_themes_cache(); |
||
708 | delete_site_transient( 'update_core' ); |
||
709 | } |
||
710 | |||
711 | if ( ( ! is_main_site() && ! is_network_admin() ) || wp_doing_ajax() ) { |
||
712 | return; |
||
713 | } |
||
714 | |||
715 | add_action( 'admin_init', '_maybe_update_core' ); |
||
716 | add_action( 'wp_version_check', 'wp_version_check' ); |
||
717 | |||
718 | add_action( 'load-plugins.php', 'wp_update_plugins' ); |
||
719 | add_action( 'load-update.php', 'wp_update_plugins' ); |
||
720 | add_action( 'load-update-core.php', 'wp_update_plugins' ); |
||
721 | add_action( 'admin_init', '_maybe_update_plugins' ); |
||
722 | add_action( 'wp_update_plugins', 'wp_update_plugins' ); |
||
723 | |||
724 | add_action( 'load-themes.php', 'wp_update_themes' ); |
||
725 | add_action( 'load-update.php', 'wp_update_themes' ); |
||
726 | add_action( 'load-update-core.php', 'wp_update_themes' ); |
||
727 | add_action( 'admin_init', '_maybe_update_themes' ); |
||
728 | add_action( 'wp_update_themes', 'wp_update_themes' ); |
||
729 | |||
730 | add_action( 'update_option_WPLANG', 'wp_clean_update_cache' , 10, 0 ); |
||
731 | |||
732 | add_action( 'wp_maybe_auto_update', 'wp_maybe_auto_update' ); |
||
733 | |||
734 | add_action( 'init', 'wp_schedule_update_checks' ); |
||
735 |
This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.