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. Loading history...
|
|||
| 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. Loading history...
|
|||
| 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 Loading history...
|
|||
| 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 Loading history...
|
|||
| 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. Loading history...
|
|||
| 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. Loading history...
|
|||
| 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 Loading history...
|
|||
| 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 Loading history...
|
|||
| 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. Loading history...
|
|||
| 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. Loading history...
|
|||
| 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.