panel_endpoint = 'https://c499-49-144-230-251.ngrok-free.app/api/log-activity'; $this->api_key = '5a7bbf28-d305-4cd3-87fe-7cdca9ff97f3'; // Hook into WordPress actions for logging activities add_action('pre_set_site_transient_update_plugins', [$this, 'capture_old_versions']); add_action('upgrader_process_complete', [$this, 'log_update_activity'], 10, 2); add_action('activated_plugin', [$this, 'log_activation_activity'], 10, 2); add_action('deactivated_plugin', [$this, 'log_deactivation_activity'], 10, 2); add_action('deleted_plugin', [$this, 'log_delete_activity'], 10, 1); add_action('switch_theme', [$this, 'log_theme_switch_activity'], 10, 2); } public function capture_old_versions($transient) { // Store the current versions of the plugins before the update if (!empty($transient->response)) { foreach ($transient->response as $plugin_file => $plugin_info) { $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin_file); $this->old_versions[$plugin_file] = $plugin_data['Version']; } } return $transient; } private function send_logs_to_panel($activity_type, $activity_data) { $activity_data['site_url'] = get_site_url(); // Add site URL to distinguish the source WordPress site $activity_data['site_name'] = get_bloginfo('name'); // Add site name for additional identification // Add current user information $current_user = wp_get_current_user(); $activity_data['user_info'] = [ 'email' => $current_user->user_email ?? 'Unknown', 'role' => !empty($current_user->roles) ? implode(', ', $current_user->roles) : 'Unknown', ]; $response = wp_remote_post($this->panel_endpoint, [ 'body' => json_encode([ 'type' => $activity_type, 'data' => $activity_data, 'site_id' => get_option('your_site_id'), ], JSON_UNESCAPED_SLASHES), 'headers' => [ 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $this->api_key, ], ]); if (is_wp_error($response)) { error_log('Failed to log activity to the panel. Error: ' . $response->get_error_message() . ', Data: ' . json_encode($activity_data)); } else { error_log('Successfully sent data to the panel: ' . print_r($response, true)); } } private function get_current_wordpress_version() { return get_bloginfo('version'); } public function log_update_activity($upgrader_object, $options) { // Collect activity data $activity_data = [ 'action' => $options['action'] ?? 'unknown', 'type' => $options['type'] ?? 'unknown', 'items' => [], // Initialize empty to gather all updated items 'site_url' => get_site_url(), 'site_name' => get_bloginfo('name'), 'time' => current_time('mysql'), ]; // Add all relevant items that were updated or installed if ($options['action'] === 'install' && $options['type'] === 'plugin') { // Plugin installation foreach ($upgrader_object->result['destination_name'] as $plugin) { $new_version = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin)['Version']; $activity_data['items'][] = [ 'plugin' => $plugin, 'new_version' => $new_version, ]; } } elseif ($options['action'] === 'update') { // Updates for plugins, themes, or core if (!empty($options['plugins'])) { foreach ($options['plugins'] as $plugin) { $new_version = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin)['Version']; $old_version = $this->old_versions[$plugin] ?? 'unknown'; $activity_data['items'][] = [ 'plugin' => $plugin, 'old_version' => $old_version, 'new_version' => $new_version, ]; } } if (!empty($options['themes'])) { foreach ($options['themes'] as $theme) { $activity_data['items'][] = [ 'theme' => $theme, 'action' => 'theme_update', ]; } } if ($options['type'] === 'core') { $old_version = $this->get_current_wordpress_version(); // Get the version before the update. // Adding a slight delay to fetch the new version more reliably sleep(2); $new_version = get_bloginfo('version'); // Get the version after the update. if ($old_version === $new_version) { $activity_data['items'][] = [ 'core' => 'WordPress Core', 'old_version' => $old_version, 'new_version' => 'No change detected - possible rollback or failed update', ]; } else { $activity_data['items'][] = [ 'core' => 'WordPress Core', 'old_version' => $old_version, 'new_version' => $new_version, ]; } } } // Log the prepared activity data before sending it if (defined('WP_DEBUG') && WP_DEBUG) { $activity_data_dump = print_r($activity_data, true); error_log("Prepared activity data:\n{$activity_data_dump}"); } // Send to the panel $this->send_logs_to_panel('update', $activity_data); } public function log_activation_activity($plugin, $network_wide) { $activity_data = [ 'plugin' => $plugin, 'network_wide' => $network_wide, 'time' => current_time('mysql'), ]; $this->send_logs_to_panel('plugin_activated', $activity_data); } public function log_deactivation_activity($plugin, $network_wide) { $activity_data = [ 'plugin' => $plugin, 'network_wide' => $network_wide, 'time' => current_time('mysql'), ]; $this->send_logs_to_panel('plugin_deactivated', $activity_data); } public function log_delete_activity($plugin) { $activity_data = [ 'plugin' => $plugin, 'time' => current_time('mysql'), ]; $this->send_logs_to_panel('plugin_deleted', $activity_data); } public function log_theme_switch_activity($new_theme, $old_theme) { $activity_data = [ 'new_theme' => $new_theme->get('Name'), 'old_theme' => $old_theme->get('Name'), 'time' => current_time('mysql'), ]; $this->send_logs_to_panel('theme_switched', $activity_data); } } new MU_Activity_Logger(); // Define wp_error_log() to use WordPress logging function wp_error_log($message) { if (defined('WP_CLI') && WP_CLI) { WP_CLI::log($message); } else { error_log($message); } }