| 1 |
<?php |
| 2 |
/** |
| 3 |
* MainWP Connect |
| 4 |
* |
| 5 |
* MainWP Connect functions. |
| 6 |
* |
| 7 |
* @package MainWP/Dashboard |
| 8 |
*/ |
| 9 |
|
| 10 |
namespace MainWP\Dashboard; |
| 11 |
|
| 12 |
/** |
| 13 |
* Class MainWP_Connect |
| 14 |
* |
| 15 |
* @package MainWP\Dashboard |
| 16 |
*/ |
| 17 |
class MainWP_Connect { |
| 18 |
|
| 19 |
// phpcs:disable WordPress.DB.RestrictedFunctions, WordPress.WP.AlternativeFunctions, WordPress.PHP.NoSilencedErrors -- Using cURL functions. |
| 20 |
|
| 21 |
/** |
| 22 |
* Method get_class_name() |
| 23 |
* |
| 24 |
* Get Class Name. |
| 25 |
* |
| 26 |
* @return object Class name. |
| 27 |
*/ |
| 28 |
public static function get_class_name() { |
| 29 |
return __CLASS__; |
| 30 |
} |
| 31 |
|
| 32 |
/** |
| 33 |
* Method try visit. |
| 34 |
* |
| 35 |
* Try connecting to Child Site via cURL. |
| 36 |
* |
| 37 |
* @param string $url Child Site URL. |
| 38 |
* @param bool $ssl_verifyhost Option to check SSL Certificate. Default = null. |
| 39 |
* @param string $http_user HTTPAuth Username. Default = null. |
| 40 |
* @param string $http_pass HTTPAuth Password. Default = null. |
| 41 |
* @param int $sslVersion Child Site SSL Version. |
| 42 |
* @param bool $forceUseIPv4 Option to force IP4. Default = null. |
| 43 |
* @param bool $no_body Option to set CURLOPT_NOBODY option. Default = false. |
| 44 |
* |
| 45 |
* @return array $out. 'host IP, Returned HTTP Code, Error Message, http Status error message. |
| 46 |
* |
| 47 |
* @uses \MainWP\Dashboard\MainWP_Logger::debug() |
| 48 |
* @uses \MainWP\Dashboard\MainWP_System::$version |
| 49 |
* @uses \MainWP\Dashboard\MainWP_Utility::value_to_string() |
| 50 |
* @uses \MainWP\Dashboard\MainWP_Utility::get_http_codes() |
| 51 |
*/ |
| 52 |
public static function try_visit( $url, $ssl_verifyhost = null, $http_user = null, $http_pass = null, $sslVersion = 0, $forceUseIPv4 = null, $no_body = false ) { // phpcs:ignore -- Current complexity is the only way to achieve desired results, pull request solutions appreciated. |
| 53 |
|
| 54 |
$agent = 'Mozilla/5.0 (compatible; MainWP/' . MainWP_System::$version . '; +http://mainwp.com)'; |
| 55 |
$postdata = array( 'test' => 'yes' ); |
| 56 |
|
| 57 |
$ch = curl_init(); |
| 58 |
|
| 59 |
$proxy = new \WP_HTTP_Proxy(); |
| 60 |
if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { |
| 61 |
curl_setopt( $ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP ); |
| 62 |
curl_setopt( $ch, CURLOPT_PROXY, $proxy->host() ); |
| 63 |
curl_setopt( $ch, CURLOPT_PROXYPORT, $proxy->port() ); |
| 64 |
|
| 65 |
if ( $proxy->use_authentication() ) { |
| 66 |
curl_setopt( $ch, CURLOPT_PROXYAUTH, CURLAUTH_ANY ); |
| 67 |
curl_setopt( $ch, CURLOPT_PROXYUSERPWD, $proxy->authentication() ); |
| 68 |
} |
| 69 |
} |
| 70 |
|
| 71 |
curl_setopt( $ch, CURLOPT_URL, $url ); |
| 72 |
if ( $no_body ) { |
| 73 |
curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, 'HEAD' ); // HTTP request is 'HEAD', but sometime return 4xx - error code. |
| 74 |
} |
| 75 |
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); |
| 76 |
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true ); |
| 77 |
curl_setopt( $ch, CURLOPT_POST, true ); |
| 78 |
curl_setopt( $ch, CURLOPT_POSTFIELDS, $postdata ); |
| 79 |
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 10 ); |
| 80 |
curl_setopt( $ch, CURLOPT_USERAGENT, $agent ); |
| 81 |
curl_setopt( $ch, CURLOPT_ENCODING, 'none' ); |
| 82 |
|
| 83 |
if ( ! empty( $http_user ) && ! empty( $http_pass ) ) { |
| 84 |
$http_pass = stripslashes( $http_pass ); |
| 85 |
curl_setopt( $ch, CURLOPT_USERPWD, "$http_user:$http_pass" ); |
| 86 |
} |
| 87 |
|
| 88 |
if ( $ssl_verifyhost ) { |
| 89 |
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 2 ); |
| 90 |
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, true ); |
| 91 |
} else { |
| 92 |
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false ); |
| 93 |
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); |
| 94 |
} |
| 95 |
|
| 96 |
curl_setopt( $ch, CURLOPT_SSLVERSION, $sslVersion ); |
| 97 |
|
| 98 |
$http_version = apply_filters( 'mainwp_curl_http_version', false, false, $url ); |
| 99 |
if ( false !== $http_version ) { |
| 100 |
curl_setopt( $ch, CURLOPT_HTTP_VERSION, $http_version ); |
| 101 |
} |
| 102 |
|
| 103 |
$curlopt_resolve = apply_filters( 'mainwp_curl_curlopt_resolve', false, false, $url ); |
| 104 |
if ( is_array( $curlopt_resolve ) && ! empty( $curlopt_resolve ) ) { |
| 105 |
curl_setopt( $ch, CURLOPT_RESOLVE, $curlopt_resolve ); |
| 106 |
curl_setopt( $ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false ); |
| 107 |
} |
| 108 |
|
| 109 |
$headers = array( 'X-Requested-With' => 'XMLHttpRequest' ); |
| 110 |
$headers['Expect'] = self::get_expect_header( $postdata ); |
| 111 |
$headers = \Requests::flatten( $headers ); |
| 112 |
|
| 113 |
curl_setopt( $ch, CURLOPT_HTTPHEADER, array( 'X-Requested-With: XMLHttpRequest' ) ); |
| 114 |
curl_setopt( $ch, CURLOPT_REFERER, get_option( 'siteurl' ) ); |
| 115 |
|
| 116 |
$force_use_ipv4 = false; |
| 117 |
if ( null !== $forceUseIPv4 ) { |
| 118 |
if ( 1 == $forceUseIPv4 ) { |
| 119 |
$force_use_ipv4 = true; |
| 120 |
} elseif ( 2 == $forceUseIPv4 ) { |
| 121 |
if ( 1 == get_option( 'mainwp_forceUseIPv4' ) ) { |
| 122 |
$force_use_ipv4 = true; |
| 123 |
} |
| 124 |
} |
| 125 |
} else { |
| 126 |
if ( 1 == get_option( 'mainwp_forceUseIPv4' ) ) { |
| 127 |
$force_use_ipv4 = true; |
| 128 |
} |
| 129 |
} |
| 130 |
|
| 131 |
if ( $force_use_ipv4 ) { |
| 132 |
if ( defined( 'CURLOPT_IPRESOLVE' ) && defined( 'CURL_IPRESOLVE_V4' ) ) { |
| 133 |
curl_setopt( $ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 ); |
| 134 |
} |
| 135 |
} |
| 136 |
|
| 137 |
$disabled_functions = ini_get( 'disable_functions' ); |
| 138 |
if ( empty( $disabled_functions ) || ( stristr( $disabled_functions, 'curl_multi_exec' ) === false ) ) { |
| 139 |
$mh = curl_multi_init(); |
| 140 |
@curl_multi_add_handle( $mh, $ch ); |
| 141 |
|
| 142 |
do { |
| 143 |
curl_multi_exec( $mh, $running ); |
| 144 |
while ( $info = curl_multi_info_read( $mh ) ) { |
| 145 |
$data = curl_multi_getcontent( $info['handle'] ); |
| 146 |
$err = curl_error( $info['handle'] ); |
| 147 |
$http_status = curl_getinfo( $info['handle'], CURLINFO_HTTP_CODE ); |
| 148 |
$errno = curl_errno( $info['handle'] ); |
| 149 |
$realurl = curl_getinfo( $info['handle'], CURLINFO_EFFECTIVE_URL ); |
| 150 |
|
| 151 |
curl_multi_remove_handle( $mh, $info['handle'] ); |
| 152 |
} |
| 153 |
usleep( 10000 ); |
| 154 |
} while ( $running > 0 ); |
| 155 |
|
| 156 |
if ( 'resource' === gettype( $mh ) ) { |
| 157 |
curl_multi_close( $mh ); |
| 158 |
} |
| 159 |
} else { |
| 160 |
$data = curl_exec( $ch ); |
| 161 |
$err = curl_error( $ch ); |
| 162 |
$http_status = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); |
| 163 |
$errno = curl_errno( $ch ); |
| 164 |
$realurl = curl_getinfo( $ch, CURLINFO_EFFECTIVE_URL ); |
| 165 |
if ( 'resource' === gettype( $ch ) ) { |
| 166 |
curl_close( $ch ); |
| 167 |
} |
| 168 |
} |
| 169 |
|
| 170 |
MainWP_Logger::instance()->debug( ' :: tryVisit :: [url=' . $url . '] [http_status=' . $http_status . '] [error=' . $err . '] [data-start]' . $data . '[data-end]' ); |
| 171 |
MainWP_Logger::instance()->log_execution_time( 'tryVisit :: [url=' . $url . '] [http_status=' . $http_status . ']' ); |
| 172 |
|
| 173 |
$host = wp_parse_url( ( empty( $realurl ) ? $url : $realurl ), PHP_URL_HOST ); |
| 174 |
$ip = false; |
| 175 |
$target = false; |
| 176 |
|
| 177 |
$found = false; |
| 178 |
$dnsRecord = @dns_get_record( $host ); |
| 179 |
MainWP_Logger::instance()->debug( ' :: tryVisit :: [dnsRecord=' . MainWP_Utility::value_to_string( $dnsRecord, 1 ) . ']' ); |
| 180 |
|
| 181 |
if ( false !== $dnsRecord && is_array( $dnsRecord ) ) { |
| 182 |
if ( ! isset( $dnsRecord['ip'] ) ) { |
| 183 |
foreach ( $dnsRecord as $dnsRec ) { |
| 184 |
if ( isset( $dnsRec['ip'] ) ) { |
| 185 |
$ip = $dnsRec['ip']; |
| 186 |
break; |
| 187 |
} |
| 188 |
} |
| 189 |
} else { |
| 190 |
$ip = $dnsRecord['ip']; |
| 191 |
} |
| 192 |
|
| 193 |
if ( ! isset( $dnsRecord['host'] ) ) { |
| 194 |
foreach ( $dnsRecord as $dnsRec ) { |
| 195 |
if ( $dnsRec['host'] == $host ) { |
| 196 |
if ( 'CNAME' == $dnsRec['type'] ) { |
| 197 |
$target = $dnsRec['target']; |
| 198 |
} |
| 199 |
$found = true; |
| 200 |
break; |
| 201 |
} |
| 202 |
} |
| 203 |
} else { |
| 204 |
$found = ( $dnsRecord['host'] == $host ); |
| 205 |
if ( 'CNAME' == $dnsRecord['type'] ) { |
| 206 |
$target = $dnsRecord['target']; |
| 207 |
} |
| 208 |
} |
| 209 |
} |
| 210 |
|
| 211 |
if ( false === $ip ) { |
| 212 |
$ip = gethostbynamel( $host ); |
| 213 |
} |
| 214 |
if ( ( false !== $target ) && ( $target != $host ) ) { |
| 215 |
$host .= ' (CNAME: ' . $target . ')'; |
| 216 |
} |
| 217 |
|
| 218 |
$out = array( |
| 219 |
'host' => $host, |
| 220 |
'httpCode' => $http_status, |
| 221 |
'httpCodeString' => MainWP_Utility::get_http_codes( $http_status ), |
| 222 |
); |
| 223 |
|
| 224 |
if ( false !== $ip ) { |
| 225 |
$out['ip'] = $ip; |
| 226 |
$found = true; |
| 227 |
} |
| 228 |
|
| 229 |
$out['error'] = ( '' == $err && false === $found ? 'Invalid host.' : $err ); |
| 230 |
|
| 231 |
return $out; |
| 232 |
} |
| 233 |
|
| 234 |
/** |
| 235 |
* Method check_ignored_http_code() |
| 236 |
* |
| 237 |
* Check if http error code is being ignored. |
| 238 |
* |
| 239 |
* @param mixed $value http error code. |
| 240 |
* |
| 241 |
* @return bolean True|False. |
| 242 |
*/ |
| 243 |
public static function check_ignored_http_code( $value ) { |
| 244 |
if ( 200 == $value ) { |
| 245 |
return true; |
| 246 |
} |
| 247 |
$ignored_code = get_option( 'mainwp_ignore_HTTP_response_status', '' ); |
| 248 |
$ignored_code = trim( $ignored_code ); |
| 249 |
if ( ! empty( $ignored_code ) ) { |
| 250 |
$ignored_code = explode( ',', $ignored_code ); |
| 251 |
foreach ( $ignored_code as $code ) { |
| 252 |
$code = trim( $code ); |
| 253 |
if ( $value == $code ) { |
| 254 |
return true; |
| 255 |
} |
| 256 |
} |
| 257 |
} |
| 258 |
return false; |
| 259 |
} |
| 260 |
|
| 261 |
/** |
| 262 |
* Method check_website_status() |
| 263 |
* |
| 264 |
* Check if the Website returns and http errors. |
| 265 |
* |
| 266 |
* @param array $website Child Site information. |
| 267 |
* |
| 268 |
* @return mixed False|try visit result. |
| 269 |
* |
| 270 |
* @uses \MainWP\Dashboard\MainWP_Utility::is_domain_valid() |
| 271 |
*/ |
| 272 |
public static function check_website_status( $website ) { |
| 273 |
$http_user = null; |
| 274 |
$http_pass = null; |
| 275 |
$sslVersion = null; |
| 276 |
$verifyCertificate = null; |
| 277 |
$forceUseIPv4 = null; |
| 278 |
if ( is_object( $website ) && isset( $website->url ) ) { |
| 279 |
$url = $website->url; |
| 280 |
$verifyCertificate = isset( $website->verify_certificate ) ? $website->verify_certificate : null; |
| 281 |
$forceUseIPv4 = $website->force_use_ipv4; |
| 282 |
$http_user = $website->http_user; |
| 283 |
$http_pass = $website->http_pass; |
| 284 |
$sslVersion = $website->ssl_version; |
| 285 |
} else { |
| 286 |
$url = $website; |
| 287 |
} |
| 288 |
|
| 289 |
if ( ! MainWP_Utility::is_domain_valid( $url ) ) { |
| 290 |
return false; |
| 291 |
} |
| 292 |
|
| 293 |
$ssl_verifyhost = false; |
| 294 |
|
| 295 |
if ( 1 == $verifyCertificate ) { |
| 296 |
$ssl_verifyhost = true; |
| 297 |
} elseif ( 2 == $verifyCertificate || null === $verifyCertificate ) { |
| 298 |
if ( ( ( false === get_option( 'mainwp_sslVerifyCertificate' ) ) || ( 1 == get_option( 'mainwp_sslVerifyCertificate' ) ) ) ) { |
| 299 |
$ssl_verifyhost = true; |
| 300 |
} |
| 301 |
} |
| 302 |
|
| 303 |
$noBody = false; |
| 304 |
return self::try_visit( $url, $ssl_verifyhost, $http_user, $http_pass, $sslVersion, $forceUseIPv4, $noBody ); |
| 305 |
} |
| 306 |
|
| 307 |
/** |
| 308 |
* Method get_post_data_authed() |
| 309 |
* |
| 310 |
* Get authorized $_POST data & build query. |
| 311 |
* |
| 312 |
* @param mixed $website Array of Child Site Info. |
| 313 |
* @param mixed $what What we are posting. |
| 314 |
* @param null $params Post parameters. |
| 315 |
* |
| 316 |
* @return mixed null|http_build_query() |
| 317 |
*/ |
| 318 |
public static function get_post_data_authed( &$website, $what, $params = null ) { |
| 319 |
if ( $website && '' != $what ) { |
| 320 |
$data = array(); |
| 321 |
$data['user'] = $website->adminname; |
| 322 |
$data['function'] = $what; |
| 323 |
$data['nonce'] = wp_rand( 0, 9999 ); |
| 324 |
|
| 325 |
$params_filter = apply_filters( 'mainwp_pre_fetch_authed_data', false, $params, $what, $website ); |
| 326 |
if ( is_array( $params_filter ) && ! empty( $params_filter ) ) { |
| 327 |
$data = array_merge( $data, $params_filter ); |
| 328 |
} |
| 329 |
|
| 330 |
if ( null != $params ) { |
| 331 |
$data = array_merge( $data, $params ); |
| 332 |
} |
| 333 |
|
| 334 |
$data = apply_filters( 'mainwp_get_post_data_authed', $data, $website, $what, $params ); |
| 335 |
|
| 336 |
if ( ( 0 == $website->nossl ) && function_exists( 'openssl_verify' ) ) { |
| 337 |
$data['nossl'] = 0; |
| 338 |
openssl_sign( $what . $data['nonce'], $signature, base64_decode( $website->privkey ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible. |
| 339 |
} else { |
| 340 |
$data['nossl'] = 1; |
| 341 |
$signature = md5( $what . $data['nonce'] . $website->nosslkey ); |
| 342 |
} |
| 343 |
$data['mainwpsignature'] = base64_encode( $signature ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible. |
| 344 |
|
| 345 |
/** This filter is documented in ../widgets/widget-mainwp-recent-posts.php */ |
| 346 |
$recent_number = apply_filters( 'mainwp_recent_posts_pages_number', 5 ); |
| 347 |
if ( 5 !== $recent_number ) { |
| 348 |
$data['recent_number'] = $recent_number; |
| 349 |
} |
| 350 |
|
| 351 |
$scan_dir = apply_filters( 'mainwp_stats_scan_dir', false, $website ); |
| 352 |
if ( ! empty( $scan_dir ) ) { |
| 353 |
$data['scan_dir'] = 1; |
| 354 |
} |
| 355 |
|
| 356 |
/** |
| 357 |
* Current user global. |
| 358 |
* |
| 359 |
* @global string |
| 360 |
*/ |
| 361 |
global $current_user; |
| 362 |
|
| 363 |
if ( ( ! defined( 'DOING_CRON' ) || false === DOING_CRON ) && ( ! defined( 'WP_CLI' ) || false === WP_CLI ) ) { |
| 364 |
if ( is_object( $current_user ) && property_exists( $current_user, 'ID' ) && $current_user->ID ) { |
| 365 |
|
| 366 |
/** |
| 367 |
* Filter: mainwp_alter_login_user |
| 368 |
* |
| 369 |
* Filters users accounts so it allows you user to jump to child site under alternative administrator account. |
| 370 |
* |
| 371 |
* @param int $website->id Child site ID. |
| 372 |
* @param int $current_user->ID User ID. |
| 373 |
* |
| 374 |
* @since Unknown |
| 375 |
*/ |
| 376 |
$alter_user = apply_filters( 'mainwp_alter_login_user', false, $website->id, $current_user->ID ); |
| 377 |
if ( ! empty( $alter_user ) ) { |
| 378 |
$data['alt_user'] = rawurlencode( $alter_user ); |
| 379 |
} |
| 380 |
} |
| 381 |
} |
| 382 |
|
| 383 |
return http_build_query( $data, '', '&' ); |
| 384 |
} |
| 385 |
|
| 386 |
return null; |
| 387 |
} |
| 388 |
|
| 389 |
/** |
| 390 |
* Method get_get_data_authed() |
| 391 |
* |
| 392 |
* Get authorized $_GET data & build query. |
| 393 |
* |
| 394 |
* @param mixed $website Child Site data. |
| 395 |
* @param mixed $paramValue OpenSSL parameter. |
| 396 |
* @param string $paramName Parameter name. |
| 397 |
* @param bool $asArray true|false Default is false. |
| 398 |
* |
| 399 |
* @return string $url |
| 400 |
*/ |
| 401 |
public static function get_get_data_authed( $website, $paramValue, $paramName = 'where', $asArray = false ) { |
| 402 |
$params = array(); |
| 403 |
if ( $website && '' != $paramValue ) { |
| 404 |
$nonce = wp_rand( 0, 9999 ); |
| 405 |
if ( ( 0 == $website->nossl ) && function_exists( 'openssl_verify' ) ) { |
| 406 |
$nossl = 0; |
| 407 |
openssl_sign( $paramValue . $nonce, $signature, base64_decode( $website->privkey ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible. |
| 408 |
} else { |
| 409 |
$nossl = 1; |
| 410 |
$signature = md5( $paramValue . $nonce . $website->nosslkey ); |
| 411 |
} |
| 412 |
$signature = base64_encode( $signature ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible. |
| 413 |
|
| 414 |
$params = array( |
| 415 |
'login_required' => 1, |
| 416 |
'user' => rawurlencode( $website->adminname ), |
| 417 |
'mainwpsignature' => rawurlencode( $signature ), |
| 418 |
'nonce' => $nonce, |
| 419 |
'nossl' => $nossl, |
| 420 |
$paramName => rawurlencode( $paramValue ), |
| 421 |
); |
| 422 |
|
| 423 |
/** |
| 424 |
* Current user global. |
| 425 |
* |
| 426 |
* @global string |
| 427 |
*/ |
| 428 |
global $current_user; |
| 429 |
|
| 430 |
if ( ( ! defined( 'DOING_CRON' ) || false === DOING_CRON ) && ( ! defined( 'WP_CLI' ) || false === WP_CLI ) ) { |
| 431 |
if ( $current_user && $current_user->ID ) { |
| 432 |
/** This filter is documented in ../class/class-mainwp-connect.php */ |
| 433 |
$alter_user = apply_filters( 'mainwp_alter_login_user', false, $website->id, $current_user->ID ); |
| 434 |
if ( ! empty( $alter_user ) ) { |
| 435 |
$params['alt_user'] = rawurlencode( $alter_user ); |
| 436 |
} |
| 437 |
} |
| 438 |
} |
| 439 |
} |
| 440 |
|
| 441 |
if ( $asArray ) { |
| 442 |
return $params; |
| 443 |
} |
| 444 |
|
| 445 |
$url = ( isset( $website->url ) && '' != $website->url ? $website->url : $website->siteurl ); |
| 446 |
$url .= ( substr( $url, - 1 ) != '/' ? '/' : '' ); |
| 447 |
$url .= '?'; |
| 448 |
|
| 449 |
foreach ( $params as $key => $value ) { |
| 450 |
$url .= $key . '=' . $value . '&'; |
| 451 |
} |
| 452 |
|
| 453 |
return rtrim( $url, '&' ); |
| 454 |
} |
| 455 |
|
| 456 |
/** |
| 457 |
* Method get_post_data_not_authed() |
| 458 |
* |
| 459 |
* Get not authorized $_POST data. |
| 460 |
* |
| 461 |
* @param mixed $url Child site URL. |
| 462 |
* @param mixed $admin Admin Username. |
| 463 |
* @param mixed $what What function to perform. |
| 464 |
* @param null $params Function parameters. |
| 465 |
* |
| 466 |
* @return mixed null|http_build_query() |
| 467 |
*/ |
| 468 |
public static function get_post_data_not_authed( $url, $admin, $what, $params = null ) { |
| 469 |
if ( '' != $url && '' != $admin && '' != $what ) { |
| 470 |
$data = array(); |
| 471 |
$data['user'] = $admin; |
| 472 |
$data['function'] = $what; |
| 473 |
if ( null != $params ) { |
| 474 |
$data = array_merge( $data, $params ); |
| 475 |
} |
| 476 |
|
| 477 |
return http_build_query( $data, '', '&' ); |
| 478 |
} |
| 479 |
|
| 480 |
return null; |
| 481 |
} |
| 482 |
|
| 483 |
/** |
| 484 |
* Method fetch_urls_authed() |
| 485 |
* |
| 486 |
* Fetch authorized URLs. |
| 487 |
* |
| 488 |
* @param object $websites Websites information. |
| 489 |
* @param string $what Action to perform. |
| 490 |
* @param array $params Request parameters. |
| 491 |
* @param mixed $handler Request handler. |
| 492 |
* @param mixed $output Request output. |
| 493 |
* @param mixed $whatPage Request URL. Default /admin-ajax.php. |
| 494 |
* @param array $others Request additional information. |
| 495 |
* @param bool $is_external_hook Check if external hook is used. |
| 496 |
* |
| 497 |
* @return bool true|false |
| 498 |
* |
| 499 |
* @uses \MainWP\Dashboard\MainWP_System::$version |
| 500 |
* @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_dir() |
| 501 |
*/ |
| 502 |
public static function fetch_urls_authed( &$websites, $what, $params, $handler, &$output, $whatPage = null, $others = array(), $is_external_hook = false ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity -- complex function. Current complexity is the only way to achieve desired results, pull request solutions appreciated. |
| 503 |
|
| 504 |
if ( ! is_array( $websites ) || empty( $websites ) ) { |
| 505 |
return false; |
| 506 |
} |
| 507 |
|
| 508 |
if ( ! is_array( $params ) ) { |
| 509 |
$params = array(); |
| 510 |
} |
| 511 |
|
| 512 |
$chunkSize = apply_filters( 'mainwp_fetch_urls_chunk_size', 10 ); |
| 513 |
if ( count( $websites ) > $chunkSize ) { |
| 514 |
$total = count( $websites ); |
| 515 |
$loops = ceil( $total / $chunkSize ); |
| 516 |
for ( $i = 0; $i < $loops; $i ++ ) { |
| 517 |
$newSites = array_slice( $websites, $i * $chunkSize, $chunkSize, true ); |
| 518 |
self::fetch_urls_authed( $newSites, $what, $params, $handler, $output, $whatPage, $others, $is_external_hook ); |
| 519 |
sleep( 5 ); |
| 520 |
} |
| 521 |
|
| 522 |
return false; |
| 523 |
} |
| 524 |
|
| 525 |
if ( $is_external_hook ) { |
| 526 |
/** |
| 527 |
* Filter: mainwp_response_json_format |
| 528 |
* |
| 529 |
* Filters whether response should be in the JSON format. |
| 530 |
* |
| 531 |
* @since Unknown |
| 532 |
*/ |
| 533 |
$json_format = apply_filters( 'mainwp_response_json_format', false ); |
| 534 |
} else { |
| 535 |
$json_format = true; |
| 536 |
} |
| 537 |
|
| 538 |
$agent = 'Mozilla/5.0 (compatible; MainWP/' . MainWP_System::$version . '; +http://mainwp.com)'; |
| 539 |
$mh = curl_multi_init(); |
| 540 |
|
| 541 |
$timeout = 20 * 60 * 60; |
| 542 |
|
| 543 |
$disabled_functions = ini_get( 'disable_functions' ); |
| 544 |
$handleToWebsite = array(); |
| 545 |
$requestUrls = array(); |
| 546 |
$requestHandles = array(); |
| 547 |
|
| 548 |
$dirs = MainWP_System_Utility::get_mainwp_dir(); |
| 549 |
$cookieDir = $dirs[0] . 'cookies'; |
| 550 |
|
| 551 |
self::init_cookiesdir( $cookieDir ); |
| 552 |
|
| 553 |
foreach ( $websites as $website ) { |
| 554 |
$url = $website->url; |
| 555 |
if ( '/' != substr( $url, - 1 ) ) { |
| 556 |
$url .= '/'; |
| 557 |
} |
| 558 |
|
| 559 |
if ( false === strpos( $url, 'wp-admin' ) ) { |
| 560 |
$url .= 'wp-admin/'; |
| 561 |
} |
| 562 |
|
| 563 |
if ( null != $whatPage ) { |
| 564 |
$url .= $whatPage; |
| 565 |
} else { |
| 566 |
$url .= 'admin-ajax.php'; |
| 567 |
} |
| 568 |
|
| 569 |
if ( property_exists( $website, 'http_user' ) ) { |
| 570 |
$http_user = $website->http_user; |
| 571 |
} |
| 572 |
if ( property_exists( $website, 'http_pass' ) ) { |
| 573 |
$http_pass = $website->http_pass; |
| 574 |
} |
| 575 |
|
| 576 |
$_new_post = null; |
| 577 |
if ( isset( $params ) && isset( $params['new_post'] ) ) { |
| 578 |
$_new_post = $params['new_post']; |
| 579 |
|
| 580 |
/** |
| 581 |
* Filter is being replaced with mainwp_pre_posting_posts. |
| 582 |
* |
| 583 |
* @deprecated |
| 584 |
*/ |
| 585 |
$params = apply_filters_deprecated( |
| 586 |
'mainwp-pre-posting-posts', |
| 587 |
array( |
| 588 |
( is_array( $params ) ? $params : array() ), |
| 589 |
(object) array( |
| 590 |
'id' => $website->id, |
| 591 |
'url' => $website->url, |
| 592 |
'name' => $website->name, |
| 593 |
), |
| 594 |
), |
| 595 |
'4.0.7.2', |
| 596 |
'mainwp_pre_posting_posts' |
| 597 |
); |
| 598 |
|
| 599 |
/** |
| 600 |
* Filter: mainwp_pre_posting_posts |
| 601 |
* |
| 602 |
* Prepares parameters for the authenticated cURL post. |
| 603 |
* |
| 604 |
* @since 4.1 |
| 605 |
*/ |
| 606 |
$params = apply_filters( |
| 607 |
'mainwp_pre_posting_posts', |
| 608 |
( is_array( $params ) ? $params : array() ), |
| 609 |
(object) array( |
| 610 |
'id' => $website->id, |
| 611 |
'url' => $website->url, |
| 612 |
'name' => $website->name, |
| 613 |
) |
| 614 |
); |
| 615 |
} |
| 616 |
|
| 617 |
$ch = curl_init(); |
| 618 |
|
| 619 |
$proxy = new \WP_HTTP_Proxy(); |
| 620 |
if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { |
| 621 |
curl_setopt( $ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP ); |
| 622 |
curl_setopt( $ch, CURLOPT_PROXY, $proxy->host() ); |
| 623 |
curl_setopt( $ch, CURLOPT_PROXYPORT, $proxy->port() ); |
| 624 |
|
| 625 |
if ( $proxy->use_authentication() ) { |
| 626 |
curl_setopt( $ch, CURLOPT_PROXYAUTH, CURLAUTH_ANY ); |
| 627 |
curl_setopt( $ch, CURLOPT_PROXYUSERPWD, $proxy->authentication() ); |
| 628 |
} |
| 629 |
} |
| 630 |
|
| 631 |
if ( ( null != $website ) && ( ( property_exists( $website, 'wpe' ) && 1 != $website->wpe ) || ( isset( $others['upgrade'] ) && ( true == $others['upgrade'] ) ) ) ) { |
| 632 |
// to fix. |
| 633 |
if ( defined( 'LOGGED_IN_SALT' ) && defined( 'NONCE_SALT' ) ) { |
| 634 |
$cookie_salt = sha1( sha1( 'mainwp' . LOGGED_IN_SALT . $website->id ) . NONCE_SALT . 'WP_Cookie' ); |
| 635 |
} else { |
| 636 |
$cookie_salt = sha1( sha1( 'mainwp' . $website->id ) . 'WP_Cookie' ); |
| 637 |
} |
| 638 |
$cookieFile = $cookieDir . '/' . $cookie_salt; |
| 639 |
if ( ! file_exists( $cookieFile ) ) { |
| 640 |
@file_put_contents( $cookieFile, '' ); |
| 641 |
} |
| 642 |
|
| 643 |
if ( file_exists( $cookieFile ) ) { |
| 644 |
@chmod( $cookieFile, 0644 ); |
| 645 |
curl_setopt( $ch, CURLOPT_COOKIEJAR, $cookieFile ); |
| 646 |
curl_setopt( $ch, CURLOPT_COOKIEFILE, $cookieFile ); |
| 647 |
} |
| 648 |
} |
| 649 |
|
| 650 |
curl_setopt( $ch, CURLOPT_URL, $url ); |
| 651 |
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); |
| 652 |
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true ); |
| 653 |
curl_setopt( $ch, CURLOPT_POST, true ); |
| 654 |
|
| 655 |
if ( is_array( $params ) ) { |
| 656 |
$params['json_result'] = $json_format; |
| 657 |
} |
| 658 |
|
| 659 |
$postdata = self::get_post_data_authed( $website, $what, $params ); |
| 660 |
curl_setopt( $ch, CURLOPT_POSTFIELDS, $postdata ); |
| 661 |
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 10 ); |
| 662 |
curl_setopt( $ch, CURLOPT_USERAGENT, $agent ); |
| 663 |
curl_setopt( $ch, CURLOPT_ENCODING, 'none' ); |
| 664 |
if ( ! empty( $http_user ) && ! empty( $http_pass ) ) { |
| 665 |
$http_pass = stripslashes( $http_pass ); |
| 666 |
curl_setopt( $ch, CURLOPT_USERPWD, "$http_user:$http_pass" ); |
| 667 |
} |
| 668 |
|
| 669 |
$ssl_verifyhost = false; |
| 670 |
$verifyCertificate = isset( $website->verify_certificate ) ? $website->verify_certificate : null; |
| 671 |
if ( null !== $verifyCertificate ) { |
| 672 |
if ( 1 == $verifyCertificate ) { |
| 673 |
$ssl_verifyhost = true; |
| 674 |
} elseif ( 2 == $verifyCertificate ) { |
| 675 |
if ( ( ( false === get_option( 'mainwp_sslVerifyCertificate' ) ) || ( 1 == get_option( 'mainwp_sslVerifyCertificate' ) ) ) ) { |
| 676 |
$ssl_verifyhost = true; |
| 677 |
} |
| 678 |
} |
| 679 |
} else { |
| 680 |
if ( ( ( false === get_option( 'mainwp_sslVerifyCertificate' ) ) || ( 1 == get_option( 'mainwp_sslVerifyCertificate' ) ) ) ) { |
| 681 |
$ssl_verifyhost = true; |
| 682 |
} |
| 683 |
} |
| 684 |
|
| 685 |
if ( $ssl_verifyhost ) { |
| 686 |
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 2 ); |
| 687 |
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, true ); |
| 688 |
} else { |
| 689 |
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false ); |
| 690 |
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); |
| 691 |
} |
| 692 |
|
| 693 |
curl_setopt( $ch, CURLOPT_SSLVERSION, $website->ssl_version ); |
| 694 |
|
| 695 |
if ( is_object( $website ) && property_exists( $website, 'id' ) ) { |
| 696 |
$http_version = apply_filters( 'mainwp_curl_http_version', false, $website->id ); |
| 697 |
if ( false !== $http_version ) { |
| 698 |
curl_setopt( $ch, CURLOPT_HTTP_VERSION, $http_version ); |
| 699 |
} |
| 700 |
|
| 701 |
$curlopt_resolve = apply_filters( 'mainwp_curl_curlopt_resolve', false, $website->id, $website->url ); |
| 702 |
if ( is_array( $curlopt_resolve ) && ! empty( $curlopt_resolve ) ) { |
| 703 |
curl_setopt( $ch, CURLOPT_RESOLVE, $curlopt_resolve ); |
| 704 |
curl_setopt( $ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false ); |
| 705 |
} |
| 706 |
} |
| 707 |
|
| 708 |
curl_setopt( $ch, CURLOPT_TIMEOUT, $timeout ); |
| 709 |
MainWP_System_Utility::set_time_limit( $timeout ); |
| 710 |
|
| 711 |
if ( empty( $disabled_functions ) || ( false === stristr( $disabled_functions, 'curl_multi_exec' ) ) ) { |
| 712 |
@curl_multi_add_handle( $mh, $ch ); |
| 713 |
} |
| 714 |
|
| 715 |
$handleToWebsite[ self::get_resource_id( $ch ) ] = $website; |
| 716 |
$requestUrls[ self::get_resource_id( $ch ) ] = $website->url; |
| 717 |
$requestHandles[ self::get_resource_id( $ch ) ] = $ch; |
| 718 |
|
| 719 |
if ( null != $_new_post ) { |
| 720 |
$params['new_post'] = $_new_post; |
| 721 |
} |
| 722 |
} |
| 723 |
|
| 724 |
if ( empty( $disabled_functions ) || ( false === stristr( $disabled_functions, 'curl_multi_exec' ) ) ) { |
| 725 |
$lastRun = 0; |
| 726 |
do { |
| 727 |
if ( 20 < time() - $lastRun ) { |
| 728 |
MainWP_System_Utility::set_time_limit( $timeout ); |
| 729 |
$lastRun = time(); |
| 730 |
} |
| 731 |
|
| 732 |
curl_multi_exec( $mh, $running ); |
| 733 |
while ( $info = curl_multi_info_read( $mh ) ) { |
| 734 |
$data = curl_multi_getcontent( $info['handle'] ); |
| 735 |
$contains = ( 0 < preg_match( '/<mainwp>(.*)<\/mainwp>/', $data, $results ) ); |
| 736 |
curl_multi_remove_handle( $mh, $info['handle'] ); |
| 737 |
|
| 738 |
if ( ! $contains && isset( $requestUrls[ self::get_resource_id( $info['handle'] ) ] ) ) { |
| 739 |
curl_setopt( $info['handle'], CURLOPT_URL, $requestUrls[ self::get_resource_id( $info['handle'] ) ] ); |
| 740 |
curl_multi_add_handle( $mh, $info['handle'] ); |
| 741 |
unset( $requestUrls[ self::get_resource_id( $info['handle'] ) ] ); |
| 742 |
$running ++; |
| 743 |
continue; |
| 744 |
} |
| 745 |
|
| 746 |
if ( null != $handler ) { |
| 747 |
$site = &$handleToWebsite[ self::get_resource_id( $info['handle'] ) ]; |
| 748 |
call_user_func_array( $handler, array( $data, $site, &$output, $params ) ); |
| 749 |
} |
| 750 |
|
| 751 |
unset( $handleToWebsite[ self::get_resource_id( $info['handle'] ) ] ); |
| 752 |
if ( 'resource' === gettype( $info['handle'] ) ) { |
| 753 |
curl_close( $info['handle'] ); |
| 754 |
} |
| 755 |
unset( $info['handle'] ); |
| 756 |
} |
| 757 |
usleep( 10000 ); |
| 758 |
} while ( $running > 0 ); |
| 759 |
|
| 760 |
if ( 'resource' === gettype( $mh ) ) { |
| 761 |
curl_multi_close( $mh ); |
| 762 |
} |
| 763 |
} else { |
| 764 |
foreach ( $requestHandles as $id => $ch ) { |
| 765 |
$data = curl_exec( $ch ); |
| 766 |
|
| 767 |
if ( null != $handler ) { |
| 768 |
$site = &$handleToWebsite[ self::get_resource_id( $ch ) ]; |
| 769 |
call_user_func_array( $handler, array( $data, $site, &$output, $params ) ); |
| 770 |
} |
| 771 |
} |
| 772 |
} |
| 773 |
|
| 774 |
return true; |
| 775 |
} |
| 776 |
|
| 777 |
/** |
| 778 |
* Credits WordPress org. |
| 779 |
* |
| 780 |
* Get the correct "Expect" header for the given request data. |
| 781 |
* |
| 782 |
* @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD. |
| 783 |
* @return string The "Expect" header. |
| 784 |
*/ |
| 785 |
protected static function get_expect_header( $data ) { |
| 786 |
if ( ! is_array( $data ) ) { |
| 787 |
return strlen( (string) $data ) >= 1048576 ? '100-Continue' : ''; |
| 788 |
} |
| 789 |
|
| 790 |
$bytesize = 0; |
| 791 |
$iterator = new \RecursiveIteratorIterator( new \RecursiveArrayIterator( $data ) ); |
| 792 |
|
| 793 |
foreach ( $iterator as $datum ) { |
| 794 |
$bytesize += strlen( (string) $datum ); |
| 795 |
|
| 796 |
if ( $bytesize >= 1048576 ) { |
| 797 |
return '100-Continue'; |
| 798 |
} |
| 799 |
} |
| 800 |
|
| 801 |
return ''; |
| 802 |
} |
| 803 |
|
| 804 |
/** |
| 805 |
* Method get_resource_id() |
| 806 |
* |
| 807 |
* Get resource id. |
| 808 |
* |
| 809 |
* @param mixed $resource The given resource. |
| 810 |
* |
| 811 |
* @return $result Resource ID only. |
| 812 |
*/ |
| 813 |
public static function get_resource_id( $resource ) { |
| 814 |
$result = false; |
| 815 |
if ( is_a( $resource, 'CurlHandle' ) ) { |
| 816 |
$result = spl_object_hash( $resource ); |
| 817 |
} elseif ( is_resource( $resource ) ) { |
| 818 |
$resourceString = (string) $resource; |
| 819 |
$exploded = explode( '#', $resourceString ); |
| 820 |
$result = array_pop( $exploded ); |
| 821 |
} |
| 822 |
return $result; |
| 823 |
} |
| 824 |
|
| 825 |
/** |
| 826 |
* Method get_lock_identifier(). |
| 827 |
* |
| 828 |
* Get lock identifier. |
| 829 |
* |
| 830 |
* @param mixed $pLockName Provided Lock Name. |
| 831 |
* |
| 832 |
* @return mixed false|sem_get()|@fopen |
| 833 |
*/ |
| 834 |
public static function get_lock_identifier( $pLockName ) { |
| 835 |
if ( ( null == $pLockName ) || ( false == $pLockName ) ) { |
| 836 |
return false; |
| 837 |
} |
| 838 |
|
| 839 |
if ( function_exists( 'sem_get' ) ) { |
| 840 |
return sem_get( $pLockName ); |
| 841 |
} else { |
| 842 |
$fh = @fopen( sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'lock' . $pLockName . '.txt', 'w+' ); |
| 843 |
if ( ! $fh ) { |
| 844 |
return false; |
| 845 |
} |
| 846 |
|
| 847 |
return $fh; |
| 848 |
} |
| 849 |
|
| 850 |
return false; |
| 851 |
} |
| 852 |
|
| 853 |
/** |
| 854 |
* Method lock() |
| 855 |
* |
| 856 |
* Use sem_acquire or @flock to lock the $identifier. |
| 857 |
* |
| 858 |
* @param mixed $identifier Identifier. |
| 859 |
* |
| 860 |
* @return mixed false|sem_acquire()|@flock |
| 861 |
*/ |
| 862 |
public static function lock( $identifier ) { |
| 863 |
if ( ( null == $identifier ) || ( false == $identifier ) ) { |
| 864 |
return false; |
| 865 |
} |
| 866 |
|
| 867 |
if ( function_exists( 'sem_acquire' ) ) { |
| 868 |
return sem_acquire( $identifier ); |
| 869 |
} else { |
| 870 |
if ( ! is_resource( $identifier ) ) { |
| 871 |
return false; // to fix. |
| 872 |
} |
| 873 |
for ( $i = 0; $i < 3; $i ++ ) { |
| 874 |
if ( @flock( $identifier, LOCK_EX ) ) { |
| 875 |
return $identifier; |
| 876 |
} else { |
| 877 |
sleep( 1 ); |
| 878 |
} |
| 879 |
} |
| 880 |
|
| 881 |
return false; |
| 882 |
} |
| 883 |
|
| 884 |
return false; |
| 885 |
} |
| 886 |
|
| 887 |
/** |
| 888 |
* Method release() |
| 889 |
* |
| 890 |
* Use sem_release or @flock, @fclose to unlock $identifier. |
| 891 |
* |
| 892 |
* @param mixed $identifier Identifier. |
| 893 |
* |
| 894 |
* @return mixed false|sem_release()|@flock |
| 895 |
*/ |
| 896 |
public static function release( $identifier ) { |
| 897 |
if ( ( null == $identifier ) || ( false == $identifier ) ) { |
| 898 |
return false; |
| 899 |
} |
| 900 |
|
| 901 |
if ( function_exists( 'sem_release' ) ) { |
| 902 |
return sem_release( $identifier ); |
| 903 |
} else { |
| 904 |
if ( ! is_resource( $identifier ) ) { |
| 905 |
return false; // to fix. |
| 906 |
} |
| 907 |
@flock( $identifier, LOCK_UN ); |
| 908 |
@fclose( $identifier ); |
| 909 |
} |
| 910 |
|
| 911 |
return false; |
| 912 |
} |
| 913 |
|
| 914 |
/** |
| 915 |
* Method fetch_url_authed() |
| 916 |
* |
| 917 |
* Updates the child site via authenticated request. |
| 918 |
* |
| 919 |
* @param object $website Website information. |
| 920 |
* @param string $what Function to perform. |
| 921 |
* @param null $params Function parameters. |
| 922 |
* @param bool $checkConstraints Whether or not to check constraints. |
| 923 |
* @param bool $pForceFetch Whether or not to force the fetch. |
| 924 |
* @param bool $pRetryFailed Whether or not to retry the fetch process. |
| 925 |
* @param null $rawResponse Raw response. |
| 926 |
* |
| 927 |
* @return mixed $information |
| 928 |
* |
| 929 |
* @uses \MainWP\Dashboard\MainWP_Monitoring_Handler::handle_check_website() |
| 930 |
* @uses \MainWP\Dashboard\MainWP_Premium_Update::maybe_request_premium_updates() |
| 931 |
* @uses \MainWP\Dashboard\MainWP_Sync::sync_information_array() |
| 932 |
*/ |
| 933 |
public static function fetch_url_authed( |
| 934 |
&$website, |
| 935 |
$what, |
| 936 |
$params = null, |
| 937 |
$checkConstraints = false, |
| 938 |
$pForceFetch = false, |
| 939 |
$pRetryFailed = true, |
| 940 |
$rawResponse = null ) { |
| 941 |
|
| 942 |
if ( ! is_array( $params ) ) { |
| 943 |
$params = array(); |
| 944 |
} |
| 945 |
|
| 946 |
$others = array( |
| 947 |
'force_use_ipv4' => $website->force_use_ipv4, |
| 948 |
'upgrade' => ( 'upgradeplugintheme' === $what || 'upgrade' === $what || 'upgradetranslation' === $what ), |
| 949 |
); |
| 950 |
|
| 951 |
$request_update = MainWP_Premium_Update::maybe_request_premium_updates( $website, $what, $params ); |
| 952 |
|
| 953 |
if ( isset( $rawResponse ) && $rawResponse ) { |
| 954 |
$others['raw_response'] = 'yes'; |
| 955 |
} |
| 956 |
|
| 957 |
$params['optimize'] = ( ( 1 == get_option( 'mainwp_optimize', 0 ) ) ? 1 : 0 ); |
| 958 |
|
| 959 |
$updating_website = false; |
| 960 |
$type = ''; |
| 961 |
$list = ''; |
| 962 |
if ( 'upgradeplugintheme' === $what || 'upgrade' === $what || 'upgradetranslation' === $what ) { |
| 963 |
$updating_website = true; |
| 964 |
if ( 'upgradeplugintheme' === $what || 'upgradetranslation' === $what ) { |
| 965 |
$type = $params['type']; |
| 966 |
$list = $params['list']; |
| 967 |
} else { |
| 968 |
$type = 'wp'; |
| 969 |
$list = ''; |
| 970 |
} |
| 971 |
} |
| 972 |
|
| 973 |
if ( $updating_website ) { |
| 974 |
/** |
| 975 |
* Action: mainwp_website_before_updated |
| 976 |
* |
| 977 |
* Fires before the child site update process. |
| 978 |
* |
| 979 |
* @param object $website Object containing child site info. |
| 980 |
* @param string $type Type parameter. |
| 981 |
* @param string $list List parameter. |
| 982 |
* |
| 983 |
* @since Unknown |
| 984 |
*/ |
| 985 |
do_action( 'mainwp_website_before_updated', $website, $type, $list ); |
| 986 |
} |
| 987 |
|
| 988 |
$params['json_result'] = true; |
| 989 |
$postdata = self::get_post_data_authed( $website, $what, $params ); |
| 990 |
$others['function'] = $what; |
| 991 |
|
| 992 |
$information = array(); |
| 993 |
|
| 994 |
if ( ! $request_update ) { |
| 995 |
$information = self::fetch_url( $website, $website->url, $postdata, $checkConstraints, $website->verify_certificate, $pRetryFailed, $website->http_user, $website->http_pass, $website->ssl_version, $others ); |
| 996 |
} else { |
| 997 |
$slug = $params['list']; |
| 998 |
$information['upgrades'] = array( $slug => 1 ); |
| 999 |
} |
| 1000 |
|
| 1001 |
if ( is_array( $information ) && isset( $information['sync'] ) && ! empty( $information['sync'] ) ) { |
| 1002 |
MainWP_Sync::sync_information_array( $website, $information['sync'] ); |
| 1003 |
unset( $information['sync'] ); |
| 1004 |
} |
| 1005 |
|
| 1006 |
if ( $updating_website ) { |
| 1007 |
/** |
| 1008 |
* Action: mainwp_website_updated |
| 1009 |
* |
| 1010 |
* Fires after the child site update process. |
| 1011 |
* |
| 1012 |
* @param object $website Object containing child site info. |
| 1013 |
* @param string $type Type parameter. |
| 1014 |
* @param string $list List parameter. |
| 1015 |
* @param array $information Array containing the information fetched from the child site. |
| 1016 |
* |
| 1017 |
* @since Unknown |
| 1018 |
*/ |
| 1019 |
do_action( 'mainwp_website_updated', $website, $type, $list, $information ); |
| 1020 |
if ( 1 == get_option( 'mainwp_check_http_response', 0 ) ) { |
| 1021 |
MainWP_Monitoring_Handler::handle_check_website( $website ); |
| 1022 |
} |
| 1023 |
} |
| 1024 |
|
| 1025 |
return $information; |
| 1026 |
} |
| 1027 |
|
| 1028 |
/** |
| 1029 |
* Method fetch_url_not_authed() |
| 1030 |
* |
| 1031 |
* Fetch not authorized URL. |
| 1032 |
* |
| 1033 |
* @param string $url URL to fetch from. |
| 1034 |
* @param string $admin Admin name. |
| 1035 |
* @param string $what Function to perform. |
| 1036 |
* @param null $params Function parameters. |
| 1037 |
* @param bool $pForceFetch true|false Whether or not to force the fetch. |
| 1038 |
* @param null $verifyCertificate Verify the SSL Certificate. |
| 1039 |
* @param null $http_user htaccess username. |
| 1040 |
* @param null $http_pass htaccess password. |
| 1041 |
* @param integer $sslVersion SSL version to check for. |
| 1042 |
* @param array $others Other functions to perform. |
| 1043 |
* @param array $output Output values. |
| 1044 |
* |
| 1045 |
* @return mixed self::fetch_url() Fetch URL. |
| 1046 |
*/ |
| 1047 |
public static function fetch_url_not_authed( |
| 1048 |
$url, |
| 1049 |
$admin, |
| 1050 |
$what, |
| 1051 |
$params = null, |
| 1052 |
$pForceFetch = false, |
| 1053 |
$verifyCertificate = null, |
| 1054 |
$http_user = null, |
| 1055 |
$http_pass = null, |
| 1056 |
$sslVersion = 0, |
| 1057 |
$others = array(), |
| 1058 |
&$output = array() ) { |
| 1059 |
|
| 1060 |
if ( empty( $params ) ) { |
| 1061 |
$params = array(); |
| 1062 |
} |
| 1063 |
|
| 1064 |
if ( is_array( $params ) ) { |
| 1065 |
$params['json_result'] = true; |
| 1066 |
} |
| 1067 |
|
| 1068 |
$postdata = self::get_post_data_not_authed( $url, $admin, $what, $params ); |
| 1069 |
$website = null; |
| 1070 |
|
| 1071 |
$others['function'] = $what; |
| 1072 |
return self::fetch_url( $website, $url, $postdata, false, $verifyCertificate, true, $http_user, $http_pass, $sslVersion, $others, $output ); |
| 1073 |
} |
| 1074 |
|
| 1075 |
/** |
| 1076 |
* Method fetch_url() |
| 1077 |
* |
| 1078 |
* Fetch URL. |
| 1079 |
* |
| 1080 |
* @param object $website Child Site info. |
| 1081 |
* @param string $url URL to fetch from. |
| 1082 |
* @param mixed $postdata Post data to fetch. |
| 1083 |
* @param bool $checkConstraints true|false Whether or not to check constraints. |
| 1084 |
* @param null $verifyCertificate Verify SSL Certificate. |
| 1085 |
* @param bool $pRetryFailed ture|false Whether or not the Retry has failed. |
| 1086 |
* @param null $http_user htaccess username. |
| 1087 |
* @param null $http_pass htaccess password. |
| 1088 |
* @param integer $sslVersion SSL version. |
| 1089 |
* @param array $others Other functions to perform. |
| 1090 |
* @param array $output Output values. |
| 1091 |
* |
| 1092 |
* @throws \Exception Exception message. |
| 1093 |
* |
| 1094 |
* @return mixed self::fetch_url_site() |
| 1095 |
*/ |
| 1096 |
public static function fetch_url( |
| 1097 |
&$website, |
| 1098 |
$url, |
| 1099 |
$postdata, |
| 1100 |
$checkConstraints = false, |
| 1101 |
$verifyCertificate = null, |
| 1102 |
$pRetryFailed = true, |
| 1103 |
$http_user = null, |
| 1104 |
$http_pass = null, |
| 1105 |
$sslVersion = 0, |
| 1106 |
$others = array(), |
| 1107 |
&$output = array() ) { |
| 1108 |
|
| 1109 |
$start = time(); |
| 1110 |
|
| 1111 |
try { |
| 1112 |
$tmpUrl = $url; |
| 1113 |
if ( '/' != substr( $tmpUrl, - 1 ) ) { |
| 1114 |
$tmpUrl .= '/'; |
| 1115 |
} |
| 1116 |
|
| 1117 |
if ( false === strpos( $url, 'wp-admin' ) ) { |
| 1118 |
$tmpUrl .= 'wp-admin/admin-ajax.php'; |
| 1119 |
} |
| 1120 |
|
| 1121 |
return self::fetch_url_site( $website, $tmpUrl, $postdata, $checkConstraints, $verifyCertificate, $http_user, $http_pass, $sslVersion, $others, $output ); |
| 1122 |
} catch ( \Exception $e ) { |
| 1123 |
if ( ! $pRetryFailed || ( 30 < ( time() - $start ) ) ) { |
| 1124 |
throw $e; |
| 1125 |
} |
| 1126 |
|
| 1127 |
try { |
| 1128 |
return self::fetch_url_site( $website, $url, $postdata, $checkConstraints, $verifyCertificate, $http_user, $http_pass, $sslVersion, $others, $output ); |
| 1129 |
} catch ( \Exception $ex ) { |
| 1130 |
throw $e; |
| 1131 |
} |
| 1132 |
} |
| 1133 |
} |
| 1134 |
|
| 1135 |
/** |
| 1136 |
* Method fetch_url_site() |
| 1137 |
* |
| 1138 |
* M Fetch URL. |
| 1139 |
* |
| 1140 |
* @param object $website Child Site info. |
| 1141 |
* @param string $url URL to fetch from. |
| 1142 |
* @param mixed $postdata Post data to fetch. |
| 1143 |
* @param bool $checkConstraints true|false Whether or not to check constraints. |
| 1144 |
* @param null $verifyCertificate Verify SSL Certificate. |
| 1145 |
* @param null $http_user htaccess username. |
| 1146 |
* @param null $http_pass htaccess password. |
| 1147 |
* @param integer $sslVersion SSL version. |
| 1148 |
* @param array $others Other functions to perform. |
| 1149 |
* @param array $output Output values. |
| 1150 |
* |
| 1151 |
* @return mixed $data, $information. |
| 1152 |
* @throws MainWP_Exception Exception message. |
| 1153 |
* |
| 1154 |
* @uses \MainWP\Dashboard\MainWP_DB_Common::insert_or_update_request_log() |
| 1155 |
* @uses \MainWP\Dashboard\MainWP_Exception |
| 1156 |
* @uses \MainWP\Dashboard\MainWP_Logger::debug_for_website() |
| 1157 |
* @uses \MainWP\Dashboard\MainWP_System::$version |
| 1158 |
* @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_dir() |
| 1159 |
* @uses \MainWP\Dashboard\MainWP_System_Utility::get_child_response() |
| 1160 |
* @uses \MainWP\Dashboard\MainWP_Utility::value_to_string() |
| 1161 |
* @uses \MainWP\Dashboard\MainWP_Utility::end_session() |
| 1162 |
*/ |
| 1163 |
public static function fetch_url_site( // phpcs:ignore -- complex method. Current complexity is the only way to achieve desired results, pull request solutions appreciated. |
| 1164 |
&$website, |
| 1165 |
$url, |
| 1166 |
$postdata, |
| 1167 |
$checkConstraints = false, |
| 1168 |
$verifyCertificate = null, |
| 1169 |
$http_user = null, |
| 1170 |
$http_pass = null, |
| 1171 |
$sslVersion = 0, |
| 1172 |
$others = array(), |
| 1173 |
&$output = array() ) { |
| 1174 |
|
| 1175 |
$agent = 'Mozilla/5.0 (compatible; MainWP/' . MainWP_System::$version . '; +http://mainwp.com)'; |
| 1176 |
|
| 1177 |
if ( ! empty( $website ) ) { |
| 1178 |
MainWP_Logger::instance()->debug_for_website( $website, 'fetch_url_site', 'Request to [' . $url . '] [' . MainWP_Utility::value_to_string( $postdata, 1 ) . ']' ); |
| 1179 |
} |
| 1180 |
|
| 1181 |
$identifier = null; |
| 1182 |
if ( $checkConstraints ) { |
| 1183 |
self::check_constraints( $identifier, $website ); |
| 1184 |
} |
| 1185 |
|
| 1186 |
if ( null != $website ) { |
| 1187 |
MainWP_DB_Common::instance()->insert_or_update_request_log( $website->id, null, microtime( true ), null ); |
| 1188 |
} |
| 1189 |
|
| 1190 |
if ( null != $identifier ) { |
| 1191 |
self::release( $identifier ); |
| 1192 |
} |
| 1193 |
|
| 1194 |
$dirs = MainWP_System_Utility::get_mainwp_dir(); |
| 1195 |
$cookieDir = $dirs[0] . 'cookies'; |
| 1196 |
|
| 1197 |
self::init_cookiesdir( $cookieDir ); |
| 1198 |
|
| 1199 |
$ch = curl_init(); |
| 1200 |
|
| 1201 |
$proxy = new \WP_HTTP_Proxy(); |
| 1202 |
if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { |
| 1203 |
curl_setopt( $ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP ); |
| 1204 |
curl_setopt( $ch, CURLOPT_PROXY, $proxy->host() ); |
| 1205 |
curl_setopt( $ch, CURLOPT_PROXYPORT, $proxy->port() ); |
| 1206 |
|
| 1207 |
if ( $proxy->use_authentication() ) { |
| 1208 |
curl_setopt( $ch, CURLOPT_PROXYAUTH, CURLAUTH_ANY ); |
| 1209 |
curl_setopt( $ch, CURLOPT_PROXYUSERPWD, $proxy->authentication() ); |
| 1210 |
} |
| 1211 |
} |
| 1212 |
|
| 1213 |
if ( ( null != $website ) && ( ( property_exists( $website, 'wpe' ) && 1 != $website->wpe ) || ( isset( $others['upgrade'] ) && ( true == $others['upgrade'] ) ) ) ) { |
| 1214 |
// to fix. |
| 1215 |
if ( defined( 'LOGGED_IN_SALT' ) && defined( 'NONCE_SALT' ) ) { |
| 1216 |
$cookie_salt = sha1( sha1( 'mainwp' . LOGGED_IN_SALT . $website->id ) . NONCE_SALT . 'WP_Cookie' ); |
| 1217 |
} else { |
| 1218 |
$cookie_salt = sha1( sha1( 'mainwp' . $website->id ) . 'WP_Cookie' ); |
| 1219 |
} |
| 1220 |
$cookieFile = $cookieDir . '/' . $cookie_salt; |
| 1221 |
if ( ! file_exists( $cookieFile ) ) { |
| 1222 |
@file_put_contents( $cookieFile, '' ); |
| 1223 |
} |
| 1224 |
|
| 1225 |
if ( file_exists( $cookieFile ) ) { |
| 1226 |
@chmod( $cookieFile, 0644 ); |
| 1227 |
curl_setopt( $ch, CURLOPT_COOKIEJAR, $cookieFile ); |
| 1228 |
curl_setopt( $ch, CURLOPT_COOKIEFILE, $cookieFile ); |
| 1229 |
} |
| 1230 |
} |
| 1231 |
|
| 1232 |
curl_setopt( $ch, CURLOPT_URL, $url ); |
| 1233 |
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); |
| 1234 |
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true ); |
| 1235 |
curl_setopt( $ch, CURLOPT_POST, true ); |
| 1236 |
curl_setopt( $ch, CURLOPT_POSTFIELDS, $postdata ); |
| 1237 |
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 10 ); |
| 1238 |
curl_setopt( $ch, CURLOPT_USERAGENT, $agent ); |
| 1239 |
curl_setopt( $ch, CURLOPT_ENCODING, 'none' ); |
| 1240 |
|
| 1241 |
if ( ! empty( $http_user ) && ! empty( $http_pass ) ) { |
| 1242 |
$http_pass = stripslashes( $http_pass ); |
| 1243 |
curl_setopt( $ch, CURLOPT_USERPWD, "$http_user:$http_pass" ); |
| 1244 |
} |
| 1245 |
|
| 1246 |
$ssl_verifyhost = false; |
| 1247 |
if ( null !== $verifyCertificate ) { |
| 1248 |
if ( 1 == $verifyCertificate ) { |
| 1249 |
$ssl_verifyhost = true; |
| 1250 |
} elseif ( 2 == $verifyCertificate ) { |
| 1251 |
if ( ( ( false === get_option( 'mainwp_sslVerifyCertificate' ) ) || ( 1 == get_option( 'mainwp_sslVerifyCertificate' ) ) ) ) { |
| 1252 |
$ssl_verifyhost = true; |
| 1253 |
} |
| 1254 |
} |
| 1255 |
} else { |
| 1256 |
if ( ( ( false === get_option( 'mainwp_sslVerifyCertificate' ) ) || ( 1 == get_option( 'mainwp_sslVerifyCertificate' ) ) ) ) { |
| 1257 |
$ssl_verifyhost = true; |
| 1258 |
} |
| 1259 |
} |
| 1260 |
|
| 1261 |
if ( $ssl_verifyhost ) { |
| 1262 |
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 2 ); |
| 1263 |
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, true ); |
| 1264 |
} else { |
| 1265 |
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false ); |
| 1266 |
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); |
| 1267 |
} |
| 1268 |
|
| 1269 |
curl_setopt( $ch, CURLOPT_SSLVERSION, $sslVersion ); |
| 1270 |
|
| 1271 |
if ( is_object( $website ) && property_exists( $website, 'id' ) ) { |
| 1272 |
$http_version = apply_filters( 'mainwp_curl_http_version', false, $website->id ); |
| 1273 |
if ( false !== $http_version ) { |
| 1274 |
curl_setopt( $ch, CURLOPT_HTTP_VERSION, $http_version ); |
| 1275 |
} |
| 1276 |
$curlopt_resolve = apply_filters( 'mainwp_curl_curlopt_resolve', false, $website->id, $website->url ); |
| 1277 |
if ( is_array( $curlopt_resolve ) && ! empty( $curlopt_resolve ) ) { |
| 1278 |
curl_setopt( $ch, CURLOPT_RESOLVE, $curlopt_resolve ); |
| 1279 |
curl_setopt( $ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false ); |
| 1280 |
} |
| 1281 |
} |
| 1282 |
|
| 1283 |
$headers = array( 'X-Requested-With' => 'XMLHttpRequest' ); |
| 1284 |
$headers['Expect'] = self::get_expect_header( $postdata ); |
| 1285 |
$headers = \Requests::flatten( $headers ); |
| 1286 |
|
| 1287 |
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers ); |
| 1288 |
curl_setopt( $ch, CURLOPT_REFERER, get_option( 'siteurl' ) ); |
| 1289 |
|
| 1290 |
$force_use_ipv4 = false; |
| 1291 |
$forceUseIPv4 = isset( $others['force_use_ipv4'] ) ? $others['force_use_ipv4'] : null; |
| 1292 |
if ( null !== $forceUseIPv4 ) { |
| 1293 |
if ( 1 == $forceUseIPv4 ) { |
| 1294 |
$force_use_ipv4 = true; |
| 1295 |
} elseif ( 2 == $forceUseIPv4 ) { |
| 1296 |
if ( 1 == get_option( 'mainwp_forceUseIPv4' ) ) { |
| 1297 |
$force_use_ipv4 = true; |
| 1298 |
} |
| 1299 |
} |
| 1300 |
} else { |
| 1301 |
if ( 1 == get_option( 'mainwp_forceUseIPv4' ) ) { |
| 1302 |
$force_use_ipv4 = true; |
| 1303 |
} |
| 1304 |
} |
| 1305 |
|
| 1306 |
if ( $force_use_ipv4 ) { |
| 1307 |
if ( defined( 'CURLOPT_IPRESOLVE' ) && defined( 'CURL_IPRESOLVE_V4' ) ) { |
| 1308 |
curl_setopt( $ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 ); |
| 1309 |
} |
| 1310 |
} |
| 1311 |
|
| 1312 |
$timeout = 20 * 60 * 60; |
| 1313 |
curl_setopt( $ch, CURLOPT_TIMEOUT, $timeout ); |
| 1314 |
MainWP_System_Utility::set_time_limit( $timeout ); |
| 1315 |
|
| 1316 |
MainWP_Utility::end_session(); |
| 1317 |
|
| 1318 |
MainWP_Logger::instance()->debug_for_website( $website, 'fetch_url_site', 'Executing handlers' ); |
| 1319 |
|
| 1320 |
$disabled_functions = ini_get( 'disable_functions' ); |
| 1321 |
if ( empty( $disabled_functions ) || ( false === stristr( $disabled_functions, 'curl_multi_exec' ) ) ) { |
| 1322 |
$mh = @curl_multi_init(); |
| 1323 |
@curl_multi_add_handle( $mh, $ch ); |
| 1324 |
|
| 1325 |
$lastRun = 0; |
| 1326 |
do { |
| 1327 |
if ( 20 < time() - $lastRun ) { |
| 1328 |
MainWP_System_Utility::set_time_limit( $timeout ); |
| 1329 |
$lastRun = time(); |
| 1330 |
} |
| 1331 |
@curl_multi_exec( $mh, $running ); |
| 1332 |
while ( $info = @curl_multi_info_read( $mh ) ) { |
| 1333 |
$data = @curl_multi_getcontent( $info['handle'] ); |
| 1334 |
|
| 1335 |
$http_status = @curl_getinfo( $info['handle'], CURLINFO_HTTP_CODE ); |
| 1336 |
$err = @curl_error( $info['handle'] ); |
| 1337 |
$real_url = @curl_getinfo( $info['handle'], CURLINFO_EFFECTIVE_URL ); |
| 1338 |
|
| 1339 |
@curl_multi_remove_handle( $mh, $info['handle'] ); |
| 1340 |
} |
| 1341 |
usleep( 10000 ); |
| 1342 |
} while ( $running > 0 ); |
| 1343 |
if ( 'resource' === gettype( $mh ) ) { |
| 1344 |
@curl_multi_close( $mh ); |
| 1345 |
} |
| 1346 |
} else { |
| 1347 |
$data = @curl_exec( $ch ); |
| 1348 |
$http_status = @curl_getinfo( $ch, CURLINFO_HTTP_CODE ); |
| 1349 |
$err = @curl_error( $ch ); |
| 1350 |
$real_url = @curl_getinfo( $ch, CURLINFO_EFFECTIVE_URL ); |
| 1351 |
} |
| 1352 |
|
| 1353 |
$host = wp_parse_url( $real_url, PHP_URL_HOST ); |
| 1354 |
$ip = gethostbyname( $host ); |
| 1355 |
|
| 1356 |
if ( null != $website ) { |
| 1357 |
MainWP_DB_Common::instance()->insert_or_update_request_log( $website->id, $ip, null, microtime( true ) ); |
| 1358 |
} |
| 1359 |
|
| 1360 |
$raw_response = isset( $others['raw_response'] ) && 'yes' == $others['raw_response'] ? true : false; |
| 1361 |
|
| 1362 |
$output['fetch_data'] = $data; |
| 1363 |
$output['http_status'] = $http_status; |
| 1364 |
|
| 1365 |
MainWP_Logger::instance()->debug_for_website( $website, 'fetch_url_site', 'http status: [' . $http_status . '] err: [' . $err . ']' ); |
| 1366 |
if ( '400' == $http_status ) { |
| 1367 |
MainWP_Logger::instance()->debug_for_website( $website, 'fetch_url_site', 'post data: [' . MainWP_Utility::value_to_string( $postdata, 1 ) . ']' ); |
| 1368 |
} |
| 1369 |
|
| 1370 |
MainWP_Logger::instance()->log_execution_time( 'fetch_url_site :: [url=' . $url . ']' ); |
| 1371 |
|
| 1372 |
$thr_error = null; |
| 1373 |
|
| 1374 |
if ( ( false === $data ) && ( 0 == $http_status ) ) { |
| 1375 |
MainWP_Logger::instance()->debug_for_website( $website, 'fetch_url', '[' . $url . '] HTTP Error: [status=0][' . $err . ']' ); |
| 1376 |
$thr_error = new MainWP_Exception( 'HTTPERROR', $err ); |
| 1377 |
} elseif ( empty( $data ) && ! empty( $err ) ) { |
| 1378 |
MainWP_Logger::instance()->debug_for_website( $website, 'fetch_url', '[' . $url . '] HTTP Error: [status=' . $http_status . '][' . $err . ']' ); |
| 1379 |
$thr_error = new MainWP_Exception( 'HTTPERROR', $err ); |
| 1380 |
} elseif ( 0 < preg_match( '/<mainwp>(.*)<\/mainwp>/', $data, $results ) ) { |
| 1381 |
$result = $results[1]; |
| 1382 |
$information = MainWP_System_Utility::get_child_response( base64_decode( $result ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible. |
| 1383 |
unset( $output['fetch_data'] ); // hide the data. |
| 1384 |
MainWP_Logger::instance()->debug_for_website( $website, 'fetch_url_site', 'information: [OK]' ); |
| 1385 |
return $information; |
| 1386 |
} elseif ( 200 == $http_status && ! empty( $err ) ) { |
| 1387 |
$thr_error = new MainWP_Exception( 'HTTPERROR', $err ); |
| 1388 |
} elseif ( $raw_response ) { |
| 1389 |
MainWP_Logger::instance()->debug_for_website( $website, 'fetch_url_site', 'Response: [RAW]' ); |
| 1390 |
return $data; |
| 1391 |
} else { |
| 1392 |
MainWP_Logger::instance()->debug_for_website( $website, 'fetch_url', '[' . $url . '] Error: NOMAINWP' ); |
| 1393 |
$detect_wsidchk = is_string( $data ) ? strpos( $data, 'wsidchk' ) : false; |
| 1394 |
if ( false !== $detect_wsidchk ) { |
| 1395 |
$thr_error = new MainWP_Exception( 'ERROR:Connection Failed. We suspect that Imunify360, a security layer added by your host, is causing this problem. Please contact your host to whitelist your Dashboard IP in their system. If you need help determining your MainWP Dashboard site IP address, check with your hosting provider.', $url ); |
| 1396 |
} else { |
| 1397 |
$thr_error = new MainWP_Exception( 'NOMAINWP', $url ); |
| 1398 |
} |
| 1399 |
} |
| 1400 |
|
| 1401 |
if ( null !== $thr_error ) { |
| 1402 |
$thr_error->set_data( $data ); |
| 1403 |
throw $thr_error; |
| 1404 |
} |
| 1405 |
} |
| 1406 |
|
| 1407 |
/** |
| 1408 |
* Method check_constraints() |
| 1409 |
* |
| 1410 |
* Check connection delay constraints. |
| 1411 |
* |
| 1412 |
* @param mixed $identifier Lock identifier. |
| 1413 |
* @param mixed $website Object child site. |
| 1414 |
* |
| 1415 |
* @uses \MainWP\Dashboard\MainWP_DB_Common::close_open_requests() |
| 1416 |
* @uses \MainWP\Dashboard\MainWP_DB::get_wp_ip() |
| 1417 |
* @uses \MainWP\Dashboard\MainWP_Utility::end_session() |
| 1418 |
*/ |
| 1419 |
private static function check_constraints( &$identifier, $website ) { // phpcs:ignore -- Current complexity is the only way to achieve desired results, pull request solutions appreciated. |
| 1420 |
$semLock = '103218'; |
| 1421 |
$identifier = self::get_lock_identifier( $semLock ); |
| 1422 |
$minimumDelay = ( ( false === get_option( 'mainwp_minimumDelay' ) ) ? 200 : get_option( 'mainwp_minimumDelay' ) ); |
| 1423 |
if ( 0 < $minimumDelay ) { |
| 1424 |
$minimumDelay = $minimumDelay / 1000; |
| 1425 |
} |
| 1426 |
$minimumIPDelay = ( ( false === get_option( 'mainwp_minimumIPDelay' ) ) ? 1000 : get_option( 'mainwp_minimumIPDelay' ) ); |
| 1427 |
if ( 0 < $minimumIPDelay ) { |
| 1428 |
$minimumIPDelay = $minimumIPDelay / 1000; |
| 1429 |
} |
| 1430 |
|
| 1431 |
MainWP_Utility::end_session(); |
| 1432 |
$delay = true; |
| 1433 |
while ( $delay ) { |
| 1434 |
self::lock( $identifier ); |
| 1435 |
if ( 0 < $minimumDelay && self::check_constraints_last_request( $identifier, $minimumDelay ) ) { |
| 1436 |
continue; |
| 1437 |
} |
| 1438 |
|
| 1439 |
if ( 0 < $minimumIPDelay && null != $website ) { |
| 1440 |
$ip = MainWP_DB::instance()->get_wp_ip( $website->id ); |
| 1441 |
if ( null != $ip && '' !== $ip ) { |
| 1442 |
if ( self::check_constraints_last_request( $identifier, $minimumIPDelay, $ip ) ) { |
| 1443 |
continue; |
| 1444 |
} |
| 1445 |
} |
| 1446 |
} |
| 1447 |
$delay = false; |
| 1448 |
} |
| 1449 |
|
| 1450 |
$maximumRequests = ( ( false === get_option( 'mainwp_maximumRequests' ) ) ? 4 : get_option( 'mainwp_maximumRequests' ) ); |
| 1451 |
$maximumIPRequests = ( ( false === get_option( 'mainwp_maximumIPRequests' ) ) ? 1 : get_option( 'mainwp_maximumIPRequests' ) ); |
| 1452 |
|
| 1453 |
$first = true; |
| 1454 |
$delay = true; |
| 1455 |
while ( $delay ) { |
| 1456 |
if ( ! $first ) { |
| 1457 |
self::lock( $identifier ); |
| 1458 |
} else { |
| 1459 |
$first = false; |
| 1460 |
} |
| 1461 |
|
| 1462 |
MainWP_DB_Common::instance()->close_open_requests(); |
| 1463 |
|
| 1464 |
if ( 0 < $maximumRequests && self::check_constraints_open_requests( $identifier, $maximumRequests ) ) { |
| 1465 |
continue; |
| 1466 |
} |
| 1467 |
|
| 1468 |
if ( 0 < $maximumIPRequests && null != $website ) { |
| 1469 |
$ip = MainWP_DB::instance()->get_wp_ip( $website->id ); |
| 1470 |
if ( null != $ip && '' != $ip ) { |
| 1471 |
if ( self::check_constraints_open_requests( $identifier, $maximumIPRequests, $ip ) ) { |
| 1472 |
continue; |
| 1473 |
} |
| 1474 |
} |
| 1475 |
} |
| 1476 |
$delay = false; |
| 1477 |
} |
| 1478 |
} |
| 1479 |
|
| 1480 |
/** |
| 1481 |
* Method check_constraints_last_request(). |
| 1482 |
* |
| 1483 |
* Check constraints for last requests. |
| 1484 |
* |
| 1485 |
* @param mixed $identifier connect identifier. |
| 1486 |
* @param int $minimumDelay minimum delay. |
| 1487 |
* @param string|null $ip ip address. |
| 1488 |
* |
| 1489 |
* @uses \MainWP\Dashboard\MainWP_DB_Common::get_last_request_timestamp() |
| 1490 |
*/ |
| 1491 |
private static function check_constraints_last_request( $identifier, $minimumDelay, $ip = null ) { |
| 1492 |
$lastRequest = MainWP_DB_Common::instance()->get_last_request_timestamp( $ip ); |
| 1493 |
if ( $lastRequest > ( ( microtime( true ) ) - $minimumDelay ) ) { |
| 1494 |
self::release( $identifier ); |
| 1495 |
$sleep = ( $minimumDelay - ( ( microtime( true ) ) - $lastRequest ) ) * 1000 * 1000; |
| 1496 |
$sleep = intval( $sleep ); |
| 1497 |
usleep( $sleep ); |
| 1498 |
return true; |
| 1499 |
} |
| 1500 |
return false; |
| 1501 |
} |
| 1502 |
|
| 1503 |
/** |
| 1504 |
* Method check_constraints_open_requests(). |
| 1505 |
* |
| 1506 |
* Check constraints for open requests. |
| 1507 |
* |
| 1508 |
* @param mixed $identifier connect identifier. |
| 1509 |
* @param int $maximumRequests maximum requests. |
| 1510 |
* @param string|null $ip ip address. |
| 1511 |
* |
| 1512 |
* @uses \MainWP\Dashboard\MainWP_DB_Common::get_nrof_open_requests() |
| 1513 |
*/ |
| 1514 |
private static function check_constraints_open_requests( $identifier, $maximumRequests, $ip = null ) { |
| 1515 |
$nrOfOpenRequests = MainWP_DB_Common::instance()->get_nrof_open_requests( $ip ); |
| 1516 |
if ( $nrOfOpenRequests >= $maximumRequests ) { |
| 1517 |
self::release( $identifier ); |
| 1518 |
usleep( 200000 ); |
| 1519 |
return true; |
| 1520 |
} |
| 1521 |
return false; |
| 1522 |
} |
| 1523 |
|
| 1524 |
/** |
| 1525 |
* Method download_to_file() |
| 1526 |
* |
| 1527 |
* Download to file. |
| 1528 |
* |
| 1529 |
* @param mixed $url Download URL. |
| 1530 |
* @param mixed $file File to download to. |
| 1531 |
* @param bool $size Size of file. |
| 1532 |
* @param null $http_user htaccess username. |
| 1533 |
* @param null $http_pass htaccess password. |
| 1534 |
* |
| 1535 |
* @throws MainWP_Exception Exception message. |
| 1536 |
* |
| 1537 |
* @uses \MainWP\Dashboard\MainWP_Exception |
| 1538 |
* @uses \MainWP\Dashboard\MainWP_System::$version |
| 1539 |
* @uses \MainWP\Dashboard\MainWP_System_Utility::get_wp_file_system() |
| 1540 |
*/ |
| 1541 |
public static function download_to_file( $url, $file, $size = false, $http_user = null, $http_pass = null ) { |
| 1542 |
|
| 1543 |
$hasWPFileSystem = MainWP_System_Utility::get_wp_file_system(); |
| 1544 |
|
| 1545 |
/** |
| 1546 |
* WordPress files system object. |
| 1547 |
* |
| 1548 |
* @global object |
| 1549 |
*/ |
| 1550 |
global $wp_filesystem; |
| 1551 |
|
| 1552 |
if ( $wp_filesystem->exists( $file ) && ( ( false == $size ) || ( $wp_filesystem->size( $file ) > $size ) ) ) { |
| 1553 |
$wp_filesystem->delete( $file ); |
| 1554 |
} |
| 1555 |
|
| 1556 |
if ( ! $wp_filesystem->exists( dirname( $file ) ) ) { |
| 1557 |
$wp_filesystem->mkdir( dirname( $file ), 0777 ); |
| 1558 |
} |
| 1559 |
|
| 1560 |
if ( ! $wp_filesystem->exists( dirname( $file ) ) ) { |
| 1561 |
throw new MainWP_Exception( esc_html__( 'MainWP plugin could not create directory in order to download the file.', 'mainwp' ) ); |
| 1562 |
} |
| 1563 |
|
| 1564 |
if ( ! is_writable( @dirname( $file ) ) ) { |
| 1565 |
throw new MainWP_Exception( esc_html__( 'MainWP upload directory is not writable.', 'mainwp' ) ); |
| 1566 |
} |
| 1567 |
|
| 1568 |
$fp = fopen( $file, 'a' ); |
| 1569 |
$agent = 'Mozilla/5.0 (compatible; MainWP/' . MainWP_System::$version . '; +http://mainwp.com)'; |
| 1570 |
if ( false !== $size ) { |
| 1571 |
if ( $wp_filesystem->exists( $file ) ) { |
| 1572 |
$size = $wp_filesystem->size( $file ); |
| 1573 |
$url .= '&foffset=' . $size; |
| 1574 |
} |
| 1575 |
} |
| 1576 |
$ch = curl_init( str_replace( ' ', '%20', $url ) ); |
| 1577 |
|
| 1578 |
$proxy = new \WP_HTTP_Proxy(); |
| 1579 |
if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { |
| 1580 |
curl_setopt( $ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP ); |
| 1581 |
curl_setopt( $ch, CURLOPT_PROXY, $proxy->host() ); |
| 1582 |
curl_setopt( $ch, CURLOPT_PROXYPORT, $proxy->port() ); |
| 1583 |
|
| 1584 |
if ( $proxy->use_authentication() ) { |
| 1585 |
curl_setopt( $ch, CURLOPT_PROXYAUTH, CURLAUTH_ANY ); |
| 1586 |
curl_setopt( $ch, CURLOPT_PROXYUSERPWD, $proxy->authentication() ); |
| 1587 |
} |
| 1588 |
} |
| 1589 |
|
| 1590 |
curl_setopt( $ch, CURLOPT_FILE, $fp ); |
| 1591 |
curl_setopt( $ch, CURLOPT_USERAGENT, $agent ); |
| 1592 |
curl_setopt( $ch, CURLOPT_ENCODING, 'none' ); |
| 1593 |
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true ); |
| 1594 |
if ( ! empty( $http_user ) && ! empty( $http_pass ) ) { |
| 1595 |
$http_pass = stripslashes( $http_pass ); |
| 1596 |
curl_setopt( $ch, CURLOPT_USERPWD, "$http_user:$http_pass" ); |
| 1597 |
} |
| 1598 |
curl_exec( $ch ); |
| 1599 |
if ( 'resource' === gettype( $ch ) ) { |
| 1600 |
curl_close( $ch ); |
| 1601 |
} |
| 1602 |
fclose( $fp ); |
| 1603 |
} |
| 1604 |
|
| 1605 |
/** |
| 1606 |
* Method init_coockiesdir() |
| 1607 |
* |
| 1608 |
* Check for cookies directory and create it if it doesn't already exist, |
| 1609 |
* set the file permissions and update htaccess. |
| 1610 |
* |
| 1611 |
* @param mixed $cookieDir Cookies directory. |
| 1612 |
* |
| 1613 |
* @return void |
| 1614 |
* |
| 1615 |
* @uses \MainWP\Dashboard\MainWP_System_Utility::get_wp_file_system() |
| 1616 |
*/ |
| 1617 |
public static function init_cookiesdir( $cookieDir ) { |
| 1618 |
|
| 1619 |
$hasWPFileSystem = MainWP_System_Utility::get_wp_file_system(); |
| 1620 |
|
| 1621 |
/** |
| 1622 |
* WordPress files system object. |
| 1623 |
* |
| 1624 |
* @global object |
| 1625 |
*/ |
| 1626 |
global $wp_filesystem; |
| 1627 |
|
| 1628 |
if ( $hasWPFileSystem && ! empty( $wp_filesystem ) ) { |
| 1629 |
|
| 1630 |
if ( ! $wp_filesystem->is_dir( $cookieDir ) ) { |
| 1631 |
$wp_filesystem->mkdir( $cookieDir, 0777 ); |
| 1632 |
} |
| 1633 |
|
| 1634 |
if ( ! file_exists( $cookieDir . '/.htaccess' ) ) { |
| 1635 |
$file_htaccess = $cookieDir . '/.htaccess'; |
| 1636 |
$wp_filesystem->put_contents( $file_htaccess, 'deny from all' ); |
| 1637 |
} |
| 1638 |
|
| 1639 |
if ( ! file_exists( $cookieDir . '/index.php' ) ) { |
| 1640 |
$file_index = $cookieDir . '/index.php'; |
| 1641 |
$wp_filesystem->touch( $file_index ); |
| 1642 |
} |
| 1643 |
} else { |
| 1644 |
|
| 1645 |
if ( ! file_exists( $cookieDir ) ) { |
| 1646 |
@mkdir( $cookieDir, 0777, true ); |
| 1647 |
} |
| 1648 |
|
| 1649 |
if ( ! file_exists( $cookieDir . '/.htaccess' ) ) { |
| 1650 |
$file_htaccess = @fopen( $cookieDir . '/.htaccess', 'w+' ); |
| 1651 |
@fwrite( $file_htaccess, 'deny from all' ); |
| 1652 |
@fclose( $file_htaccess ); |
| 1653 |
} |
| 1654 |
|
| 1655 |
if ( ! file_exists( $cookieDir . '/index.php' ) ) { |
| 1656 |
$file_index = @fopen( $cookieDir . '/index.php', 'w+' ); |
| 1657 |
@fclose( $file_index ); |
| 1658 |
} |
| 1659 |
} |
| 1660 |
} |
| 1661 |
|
| 1662 |
/** |
| 1663 |
* Method get_file_content() |
| 1664 |
* |
| 1665 |
* Get contents of file. |
| 1666 |
* |
| 1667 |
* @param mixed $url File Location. |
| 1668 |
* |
| 1669 |
* @return mixed false|$data |
| 1670 |
* |
| 1671 |
* @uses \MainWP\Dashboard\MainWP_System::$version |
| 1672 |
*/ |
| 1673 |
public static function get_file_content( $url ) { |
| 1674 |
$agent = 'Mozilla/5.0 (compatible; MainWP/' . MainWP_System::$version . '; +http://mainwp.com)'; |
| 1675 |
$ch = curl_init(); |
| 1676 |
|
| 1677 |
$proxy = new \WP_HTTP_Proxy(); |
| 1678 |
if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { |
| 1679 |
curl_setopt( $ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP ); |
| 1680 |
curl_setopt( $ch, CURLOPT_PROXY, $proxy->host() ); |
| 1681 |
curl_setopt( $ch, CURLOPT_PROXYPORT, $proxy->port() ); |
| 1682 |
|
| 1683 |
if ( $proxy->use_authentication() ) { |
| 1684 |
curl_setopt( $ch, CURLOPT_PROXYAUTH, CURLAUTH_ANY ); |
| 1685 |
curl_setopt( $ch, CURLOPT_PROXYUSERPWD, $proxy->authentication() ); |
| 1686 |
} |
| 1687 |
} |
| 1688 |
|
| 1689 |
curl_setopt( $ch, CURLOPT_HEADER, 0 ); |
| 1690 |
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 ); |
| 1691 |
curl_setopt( $ch, CURLOPT_URL, $url ); |
| 1692 |
curl_setopt( $ch, CURLOPT_USERAGENT, $agent ); |
| 1693 |
curl_setopt( $ch, CURLOPT_ENCODING, 'none' ); |
| 1694 |
|
| 1695 |
$data = @curl_exec( $ch ); |
| 1696 |
$httpCode = @curl_getinfo( $ch, CURLINFO_HTTP_CODE ); |
| 1697 |
if ( 'resource' === gettype( $ch ) ) { |
| 1698 |
curl_close( $ch ); |
| 1699 |
} |
| 1700 |
if ( 200 == $httpCode ) { |
| 1701 |
return $data; |
| 1702 |
} else { |
| 1703 |
return false; |
| 1704 |
} |
| 1705 |
} |
| 1706 |
|
| 1707 |
/** |
| 1708 |
* Method get_favico_url() |
| 1709 |
* |
| 1710 |
* Get Child Site favicon URL. |
| 1711 |
* |
| 1712 |
* @param mixed $website Child Site info. |
| 1713 |
* |
| 1714 |
* @return mixed $faviurl Favicon URL. |
| 1715 |
* |
| 1716 |
* @uses \MainWP\Dashboard\MainWP_DB::get_website_option() |
| 1717 |
* @uses \MainWP\Dashboard\MainWP_System_Utility::get_icons_dir() |
| 1718 |
* @uses \MainWP\Dashboard\MainWP_Utility::remove_http_prefix() |
| 1719 |
*/ |
| 1720 |
public static function get_favico_url( $website ) { |
| 1721 |
$favi = MainWP_DB::instance()->get_website_option( $website, 'favi_icon', '' ); |
| 1722 |
$faviurl = ''; |
| 1723 |
|
| 1724 |
if ( ! empty( $favi ) ) { |
| 1725 |
if ( false !== strpos( $favi, 'favi-' . intval( $website->id ) . '-' ) ) { |
| 1726 |
$dirs = MainWP_System_Utility::get_icons_dir(); |
| 1727 |
if ( file_exists( $dirs[0] . $favi ) ) { |
| 1728 |
$faviurl = $dirs[1] . $favi; |
| 1729 |
} else { |
| 1730 |
$faviurl = ''; |
| 1731 |
} |
| 1732 |
} elseif ( ( 0 === strpos( $favi, '//' ) ) || ( 0 === strpos( $favi, 'http' ) ) ) { |
| 1733 |
$faviurl = $favi; |
| 1734 |
} else { |
| 1735 |
$faviurl = $website->url . $favi; |
| 1736 |
$faviurl = MainWP_Utility::remove_http_prefix( $faviurl ); |
| 1737 |
} |
| 1738 |
} |
| 1739 |
if ( empty( $faviurl ) ) { |
| 1740 |
$faviurl = false; |
| 1741 |
} |
| 1742 |
|
| 1743 |
return $faviurl; |
| 1744 |
} |
| 1745 |
} |
| 1746 |
|