File "class-wpb-sdk-logger.php"
Full Path: /home/theinspectionboy/public_html/suffolk/lib-20250622113736/wpb-sdk/includes/class-wpb-sdk-logger.php
File size: 19.78 KB
MIME-type: text/x-php
Charset: utf-8
<?php
class WPBRIGADE_Logger
{
private static $_instances = array();
private static $product_data = array();
private static $_module_id;
private static $current_uninstall_slug = null;
// Constructor for the Logger class
private function __construct($module_id, $slug = false, $is_init = false)
{
if (!$is_init && !is_numeric($module_id) && !is_string($slug)) {
return false;
}
self::$_module_id = $module_id;
self::$current_uninstall_slug = $slug; // Set current uninstall slug
}
// Method to create or retrieve a Logger instance
public static function instance($module_id, $slug = false, $is_init = false)
{
if (empty($module_id)) {
return false;
}
if (!$is_init && true === $slug) {
$is_init = true;
}
if (!isset(self::$_instances[$slug])) {
self::$_instances[$slug] = new WPBRIGADE_Logger($module_id, $slug, $is_init);
}
return self::$_instances[$slug];
}
// Method to initialize the Logger with module data
public function wpb_init(array $module)
{
$key = $module['slug'];
self::$product_data[$key] = [];
self::$product_data[$key]['module'] = $module;
$this->hooks($module['slug']);
}
// Method to attach hooks for scheduled events and AJAX
public function hooks($slug)
{
// Initialize custom schedules
add_action('init', function () use ($slug) {
$this->set_logs_schedule($slug);
});
// Daily log plugin execution
add_action('wpb_data_sync_' . $slug, function () use ($slug) {
$this->daily_log_plugin($slug);
});
// Admin footer hook
add_action('admin_footer', function () use ($slug) {
$this->deactivation_model($slug);
});
// AJAX deactivation action
add_action('wp_ajax_wpb_sdk_' . $slug . '_deactivation', function () use ($slug) {
$this->ajax_deactivation($slug);
});
// Plugin activation hook
register_activation_hook(wpb_get_plugin_path($slug), function () use ($slug) {
$this->log_activation($slug);
});
// Plugin deactivation hook
register_deactivation_hook(wpb_get_plugin_path($slug), function () use ($slug) {
$this->product_deactivation($slug);
});
// Plugin uninstallation hook
register_uninstall_hook(wpb_get_plugin_path($slug), array(__CLASS__, 'log_uninstallation'));
}
// Method to set scheduled events for logging
public function set_logs_schedule($slug)
{
//Clean Old Cron jobs
wp_clear_scheduled_hook('wpb_logger_cron_' . $slug);
wp_clear_scheduled_hook('wpb_daily_sync_cron_' . $slug);
// Calculate future timestamps for scheduling
$daily_start_time = strtotime('+1 day');
// Schedule daily cron event if not already scheduled
if (!wp_next_scheduled('wpb_data_sync_' . $slug)) {
wp_schedule_event($daily_start_time, 'daily', 'wpb_data_sync_' . $slug);
}
}
public static function reset_logs_schedule($slug)
{
// Calculate future timestamps for scheduling
$daily_start_time = strtotime('+1 day');
// Schedule daily cron event if not already scheduled
if (!wp_next_scheduled('wpb_data_sync_' . $slug)) {
wp_schedule_event($daily_start_time, 'daily', 'wpb_data_sync_' . $slug);
}
}
public static function remove_logs_schedule($slug)
{
wp_clear_scheduled_hook('wpb_data_sync_' . $slug);
}
// Method to log plugin activity on daily scheduled events
public function daily_log_plugin($slug)
{
$sdk_data = json_decode(get_option('wpb_sdk_' . $slug), true);
$user_skip = isset($sdk_data['user_skip']) ? $sdk_data['user_skip'] : false;
$user_skip = $user_skip === "1" ? true : false;
if ($user_skip) {
$logs_data = self::get_logs_data($slug, 'user_skip');
$sdk_data['user_skip'] = "0";
$sdk_data_json = json_encode($sdk_data);
update_option('wpb_sdk_' . $slug, $sdk_data_json);
} else {
$logs_data = self::get_logs_data($slug, 'daily');
}
if (!empty($logs_data)) {
$logs_to_send = array_merge(
$logs_data,
array(
'explicit_logs' => array(
'action' => 'daily',
),
)
);
self::send($slug, $logs_to_send);
}
}
// Method to log plugin activation
public function log_activation($slug)
{
$logs_data = self::get_logs_data($slug, 'activate');
if (!empty($logs_data)) {
$logs_to_send = array_merge(
$logs_data,
array(
'explicit_logs' => array(
'action' => 'activate',
),
)
);
self::send($slug, $logs_to_send);
}
}
// Method to add deactivation model HTML to admin footer
public function deactivation_model($slug)
{
if (function_exists('get_current_screen')) {
$screen = get_current_screen();
if ('plugins.php' === $screen->parent_file) {
$plugin_data = wpb_get_plugin_details($slug);
$product_name = $plugin_data['Name'];
$product_slug = $slug;
$has_pro_version = self::$product_data[$slug]['module']['is_premium'] === true;
include dirname(__DIR__) . '/views/wpb-sdk-deactivate-form.php';
}
}
}
// Method to handle AJAX request for plugin deactivation
public function ajax_deactivation($slug)
{
$path = wpb_get_plugin_path($slug);
if (isset($_POST['nonce']) && empty($_POST['nonce'])) {
return;
}
$nonce = sanitize_text_field(wp_unslash($_POST['nonce']));
$verify_nonce = wp_verify_nonce($nonce, 'deactivate-plugin_' . plugin_basename($path));
if (!$verify_nonce) {
return;
}
$this->log_deactivation($slug);
wp_die();
}
// Method to handle plugin deactivation
public function product_deactivation($slug)
{
wp_clear_scheduled_hook('wpb_data_sync_' . $slug);
}
// Method to log plugin deactivation
public function log_deactivation($slug)
{
$reason = isset($_POST['reason']) ? $_POST['reason'] : '';
$reason_detail = isset($_POST['reason_detail']) ? $_POST['reason_detail'] : '';
$logs_data = self::get_logs_data($slug, 'deactivate');
if (!empty($logs_data)) {
$logs_to_send = array_merge(
$logs_data,
array(
'explicit_logs' => array(
'action' => 'deactivate',
'reason' => sanitize_text_field(wp_unslash($reason)),
'reason_detail' => sanitize_text_field(wp_unslash($reason_detail)),
),
)
);
self::send($slug, $logs_to_send);
}
}
// Method to log plugin uninstallation
public static function log_uninstallation()
{
$slug = self::$current_uninstall_slug;
$logs_data = self::get_logs_data($slug, 'uninstall');
if (!empty($logs_data)) {
$logs_to_send = array_merge(
$logs_data,
array(
'explicit_logs' => array(
'action' => 'uninstall',
),
)
);
self::send($slug, $logs_to_send);
}
// Call Plugin uninstall hook
do_action('wp_wpb_sdk_after_uninstall');
}
/**
* Collect all data for logging.
*
* @return array
*/
public static function get_logs_data($slug, $action = '')
{
global $wpdb;
// Get product data
$module = self::$product_data[$slug]['module'];
// Initialize variables
$data = array();
$theme_data = wp_get_theme();
$curl_version = '';
$external_http_blocked = '';
$users_count = '';
$sdk_data = json_decode(get_option('wpb_sdk_' . $slug), true);
$sdk_communication = isset($sdk_data['communication']) ? $sdk_data['communication'] : '0';
$sdk_diagnostic_info = isset($sdk_data['diagnostic_info']) ? $sdk_data['diagnostic_info'] : '0';
$sdk_extensions = isset($sdk_data['extensions']) ? $sdk_data['extensions'] : '0';
$send_wpb_sdk_communication = $sdk_communication === "1" ? true : false;
$send_wpb_sdk_diagnostic_info = $sdk_diagnostic_info === "1" ? true : false;
$send_wpb_sdk_extensions = $sdk_extensions === "1" ? true : false;
if ($action != "user_skip") {
if (!$send_wpb_sdk_communication && !$send_wpb_sdk_diagnostic_info && !$send_wpb_sdk_extensions) {
WPBRIGADE_Logger::remove_logs_schedule($slug);
return [];
} else {
WPBRIGADE_Logger::reset_logs_schedule($slug);
}
}
// Get admin user data
$admin_users = get_users(array('role' => 'Administrator'));
$admin = isset($admin_users[0]) ? $admin_users[0]->data : '';
$admin_meta = !empty($admin) ? get_user_meta($admin->ID) : '';
// Collect data
$data['authentication']['public_key'] = $module['public_key'];
if ($action == "user_skip"||$send_wpb_sdk_communication) {
// USER INFO
$data['user_info'] = array(
'user_email' => !empty($admin) ? sanitize_email($admin->user_email) : '',
'user_nickname' => !empty($admin) ? sanitize_text_field($admin->user_nicename) : '',
'user_firstname' => isset($admin_meta['first_name'][0]) ? sanitize_text_field($admin_meta['first_name'][0]) : '',
'user_lastname' => isset($admin_meta['last_name'][0]) ? sanitize_text_field($admin_meta['last_name'][0]) : '',
);
}
// PRODUCT INFO MUST HAVE
$data['product_info'] = self::get_product_data($slug);
$data['product_info']['sdk_version'] = WP_WPBRIGADE_SDK_VERSION;
if ($action == "user_skip"||$send_wpb_sdk_diagnostic_info) {
$data['product_info']['product_settings'] = self::get_product_settings($slug);
}
// SITE INFO MUST HAVE
$data['site_info'] = array(
'site_url' => site_url(),
'home_url' => home_url(),
);
if ($action == "user_skip"||$send_wpb_sdk_diagnostic_info) {
$ip = self::get_ip();
$location = self::get_location_details($ip);
// Check if get_plugins function exists
if (!function_exists('get_plugins')) {
include ABSPATH . '/wp-admin/includes/plugin.php';
}
// Get users count if function exists
if (function_exists('count_users')) {
$users_count = count_users();
$users_count = isset($users_count['total_users']) ? intval($users_count['total_users']) : '';
}
// Check external http request blocking
if (!defined('WP_HTTP_BLOCK_EXTERNAL') || !WP_HTTP_BLOCK_EXTERNAL) {
$external_http_blocked = 'none';
} else {
$external_http_blocked = defined('WP_ACCESSIBLE_HOSTS') ? 'partially (accessible hosts: ' . esc_html(WP_ACCESSIBLE_HOSTS) . ')' : 'all';
}
// Get curl version if function exists
if (function_exists('curl_init')) {
$curl = curl_version();
$curl_version = '(' . $curl['version'] . ' ' . $curl['ssl_version'] . ')';
}
$data['site_info']['site_meta_info'] = array(
'is_multisite' => is_multisite(),
'multisites' => self::get_multisites(),
'php_version' => phpversion(),
'wp_version' => get_bloginfo('version'),
'server' => isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : '',
'timezoneoffset' => date('P'),
'ext/mysqli' => isset($wpdb->use_mysqli) && !empty($wpdb->use_mysqli) ? true : false,
'mysql_version' => function_exists('mysqli_get_server_info') ? mysqli_get_server_info($wpdb->dbh) : '',
'memory_limit' => (defined(WP_MEMORY_LIMIT) ? WP_MEMORY_LIMIT : ini_get('memory_limit')) ? ini_get('memory_limit') : '',
'external_http_blocked' => $external_http_blocked,
'wp_locale' => get_locale(),
'db_charset' => defined('DB_CHARSET') ? DB_CHARSET : '',
'debug_mode' => defined('WP_DEBUG') && WP_DEBUG ? true : false,
'wp_max_upload' => size_format(wp_max_upload_size()),
'php_time_limit' => function_exists('ini_get') ? ini_get('max_execution_time') : '',
'php_error_log' => function_exists('ini_get') ? ini_get('error_log') : '',
'fsockopen' => function_exists('fsockopen') ? true : false,
'open_ssl' => defined('OPENSSL_VERSION_TEXT') ? OPENSSL_VERSION_TEXT : '',
'curl' => $curl_version,
'ip' => $ip,
'user_count' => $users_count,
'admin_email' => sanitize_email(get_bloginfo('admin_email')),
'theme_name' => sanitize_text_field($theme_data->Name),
'theme_version' => sanitize_text_field($theme_data->Version),
);
$data['site_info']['location_details'] = $location !== null ? $location : '';
}
// SITE PLUGINS
if ($action == "user_skip"||$send_wpb_sdk_extensions) {
$data['site_plugins'] = self::get_all_plugins();
}
return $data;
}
/**
* Retrieve plugin settings related to the product.
*
* @return array
*/
private static function get_product_settings($slug)
{
$product_data = self::$product_data[$slug]['module'];
$plugin_options = array();
// Pull settings data from db.
foreach ($product_data['settings'] as $option_name => $default_value) {
$get_option = get_option($option_name);
$plugin_options[] = array(
'option' => $option_name,
'value' => !empty($get_option) ? wp_json_encode($get_option) : $default_value
);
}
return $plugin_options;
}
/**
* Collect multisite data.
*
* @return array|false
*/
private static function get_multisites()
{
if (!is_multisite()) {
return false;
}
$sites_info = array();
$sites = get_sites();
foreach ($sites as $site) {
$sites_info[$site->blog_id] = array(
'name' => get_blog_details($site->blog_id)->blogname,
'domain' => $site->domain,
'path' => $site->path,
);
}
return $sites_info;
}
/**
* Get user IP information.
*
* @return string|null
*/
private static function get_ip()
{
$fields = array(
'HTTP_CF_CONNECTING_IP',
'HTTP_CLIENT_IP',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED',
'REMOTE_ADDR',
);
foreach ($fields as $ip_field) {
if (!empty($_SERVER[$ip_field])) {
return $_SERVER[$ip_field];
}
}
return null;
}
/**
* Collect plugins information: Active/Inactive plugins.
*
* @return array
*/
private static function get_all_plugins()
{
$all_plugins = array_keys(get_plugins());
$active_plugins = get_option('active_plugins', array());
$in_active_plugins = [];
foreach ($all_plugins as $plugin) {
if (!in_array($plugin, $active_plugins)) {
// add in-active plugins in list.
$in_active_plugins[] = $plugin;
}
}
return array(
'active' => $active_plugins,
'inactive' => $in_active_plugins,
);
}
/**
* Get location details based on IP.
*
* @param string|null $ip
* @return array
*/
private static function get_location_details($ip)
{
$location_details = array();
try {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.iplocation.net/?ip={$ip}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$execute = curl_exec($ch);
curl_close($ch);
$result = json_decode($execute);
if ($result && $result->response_code === '200') {
if ($result->country_name !== '-' && $result->country_code2 !== '-') {
$location_details['response_code'] = $result->response_code;
$location_details['message'] = 'Success';
$location_details['data']['country_name'] = $result->country_name;
$location_details['data']['country_code'] = $result->country_code2;
} else {
$missing_info = array();
if ($result->country_name === '-') {
$missing_info[] = 'country_name';
}
if ($result->country_code2 === '-') {
$missing_info[] = 'country_code';
}
$location_details['response_code'] = '400';
$location_details['message'] = 'Error: Missing information for ' . implode(', ', $missing_info) . ' for the IP Address: ' . $ip;
}
} else {
$location_details['response_code'] = '400';
$location_details['message'] = 'Error: Invalid response code or data for the IP Address: ' . $ip;
}
return $location_details;
} catch (\Exception $e) {
$location_details['response_code'] = '400';
$location_details['message'] = 'Error: ' . $e->getMessage();
return $location_details;
}
}
/**
* Get product data.
*
* @param string $slug
* @return array
*/
private static function get_product_data($slug)
{
$plugin_data = wpb_get_plugin_details($slug);
$data = array();
$data['name'] = isset($plugin_data['Name']) ? $plugin_data['Name'] : $plugin_data['Title'];
$data['slug'] = $slug;
$data['id'] = self::$_module_id;
$data['type'] = 'Plugin';
$data['path'] = wpb_get_plugin_path($slug);
$data['version'] = $plugin_data['Version'];
return $data;
}
/**
* Send log data to the API.
*
* @param array $payload The log data payload.
*/
private static function send($slug, $payload)
{
// Add timestamp to the payload
$payload['sent_at'] = current_time('mysql', 1);
// Determine the log status
$logStatus = 'new';
$payload['log_status'] = $logStatus;
self::sendDataToAPI($slug, $payload);
}
/**
* Send data to the API endpoint.
*
* @param array $data The data to be sent.
*/
private static function sendDataToAPI($slug, $data)
{
$token = self::$product_data[$slug]['module']['public_key'];
$response = wp_remote_post(
WPBRIGADE_SDK_API_ENDPOINT . '/logger',
array(
'method' => 'POST',
'body' => $data,
'headers' => array(
'Authorization' => 'Bearer ' . $token, // Add the token in the request headers
),
)
);
}
}