PluginProbe
ManageWP Worker / 4.9.15
ManageWP Worker v4.9.15
4.9.38 4.9.37 4.9.36 4.9.35 4.9.34 3.8.7 3.8.8 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.18 3.9.19 3.9.2 3.9.20 3.9.21 3.9.22 3.9.23 3.9.24 All 73 releases
worker / init.php

init.php in ManageWP Worker 4.9.15, at init.php

757 lines 29.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: ManageWP - Worker
4 Plugin URI: https://managewp.com
5 Description: We help you efficiently manage all your WordPress websites. <strong>Updates, backups, 1-click login, migrations, security</strong> and more, on one dashboard. This service comes in two versions: standalone <a href="https://managewp.com">ManageWP</a> service that focuses on website management, and <a href="https://godaddy.com/pro">GoDaddy Pro</a> that includes additional tools for hosting, client management, lead generation, and more.
6 Version: 4.9.15
7 Author: GoDaddy
8 Author URI: https://godaddy.com
9 License: GPL2
10 Text Domain: worker
11 Network: true
12 */
13
14 /*
15 * This file is part of the ManageWP Worker plugin.
16 *
17 * (c) ManageWP LLC <contact@managewp.com>
18 *
19 * For the full copyright and license information, please view the LICENSE
20 * file that was distributed with this source code.
21 */
22
23 if (!defined('ABSPATH') && (!defined('MWP_SKIP_BOOTSTRAP') || !MWP_SKIP_BOOTSTRAP)) {
24 exit;
25 }
26
27 if (!defined('MAX_PRIORITY_HOOK')) {
28 define('MAX_PRIORITY_HOOK', 2147483647);
29 }
30
31 /**
32 * Handler for incomplete plugin installations.
33 */
34 if (!function_exists('mwp_fail_safe')):
35 /**
36 * Reserved memory for fatal error handling execution context.
37 */
38 $GLOBALS['mwp_reserved_memory'] = str_repeat(' ', 1024 * 20);
39 /**
40 * If we ever get only partially upgraded due to a server error or misconfiguration,
41 * attempt to disable the plugin.
42 */
43 function mwp_fail_safe()
44 {
45 $GLOBALS['mwp_reserved_memory'] = null;
46
47 $lastError = error_get_last();
48
49 $acceptedErrorTypes = array(
50 E_ERROR,
51 E_COMPILE_ERROR,
52 );
53
54 if (!$lastError || !in_array($lastError['type'], $acceptedErrorTypes)) {
55 return;
56 }
57
58 $activePlugins = get_option('active_plugins');
59 $workerIndex = array_search(plugin_basename(__FILE__), $activePlugins);
60 if ($workerIndex === false) {
61 // Plugin is not yet enabled, possibly in activation context.
62 return;
63 }
64
65 $errorSource = realpath($lastError['file']);
66 // We might be in eval() context.
67 if (!$errorSource) {
68 return;
69 }
70
71 // The only fatal error that we would get would be a 'Class 'X' not found in ...', so look out only for those messages.
72 if (!preg_match('/^(Uncaught Error: )?Class \'[^\']+\' not found/', $lastError['message']) &&
73 !preg_match('/^(Uncaught Error: )?Call to undefined method /', $lastError['message']) &&
74 !preg_match('/^require_once\(\): Failed opening required \'[^\']+\'/', $lastError['message'])
75 ) {
76 return;
77 }
78
79 // Only look for files that belong to this plugin.
80 $pluginBase = realpath(dirname(__FILE__));
81 if (stripos($errorSource, $pluginBase) !== 0) {
82 return;
83 }
84
85 // Signal ourselves that the installation is corrupt.
86 update_option('mwp_recovering', time());
87
88 $siteUrl = get_option('siteurl');
89 $path = (string)parse_url($siteUrl, PHP_URL_PATH);
90 $title = sprintf("ManageWP Worker corrupt on %s", $siteUrl);
91 $to = get_option('admin_email');
92 $brand = get_option('mwp_worker_brand');
93 if (!empty($brand['admin_email'])) {
94 $to = $brand['admin_email'];
95 }
96
97 $fullError = print_r($lastError, 1);
98 $serviceID = (string)get_option('mwp_service_key');
99 $body = sprintf("Corrupt ManageWP Worker v%s installation detected. Site URL in question is %s. User email is %s (service ID: %s). Attempting recovery process at %s. The error that caused this:\n\n<pre>%s</pre>", $GLOBALS['MMB_WORKER_VERSION'], $siteUrl, $to, $serviceID, date('Y-m-d H:i:s'), $fullError);
100 mail('recovery@managewp.com', $title, $body, "Content-Type: text/html");
101
102 // If we're inside a cron scope, don't attempt to hide this error.
103 if (defined('DOING_CRON') && DOING_CRON) {
104 return;
105 }
106
107 // If we're inside a normal request scope retry the request so user doesn't have to see an ugly error page.
108 if (!empty($_SERVER['REQUEST_URI'])) {
109 $siteUrl .= substr($_SERVER['REQUEST_URI'], strlen($path));
110 }
111 if (isset($_SERVER['HTTP_MWP_ACTION'])) {
112 echo "\nMWP_RETRY_ME: 1\n", json_encode(array('error' => 'Worker recover started', 'exception' => array(
113 'class' => 'Exception',
114 'message' => 'Worker recover started',
115 'code' => 10038,
116 'file' => __FILE__,
117 'line' => __LINE__,
118 'traceString' => '',
119 'context' => array(),
120 'type' => 'WORKER_RECOVER_STARTED',
121 ))), "\n";
122 exit;
123 } elseif (headers_sent()) {
124 // The headers are probably sent if the PHP configuration has the 'display_errors' directive enabled. In that case try a meta redirect.
125 printf('<meta http-equiv="refresh" content="0; url=%s">', htmlspecialchars($siteUrl, ENT_QUOTES));
126 } else {
127 header('Location: '.htmlspecialchars($siteUrl, ENT_QUOTES));
128 }
129 exit;
130 }
131
132 register_shutdown_function('mwp_fail_safe');
133 endif;
134
135 if (!class_exists('MwpWorkerResponder', false)):
136 /**
137 * We're not allowed to use lambda functions because this is PHP 5.2, so use a responder
138 * class that's able to access the service container.
139 */
140 class MwpWorkerResponder
141 {
142
143 private $container;
144
145 private $responseSent = false;
146
147 function __construct(MWP_ServiceContainer_Interface $container)
148 {
149 $this->container = $container;
150 }
151
152 /**
153 * @param Exception|Error $e
154 * @param MWP_Http_ResponseInterface|null $response
155 *
156 * @throws null
157 */
158 function callback($e = null, MWP_Http_ResponseInterface $response = null)
159 {
160 if ($response !== null) {
161 $responseEvent = new MWP_Event_MasterResponse($response);
162 $this->container->getEventDispatcher()->dispatch(MWP_Event_Events::MASTER_RESPONSE, $responseEvent);
163 $lastResponse = $responseEvent->getResponse();
164
165 if ($lastResponse !== null) {
166 if (!$this->responseSent) {
167 // This looks pretty ugly, but the "execute PHP" function handles fatal errors and wraps them
168 // in a valid action response. That fatal error may also be handled by the global fatal error
169 // handler, which also wraps the error in a response. We keep the state in this class, so we
170 // don't send a worker response twice, first time as an action response, second time as a
171 // global response.
172 // If this is to be removed, simply remove fatal error handling from the "execute PHP" action.
173 $lastResponse->send();
174 $this->responseSent = true;
175 }
176 exit;
177 }
178 } elseif ($e !== null) {
179 // Exception is thrown and the response is empty. This should never happen, so don't try to hide it.
180 throw $e;
181 }
182 }
183
184 /**
185 * @return callable
186 */
187 public function getCallback()
188 {
189 return array($this, 'callback');
190 }
191 }
192 endif;
193
194 if (!function_exists('mwp_container')):
195 /**
196 * @return MWP_ServiceContainer_Interface
197 */
198 function mwp_container()
199 {
200 static $container;
201
202 if ($container === null) {
203 $parameters = (array)get_option('mwp_container_parameters', array()) + (array)get_option('mwp_container_site_parameters', array());
204 $requestId = isset($_GET['mwprid']) && is_string($_GET['mwprid']) ? $_GET['mwprid'] : null;
205 $container = new MWP_ServiceContainer_Production(array(
206 'worker_realpath' => __FILE__,
207 'worker_basename' => 'worker/init.php',
208 'worker_version' => $GLOBALS['MMB_WORKER_VERSION'],
209 'worker_revision' => $GLOBALS['MMB_WORKER_REVISION'],
210 'request_id' => $requestId,
211 ) + $parameters);
212 }
213
214 return $container;
215 }
216 endif;
217
218 if (!class_exists('MwpRecoveryKit', false)):
219 /**
220 * This class must be isolated from the rest of the ManageWP Worker library, because
221 * we're counting that we have only this file and WordPress bootstrapped.
222 */
223 class MwpRecoveryKit
224 {
225 const MAX_LOGGED_ERRORS = 5;
226
227 private static $errorLog = array();
228
229 private static function requestJson($url)
230 {
231 $response = wp_remote_get($url, array('timeout' => 60));
232 if ($response instanceof WP_Error) {
233 throw new Exception('Unable to download checksum.json: '.$response->get_error_message());
234 }
235 if ($response['response']['code'] !== 200) {
236 throw new Exception('Unable to download checksum.json: invalid status code ('.$response['response']['code'].')');
237 }
238
239 $responseJson = json_decode($response['body'], true);
240
241 if (empty($responseJson) || !is_array($responseJson)) {
242 throw new Exception('Error while parsing checksum.json.');
243 }
244
245 return $responseJson;
246 }
247
248 public function recover($version)
249 {
250 global $wpdb;
251 $lockTime = $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = 'mwp_incremental_recover_lock' LIMIT 1");
252
253
254 if ($lockTime && time() - (int)$lockTime < 1200) { // lock for 20 minutes
255 throw new Exception('Another incremental update or recovery process is already active', 1337);
256 }
257
258 register_shutdown_function(array($this, 'releaseLock'));
259
260 update_option('mwp_incremental_recover_lock', time());
261
262 ignore_user_abort(true);
263 $dirName = realpath(dirname(__FILE__));
264 $filesAndChecksums = $this->requestJson(sprintf('http://s3-us-west-2.amazonaws.com/mwp-orion-public/worker/raw/%s/checksum.json', $version));
265
266 try {
267 $files = $this->recoverFiles($dirName, $filesAndChecksums, $version);
268 } catch (Exception $e) {
269 $this->releaseLock();
270 throw $e;
271 }
272
273 $this->releaseLock();
274
275 return $files;
276 }
277
278 public function releaseLock()
279 {
280 delete_option('mwp_incremental_recover_lock');
281 }
282
283 public static function selfUpdate()
284 {
285 if (get_option('mwp_recovering')) {
286 return false;
287 }
288
289 try {
290 $response = self::requestJson('http://s3-us-west-2.amazonaws.com/mwp-orion-public/worker/latest.json');
291 $response += array('version' => '0.0.0', 'schedule' => 86400, 'autoUpdate' => false, 'checksum' => array());
292 wp_clear_scheduled_hook('mwp_auto_update');
293 wp_schedule_single_event(current_time('timestamp') + $response['schedule'], 'mwp_auto_update');
294 if (!$response['autoUpdate']) {
295 return false;
296 }
297 if (version_compare($response['version'], $GLOBALS['MMB_WORKER_VERSION'], '<')) {
298 return false;
299 }
300 self::recoverFiles(dirname(__FILE__), $response['checksum'], $response['version']);
301 } catch (Exception $e) {
302 mwp_logger()->error("Self-update failed.", array('exception' => $e));
303
304 return false;
305 }
306
307 return true;
308 }
309
310 private static function clearUnknownFiles($filesAndChecksums, $fs)
311 {
312 /** @var WP_Filesystem_Base $fs */
313 $base = dirname(__FILE__);
314 if (version_compare(phpversion(), '5.3', '<')) {
315 $directory = new RecursiveDirectoryIterator($base);
316 } else {
317 /** @handled constant */
318 $directory = new RecursiveDirectoryIterator($base, RecursiveDirectoryIterator::SKIP_DOTS);
319 }
320
321 $ignoreDelete = array(
322 'log.html' => 1,
323 'worker.json' => 1,
324 'init.php' => 1, // safe-guard
325 'functions.php' => 1, // safe-guard
326 );
327
328 $files = array_keys(iterator_to_array(new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD)));
329
330 foreach ($files as $file) {
331 $file = preg_replace('/^'.preg_quote($base, '/').'/', '', $file, 1, $count);
332
333 if (!$count) {
334 continue;
335 }
336
337 $file = strtr($file, '\\', '/');
338 $file = ltrim($file, '/');
339
340 if (isset($filesAndChecksums[$file]) || isset($ignoreDelete[$file])) {
341 continue;
342 }
343
344 $fs->delete($fs->find_folder(WP_PLUGIN_DIR).'worker/'.$file, false, 'f');
345 }
346 }
347
348 public static function recoverFiles($dirName, array $filesAndChecksums, $version)
349 {
350 set_error_handler(array(__CLASS__, 'logError'));
351 require_once ABSPATH.'wp-admin/includes/file.php';
352 require_once ABSPATH.'wp-admin/includes/template.php';
353
354 $options = array();
355
356 $fsMethod = get_filesystem_method();
357 if ($fsMethod !== 'direct') {
358 ob_start();
359 $options = request_filesystem_credentials('');
360 ob_end_clean();
361 }
362
363 /** @var WP_Filesystem_Base $fs */
364 WP_Filesystem($options);
365 $fs = $GLOBALS['wp_filesystem'];
366
367 if (!$fs->connect()) {
368 $lastError = error_get_last();
369 $errorMessage = $lastError ? $lastError['message'] : '(no error logged)';
370 throw new Exception('Unable to connect to the file system: '.$errorMessage);
371 }
372
373 $cachedFilesAndChecksums = $filesAndChecksums;
374
375 // First create directories and remove them from the array.
376 // Must be done before shuffling because of nesting.
377 foreach ($filesAndChecksums as $relativePath => $checksum) {
378 if ($checksum !== '') {
379 continue;
380 }
381 unset ($filesAndChecksums[$relativePath]);
382 $absolutePath = $dirName.'/'.$relativePath;
383 // Directories are ordered first.
384 if (!is_dir($absolutePath)) {
385 $fs->mkdir($fs->find_folder(WP_PLUGIN_DIR).'worker/'.$relativePath);
386 }
387 }
388
389 // Check and recreate files. Shuffle them so multiple running instances have a smaller collision.
390 $recoveredFiles = array();
391 $filesAndChecksums = self::shuffleAssoc($filesAndChecksums);
392 $retryCount = 0;
393 $retryUpTo = 5;
394 $lastError = null;
395 while ($checksum = current($filesAndChecksums)) {
396 if ($retryCount >= $retryUpTo) {
397 restore_error_handler();
398 throw new Exception($lastError);
399 }
400 $relativePath = key($filesAndChecksums);
401 $absolutePath = $dirName.'/'.$relativePath;
402 if (file_exists($absolutePath) && md5_file($absolutePath) === $checksum) {
403 next($filesAndChecksums);
404 continue;
405 }
406 $fileUrl = sprintf('http://s3-us-west-2.amazonaws.com/mwp-orion-public/worker/raw/%s/%s', $version, $relativePath);
407 $response = wp_remote_get($fileUrl, array('timeout' => 60));
408 if ($response instanceof WP_Error) {
409 $lastError = 'Unable to download file '.$fileUrl.': '.$response->get_error_message();
410 $retryCount++;
411 continue;
412 }
413 if ($response['response']['code'] !== 200) {
414 $lastError = 'Unable to download file '.$fileUrl.': invalid status code ('.$response['response']['code'].')';
415 $retryCount++;
416 continue;
417 }
418 $saved = $fs->put_contents($fs->find_folder(WP_PLUGIN_DIR).'worker/'.$relativePath, $response['body']);
419
420 if (!$saved) {
421 if (is_callable(array($fs, '__destruct'))) {
422 $fs->__destruct();
423 }
424 $fs->connect();
425 $lastError = 'File saving failed.';
426 if (count(self::$errorLog)) {
427 $lastError .= sprintf(" Last %d logged errors:%s", min(self::MAX_LOGGED_ERRORS, count(self::$errorLog)), "\n - ".implode("\n - ", self::$errorLog));
428 }
429 $retryCount++;
430 continue;
431 }
432
433 $lastError = null;
434 $retryCount = 0;
435 $recoveredFiles[] = $relativePath;
436 next($filesAndChecksums);
437 }
438
439 self::clearUnknownFiles($cachedFilesAndChecksums, $fs);
440
441 if (function_exists('opcache_reset')) {
442 @opcache_reset();
443 }
444
445 restore_error_handler();
446
447 return $recoveredFiles;
448 }
449
450 public static function logError($code, $message, $file = 'Unknown', $line = 0)
451 {
452 self::$errorLog[] = sprintf('Error [%d]: %s in %s on line %d', $code, $message, $file, $line);
453
454 if (count(self::$errorLog) > self::MAX_LOGGED_ERRORS) {
455 array_shift(self::$errorLog);
456 }
457 }
458
459 private static function shuffleAssoc($array)
460 {
461 $keys = array_keys($array);
462 shuffle($keys);
463 $shuffled = array();
464 foreach ($keys as $key) {
465 $shuffled[$key] = $array[$key];
466 }
467
468 return $shuffled;
469 }
470
471 public function selfDeactivate($reason)
472 {
473 if (isset($_SERVER['MWP2_VERSION_ID'])) {
474 return;
475 }
476
477 $activePlugins = get_option('active_plugins');
478 $workerIndex = array_search(plugin_basename(__FILE__), $activePlugins);
479 if ($workerIndex === false) {
480 // Plugin is not yet enabled, possibly in activation context.
481 return;
482 }
483 unset($activePlugins[$workerIndex]);
484 // Reset indexes.
485 $activePlugins = array_values($activePlugins);
486
487 delete_option('mwp_recovering');
488 update_option('active_plugins', $activePlugins);
489
490 $lastErrorMessage = '';
491 if ($lastError = error_get_last()) {
492 $lastErrorMessage = "\n\nLast error: ".$lastError['message'];
493 }
494 mail('recovery@managewp.com', sprintf("ManageWP Worker recovery aborted on %s", get_option('siteurl')), sprintf("ManageWP Worker v%s. Reason: %s%s", $GLOBALS['MMB_WORKER_VERSION'], $reason, $lastErrorMessage));
495 }
496 }
497 endif;
498
499 if (!function_exists('mwp_activation_hook')) {
500 function mwp_activation_hook()
501 {
502 update_option('mwp_incremental_update_active', '');
503
504 if (get_option('mwp_recovering')) {
505 update_option('mwp_recovering', '');
506 // Run the checksum one last time.
507 $recoveryKit = new MwpRecoveryKit();
508 try {
509 $recoveryKit->recover($GLOBALS['MMB_WORKER_VERSION']);
510 } catch (Exception $e) {
511 // Deactivating the plugin in activation hook wouldn't work, prevent the activation by triggering an error.
512 trigger_error($e->getMessage(), E_USER_ERROR);
513 }
514 }
515
516 mwp_core()->install();
517 }
518 }
519
520 if (!function_exists('mwp_try_recovery')):
521 function mwp_try_recovery()
522 {
523 global $wpdb;
524 $recoveringTime = $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = 'mwp_recovering' LIMIT 1");
525
526 if (empty($recoveringTime)) {
527 return true;
528 }
529
530 delete_transient('mwp_recovery_key');
531 $recoveryKit = new MwpRecoveryKit();
532 try {
533 $recoveredFiles = $recoveryKit->recover($GLOBALS['MMB_WORKER_VERSION']);
534
535 // Recovery complete.
536 update_option('mwp_recovering', '');
537 mail('recovery@managewp.com', sprintf("ManageWP Worker recovered on %s", get_option('siteurl')), sprintf("%d files successfully recovered in this recovery fork of ManageWP Worker v%s. Filesystem method used was <code>%s</code>.\n\n<pre>%s</pre>", count($recoveredFiles), $GLOBALS['MMB_WORKER_VERSION'], get_filesystem_method(), implode("\n", $recoveredFiles)), 'Content-Type: text/html');
538 } catch (Exception $e) {
539 if ($e->getCode() === 1337) {
540 return false;
541 }
542
543 if (time() - $recoveringTime > 3600) {
544 // If the recovery process does not complete after an hour, deactivate the Worker for safety
545 $recoveryKit->selfDeactivate($e->getMessage());
546 }
547
548 return false;
549 }
550
551 return true;
552 }
553 endif;
554
555 if (!function_exists('add_worker_update_info')):
556 function add_worker_update_info()
557 {
558 echo ' The plugin is going to update itself automatically in the next few days.';
559 }
560 endif;
561
562 if (!function_exists('mwp_init')):
563 function mwp_init()
564 {
565 // When the plugin deactivates due to a corrupt installation, (de)activation hooks
566 // will never get executed, so the 'mwp_recovering' option will never be deleted,
567 // making the plugin always force the recovery mode , which may always fail for any
568 // reason (eg. the site can't ping itself). Handle that case early.
569 register_activation_hook(__FILE__, 'mwp_activation_hook');
570
571 $GLOBALS['MMB_WORKER_VERSION'] = '4.9.15';
572 $GLOBALS['MMB_WORKER_REVISION'] = '2022-11-03 00:00:00';
573
574 // Ensure PHP version compatibility.
575 if (version_compare(PHP_VERSION, '5.2', '<')) {
576 trigger_error("ManageWP Worker plugin requires PHP 5.2 or higher.", E_USER_ERROR);
577 exit;
578 }
579
580 if ($incrementalUpdateTime = get_option('mwp_incremental_update_active')) {
581 if (time() - $incrementalUpdateTime > 600) { // lock for a maximum of 10 minutes for incremental update
582 update_option('mwp_incremental_update_active', '');
583 } else {
584 if (!isset($_SERVER['HTTP_MWP_ACTION'])) {
585 return;
586 }
587
588 global $wpdb;
589
590 $tries = 0;
591 $lastResult = true;
592
593 while ($tries < 60 && ($lastResult = $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = 'mwp_incremental_update_active' LIMIT 1"))) {
594 sleep(1);
595 ++$tries;
596 }
597
598 if (!$lastResult) {
599 echo "\nMWP_RETRY_ME: 1\n";
600 }
601
602 echo "\n", json_encode(array('error' => 'Worker is currently updating; please retry this action in a few seconds.', 'exception' => array(
603 'class' => 'Exception',
604 'message' => 'Worker is currently updating; please retry this action in a few seconds.',
605 'code' => 10037,
606 'file' => __FILE__,
607 'line' => __LINE__,
608 'traceString' => '',
609 'context' => array(),
610 'type' => 'WORKER_UPDATING',
611 ))), "\n";
612 exit;
613 }
614 }
615
616 if ($recoveringTime = get_option('mwp_recovering')) {
617 if (isset($_SERVER['HTTP_MWP_ACTION'])) {
618 $tries = 0;
619 $lastResult = false;
620
621 while ($tries < 60 && !($lastResult = mwp_try_recovery())) {
622 sleep(1);
623 ++$tries;
624 }
625
626 if ($lastResult) {
627 echo "\nMWP_RETRY_ME: 1\n";
628 }
629
630 echo "\n", json_encode(array('error' => 'Worker is currently recovering; please retry this action in a few seconds.', 'exception' => array(
631 'class' => 'Exception',
632 'message' => 'Worker is currently recovering; please retry this action in a few seconds.',
633 'code' => 10036,
634 'file' => __FILE__,
635 'line' => __LINE__,
636 'traceString' => '',
637 'context' => array(),
638 'type' => 'WORKER_RECOVERING',
639 ))), "\n";
640
641 exit;
642 } else {
643 $recoveryKey = get_transient('mwp_recovery_key');
644 if (!$passedRecoveryKey = filter_input(INPUT_POST, 'mwp_recovery_key')) {
645 $recoveryKey = md5(uniqid('', true));
646 set_transient('mwp_recovery_key', $recoveryKey, time() + 604800); // 1 week.
647
648 $headers = array();
649 if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
650 $headers['AUTHORIZATION'] = $_SERVER['HTTP_AUTHORIZATION'];
651 }
652
653 // fork only once, so we do not make too many parallel requests to the website
654 $lockTime = get_option('mwp_incremental_recover_lock');
655
656 if ($lockTime && time() - $lockTime < 1200) { // lock for 20 minutes
657 return;
658 }
659
660 wp_remote_post(get_bloginfo('wpurl'), array(
661 'reject_unsafe_urls' => false,
662 'headers' => $headers,
663 'body' => array(
664 'mwp_recovery_key' => $recoveryKey,
665 ),
666 'timeout' => 0.01,
667 ));
668 } else {
669 if ($recoveryKey !== $passedRecoveryKey) {
670 return;
671 }
672
673 mwp_try_recovery();
674 }
675
676 return;
677 }
678 }
679
680 if (version_compare(PHP_VERSION, '5.3', '<')) {
681 spl_autoload_register('mwp_autoload');
682 } else {
683 // The prepend parameter was added in PHP 5.3.0
684 spl_autoload_register('mwp_autoload', true, true);
685 }
686
687 $GLOBALS['mmb_plugin_dir'] = WP_PLUGIN_DIR.'/'.basename(dirname(__FILE__));
688 $GLOBALS['_mmb_item_filter'] = array();
689 $core = mwp_core();
690
691 $siteUrl = function_exists('get_site_option') ? get_site_option('siteurl') : get_option('siteurl');
692 define('MMB_XFRAME_COOKIE', 'wordpress_'.md5($siteUrl).'_xframe');
693
694 define('MWP_BACKUP_DIR', WP_CONTENT_DIR.'/managewp/backups');
695 define('MWP_DB_DIR', MWP_BACKUP_DIR.'/mwp_db');
696
697 add_filter('deprecated_function_trigger_error', '__return_false');
698 add_action('mwp_update_public_keys', 'mwp_refresh_live_public_keys');
699 add_action('init', 'mmb_plugin_actions', 99999);
700 add_filter('install_plugin_complete_actions', 'mmb_iframe_plugins_fix');
701 add_filter('comment_edit_redirect', 'mwb_edit_redirect_override');
702 add_action('mwp_auto_update', 'MwpRecoveryKit::selfUpdate');
703 add_action('in_plugin_update_message-'.plugin_basename(__FILE__), 'add_worker_update_info');
704
705 add_filter('cron_schedules', 'mwp_link_monitor_cron_recurrence_interval');
706 add_action('mwp_check_for_post_update', 'mwp_send_posts_to_link_monitor');
707 if (mwp_context()->optionGet('mwp_link_monitor_enabled')) {
708 add_action('save_post', 'mwp_add_post_to_link_monitor_check');
709 add_action('delete_post', 'mwp_add_post_to_link_monitor_check');
710
711 if (!wp_next_scheduled('mwp_check_for_post_update')) {
712 wp_schedule_event(time(), 'every_five_minutes', 'mwp_check_for_post_update');
713 }
714 }
715 // Public key updating cron.
716 if (!wp_next_scheduled('mwp_update_public_keys')) {
717 wp_schedule_event(time(), 'daily', 'mwp_update_public_keys');
718 }
719
720 register_deactivation_hook(__FILE__, array($core, 'deactivate'));
721 register_uninstall_hook(dirname(__FILE__).'/functions.php', 'mwp_uninstall');
722
723 // Don't send the "X-Frame-Options: SAMEORIGIN" header if we're logging in inside an iframe.
724 if (isset($_COOKIE[MMB_XFRAME_COOKIE])) {
725 remove_action('admin_init', 'send_frame_options_header');
726 remove_action('login_init', 'send_frame_options_header');
727 }
728
729 // Remove legacy scheduler.
730 if (wp_next_scheduled('mwp_backup_tasks')) {
731 wp_clear_scheduled_hook('mwp_backup_tasks');
732 }
733 mwp_provision_keys();
734 mwp_set_plugin_priority();
735
736 $request = MWP_Worker_Request::createFromGlobals();
737 $container = mwp_container();
738 $responder = new MwpWorkerResponder($container);
739
740 $kernel = new MWP_Worker_Kernel($container);
741 $kernel->handleRequest($request, $responder->getCallback(), true);
742
743 $mwpMM = get_option('mwp_maintenace_mode');
744 if (!empty($mwpMM) && $mwpMM['active']) {
745 add_action('admin_notices', 'site_in_mwp_maintenance_mode');
746 }
747 }
748
749 if (!defined('MWP_SKIP_BOOTSTRAP') || !MWP_SKIP_BOOTSTRAP) {
750 if (!get_option('mwp_recovering')) {
751 require_once dirname(__FILE__).'/functions.php';
752 }
753
754 mwp_init();
755 }
756 endif;
757