PluginProbe
ManageWP Worker / trunk
ManageWP Worker vtrunk
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
← All changes | init.php +702 -771 3.9.15 → trunk View file →
@@ -1,836 +1,767 @@
1 1 <?php
2 -/*
2 +/*
3 3 Plugin Name: ManageWP - Worker
4 -Plugin URI: http://managewp.com/
5 -Description: Manage all your blogs from one dashboard. Visit <a href="http://managewp.com">ManageWP.com</a> to sign up.
6 -Author: Prelovac Media
7 -Version: 3.9.16
8 -Author URI: http://www.prelovac.com
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.38
7 +Author: GoDaddy
8 +Author URI: https://godaddy.com
9 +License: GPL2
10 +Text Domain: worker
11 +Network: true
9 12 */
10 13
11 -/*************************************************************
12 - *
13 - * init.php
14 - *
15 - * Initialize the communication with master
16 - *
17 - *
18 - * Copyright (c) 2011 Prelovac Media
19 - * www.prelovac.com
20 - **************************************************************/
14 +/*
15 + * This file is part of the ManageWP Worker plugin.
16 + *
17 + * (c) ManageWP LLC <[email protected]>
18 + *
19 + * For the full copyright and license information, please view the LICENSE
20 + * file that was distributed with this source code.
21 + */
21 22
22 -if(!defined('MMB_WORKER_VERSION'))
23 - define('MMB_WORKER_VERSION', '3.9.16');
23 +if (!defined('ABSPATH') && (!defined('MWP_SKIP_BOOTSTRAP') || !MWP_SKIP_BOOTSTRAP)) {
24 + exit;
25 +}
24 26
25 -if ( !defined('MMB_XFRAME_COOKIE')){
26 - $siteurl = function_exists('get_site_option') ? get_site_option( 'siteurl' ) : get_option('siteurl');
27 - define('MMB_XFRAME_COOKIE', $xframe = 'wordpress_'.md5($siteurl).'_xframe');
27 +if (!defined('MAX_PRIORITY_HOOK')) {
28 + define('MAX_PRIORITY_HOOK', 2147483647);
28 29 }
29 -global $wpdb, $mmb_plugin_dir, $mmb_plugin_url, $wp_version, $mmb_filters, $_mmb_item_filter;
30 -if (version_compare(PHP_VERSION, '5.0.0', '<')) // min version 5 supported
31 - exit("<p>ManageWP Worker plugin requires PHP 5 or higher.</p>");
32 30
31 +if (version_compare(phpversion(), '8.0', '>=') && !function_exists('set_time_limit')){
32 + function set_time_limit($seconds)
33 + {
34 + return false;
35 + }
36 +}
33 37
34 -$mmb_wp_version = $wp_version;
35 -$mmb_plugin_dir = WP_PLUGIN_DIR . '/' . basename(dirname(__FILE__));
36 -$mmb_plugin_url = WP_PLUGIN_URL . '/' . basename(dirname(__FILE__));
38 +/**
39 + * Handler for incomplete plugin installations.
40 + */
41 +if (!function_exists('mwp_fail_safe')):
42 + /**
43 + * Reserved memory for fatal error handling execution context.
44 + */
45 + $GLOBALS['mwp_reserved_memory'] = str_repeat(' ', 1024 * 20);
46 + /**
47 + * If we ever get only partially upgraded due to a server error or misconfiguration,
48 + * attempt to disable the plugin.
49 + */
50 + function mwp_fail_safe()
51 + {
52 + $GLOBALS['mwp_reserved_memory'] = null;
37 53
38 -require_once("$mmb_plugin_dir/helper.class.php");
39 -require_once("$mmb_plugin_dir/core.class.php");
40 -require_once("$mmb_plugin_dir/post.class.php");
41 -require_once("$mmb_plugin_dir/comment.class.php");
42 -require_once("$mmb_plugin_dir/stats.class.php");
43 -require_once("$mmb_plugin_dir/backup.class.php");
44 -require_once("$mmb_plugin_dir/installer.class.php");
45 -require_once("$mmb_plugin_dir/link.class.php");
46 -require_once("$mmb_plugin_dir/user.class.php");
47 -require_once("$mmb_plugin_dir/api.php");
54 + $lastError = error_get_last();
48 55
49 -require_once("$mmb_plugin_dir/plugins/search/search.php");
50 -require_once("$mmb_plugin_dir/plugins/cleanup/cleanup.php");
56 + $acceptedErrorTypes = array(
57 + E_ERROR,
58 + E_COMPILE_ERROR,
59 + );
51 60
61 + if (!$lastError || !in_array($lastError['type'], $acceptedErrorTypes)) {
62 + return;
63 + }
52 64
53 -if( !function_exists ( 'mmb_parse_request' )) {
54 - function mmb_parse_request()
55 - {
56 -
57 - if (!isset($HTTP_RAW_POST_DATA)) {
58 - $HTTP_RAW_POST_DATA = file_get_contents('php://input');
59 - }
60 - ob_start();
61 -
62 - global $current_user, $mmb_core, $new_actions, $wp_db_version, $wpmu_version, $_wp_using_ext_object_cache;
63 - $data = base64_decode($HTTP_RAW_POST_DATA);
64 - if ($data)
65 - $num = @extract(unserialize($data));
66 -
67 - if (isset($action)) {
68 - $_wp_using_ext_object_cache = false;
69 - @set_time_limit(600);
70 -
71 - if (!$mmb_core->check_if_user_exists($params['username']))
72 - mmb_response('Username <b>' . $params['username'] . '</b> does not have administrator capabilities. Enter the correct username in the site options.', false);
73 -
74 - if ($action == 'add_site') {
75 - mmb_add_site($params);
76 - mmb_response('You should never see this.', false);
77 - }
65 + $activePlugins = get_option('active_plugins');
66 + $workerIndex = array_search(plugin_basename(__FILE__), is_array($activePlugins) ? $activePlugins : array());
67 + if ($workerIndex === false) {
68 + // Plugin is not yet enabled, possibly in activation context.
69 + return;
70 + }
78 71
79 - $auth = $mmb_core->authenticate_message($action . $id, $signature, $id);
80 - if ($auth === true) {
81 -
82 - if(isset($params['username']) && !is_user_logged_in()){
83 - $user = function_exists('get_user_by') ? get_user_by('login', $params['username']) : get_userdatabylogin( $params['username'] );
84 - wp_set_current_user($user->ID);
85 - }
86 -
87 - /* in case database upgrade required, do database backup and perform upgrade ( wordpress wp_upgrade() function ) */
88 - if( strlen(trim($wp_db_version)) && !defined('ACX_PLUGIN_DIR') ){
89 - if ( get_option('db_version') != $wp_db_version ) {
90 - /* in multisite network, please update database manualy */
91 - if (empty($wpmu_version) || (function_exists('is_multisite') && !is_multisite())){
92 - if( ! function_exists('wp_upgrade'))
93 - include_once(ABSPATH.'wp-admin/includes/upgrade.php');
94 -
95 - ob_clean();
96 - @wp_upgrade();
97 - @do_action('after_db_upgrade');
98 - ob_end_clean();
99 - }
100 - }
101 - }
102 -
103 - if(isset($params['secure'])){
104 - if($decrypted = $mmb_core->_secure_data($params['secure'])){
105 - $decrypted = maybe_unserialize($decrypted);
106 - if(is_array($decrypted)){
107 - foreach($decrypted as $key => $val){
108 - if(!is_numeric($key))
109 - $params[$key] = $val;
110 - }
111 - unset($params['secure']);
112 - } else $params['secure'] = $decrypted;
113 - }
114 - }
115 -
116 - if( !$mmb_core->register_action_params( $action, $params ) ){
117 - global $_mmb_plugin_actions;
118 - $_mmb_plugin_actions[$action] = $params;
119 - }
120 -
121 -
122 - } else {
123 - mmb_response($auth['error'], false);
124 - }
125 - } else {
126 - MMB_Stats::set_hit_count();
127 - }
128 - ob_end_clean();
129 - }
130 -}
131 -/* Main response function */
132 -if( !function_exists ( 'mmb_response' )) {
72 + $errorSource = realpath($lastError['file']);
73 + // We might be in eval() context.
74 + if (!$errorSource) {
75 + return;
76 + }
133 77
134 - function mmb_response($response = false, $success = true)
135 - {
136 - $return = array();
137 -
138 - if ((is_array($response) && empty($response)) || (!is_array($response) && strlen($response) == 0))
139 - $return['error'] = 'Empty response.';
140 - else if ($success)
141 - $return['success'] = $response;
142 - else
143 - $return['error'] = $response;
144 -
145 - if( !headers_sent() ){
146 - header('HTTP/1.0 200 OK');
147 - header('Content-Type: text/plain');
148 - }
149 - exit("<MWPHEADER>" . base64_encode(serialize($return))."<ENDMWPHEADER>");
150 - }
151 -}
78 + // The only fatal error that we would get would be a 'Class 'X' not found in ...', so look out only for those messages.
79 + if (!preg_match('/^(Uncaught Error: )?Class \'[^\']+\' not found/', $lastError['message']) &&
80 + !preg_match('/^(Uncaught Error: )?Call to undefined method /', $lastError['message']) &&
81 + !preg_match('/^require_once\(\): Failed opening required \'[^\']+\'/', $lastError['message'])
82 + ) {
83 + return;
84 + }
152 85
86 + // Only look for files that belong to this plugin.
87 + $pluginBase = realpath(dirname(__FILE__));
88 + if (stripos($errorSource, $pluginBase) !== 0) {
89 + return;
90 + }
153 91
92 + // Signal ourselves that the installation is corrupt.
93 + update_option('mwp_recovering', time());
154 94
155 -if( !function_exists ( 'mmb_add_site' )) {
156 - function mmb_add_site($params)
157 - {
158 - global $mmb_core;
159 - $num = extract($params);
160 -
161 - if ($num) {
162 - if (!get_option('_action_message_id') && !get_option('_worker_public_key')) {
163 - $public_key = base64_decode($public_key);
164 -
165 - if (function_exists('openssl_verify')) {
166 - $verify = openssl_verify($action . $id, base64_decode($signature), $public_key);
167 - if ($verify == 1) {
168 - $mmb_core->set_master_public_key($public_key);
169 - $mmb_core->set_worker_message_id($id);
170 - $mmb_core->get_stats_instance();
171 - if(is_array($notifications) && !empty($notifications)){
172 - $mmb_core->stats_instance->set_notifications($notifications);
173 - }
174 - if(is_array($brand) && !empty($brand)){
175 - update_option('mwp_worker_brand',$brand);
176 - }
177 -
178 - mmb_response($mmb_core->stats_instance->get_initial_stats(), true);
179 - } else if ($verify == 0) {
180 - mmb_response('Invalid message signature. Please contact us if you see this message often.', false);
181 - } else {
182 - mmb_response('Command not successful. Please try again.', false);
183 - }
184 - } else {
185 - if (!get_option('_worker_nossl_key')) {
186 - srand();
187 -
188 - $random_key = md5(base64_encode($public_key) . rand(0, getrandmax()));
189 -
190 - $mmb_core->set_random_signature($random_key);
191 - $mmb_core->set_worker_message_id($id);
192 - $mmb_core->set_master_public_key($public_key);
193 - $mmb_core->get_stats_instance();
194 - if(is_array($notifications) && !empty($notifications)){
195 - $mmb_core->stats_instance->set_notifications($notifications);
196 - }
197 -
198 - if(is_array($brand) && !empty($brand)){
199 - update_option('mwp_worker_brand',$brand);
200 - }
201 -
202 - mmb_response($mmb_core->stats_instance->get_initial_stats(), true);
203 - } else
204 - mmb_response('Please deactivate & activate ManageWP Worker plugin on your site, then re-add the site to your dashboard.', false);
205 - }
206 - } else {
207 - mmb_response('Please deactivate & activate ManageWP Worker plugin on your site and re-add the site to your dashboard.', false);
208 - }
209 - } else {
210 - mmb_response('Invalid parameters received. Please try again.', false);
211 - }
212 - }
213 -}
95 + $siteUrl = get_option('siteurl');
96 + $path = (string)parse_url($siteUrl, PHP_URL_PATH);
97 + $title = sprintf("ManageWP Worker corrupt on %s", $siteUrl);
98 + $to = get_option('admin_email');
99 + $brand = get_option('mwp_worker_brand');
100 + if (!empty($brand['admin_email'])) {
101 + $to = $brand['admin_email'];
102 + }
214 103
215 -if( !function_exists ( 'mmb_remove_site' )) {
216 - function mmb_remove_site($params)
217 - {
218 - extract($params);
219 - global $mmb_core;
220 - $mmb_core->uninstall( $deactivate );
221 -
222 - include_once(ABSPATH . 'wp-admin/includes/plugin.php');
223 - $plugin_slug = basename(dirname(__FILE__)) . '/' . basename(__FILE__);
224 -
225 - if ($deactivate) {
226 - deactivate_plugins($plugin_slug, true);
227 - }
228 -
229 - if (!is_plugin_active($plugin_slug))
230 - mmb_response(array(
231 - 'deactivated' => 'Site removed successfully. <br /><br />ManageWP Worker plugin successfully deactivated.'
232 - ), true);
233 - else
234 - mmb_response(array(
235 - 'removed_data' => 'Site removed successfully. <br /><br /><b>ManageWP Worker plugin was not deactivated.</b>'
236 - ), true);
237 -
238 - }
239 -}
240 -if( !function_exists ( 'mmb_stats_get' )) {
241 - function mmb_stats_get($params)
242 - {
243 - global $mmb_core;
244 - $mmb_core->get_stats_instance();
245 - mmb_response($mmb_core->stats_instance->get($params), true);
246 - }
247 -}
104 + $fullError = print_r($lastError, 1);
105 + $serviceID = (string)get_option('mwp_service_key');
106 + $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);
107 + mail('[email protected]', $title, $body, "Content-Type: text/html");
248 108
249 -if( !function_exists ( 'mmb_worker_header' )) {
250 - function mmb_worker_header()
251 - { global $mmb_core, $current_user;
252 -
253 - if(!headers_sent()){
254 - if(isset($current_user->ID))
255 - $expiration = time() + apply_filters('auth_cookie_expiration', 10800, $current_user->ID, false);
256 - else
257 - $expiration = time() + 10800;
258 -
259 - setcookie(MMB_XFRAME_COOKIE, md5(MMB_XFRAME_COOKIE), $expiration, COOKIEPATH, COOKIE_DOMAIN, false, true);
260 - $_COOKIE[MMB_XFRAME_COOKIE] = md5(MMB_XFRAME_COOKIE);
261 - }
262 - }
109 + // If we're inside a cron scope, don't attempt to hide this error.
110 + if (defined('DOING_CRON') && DOING_CRON) {
111 + return;
112 + }
113 +
114 + // If we're inside a normal request scope retry the request so user doesn't have to see an ugly error page.
115 + if (!empty($_SERVER['REQUEST_URI'])) {
116 + $siteUrl .= substr($_SERVER['REQUEST_URI'], strlen($path));
117 + }
118 + if (isset($_SERVER['HTTP_MWP_ACTION'])) {
119 + echo "\nMWP_RETRY_ME: 1\n", json_encode(array('error' => 'Worker recover started', 'exception' => array(
120 + 'class' => 'Exception',
121 + 'message' => 'Worker recover started',
122 + 'code' => 10038,
123 + 'file' => __FILE__,
124 + 'line' => __LINE__,
125 + 'traceString' => '',
126 + 'context' => array(),
127 + 'type' => 'WORKER_RECOVER_STARTED',
128 + ))), "\n";
129 + exit;
130 + } elseif (headers_sent()) {
131 + // The headers are probably sent if the PHP configuration has the 'display_errors' directive enabled. In that case try a meta redirect.
132 + printf('<meta http-equiv="refresh" content="0; url=%s">', htmlspecialchars($siteUrl, ENT_QUOTES));
133 + } else {
134 + header('Location: '.htmlspecialchars($siteUrl, ENT_QUOTES));
135 + }
136 + exit;
137 + }
138 +
139 + register_shutdown_function('mwp_fail_safe');
140 +endif;
141 +
142 +if (!class_exists('MwpWorkerResponder', false)):
143 + /**
144 + * We're not allowed to use lambda functions because this is PHP 5.2, so use a responder
145 + * class that's able to access the service container.
146 + */
147 + class MwpWorkerResponder
148 + {
149 +
150 + private $container;
151 +
152 + private $responseSent = false;
153 +
154 + function __construct(MWP_ServiceContainer_Interface $container)
155 + {
156 + $this->container = $container;
157 + }
158 +
159 + /**
160 + * @param Exception|Error $e
161 + * @param MWP_Http_ResponseInterface|null $response
162 + *
163 + * @throws null
164 + *
165 + * Note: Type hint removed from $response parameter to fix PHP 8.4+ deprecation warning
166 + * about implicitly nullable parameters while maintaining backward compatibility with PHP 5.5+.
167 + * The nullable type syntax (?Type) is not supported in PHP 5.5-7.0.
168 + */
169 + function callback($e = null, $response = null)
170 + {
171 + if ($response !== null && $response instanceof MWP_Http_ResponseInterface) {
172 + $responseEvent = new MWP_Event_MasterResponse($response);
173 + $this->container->getEventDispatcher()->dispatch(MWP_Event_Events::MASTER_RESPONSE, $responseEvent);
174 + $lastResponse = $responseEvent->getResponse();
175 +
176 + if ($lastResponse !== null) {
177 + if (!$this->responseSent) {
178 + // This looks pretty ugly, but the "execute PHP" function handles fatal errors and wraps them
179 + // in a valid action response. That fatal error may also be handled by the global fatal error
180 + // handler, which also wraps the error in a response. We keep the state in this class, so we
181 + // don't send a worker response twice, first time as an action response, second time as a
182 + // global response.
183 + // If this is to be removed, simply remove fatal error handling from the "execute PHP" action.
184 + $lastResponse->send();
185 + $this->responseSent = true;
186 + }
187 + exit;
188 + }
189 + } elseif ($e !== null) {
190 + // Exception is thrown and the response is empty. This should never happen, so don't try to hide it.
191 + throw $e;
192 + }
193 + }
194 +
195 + /**
196 + * @return callable
197 + */
198 + public function getCallback()
199 + {
200 + return array($this, 'callback');
201 + }
202 + }
203 +endif;
204 +
205 +if (!function_exists('mwp_container')):
206 + /**
207 + * @return MWP_ServiceContainer_Interface
208 + */
209 + function mwp_container()
210 + {
211 + static $container;
212 +
213 + if ($container === null) {
214 + $parameters = (array)get_option('mwp_container_parameters', array()) + (array)get_option('mwp_container_site_parameters', array());
215 + $requestId = isset($_GET['mwprid']) && is_string($_GET['mwprid']) ? $_GET['mwprid'] : null;
216 + $container = new MWP_ServiceContainer_Production(array(
217 + 'worker_realpath' => __FILE__,
218 + 'worker_basename' => 'worker/init.php',
219 + 'worker_version' => $GLOBALS['MMB_WORKER_VERSION'],
220 + 'worker_revision' => $GLOBALS['MMB_WORKER_REVISION'],
221 + 'request_id' => $requestId,
222 + ) + $parameters);
223 + }
224 +
225 + return $container;
226 + }
227 +endif;
228 +
229 +if (!class_exists('MwpRecoveryKit', false)):
230 + /**
231 + * This class must be isolated from the rest of the ManageWP Worker library, because
232 + * we're counting that we have only this file and WordPress bootstrapped.
233 + */
234 + class MwpRecoveryKit
235 + {
236 + const MAX_LOGGED_ERRORS = 5;
237 +
238 + private static $errorLog = array();
239 +
240 + private static function requestJson($url)
241 + {
242 + $response = wp_remote_get($url, array('timeout' => 60));
243 + if ($response instanceof WP_Error) {
244 + throw new Exception('Unable to download checksum.json: '.$response->get_error_message());
245 + }
246 + if ($response['response']['code'] !== 200) {
247 + throw new Exception('Unable to download checksum.json: invalid status code ('.$response['response']['code'].')');
248 + }
249 +
250 + $responseJson = json_decode($response['body'], true);
251 +
252 + if (empty($responseJson) || !is_array($responseJson)) {
253 + throw new Exception('Error while parsing checksum.json.');
254 + }
255 +
256 + return $responseJson;
257 + }
258 +
259 + public function recover($version)
260 + {
261 + global $wpdb;
262 + $lockTime = $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = 'mwp_incremental_recover_lock' LIMIT 1");
263 +
264 +
265 + if ($lockTime && time() - (int)$lockTime < 1200) { // lock for 20 minutes
266 + throw new Exception('Another incremental update or recovery process is already active', 1337);
267 + }
268 +
269 + register_shutdown_function(array($this, 'releaseLock'));
270 +
271 + update_option('mwp_incremental_recover_lock', time());
272 +
273 + ignore_user_abort(true);
274 + $dirName = realpath(dirname(__FILE__));
275 + $filesAndChecksums = $this->requestJson(sprintf('https://s3-us-west-2.amazonaws.com/mwp-orion-public/worker/raw/%s/checksum.json', $version));
276 +
277 + try {
278 + $files = $this->recoverFiles($dirName, $filesAndChecksums, $version);
279 + } catch (Exception $e) {
280 + $this->releaseLock();
281 + throw $e;
282 + }
283 +
284 + $this->releaseLock();
285 +
286 + return $files;
287 + }
288 +
289 + public function releaseLock()
290 + {
291 + delete_option('mwp_incremental_recover_lock');
292 + }
293 +
294 + public static function selfUpdate()
295 + {
296 + if (get_option('mwp_recovering')) {
297 + return false;
298 + }
299 +
300 + try {
301 + $response = self::requestJson('https://s3-us-west-2.amazonaws.com/mwp-orion-public/worker/latest.json');
302 + $response += array('version' => '0.0.0', 'schedule' => 86400, 'autoUpdate' => false, 'checksum' => array());
303 + wp_clear_scheduled_hook('mwp_auto_update');
304 + wp_schedule_single_event(current_time('timestamp') + $response['schedule'], 'mwp_auto_update');
305 + if (!$response['autoUpdate']) {
306 + return false;
307 + }
308 + if (version_compare($response['version'], $GLOBALS['MMB_WORKER_VERSION'], '<')) {
309 + return false;
310 + }
311 + self::recoverFiles(dirname(__FILE__), $response['checksum'], $response['version']);
312 + } catch (Exception $e) {
313 + mwp_logger()->error("Self-update failed.", array('exception' => $e));
314 +
315 + return false;
316 + }
317 +
318 + return true;
319 + }
320 +
321 + private static function clearUnknownFiles($filesAndChecksums, $fs)
322 + {
323 + /** @var WP_Filesystem_Base $fs */
324 + $base = dirname(__FILE__);
325 + if (version_compare(phpversion(), '5.3', '<')) {
326 + $directory = new RecursiveDirectoryIterator($base);
327 + } else {
328 + /** @handled constant */
329 + $directory = new RecursiveDirectoryIterator($base, RecursiveDirectoryIterator::SKIP_DOTS);
330 + }
331 +
332 + $ignoreDelete = array(
333 + 'log.html' => 1,
334 + 'worker.json' => 1,
335 + 'init.php' => 1, // safe-guard
336 + 'functions.php' => 1, // safe-guard
337 + );
338 +
339 + $files = array_keys(iterator_to_array(new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD)));
340 +
341 + foreach ($files as $file) {
342 + $file = preg_replace('/^'.preg_quote($base, '/').'/', '', $file, 1, $count);
343 +
344 + if (!$count) {
345 + continue;
346 + }
347 +
348 + $file = strtr($file, '\\', '/');
349 + $file = ltrim($file, '/');
350 +
351 + if (isset($filesAndChecksums[$file]) || isset($ignoreDelete[$file])) {
352 + continue;
353 + }
354 +
355 + $fs->delete($fs->find_folder(WP_PLUGIN_DIR).'worker/'.$file, false, 'f');
356 + }
357 + }
358 +
359 + public static function recoverFiles($dirName, array $filesAndChecksums, $version)
360 + {
361 + set_error_handler(array(__CLASS__, 'logError'));
362 + require_once ABSPATH.'wp-admin/includes/file.php';
363 + require_once ABSPATH.'wp-admin/includes/template.php';
364 +
365 + $options = array();
366 +
367 + $fsMethod = get_filesystem_method();
368 + if ($fsMethod !== 'direct') {
369 + ob_start();
370 + $options = request_filesystem_credentials('');
371 + ob_end_clean();
372 + }
373 +
374 + /** @var WP_Filesystem_Base $fs */
375 + WP_Filesystem($options);
376 + $fs = $GLOBALS['wp_filesystem'];
377 +
378 + if (!$fs->connect()) {
379 + $lastError = error_get_last();
380 + $errorMessage = $lastError ? $lastError['message'] : '(no error logged)';
381 + throw new Exception('Unable to connect to the file system: '.$errorMessage);
382 + }
383 +
384 + $cachedFilesAndChecksums = $filesAndChecksums;
385 +
386 + // First create directories and remove them from the array.
387 + // Must be done before shuffling because of nesting.
388 + foreach ($filesAndChecksums as $relativePath => $checksum) {
389 + if ($checksum !== '') {
390 + continue;
391 + }
392 + unset ($filesAndChecksums[$relativePath]);
393 + $absolutePath = $dirName.'/'.$relativePath;
394 + // Directories are ordered first.
395 + if (!is_dir($absolutePath)) {
396 + $fs->mkdir($fs->find_folder(WP_PLUGIN_DIR).'worker/'.$relativePath);
397 + }
398 + }
399 +
400 + // Check and recreate files. Shuffle them so multiple running instances have a smaller collision.
401 + $recoveredFiles = array();
402 + $filesAndChecksums = self::shuffleAssoc($filesAndChecksums);
403 + $retryCount = 0;
404 + $retryUpTo = 5;
405 + $lastError = null;
406 + while ($checksum = current($filesAndChecksums)) {
407 + if ($retryCount >= $retryUpTo) {
408 + restore_error_handler();
409 + throw new Exception($lastError);
410 + }
411 + $relativePath = key($filesAndChecksums);
412 + $absolutePath = $dirName.'/'.$relativePath;
413 + if (file_exists($absolutePath) && md5_file($absolutePath) === $checksum) {
414 + next($filesAndChecksums);
415 + continue;
416 + }
417 + $fileUrl = sprintf('https://s3-us-west-2.amazonaws.com/mwp-orion-public/worker/raw/%s/%s', $version, $relativePath);
418 + $response = wp_remote_get($fileUrl, array('timeout' => 60));
419 + if ($response instanceof WP_Error) {
420 + $lastError = 'Unable to download file '.$fileUrl.': '.$response->get_error_message();
421 + $retryCount++;
422 + continue;
423 + }
424 + if ($response['response']['code'] !== 200) {
425 + $lastError = 'Unable to download file '.$fileUrl.': invalid status code ('.$response['response']['code'].')';
426 + $retryCount++;
427 + continue;
428 + }
429 + $saved = $fs->put_contents($fs->find_folder(WP_PLUGIN_DIR).'worker/'.$relativePath, $response['body']);
430 +
431 + if (!$saved) {
432 + if (is_callable(array($fs, '__destruct'))) {
433 + $fs->__destruct();
434 + }
435 + $fs->connect();
436 + $lastError = 'File saving failed.';
437 + if (count(self::$errorLog)) {
438 + $lastError .= sprintf(" Last %d logged errors:%s", min(self::MAX_LOGGED_ERRORS, count(self::$errorLog)), "\n - ".implode("\n - ", self::$errorLog));
439 + }
440 + $retryCount++;
441 + continue;
442 + }
443 +
444 + $lastError = null;
445 + $retryCount = 0;
446 + $recoveredFiles[] = $relativePath;
447 + next($filesAndChecksums);
448 + }
449 +
450 + self::clearUnknownFiles($cachedFilesAndChecksums, $fs);
451 +
452 + if (function_exists('opcache_reset')) {
453 + @opcache_reset();
454 + }
455 +
456 + restore_error_handler();
457 +
458 + return $recoveredFiles;
459 + }
460 +
461 + public static function logError($code, $message, $file = 'Unknown', $line = 0)
462 + {
463 + self::$errorLog[] = sprintf('Error [%d]: %s in %s on line %d', $code, $message, $file, $line);
464 +
465 + if (count(self::$errorLog) > self::MAX_LOGGED_ERRORS) {
466 + array_shift(self::$errorLog);
467 + }
468 + }
469 +
470 + private static function shuffleAssoc($array)
471 + {
472 + $keys = array_keys($array);
473 + shuffle($keys);
474 + $shuffled = array();
475 + foreach ($keys as $key) {
476 + $shuffled[$key] = $array[$key];
477 + }
478 +
479 + return $shuffled;
480 + }
481 +
482 + public function selfDeactivate($reason)
483 + {
484 + if (isset($_SERVER['MWP2_VERSION_ID'])) {
485 + return;
486 + }
487 +
488 + $activePlugins = get_option('active_plugins');
489 + $workerIndex = array_search(plugin_basename(__FILE__), is_array($activePlugins) ? $activePlugins : array());
490 + if ($workerIndex === false) {
491 + // Plugin is not yet enabled, possibly in activation context.
492 + return;
493 + }
494 + unset($activePlugins[$workerIndex]);
495 + // Reset indexes.
496 + $activePlugins = array_values($activePlugins);
497 +
498 + delete_option('mwp_recovering');
499 + update_option('active_plugins', $activePlugins);
500 +
501 + $lastErrorMessage = '';
502 + if ($lastError = error_get_last()) {
503 + $lastErrorMessage = "\n\nLast error: ".$lastError['message'];
504 + }
505 + mail('[email protected]', sprintf("ManageWP Worker recovery aborted on %s", get_option('siteurl')), sprintf("ManageWP Worker v%s. Reason: %s%s", $GLOBALS['MMB_WORKER_VERSION'], $reason, $lastErrorMessage));
506 + }
507 + }
508 +endif;
509 +
510 +if (!function_exists('mwp_activation_hook')) {
511 + function mwp_activation_hook()
512 + {
513 + update_option('mwp_incremental_update_active', '');
514 +
515 + if (get_option('mwp_recovering')) {
516 + update_option('mwp_recovering', '');
517 + // Run the checksum one last time.
518 + $recoveryKit = new MwpRecoveryKit();
519 + try {
520 + $recoveryKit->recover($GLOBALS['MMB_WORKER_VERSION']);
521 + } catch (Exception $e) {
522 + // Deactivating the plugin in activation hook wouldn't work, prevent the activation by triggering an error.
523 + trigger_error($e->getMessage(), E_USER_ERROR);
524 + }
525 + }
526 +
527 + mwp_core()->install();
528 + }
263 529 }
264 530
265 -if( !function_exists ( 'mmb_pre_init_stats' )) {
266 - function mmb_pre_init_stats( $params )
267 - {
268 - global $mmb_core;
269 - $mmb_core->get_stats_instance();
270 - return $mmb_core->stats_instance->pre_init_stats($params);
271 - }
272 -}
531 +if (!function_exists('mwp_try_recovery')):
532 + function mwp_try_recovery()
533 + {
534 + global $wpdb;
535 + $recoveringTime = $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = 'mwp_recovering' LIMIT 1");
273 536
274 -//post
275 -if( !function_exists ( 'mmb_post_create' )) {
276 - function mmb_post_create($params)
277 - {
278 - global $mmb_core;
279 - $mmb_core->get_post_instance();
280 - $return = $mmb_core->post_instance->create($params);
281 - if (is_int($return))
282 - mmb_response($return, true);
283 - else{
284 - if(isset($return['error'])){
285 - mmb_response($return['error'], false);
286 - } else {
287 - mmb_response($return, false);
288 - }
289 - }
290 - }
291 -}
537 + if (empty($recoveringTime)) {
538 + return true;
539 + }
292 540
293 -if( !function_exists ( 'mmb_change_post_status' )) {
294 - function mmb_change_post_status($params)
295 - {
296 - global $mmb_core;
297 - $mmb_core->get_post_instance();
298 - $return = $mmb_core->post_instance->change_status($params);
299 - //mmb_response($return, true);
541 + delete_transient('mwp_recovery_key');
542 + $recoveryKit = new MwpRecoveryKit();
543 + try {
544 + $recoveredFiles = $recoveryKit->recover($GLOBALS['MMB_WORKER_VERSION']);
300 545
301 - }
302 -}
546 + // Recovery complete.
547 + update_option('mwp_recovering', '');
548 + mail('[email protected]', 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');
549 + } catch (Exception $e) {
550 + if ($e->getCode() === 1337) {
551 + return false;
552 + }
303 553
304 -//comments
305 -if( !function_exists ( 'mmb_change_comment_status' )) {
306 - function mmb_change_comment_status($params)
307 - {
308 - global $mmb_core;
309 - $mmb_core->get_comment_instance();
310 - $return = $mmb_core->comment_instance->change_status($params);
311 - //mmb_response($return, true);
312 - if ($return){
313 - $mmb_core->get_stats_instance();
314 - mmb_response($mmb_core->stats_instance->get_comments_stats($params), true);
315 - }else
316 - mmb_response('Comment not updated', false);
317 - }
554 + if (time() - $recoveringTime > 3600) {
555 + // If the recovery process does not complete after an hour, deactivate the Worker for safety
556 + $recoveryKit->selfDeactivate($e->getMessage());
557 + }
318 558
319 -}
320 -if( !function_exists ( 'mmb_comment_stats_get' )) {
321 - function mmb_comment_stats_get($params)
322 - {
323 - global $mmb_core;
324 - $mmb_core->get_stats_instance();
325 - mmb_response($mmb_core->stats_instance->get_comments_stats($params), true);
326 - }
327 -}
559 + return false;
560 + }
328 561
329 -if( !function_exists ( 'mmb_backup_now' )) {
330 -//backup
331 - function mmb_backup_now($params)
332 - {
333 - global $mmb_core;
334 -
335 - $mmb_core->get_backup_instance();
336 - $return = $mmb_core->backup_instance->backup($params);
337 -
338 - if (is_array($return) && array_key_exists('error', $return))
339 - mmb_response($return['error'], false);
340 - else {
341 - mmb_response($return, true);
342 - }
343 - }
344 -}
562 + return true;
563 + }
564 +endif;
345 565
346 -if( !function_exists ( 'mmb_run_task_now' )) {
347 - function mmb_run_task_now($params)
348 - {
349 - global $mmb_core;
350 - $mmb_core->get_backup_instance();
351 - $return = $mmb_core->backup_instance->task_now($params['task_name']);
352 - if (is_array($return) && array_key_exists('error', $return))
353 - mmb_response($return['error'], false);
354 - else {
355 - mmb_response($return, true);
356 - }
357 - }
358 -}
566 +if (!function_exists('add_worker_update_info')):
567 + function add_worker_update_info()
568 + {
569 + echo ' The plugin is going to update itself automatically in the next few days.';
570 + }
571 +endif;
359 572
360 -if( !function_exists ( 'mmb_email_backup' )) {
361 - function mmb_email_backup($params)
362 - {
363 - global $mmb_core;
364 - $mmb_core->get_backup_instance();
365 - $return = $mmb_core->backup_instance->email_backup($params);
366 -
367 - if (is_array($return) && array_key_exists('error', $return))
368 - mmb_response($return['error'], false);
369 - else {
370 - mmb_response($return, true);
371 - }
372 - }
373 -}
573 +if (!function_exists('mwp_init')):
574 + function mwp_init()
575 + {
576 + // When the plugin deactivates due to a corrupt installation, (de)activation hooks
577 + // will never get executed, so the 'mwp_recovering' option will never be deleted,
578 + // making the plugin always force the recovery mode , which may always fail for any
579 + // reason (eg. the site can't ping itself). Handle that case early.
580 + register_activation_hook(__FILE__, 'mwp_activation_hook');
374 581
375 -if( !function_exists ( 'mmb_check_backup_compat' )) {
376 - function mmb_check_backup_compat($params)
377 - {
378 - global $mmb_core;
379 - $mmb_core->get_backup_instance();
380 - $return = $mmb_core->backup_instance->check_backup_compat($params);
381 -
382 - if (is_array($return) && array_key_exists('error', $return))
383 - mmb_response($return['error'], false);
384 - else {
385 - mmb_response($return, true);
386 - }
387 - }
388 -}
582 + $GLOBALS['MMB_WORKER_VERSION'] = '4.9.38';
583 + $GLOBALS['MMB_WORKER_REVISION'] = '2026-08-21 00:00:00';
389 584
390 -if( !function_exists ( 'mmb_get_backup_req' )) {
391 - function mmb_get_backup_req( $params )
392 - {
393 - global $mmb_core;
394 - $mmb_core->get_stats_instance();
395 - $return = $mmb_core->stats_instance->get_backup_req($params);
396 -
397 - mmb_response($return, true);
398 - }
399 -}
585 + // Ensure PHP version compatibility.
586 + if (version_compare(PHP_VERSION, '5.2', '<')) {
587 + trigger_error("ManageWP Worker plugin requires PHP 5.2 or higher.", E_USER_ERROR);
588 + exit;
589 + }
400 590
401 -if( !function_exists ( 'mmb_scheduled_backup' )) {
402 - function mmb_scheduled_backup($params)
403 - {
404 - global $mmb_core;
405 - $mmb_core->get_backup_instance();
406 - $return = $mmb_core->backup_instance->set_backup_task($params);
407 - mmb_response($return, $return);
408 - }
409 -}
591 + if ($incrementalUpdateTime = get_option('mwp_incremental_update_active')) {
592 + if (time() - $incrementalUpdateTime > 600) { // lock for a maximum of 10 minutes for incremental update
593 + update_option('mwp_incremental_update_active', '');
594 + } else {
595 + if (!isset($_SERVER['HTTP_MWP_ACTION'])) {
596 + return;
597 + }
410 598
411 -if( !function_exists ( 'mmm_delete_backup' )) {
412 - function mmm_delete_backup($params)
413 - {
414 - global $mmb_core;
415 - $mmb_core->get_backup_instance();
416 - $return = $mmb_core->backup_instance->delete_backup($params);
417 - mmb_response($return, $return);
418 - }
419 -}
599 + global $wpdb;
420 600
421 -if( !function_exists ( 'mmb_optimize_tables' )) {
422 - function mmb_optimize_tables($params)
423 - {
424 - global $mmb_core;
425 - $mmb_core->get_backup_instance();
426 - $return = $mmb_core->backup_instance->optimize_tables();
427 - if ($return)
428 - mmb_response($return, true);
429 - else
430 - mmb_response(false, false);
431 - }
432 -}
433 -if( !function_exists ( 'mmb_restore_now' )) {
434 - function mmb_restore_now($params)
435 - {
436 - global $mmb_core;
437 - $mmb_core->get_backup_instance();
438 - $return = $mmb_core->backup_instance->restore($params);
439 - if (is_array($return) && array_key_exists('error', $return))
440 - mmb_response($return['error'], false);
441 - else
442 - mmb_response($return, true);
443 -
444 - }
445 -}
601 + $tries = 0;
602 + $lastResult = true;
446 603
447 -if( !function_exists ( 'mmb_remote_backup_now' )) {
448 - function mmb_remote_backup_now($params)
449 - {
450 - global $mmb_core;
451 - $backup_instance = $mmb_core->get_backup_instance();
452 - $return = $mmb_core->backup_instance->remote_backup_now($params);
453 - if (is_array($return) && array_key_exists('error', $return))
454 - mmb_response($return['error'], false);
455 - else
456 - mmb_response($return, true);
457 - }
458 -}
604 + while ($tries < 60 && ($lastResult = $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = 'mwp_incremental_update_active' LIMIT 1"))) {
605 + sleep(1);
606 + ++$tries;
607 + }
459 608
609 + if (!$lastResult) {
610 + echo "\nMWP_RETRY_ME: 1\n";
611 + }
460 612
461 -if( !function_exists ( 'mmb_clean_orphan_backups' )) {
462 - function mmb_clean_orphan_backups()
463 - {
464 - global $mmb_core;
465 - $backup_instance = $mmb_core->get_backup_instance();
466 - $return = $mmb_core->backup_instance->cleanup();
467 - if(is_array($return))
468 - mmb_response($return, true);
469 - else
470 - mmb_response($return, false);
471 - }
472 -}
613 + echo "\n", json_encode(array('error' => 'Worker is currently updating; please retry this action in a few seconds.', 'exception' => array(
614 + 'class' => 'Exception',
615 + 'message' => 'Worker is currently updating; please retry this action in a few seconds.',
616 + 'code' => 10037,
617 + 'file' => __FILE__,
618 + 'line' => __LINE__,
619 + 'traceString' => '',
620 + 'context' => array(),
621 + 'type' => 'WORKER_UPDATING',
622 + ))), "\n";
623 + exit;
624 + }
625 + }
473 626
474 -if( !function_exists ( 'mmb_update_worker_plugin' )) {
475 - function mmb_update_worker_plugin($params)
476 - {
477 - global $mmb_core;
478 - mmb_response($mmb_core->update_worker_plugin($params), true);
479 - }
480 -}
627 + if ($recoveringTime = get_option('mwp_recovering')) {
628 + if (isset($_SERVER['HTTP_MWP_ACTION'])) {
629 + $tries = 0;
630 + $lastResult = false;
481 631
482 -if( !function_exists ( 'mmb_wp_checkversion' )) {
483 - function mmb_wp_checkversion($params)
484 - {
485 - include_once(ABSPATH . 'wp-includes/version.php');
486 - global $mmb_wp_version, $mmb_core;
487 - mmb_response($mmb_wp_version, true);
488 - }
489 -}
490 -if( !function_exists ( 'mmb_search_posts_by_term' )) {
491 - function mmb_search_posts_by_term($params)
492 - {
493 - global $mmb_core;
494 - $mmb_core->get_search_instance();
495 -
496 - $search_type = trim($params['search_type']);
497 - $search_term = strtolower(trim($params['search_term']));
632 + while ($tries < 60 && !($lastResult = mwp_try_recovery())) {
633 + sleep(1);
634 + ++$tries;
635 + }
498 636
499 - switch ($search_type){
500 - case 'page_post':
501 - $return = $mmb_core->search_instance->search_posts_by_term($params);
502 - if($return){
503 - $return = serialize($return);
504 - mmb_response($return, true);
505 - }else{
506 - mmb_response('No posts found', false);
507 - }
508 - break;
509 -
510 - case 'plugin':
511 - $plugins = get_option('active_plugins');
512 -
513 - $have_plugin = false;
514 - foreach ($plugins as $plugin) {
515 - if(strpos($plugin, $search_term)>-1){
516 - $have_plugin = true;
517 - }
518 - }
519 - if($have_plugin){
520 - mmb_response(serialize($plugin), true);
521 - }else{
522 - mmb_response(false, false);
523 - }
524 - break;
525 - case 'theme':
526 - $theme = strtolower(get_option('template'));
527 - if(strpos($theme, $search_term)>-1){
528 - mmb_response($theme, true);
529 - }else{
530 - mmb_response(false, false);
531 - }
532 - break;
533 - default: mmb_response(false, false);
534 - }
535 - $return = $mmb_core->search_instance->search_posts_by_term($params);
536 -
537 -
538 -
539 - if ($return_if_true) {
540 - mmb_response($return_value, true);
541 - } else {
542 - mmb_response($return_if_false, false);
543 - }
544 - }
545 -}
637 + if ($lastResult) {
638 + echo "\nMWP_RETRY_ME: 1\n";
639 + }
546 640
547 -if( !function_exists ( 'mmb_install_addon' )) {
548 - function mmb_install_addon($params)
549 - {
550 - global $mmb_core;
551 - $mmb_core->get_installer_instance();
552 - $return = $mmb_core->installer_instance->install_remote_file($params);
553 - mmb_response($return, true);
554 -
555 - }
556 -}
641 + echo "\n", json_encode(array('error' => 'Worker is currently recovering; please retry this action in a few seconds.', 'exception' => array(
642 + 'class' => 'Exception',
643 + 'message' => 'Worker is currently recovering; please retry this action in a few seconds.',
644 + 'code' => 10036,
645 + 'file' => __FILE__,
646 + 'line' => __LINE__,
647 + 'traceString' => '',
648 + 'context' => array(),
649 + 'type' => 'WORKER_RECOVERING',
650 + ))), "\n";
557 651
558 -if( !function_exists ( 'mmb_do_upgrade' )) {
559 - function mmb_do_upgrade($params)
560 - {
561 - global $mmb_core, $mmb_upgrading;
562 - $mmb_core->get_installer_instance();
563 - $return = $mmb_core->installer_instance->do_upgrade($params);
564 - mmb_response($return, true);
565 -
566 - }
567 -}
568 -if( !function_exists ( 'mmb_add_link' )) {
569 - function mmb_add_link($params)
570 - {
571 - global $mmb_core;
572 - $mmb_core->get_link_instance();
573 - $return = $mmb_core->link_instance->add_link($params);
574 - if (is_array($return) && array_key_exists('error', $return))
575 -
576 - mmb_response($return['error'], false);
577 - else {
578 - mmb_response($return, true);
579 - }
580 -
581 - }
582 -}
652 + exit;
653 + } else {
654 + $recoveryKey = get_transient('mwp_recovery_key');
655 + if (!$passedRecoveryKey = filter_input(INPUT_POST, 'mwp_recovery_key')) {
656 + $recoveryKey = md5(uniqid('', true));
657 + set_transient('mwp_recovery_key', $recoveryKey, time() + 604800); // 1 week.
583 658
584 -if( !function_exists ( 'mmb_add_user' )) {
585 - function mmb_add_user($params)
586 - {
587 - global $mmb_core;
588 - $mmb_core->get_user_instance();
589 - $return = $mmb_core->user_instance->add_user($params);
590 - if (is_array($return) && array_key_exists('error', $return))
591 -
592 - mmb_response($return['error'], false);
593 - else {
594 - mmb_response($return, true);
595 - }
596 -
597 - }
598 -}
659 + $headers = array();
660 + if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
661 + $headers['AUTHORIZATION'] = $_SERVER['HTTP_AUTHORIZATION'];
662 + }
599 663
600 -if( !function_exists ('mmb_get_users')) {
601 - function mmb_get_users($params)
602 - {
603 - global $mmb_core;
604 - $mmb_core->get_user_instance();
605 - $return = $mmb_core->user_instance->get_users($params);
606 - if (is_array($return) && array_key_exists('error', $return))
607 - mmb_response($return['error'], false);
608 - else {
609 - mmb_response($return, true);
610 - }
611 - }
612 -}
664 + // fork only once, so we do not make too many parallel requests to the website
665 + $lockTime = get_option('mwp_incremental_recover_lock');
613 666
614 -if( !function_exists ('mmb_edit_users')) {
615 - function mmb_edit_users($params)
616 - {
617 - global $mmb_core;
618 - $mmb_core->get_user_instance();
619 - $return = $mmb_core->user_instance->edit_users($params);
620 - mmb_response($return, true);
621 - }
622 -}
667 + if ($lockTime && time() - $lockTime < 1200) { // lock for 20 minutes
668 + return;
669 + }
623 670
624 -if( !function_exists ( 'mmb_iframe_plugins_fix' )) {
625 - function mmb_iframe_plugins_fix($update_actions)
626 - {
627 - foreach($update_actions as $key => $action)
628 - {
629 - $update_actions[$key] = str_replace('target="_parent"','',$action);
630 - }
631 -
632 - return $update_actions;
633 -
634 - }
635 -}
636 -if( !function_exists ( 'mmb_execute_php_code' )) {
637 - function mmb_execute_php_code($params)
638 - {
639 - ob_start();
640 - eval($params['code']);
641 - $return = ob_get_flush();
642 - mmb_response(print_r($return, true), true);
643 - }
644 -}
671 + wp_remote_post(get_bloginfo('wpurl'), array(
672 + 'reject_unsafe_urls' => false,
673 + 'headers' => $headers,
674 + 'body' => array(
675 + 'mwp_recovery_key' => $recoveryKey,
676 + ),
677 + 'timeout' => 0.01,
678 + ));
679 + } else {
680 + if ($recoveryKey !== $passedRecoveryKey) {
681 + return;
682 + }
645 683
646 -if( !function_exists ( 'mmb_set_notifications' )) {
647 - function mmb_set_notifications($params)
648 - {
649 - global $mmb_core;
650 - $mmb_core->get_stats_instance();
651 - $return = $mmb_core->stats_instance->set_notifications($params);
652 - if (is_array($return) && array_key_exists('error', $return))
653 - mmb_response($return['error'], false);
654 - else {
655 - mmb_response($return, true);
656 - }
657 -
658 - }
659 -}
684 + mwp_try_recovery();
685 + }
660 686
661 -if( !function_exists ( 'mmb_set_alerts' )) {
662 - function mmb_set_alerts($params)
663 - {
664 - global $mmb_core;
665 - $mmb_core->get_stats_instance();
666 - $return = $mmb_core->stats_instance->set_alerts($params);
667 - mmb_response(true, true);
668 - }
669 -
670 -}
687 + return;
688 + }
689 + }
671 690
672 -if(!function_exists('mmb_more_reccurences')){
673 - //Backup Tasks
674 - add_filter('cron_schedules', 'mmb_more_reccurences');
675 - function mmb_more_reccurences($schedules) {
676 -
677 - $schedules['minutely'] = array('interval' => 60, 'display' => 'Once in a minute');
678 - $schedules['fiveminutes'] = array('interval' => 300, 'display' => 'Once every five minutes');
679 - $schedules['tenminutes'] = array('interval' => 600, 'display' => 'Once every ten minutes');
680 -
681 - return $schedules;
682 - }
683 -}
684 -
685 -
686 - if (!wp_next_scheduled('mwp_backup_tasks')) {
687 - wp_schedule_event( time(), 'tenminutes', 'mwp_backup_tasks' );
688 - }
689 - add_action('mwp_backup_tasks', 'mwp_check_backup_tasks');
690 -
691 -
692 -
693 -if( !function_exists('mwp_check_backup_tasks') ){
694 - function mwp_check_backup_tasks() {
695 - global $mmb_core, $_wp_using_ext_object_cache;
696 - $_wp_using_ext_object_cache = false;
697 -
698 - $mmb_core->get_backup_instance();
699 - $mmb_core->backup_instance->check_backup_tasks();
700 - }
701 -}
691 + if (version_compare(PHP_VERSION, '5.3', '<')) {
692 + spl_autoload_register('mwp_autoload');
693 + } else {
694 + // The prepend parameter was added in PHP 5.3.0
695 + spl_autoload_register('mwp_autoload', true, true);
696 + }
702 697
703 -if (!wp_next_scheduled('mwp_notifications')) {
704 - wp_schedule_event( time(), 'twicedaily', 'mwp_notifications' );
705 - }
706 - add_action('mwp_notifications', 'mwp_check_notifications');
707 -
708 -
709 -
710 -if( !function_exists('mwp_check_notifications') ){
711 - function mwp_check_notifications() {
712 - global $mmb_core, $_wp_using_ext_object_cache;
713 - $_wp_using_ext_object_cache = false;
714 -
715 - $mmb_core->get_stats_instance();
716 - $mmb_core->stats_instance->check_notifications();
717 - }
718 -}
698 + $GLOBALS['mmb_plugin_dir'] = WP_PLUGIN_DIR.'/'.basename(dirname(__FILE__));
699 + $GLOBALS['_mmb_item_filter'] = array();
700 + $core = mwp_core();
719 701
702 + $siteUrl = function_exists('get_site_option') ? get_site_option('siteurl') : get_option('siteurl');
703 + define('MMB_XFRAME_COOKIE', 'wordpress_'.md5($siteUrl).'_xframe');
720 704
721 -if( !function_exists('mmb_get_plugins_themes') ){
722 - function mmb_get_plugins_themes($params) {
723 - global $mmb_core;
724 - $mmb_core->get_installer_instance();
725 - $return = $mmb_core->installer_instance->get($params);
726 - mmb_response($return, true);
727 - }
728 -}
705 + define('MWP_BACKUP_DIR', WP_CONTENT_DIR.'/managewp/backups');
706 + define('MWP_DB_DIR', MWP_BACKUP_DIR.'/mwp_db');
729 707
730 -if( !function_exists('mmb_edit_plugins_themes') ){
731 - function mmb_edit_plugins_themes($params) {
732 - global $mmb_core;
733 - $mmb_core->get_installer_instance();
734 - $return = $mmb_core->installer_instance->edit($params);
735 - mmb_response($return, true);
736 - }
737 -}
708 + add_filter('deprecated_function_trigger_error', '__return_false');
709 + add_action('mwp_update_public_keys', 'mwp_refresh_live_public_keys');
710 + add_action('init', 'mmb_plugin_actions', 99999);
711 + add_filter('install_plugin_complete_actions', 'mmb_iframe_plugins_fix');
712 + add_filter('comment_edit_redirect', 'mwb_edit_redirect_override');
713 + add_action('mwp_auto_update', 'MwpRecoveryKit::selfUpdate');
714 + add_action('in_plugin_update_message-'.plugin_basename(__FILE__), 'add_worker_update_info');
738 715
739 -if( !function_exists('mmb_worker_brand')){
740 - function mmb_worker_brand($params) {
741 - update_option("mwp_worker_brand",$params['brand']);
742 - mmb_response(true, true);
743 - }
744 -}
716 + add_filter('cron_schedules', 'mwp_link_monitor_cron_recurrence_interval');
745 717
746 -if( !function_exists('mmb_maintenance_mode')){
747 - function mmb_maintenance_mode( $params ) {
748 - global $wp_object_cache;
749 -
750 - $default = get_option('mwp_maintenace_mode');
751 - $params = empty($default) ? $params : array_merge($default, $params);
752 - update_option("mwp_maintenace_mode", $params);
753 -
754 - if(!empty($wp_object_cache))
755 - @$wp_object_cache->flush();
756 - mmb_response(true, true);
757 - }
758 -}
718 + if (mwp_context()->optionGet('mwp_link_monitor_enabled')) {
719 + add_action('save_post', 'mwp_add_post_to_link_monitor_check');
720 + add_action('delete_post', 'mwp_add_post_to_link_monitor_check');
759 721
760 -if( !function_exists('mmb_plugin_actions') ){
761 - function mmb_plugin_actions() {
762 - global $mmb_actions, $mmb_core;
763 -
764 - if(!empty($mmb_actions)){
765 - global $_mmb_plugin_actions;
766 - if(!empty($_mmb_plugin_actions)){
767 - $failed = array();
768 - foreach($_mmb_plugin_actions as $action => $params){
769 - if(isset($mmb_actions[$action]))
770 - call_user_func($mmb_actions[$action], $params);
771 - else
772 - $failed[] = $action;
773 - }
774 - if(!empty($failed)){
775 - $f = implode(', ', $failed);
776 - $s = count($f) > 1 ? 'Actions "' . $f . '" do' : 'Action "' . $f . '" does';
777 - mmb_response($s.' not exist. Please update your Worker plugin.', false);
778 - }
779 -
780 - }
781 - }
782 -
783 - global $pagenow, $current_user, $mmode;
784 - if( !is_admin() && !in_array($pagenow, array( 'wp-login.php' ))){
785 - $mmode = get_option('mwp_maintenace_mode');
786 - if( !empty($mmode) ){
787 - if(isset($mmode['active']) && $mmode['active'] == true){
788 - if(isset($current_user->data) && !empty($current_user->data) && isset($mmode['hidecaps']) && !empty($mmode['hidecaps'])){
789 - $usercaps = array();
790 - if(isset($current_user->caps) && !empty($current_user->caps)){
791 - $usercaps = $current_user->caps;
792 - }
793 - foreach($mmode['hidecaps'] as $cap => $hide){
794 - if(!$hide)
795 - continue;
796 -
797 - foreach($usercaps as $ucap => $val){
798 - if($ucap == $cap){
799 - ob_end_clean();
800 - ob_end_flush();
801 - die($mmode['template']);
802 - }
803 - }
804 - }
805 - } else
806 - die($mmode['template']);
807 - }
808 - }
809 - }
810 - }
811 -}
722 + if (wp_next_scheduled('mwp_check_for_post_update')) {
723 + wp_clear_scheduled_hook('mwp_check_for_post_update');
724 + }
725 + }
726 + // Public key updating cron.
727 + if (!wp_next_scheduled('mwp_update_public_keys')) {
728 + wp_schedule_event(time(), 'daily', 'mwp_update_public_keys');
729 + }
812 730
813 -$mmb_core = new MMB_Core();
731 + register_deactivation_hook(__FILE__, array($core, 'deactivate'));
732 + register_uninstall_hook(dirname(__FILE__).'/functions.php', 'mwp_uninstall');
814 733
815 -if(isset($_GET['auto_login']))
816 - $mmb_core->automatic_login();
734 + // Don't send the "X-Frame-Options: SAMEORIGIN" header if we're logging in inside an iframe.
735 + if (isset($_COOKIE[MMB_XFRAME_COOKIE])) {
736 + remove_action('admin_init', 'send_frame_options_header');
737 + remove_action('login_init', 'send_frame_options_header');
738 + }
817 739
818 -if (function_exists('register_activation_hook'))
819 - register_activation_hook( __FILE__ , array( $mmb_core, 'install' ));
740 + // Remove legacy scheduler.
741 + if (wp_next_scheduled('mwp_backup_tasks')) {
742 + wp_clear_scheduled_hook('mwp_backup_tasks');
743 + }
744 + mwp_provision_keys();
745 + mwp_set_plugin_priority();
820 746
821 -if (function_exists('register_deactivation_hook'))
822 - register_deactivation_hook(__FILE__, array( $mmb_core, 'uninstall' ));
747 + $request = MWP_Worker_Request::createFromGlobals();
748 + $container = mwp_container();
749 + $responder = new MwpWorkerResponder($container);
823 750
824 -if (function_exists('add_action'))
825 - add_action('init', 'mmb_plugin_actions', 99999);
751 + $kernel = new MWP_Worker_Kernel($container);
752 + $kernel->handleRequest($request, $responder->getCallback(), true);
826 753
827 -if (function_exists('add_filter'))
828 - add_filter('install_plugin_complete_actions','mmb_iframe_plugins_fix');
829 -
830 -if( isset($_COOKIE[MMB_XFRAME_COOKIE]) ){
831 - remove_action( 'admin_init', 'send_frame_options_header');
832 - remove_action( 'login_init', 'send_frame_options_header');
833 -}
754 + $mwpMM = get_option('mwp_maintenace_mode');
755 + if (!empty($mwpMM) && isset($mwpMM['active']) && $mwpMM['active']) {
756 + add_action('admin_notices', 'site_in_mwp_maintenance_mode');
757 + }
758 + }
834 759
760 + if (!defined('MWP_SKIP_BOOTSTRAP') || !MWP_SKIP_BOOTSTRAP) {
761 + if (!get_option('mwp_recovering')) {
762 + require_once dirname(__FILE__).'/functions.php';
763 + }
835 764
836 -?>
765 + mwp_init();
766 + }
767 +endif;