wpdb->get_charset_collate(); $tbl = 'CREATE TABLE ' . $this->table_name( 'monitors' ) . " ( monitor_id int(11) NOT NULL auto_increment, wpid int(11) NOT NULL, `active` tinyint(1) DEFAULT -1, `type` varchar(20) NOT NULL DEFAULT '', `keyword` varchar(255) NOT NULL DEFAULT '', `suburl` varchar(255) NOT NULL DEFAULT '', `issub` tinyint(1) DEFAULT 0, `timeout` smallint NOT NULL DEFAULT -1, `interval` int(11) NOT NULL DEFAULT -1, `retry_interval` int(11) NOT NULL DEFAULT 1, `up_status_codes` text NOT NULL DEFAULT '', `last_status` tinyint(1) DEFAULT 99, `last_http_code` int(11) NOT NULL DEFAULT 0, `lasttime_check` int(11) NOT NULL, `retries` tinyint(1) DEFAULT 0, `maxretries` tinyint(1) DEFAULT -1, `maxredirects` tinyint(1) DEFAULT 2, `method` varchar(20) NOT NULL DEFAULT '', `dts_interval_lasttime` int(11) NOT NULL DEFAULT 0, `dts_auto_monitoring_time` int(11) NOT NULL DEFAULT 0, `dts_auto_monitoring_start` int(11) NOT NULL DEFAULT 0, `dts_auto_monitoring_retry_time` int(11) NOT NULL DEFAULT 0, KEY idx_wpid (wpid)"; if ( empty( $currentVersion ) || version_compare( $currentVersion, '9.0.0.41', '<' ) ) { // NOSONAR - no ip. $tbl .= ', PRIMARY KEY (monitor_id) '; } $tbl .= ') ' . $charset_collate; $sql[] = $tbl; $tbl = 'CREATE TABLE ' . $this->table_name( 'monitor_heartbeat' ) . ' ( heartbeat_id int(11) NOT NULL auto_increment, monitor_id int(11) NOT NULL, `msg` text NOT NULL, `importance` tinyint(1) NOT NULL DEFAULT 0, `status` smallint NOT NULL DEFAULT 3, `time` DATETIME NOT NULL, `ping_ms` int DEFAULT 0, `duration` int DEFAULT 0, `down_count` tinyint(1) NOT NULL DEFAULT 0, `http_code` smallint NOT NULL DEFAULT 0, KEY idx_monitor_id (monitor_id), KEY idx_monitor_time (`time`)'; if ( empty( $currentVersion ) || version_compare( $currentVersion, '9.0.0.41', '<' ) ) { // NOSONAR - no ip. $tbl .= ', PRIMARY KEY (heartbeat_id) '; } $tbl .= ') ' . $charset_collate; $sql[] = $tbl; $tbl = 'CREATE TABLE ' . $this->table_name( 'monitor_stat_hourly' ) . ' ( stat_hourly_id int(11) NOT NULL auto_increment, monitor_id int(11) NOT NULL, `up` int DEFAULT 0, `down` int DEFAULT 0, `ping_avg` int DEFAULT 0, `ping_min` int DEFAULT 0, `ping_max` int DEFAULT 0, `timestamp` int DEFAULT 0, KEY idx_monitor_id (monitor_id), KEY idx_hourly_timestamp (`timestamp`)'; if ( empty( $currentVersion ) || version_compare( $currentVersion, '9.0.0.42', '<' ) ) { // NOSONAR - no ip. $tbl .= ', PRIMARY KEY (stat_hourly_id) '; } $tbl .= ') ' . $charset_collate; $sql[] = $tbl; add_action( 'mainwp_db_after_update', array( $this, 'update_db_data' ), 10, 2 ); } /** * Method update_db_data action. * * @param string $current_version current version. * * @return void */ public function update_db_data( $current_version ) { $suppress = $this->wpdb->suppress_errors(); $this->update_db_90041( $current_version ); $this->update_db_90043( $current_version ); $this->wpdb->suppress_errors( $suppress ); } /** * Method update_db_data action. * * @param string $current_version current version. * * @return void */ public function update_db_90041( $current_version ) { //phpcs:ignore -- NOSONAR - complexity. $update_ver = '9.0.0.41'; // NOSONAR - no ip. if ( ! empty( $current_version ) && version_compare( $current_version, $update_ver, '<' ) ) { // To compatible with basic monitoring settings. $disableSitesMonitoring = (int) get_option( 'mainwp_disableSitesChecking' ); $frequencySitesChecking = (int) get_option( 'mainwp_frequencySitesChecking', 60 ); $ignored_codes = get_option( 'mainwp_ignore_HTTP_response_status' ); $interval_values = MainWP_Uptime_Monitoring_Edit::get_interval_values( false ); if ( ! isset( $interval_values[ $frequencySitesChecking ] ) ) { $frequencySitesChecking = 60; } $global_settings = MainWP_Uptime_Monitoring_Handle::get_global_monitoring_settings(); $global_settings['active'] = $disableSitesMonitoring ? 0 : 1; $global_settings['interval'] = $frequencySitesChecking; if ( ! empty( $ignored_codes ) ) { $global_settings['up_status_codes'] = $ignored_codes; } $legacy_enabled_monitors = $this->wpdb->get_results( $this->get_legacy_sql_websites_enabled_check_status( true ) ); //phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL from wpdb->prepare(). if ( $legacy_enabled_monitors ) { foreach ( $legacy_enabled_monitors as $mo ) { $this->update_wp_monitor( array( 'wpid' => $mo->id, 'active' => $disableSitesMonitoring ? 1 : -1, // if global setting is disabled, it will be 1 - individual active, else it will be -1 use global setting - active. 'interval' => $mo->status_check_interval > 0 ? $mo->status_check_interval : -1, // 0 then -1, use global setting. 'timeout' => -1, 'method' => 'useglobal', 'type' => 'useglobal', 'up_status_codes' => 'useglobal', ) ); // use global setting. } } $legacy_disabled_monitors = $this->wpdb->get_results( $this->get_legacy_sql_websites_enabled_check_status( false ) ); //phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL from wpdb->prepare(). if ( $legacy_disabled_monitors ) { if ( ! $disableSitesMonitoring ) { $this->update_db_legacy_first_enable_monitoring_create_monitors( $legacy_disabled_monitors, 0 ); } else { $global_settings['first_enable_update'] = 1; } } MainWP_Uptime_Monitoring_Handle::update_uptime_global_settings( $global_settings ); delete_option( 'mainwp_frequencySitesChecking' ); delete_option( 'mainwp_disableSitesChecking' ); delete_option( 'mainwp_ignore_HTTP_response_status' ); $delColumns = array( 'status_check_interval' ); $table_wp = esc_sql( $this->table_name( 'wp' ) ); foreach ( $delColumns as $column ) { $this->wpdb->query( 'ALTER TABLE ' . $table_wp . ' DROP COLUMN ' . esc_sql( $column ) ); } } } /** * Method update_db_data action. * * @param string $current_version current version. * * @return void */ public function update_db_90043( $current_version ) { $update_ver = '9.0.0.43'; // NOSONAR - no ip. $update_ver2 = '9.0.0.41'; // NOSONAR - no ip. if ( ! empty( $current_version ) && version_compare( $current_version, $update_ver, '<' ) && version_compare( $current_version, $update_ver2, '>=' ) ) { $table_wp = esc_sql( $this->table_name( 'wp' ) ); $this->wpdb->query( 'ALTER TABLE ' . $table_wp . ' CHANGE up_statuscodes_json up_status_codes text NOT NULL DEFAULT ""' ); //phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared } $update_ver3 = '9.0.0.49'; // NOSONAR - no ip. if ( empty( $current_version ) || version_compare( $current_version, $update_ver3, '<' ) ) { // default up codes for new install. $up_codes = array( 200, 201, 202, 203, 204, 205, 206 ); $global_settings = MainWP_Uptime_Monitoring_Handle::get_global_monitoring_settings(); $current_codes = ! empty( $global_settings['up_status_codes'] ) ? explode( ',', $global_settings['up_status_codes'] ) : array(); if ( ! empty( $current_codes ) ) { $up_codes = array_unique( array_merge( $up_codes, $current_codes ) ); } $global_settings['up_status_codes'] = implode( ',', $up_codes ); MainWP_Uptime_Monitoring_Handle::update_uptime_global_settings( $global_settings ); } } /** * Method dev_update_db_90050 action. * * @param string $current_version current version. * * @return void */ public function dev_update_db_90050( $current_version ) { //phpcs:ignore -- NOSONAR - complex. $update_ver = '9.0.0.61'; // NOSONAR - no ip. if ( ! empty( $current_version ) && version_compare( $current_version, $update_ver, '<=' ) ) { $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites() ); while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) { $table_monitors = esc_sql( $this->table_name( 'monitors' ) ); $sql = $this->wpdb->prepare( 'SELECT mo.* FROM ' . $table_monitors . ' mo WHERE mo.wpid = %d AND mo.issub = 0 ORDER BY mo.monitor_id ASC', intval( $website->id ) ); $site_mos = $this->wpdb->get_results( $sql ); if ( $site_mos ) { $first_mo_id = false; foreach ( $site_mos as $mo ) { if ( ! $first_mo_id ) { $first_mo_id = $mo->monitor_id; } elseif ( $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $table_monitors . ' WHERE monitor_id=%d', $mo->monitor_id ) ) ) { $this->wpdb->update( $this->table_name( 'monitor_heartbeat' ), array( 'monitor_id' => $first_mo_id ), array( 'monitor_id' => $mo->monitor_id ) ); $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . esc_sql( $this->table_name( 'monitor_stat_hourly' ) ) . ' WHERE monitor_id=%d', $mo->monitor_id ) ); } } } } MainWP_DB::free_result( $websites ); } } /** * Method update_db_legacy_first_enable_monitoring_create_monitors * * @param mixed $disabled_monitors disabled monitors. * @param mixed $active active. * @return void */ public function update_db_legacy_first_enable_monitoring_create_monitors( $disabled_monitors = null, $active = null ) { if ( null === $disabled_monitors ) { $disabled_monitors = $this->wpdb->get_results( $this->get_legacy_sql_websites_enabled_check_status( false ) ); //phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL from wpdb->prepare(). } if ( is_array( $disabled_monitors ) ) { if ( null === $active ) { $act = - 1; // create and enable monitors - -1: use global active setting. } else { $act = $active ? -1 : 0; // create and set active/deactive monitors - -1: use global active setting, 0: individual disable. } foreach ( $disabled_monitors as $mo ) { $this->update_wp_monitor( array( 'wpid' => $mo->id, 'active' => $act, 'interval' => $mo->status_check_interval > 0 ? $mo->status_check_interval : -1, // 0 then -1, use global setting. 'timeout' => -1, 'method' => 'useglobal', 'type' => 'useglobal', 'up_status_codes' => 'useglobal', 'issub' => 0, ) ); } } } /** * Get legacy sql websites by check status. * * @param bool $enabled enabled or not. * @return string SQL string. */ public function get_legacy_sql_websites_enabled_check_status( $enabled ) { $table_wp = esc_sql( $this->table_name( 'wp' ) ); return $this->wpdb->prepare( 'SELECT wp.id FROM ' . $table_wp . ' wp WHERE wp.disable_status_check = %d', $enabled ? 0 : 1 ); } /** * Method get_monitor_by * * @param int $site_id site id. * @param string $by Get by. * @param mixed $value value. * @param array $params params. * @param string $obj OBJECT|ARRAY_A. * @return object|null */ public function get_monitor_by( $site_id, $by, $value, $params = array(), $obj = OBJECT ) { if ( ! is_array( $params ) ) { $params = array(); } if ( 'monitor_id' !== $by && empty( $site_id ) ) { // get by monitor_id, site id may be empty. return false; } if ( ! empty( $site_id ) ) { $params['wpid'] = $site_id; } if ( in_array( $by, array( 'suburl', 'monitor_id', 'issub' ), true ) ) { $params[ $by ] = $value; } else { return false; } if ( empty( $params['view'] ) ) { $params['view'] = 'monitor_view'; } return $this->get_row_result( $this->get_sql_monitor( $params ), $obj ); } /** * Get moniyor's sub page. * * @param array $params params. * @return mixed result. */ public function get_monitor_sub_pages( $params ) { if ( ! is_array( $params ) ) { $params = array(); } $params['issub'] = 1; if ( empty( $params['view'] ) ) { $params['view'] = 'monitor_view'; } $sql = $this->get_sql_monitor( $params ); $this->log_system_query( $params, $sql ); return $this->wpdb->get_results( $sql, ARRAY_A ); //phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL built with esc_sql() table names. } /** * Get monitors. * * @param array $params params. * @param int $obj OBJECT|ARRAY_A. * * @return object|null Database query results or null on failure. */ public function get_monitors( $params = array(), $obj = OBJECT ) { if ( empty( $params['view'] ) ) { $params['view'] = 'monitor_view'; } $sql = $this->get_sql_monitor( $params ); return $this->wpdb->get_results( $sql, $obj ); //phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL built with esc_sql() table names. } /** * Get sites monitors to check. * * @param array $params params. * * @return object|null Database query result or null on failure. */ public function get_monitors_to_check_uptime( $params = array() ) { //phpcs:ignore -- NOSONAR - complexity. $params = apply_filters( 'mainwp_uptime_monitoring_get_monitors_to_check_params', $params ); $local_timestamp = mainwp_get_timestamp(); $lasttime_counter = isset( $params['main_counter_lasttime'] ) ? intval( $params['main_counter_lasttime'] ) : 0; $glo_settings = isset( $params['global_settings'] ) && is_array( $params['global_settings'] ) ? $params['global_settings'] : array(); $limit = isset( $glo_settings['limit'] ) ? intval( $glo_settings['limit'] ) : 10; $glo_interval = isset( $glo_settings['interval'] ) ? intval( $glo_settings['interval'] ) : 60; // mins. if ( empty( $glo_interval ) ) { $glo_interval = 60; } if ( $limit < 1 || $limit > 100 ) { $limit = 10; } $glo_active = 1; if ( isset( $glo_settings['active'] ) ) { $glo_active = 1 === (int) $glo_settings['active'] ? 1 : 0; } $glo_maxretries = isset( $glo_settings['maxretries'] ) ? (int) $glo_settings['maxretries'] : 0; if ( $glo_maxretries < 0 || $glo_maxretries > 5 ) { $glo_maxretries = 0; } $not_suspended = true; if ( isset( $params['not_suspended'] ) ) { $not_suspended = $params['not_suspended'] ? true : false; } $where = ''; if ( true === $not_suspended ) { $where .= ' AND wp.suspended = 0 '; } $_params = array( 'view' => 'ping_view', ); $and_active = ' AND ( mo.active = 1 OR ( mo.active = -1 AND 1 = ' . $glo_active . ') ) '; // interval = 0, use global settings. $and_interval_run = ' ( mo.interval != -1 AND mo.dts_interval_lasttime + mo.interval * 60 < ' . intval( $local_timestamp ) . ' ) OR ( mo.interval = -1 AND mo.dts_interval_lasttime + ' . intval( $glo_interval ) . ' * 60 < ' . intval( $local_timestamp ) . ') '; $and_interval_run = ' ( ' . $and_interval_run . ' )'; $and_main_round_run = ' ( mo.dts_auto_monitoring_start = 0 OR ( mo.dts_auto_monitoring_start < ' . intval( $lasttime_counter ) . ' ) ) '; // To ensure the check request is not completed. $and_retry_run = ' ( ( mo.maxretries != 0 AND mo.maxretries != -1 AND mo.retries < mo.maxretries ) OR ( mo.maxretries = -1 AND 0 != ' . intval( $glo_maxretries ) . ' AND mo.retries < ' . intval( $glo_maxretries ) . ' ) ) AND '; // in case maxretries >= 1, validate the maximum allowed retries. $and_retry_run .= ' ( mo.dts_auto_monitoring_retry_time != 0 AND ( mo.dts_auto_monitoring_retry_time + mo.retry_interval * 60 <= ' . intval( $local_timestamp ) . ' ) ) '; // if retry is set, do it after retry_interval mins. $and_retry_run = ' ( ' . $and_retry_run . ' )'; $where .= $and_active . ' AND ( ' . $and_interval_run . ' OR ' . $and_main_round_run . ' OR ' . $and_retry_run . ' ) '; $_params['limit'] = $limit; $_params['custom_where'] = $where; $_params['order_by'] = ' mo.dts_auto_monitoring_time ASC '; $sql = $this->get_sql_monitor( $_params ); $this->log_system_query( $params, $sql ); return $this->wpdb->get_results( $sql, OBJECT ); //phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL built with esc_sql() table names. } /** * Count individual enabled sites monitors. * * @return int */ public function count_monitors_individual_active_enabled() { $table_monitors = esc_sql( $this->table_name( 'monitors' ) ); return $this->wpdb->get_var( 'SELECT count(*) FROM ' . $table_monitors . ' WHERE active = 1 ' ); } /** * Get uptime notifcation to send. * * @param int $limit limit. * @return mixed */ public function get_uptime_notification_to_start_send( $limit = 50 ) { $table_monitors = esc_sql( $this->table_name( 'monitors' ) ); $table_schedule_processes = esc_sql( $this->table_name( 'schedule_processes' ) ); $sql = $this->wpdb->prepare( ' SELECT pro.process_id,pro.status,pro.dts_process_start,pro.dts_process_stop,mo.* FROM ' . $table_monitors . ' mo ' . ' LEFT JOIN ' . $table_schedule_processes . ' pro ON mo.monitor_id = pro.item_id ' . " WHERE ( pro.type = 'monitor' AND pro.process_slug = 'uptime_notification' " . " AND ( pro.dts_process_stop > pro.dts_process_start OR pro.dts_process_start = 0 ) AND pro.status = 'active' ) " . ' ORDER BY pro.dts_process_start ASC LIMIT %d ', $limit ); return $this->wpdb->get_results( $sql ); } /** * Get uptime notifcation to continue send. * * @param array $params params. * @return mixed result */ public function get_uptime_notification_to_continue_send( $params ) { if ( ! is_array( $params ) ) { $params = array(); } $params['view'] = 'uptime_notification'; $params['custom_where'] = " AND ( pro.type = 'monitor' AND pro.process_slug = 'uptime_notification' AND pro.status = 'active' AND pro.dts_process_stop < pro.dts_process_start ) "; $params['others_fields'] = array( 'monitoring_notification_emails', 'settings_notification_emails', 'site_info' ); // other wp options fields. $sql = $this->get_sql_monitor( $params ); $this->log_system_query( $params, $sql ); return $this->wpdb->get_results( $sql ); //phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL built with esc_sql() table names. } /** * Get uptime monitor notifcation heartbeats to send. * * @param int $mo_id Monitor id. * @param int $hb_timestamp Heartbeat init time. * * @return mixed result */ public function get_monitor_notification_heartbeats_to_send( $mo_id, $hb_timestamp ) { if ( empty( $hb_timestamp ) ) { return false; } $table_monitor_heartbeat = esc_sql( $this->table_name( 'monitor_heartbeat' ) ); $hb_time = gmdate( 'Y-m-d H:i:S', $hb_timestamp ); $sql = $this->wpdb->prepare( 'SELECT he.* FROM ' . $table_monitor_heartbeat . ' he ' . ' WHERE he.monitor_id = %d AND ( he.status = 0 OR he.status = 1 ) AND he.time >= %s ' . ' AND he.importance = 1 ORDER BY he.heartbeat_id ASC ', $mo_id, $hb_time ); return $this->wpdb->get_results( $sql ); } /** * Update site monitor. * * @param array $data data. * * @return object|null Database query results or null on failure. */ public function update_wp_monitor( $data ) { if ( ! is_array( $data ) ) { return false; } $allowed_methods = MainWP_Uptime_Monitoring_Edit::get_allowed_methods(); if ( isset( $data['method'] ) ) { $data['method'] = strtolower( $data['method'] ); if ( empty( $data['method'] ) || ! isset( $allowed_methods[ $data['method'] ] ) ) { $data['method'] = 'get'; } } if ( isset( $data['monitor_id'] ) ) { $id = $data['monitor_id']; unset( $data['monitor_id'] ); $this->wpdb->update( $this->table_name( 'monitors' ), $data, array( 'monitor_id' => $id ) ); return $id; } else { if ( empty( $data['method'] ) || ! isset( $allowed_methods[ $data['method'] ] ) ) { $data['method'] = 'get'; } $data['issub'] = ! empty( $data['suburl'] ) ? 1 : 0; $this->wpdb->insert( $this->table_name( 'monitors' ), $data ); return $this->wpdb->insert_id; } } /** * Get child site monitor by id via SQL. * * @param array $params params. * * @return object|null Database query result or null on failure. */ public function get_sql_monitor( $params ) { //phpcs:ignore -- NOSONAR - complexity. if ( ! is_array( $params ) ) { $params = array(); } $table_wp = esc_sql( $this->table_name( 'wp' ) ); $table_wp_sync = esc_sql( $this->table_name( 'wp_sync' ) ); $table_monitors = esc_sql( $this->table_name( 'monitors' ) ); $table_wp_clients = esc_sql( $this->table_name( 'wp_clients' ) ); $table_wp_group = esc_sql( $this->table_name( 'wp_group' ) ); $table_group = esc_sql( $this->table_name( 'group' ) ); $table_schedule_processes = esc_sql( $this->table_name( 'schedule_processes' ) ); $view = ! empty( $params['view'] ) ? $params['view'] : 'default'; $extra_view = ! empty( $params['extra_view'] ) ? $params['extra_view'] : array(); $site_id = isset( $params['wpid'] ) ? intval( $params['wpid'] ) : false; $monitorid = isset( $params['monitor_id'] ) ? intval( $params['monitor_id'] ) : false; $sub_url = isset( $params['suburl'] ) ? $params['suburl'] : false; $is_sub = isset( $params['issub'] ) ? intval( $params['issub'] ) : false; $limit = ! empty( $params['limit'] ) ? $params['limit'] : 0; $with_clients = isset( $params['with_clients'] ) && $params['with_clients'] ? true : false; $select_grps = isset( $params['selectgroups'] ) && $params['selectgroups'] ? true : false; $is_staging = isset( $params['is_staging'] ) && in_array( $params['is_staging'], array( 'yes', 'no' ) ) ? $params['is_staging'] : 'no'; $others_fields = isset( $params['others_fields'] ) && is_array( $params['others_fields'] ) ? $params['others_fields'] : array( 'favi_icon' ); $for_manager = isset( $params['for_manager'] ) && $params['for_manager'] ? true : false; $custom_where = ! empty( $params['custom_where'] ) ? $params['custom_where'] : ''; $order_by = isset( $params['order_by'] ) && ! empty( $params['order_by'] ) ? $params['order_by'] : ''; if ( ! empty( $extra_view ) && is_array( $extra_view ) && is_array( $others_fields ) ) { $others_fields = array_unique( array_merge( $extra_view, $others_fields ) ); } $select_clients = ''; $join_clients = ''; if ( $with_clients ) { $select_clients = ', wpclient.name as client_name '; $join_clients = ' LEFT JOIN ' . $table_wp_clients . ' wpclient ON wp.client_id = wpclient.client_id '; } $where = ''; if ( false !== $site_id ) { $where .= ' AND wp.id = ' . intval( $site_id ); } if ( false !== $monitorid ) { $where .= ' AND mo.monitor_id = ' . intval( $monitorid ); } if ( false !== $sub_url ) { $where .= $this->wpdb->prepare( ' AND mo.suburl = %s', $sub_url ); } if ( false !== $is_sub ) { $where .= ' AND mo.issub = ' . intval( $is_sub ); } if ( ! $for_manager ) { $where .= $this->get_sql_where_allow_access_sites( 'wp', $is_staging ); } $light_fields = array( 'wp.id', 'wp.url', 'wp.name', 'wp.client_id', 'wp.verify_certificate', 'wp.http_user', 'wp.http_pass', 'wp.ssl_version', 'wp.adminname', 'wp.privkey', 'wp.pubkey', 'wp.wpe', 'wp.is_staging', 'wp.pubkey', 'wp.force_use_ipv4', 'wp.siteurl', 'wp.suspended', 'wp.mainwpdir', 'wp.is_ignoreCoreUpdates', 'wp.is_ignorePluginUpdates', 'wp.is_ignoreThemeUpdates', 'wp.backup_before_upgrade', 'wp.userid', 'wp_sync.sync_errors', ); $legacy_status_fields = array( 'wp.offline_check_result', // 1 - online, -1 offline. 'wp.http_response_code', 'wp.offline_checks_last', ); $light_fields = array_merge( $light_fields, $legacy_status_fields ); $base_fields = array( $light_fields, array( 'wp.plugins', 'wp.themes', ), ); $default_fields = array( 'wp.*', 'wp_sync.*', ); if ( 'ping_view' === $view || 'monitor_view' === $view ) { $select_fields = $light_fields; } elseif ( 'base_view' === $view ) { $select_fields = $base_fields; } elseif ( 'uptime_notification' === $view ) { $select_fields = $light_fields; $select_fields[] = 'pro.*'; } else { $select_fields = $default_fields; } $select_fields[] = 'mo.*'; $select_fields[] = 'wp_optionview.*'; $select = implode( ',', $select_fields ); $select_groups = ''; $join_groups = ''; if ( $select_grps ) { $select_groups = ', GROUP_CONCAT(gr.name ORDER BY gr.name SEPARATOR ",") as wpgroups, GROUP_CONCAT(gr.id ORDER BY gr.name SEPARATOR ",") as wpgroupids, GROUP_CONCAT(gr.color ORDER BY gr.name SEPARATOR ",") as wpgroups_colors, '; $join_groups = ' LEFT JOIN ' . $table_wp_group . ' wpgr ON wp.id = wpgr.wpid LEFT JOIN ' . $table_group . ' gr ON wpgr.groupid = gr.id'; } $join_monitors = 'LEFT JOIN ' . $table_monitors . ' mo ON wp.id = mo.wpid'; $join_process = ''; if ( 'uptime_notification' === $view ) { $join_process = ' LEFT JOIN ' . $table_schedule_processes . ' pro ON mo.monitor_id = pro.item_id '; } if ( ! empty( $params['count_only'] ) ) { $select = ' count(*) '; } else { $select = $select . $select_clients . $select_groups; } if ( empty( $order_by ) ) { $order_by = ' mo.monitor_id DESC'; } $limit_str = ''; if ( ! empty( $limit ) ) { $limit_str = ' LIMIT ' . intval( $limit ); } $qry = 'SELECT ' . $select . ' FROM ' . $table_wp . ' wp ' . $join_clients . ' ' . $join_groups . ' ' . $join_monitors . ' ' . $join_process . ' JOIN ' . $table_wp_sync . ' wp_sync ON wp.id = wp_sync.wpid JOIN ' . $this->get_option_view_by( $view, $others_fields ) . ' wp_optionview ON wp.id = wp_optionview.wpid WHERE 1 ' . $where . $custom_where . ' GROUP BY mo.monitor_id ORDER BY ' . $order_by . $limit_str; $this->log_system_query( $params, $qry ); return $qry; } /** * Delete monitor and uptime data. * * @param array $params data. * * @return bool success|failed. */ public function delete_monitor( $params ) { if ( ! is_array( $params ) ) { return false; } $table_monitors = esc_sql( $this->table_name( 'monitors' ) ); $sql = ''; if ( ! empty( $params['monitor_id'] ) ) { $sql = $this->wpdb->prepare( 'SELECT monitor_id, wpid FROM ' . $table_monitors . ' WHERE monitor_id=%d', $params['monitor_id'] ); } elseif ( ! empty( $params['wpid'] ) ) { $sql = $this->wpdb->prepare( 'SELECT monitor_id, wpid FROM ' . $table_monitors . ' WHERE wpid=%d AND issub = 0 ', $params['wpid'] ); } $current = 0; if ( ! empty( $sql ) ) { $current = $this->wpdb->get_row( $sql ); //phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL from wpdb->prepare(). } if ( empty( $current ) ) { return false; } $monitor_id = $current->monitor_id; $wp_id = $current->wpid; if ( ! empty( $current->issub ) ) { if ( $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $table_monitors . ' WHERE monitor_id=%d', $monitor_id ) ) ) { $this->delete_heartbeat( $monitor_id ); $this->delete_stats( $monitor_id ); return true; } return false; } $sql = $this->wpdb->prepare( 'SELECT monitor_id FROM ' . $table_monitors . ' WHERE wpid=%d ', $wp_id ); $monitors = $this->wpdb->get_results( $sql ); //phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL from wpdb->prepare(). if ( $monitors ) { foreach ( $monitors as $mo ) { if ( $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $table_monitors . ' WHERE monitor_id=%d', $mo->monitor_id ) ) ) { $this->delete_heartbeat( $mo->monitor_id ); $this->delete_stats( $mo->monitor_id ); } } return true; } return false; } /** * Method delete_heartbeat by monitor id. * * @param int $monitorid monitor id. * @return bool */ public function delete_heartbeat( $monitorid ) { if ( empty( $monitorid ) ) { return false; } $table_monitor_heartbeat = esc_sql( $this->table_name( 'monitor_heartbeat' ) ); if ( $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $table_monitor_heartbeat . ' WHERE monitor_id=%d', $monitorid ) ) ) { return true; } return false; } /** * Update heartbeat monitor. * * @param array $data data. * * @return int|bool Database query results or null on failure. */ public function update_heartbeat( $data ) { if ( ! is_array( $data ) ) { return false; } MainWP_Logger::instance()->log_uptime_check( 'Update heartbeat :: ' . print_r( $data, true ) ); //phpcs:ignore --NOSONAR -for dev logs. if ( isset( $data['heartbeat_id'] ) ) { $id = $data['heartbeat_id']; unset( $data['heartbeat_id'] ); $this->wpdb->update( $this->table_name( 'monitor_heartbeat' ), $data, array( 'heartbeat_id' => $id ) ); return $id; } else { $this->wpdb->insert( $this->table_name( 'monitor_heartbeat' ), $data ); return $this->wpdb->insert_id; } } /** * Get last monitor heartbeat. * * @param int $monitor_id monitor id. * * @return object|null Database query results or null on failure. */ public function get_previous_monitor_heartbeat( $monitor_id ) { $table_monitor_heartbeat = esc_sql( $this->table_name( 'monitor_heartbeat' ) ); $sql = $this->wpdb->prepare( 'SELECT * FROM ' . $table_monitor_heartbeat . ' WHERE monitor_id = %d ORDER BY time DESC LIMIT 1', $monitor_id ); return $this->wpdb->get_row( $sql ); } /** * Get last site's heartbeat. * * @param int $siteid site id. * @param bool $include_suburl include suburl. * * @return object|null Database query results or null on failure. */ public function get_last_site_heartbeat( $siteid, $include_suburl = true ) { $table_monitors = esc_sql( $this->table_name( 'monitors' ) ); $table_monitor_heartbeat = esc_sql( $this->table_name( 'monitor_heartbeat' ) ); if ( $include_suburl ) { $where = ' AND ( mo.issub = 1 OR mo.issub = 0 ) '; } else { $where = ' AND mo.issub = 0'; } $sql = $this->wpdb->prepare( 'SELECT he.*,mo.active FROM ' . $table_monitors . ' mo ' . ' LEFT JOIN ' . $table_monitor_heartbeat . ' he ' . ' ON mo.monitor_id = he.monitor_id ' . ' WHERE mo.wpid = %d ' . $where . ' ORDER BY he.time DESC LIMIT 1', $siteid ); return $this->wpdb->get_row( $sql ); //phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL from wpdb->prepare(). } /** * Count up down monitors. * * @return array data. */ public function get_count_up_down_monitors() { $table_monitors = esc_sql( $this->table_name( 'monitors' ) ); $sql = ' SELECT ' . ' ( SELECT count(*) FROM ' . $table_monitors . ' up WHERE up.last_status = 1 ) AS count_up, ' . ' ( SELECT count(*) FROM ' . $table_monitors . ' down WHERE down.last_status = 0 ) AS count_down ' . ' FROM ' . $table_monitors . ' mo LIMIT 1'; return $this->wpdb->get_row( $sql, ARRAY_A ); //phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL from wpdb->prepare(). } /** * Count last site's incidents. * * @param int $siteid site id. * @param array $days_num days number. * * @return array data. */ public function get_site_count_last_incidents( $siteid, $days_num ) { $table_monitors = esc_sql( $this->table_name( 'monitors' ) ); $table_monitor_heartbeat = esc_sql( $this->table_name( 'monitor_heartbeat' ) ); if ( empty( $days_num ) ) { $days_num = 1; } $start_date = gmdate( 'Y-m-d 00:00:00', time() - $days_num * DAY_IN_SECONDS ); $sql = $this->wpdb->prepare( 'SELECT ' . ' ( SELECT count(*) FROM ' . $table_monitor_heartbeat . ' he2 WHERE he2.time > %s AND he2.monitor_id = he.monitor_id AND he2.status = 0 AND he2.importance = 1 ) AS count ' . ' FROM ' . $table_monitors . ' mo ' . ' LEFT JOIN ' . $table_monitor_heartbeat . ' he ' . ' ON mo.monitor_id = he.monitor_id ' . ' WHERE mo.wpid = %d AND mo.issub = 0 LIMIT 1', $start_date, $siteid ); return $this->wpdb->get_row( $sql, ARRAY_A ); } /** * Get last site's incidents stats. * * @param int $siteid site id. * * @return object|null Database query results or null on failure. */ public function get_last_site_incidents_stats( $siteid ) { $table_monitors = esc_sql( $this->table_name( 'monitors' ) ); $table_monitor_heartbeat = esc_sql( $this->table_name( 'monitor_heartbeat' ) ); $sql = $this->wpdb->prepare( 'SELECT ' . ' ( SELECT count(*) FROM ' . $table_monitor_heartbeat . ' he24 WHERE ( he24.time >= NOW() - INTERVAL 1 DAY ) AND he24.monitor_id = he.monitor_id AND he24.status = 0 AND he.importance = 1 ) AS total24,' . ' ( SELECT count(*) FROM ' . $table_monitor_heartbeat . ' he7 WHERE ( he7.time >= NOW() - INTERVAL 7 DAY ) AND he7.monitor_id = he.monitor_id AND he7.status = 0 AND he.importance = 1 ) AS total7,' . ' ( SELECT count(*) FROM ' . $table_monitor_heartbeat . ' he30 WHERE ( he30.time >= NOW() - INTERVAL 30 DAY ) AND he30.monitor_id = he.monitor_id AND he30.status = 0 AND he.importance = 1 ) AS total30 ' . ' FROM ' . $table_monitors . ' mo ' . ' LEFT JOIN ' . $table_monitor_heartbeat . ' he ' . ' ON mo.monitor_id = he.monitor_id ' . ' WHERE mo.wpid = %d LIMIT 1', $siteid ); return $this->wpdb->get_row( $sql, ARRAY_A ); } /** * Get site's incidents stats. * * @param int $siteid site id. * @param array $params params. * * @return array data. */ public function get_site_incidents_stats( $siteid, $params = array() ) { $table_monitors = esc_sql( $this->table_name( 'monitors' ) ); $table_monitor_heartbeat = esc_sql( $this->table_name( 'monitor_heartbeat' ) ); $start = isset( $params['start'] ) ? $params['start'] . ' 00:00:00' : gmdate( 'Y-m-d 00:00:00', time() - 7 * DAY_IN_SECONDS ); $end = isset( $params['end'] ) ? $params['end'] . ' 23:59:59' : gmdate( 'Y-m-d 23:59:59', time() ); $sql = $this->wpdb->prepare( 'SELECT mo.wpid, mo.monitor_id, ' . ' ( SELECT count(*) FROM ' . $table_monitor_heartbeat . ' he2 WHERE he2.time > %s AND he2.time <= %s AND he2.monitor_id = mo.monitor_id AND he2.status = 0 AND he2.importance = 1 ) AS count_incidents' . ' FROM ' . $table_monitors . ' mo ' . ' LEFT JOIN ' . $table_monitor_heartbeat . ' he ' . ' ON mo.monitor_id = he.monitor_id ' . ' WHERE mo.wpid = %d AND mo.issub = 0 LIMIT 1 ', $start, $end, $siteid ); $results = $this->wpdb->get_row( $sql, ARRAY_A ); return array( 'start' => $start, 'end' => $end, 'count_incidents' => is_array( $results ) && isset( $results['count_incidents'] ) ? $results['count_incidents'] : 0, ); } /** * Get last site's uptime ratios stats. * * @param int $siteid site id. * @param int $days_num day number. * * @return object|null Database query results or null on failure. */ public function get_last_site_uptime_ratios_values( $siteid, $days_num ) { $table_monitors = esc_sql( $this->table_name( 'monitors' ) ); $table_monitor_heartbeat = esc_sql( $this->table_name( 'monitor_heartbeat' ) ); if ( empty( $days_num ) ) { $days_num = 1; } $start_date = gmdate( 'Y-m-d 00:00:00', time() - $days_num * DAY_IN_SECONDS ); $sql = $this->wpdb->prepare( 'SELECT ' . ' ( SELECT SUM(he.duration) FROM ' . $table_monitor_heartbeat . ' he WHERE he.time > %s AND he.monitor_id = mo.monitor_id AND he.status = 1 ) AS up_value,' . ' ( SELECT SUM(he.duration) FROM ' . $table_monitor_heartbeat . ' he WHERE he.time > %s AND he.monitor_id = mo.monitor_id AND ( he.status = 0 OR he.status = 1 ) ) AS total_value ' . ' FROM ' . $table_monitors . ' mo ' . ' LEFT JOIN ' . $table_monitor_heartbeat . ' he ' . ' ON mo.monitor_id = he.monitor_id ' . ' WHERE mo.wpid = %d AND mo.issub = 0 LIMIT 1', $start_date, $start_date, $siteid ); return $this->wpdb->get_row( $sql, ARRAY_A ); } /** * Get last site's uptime ratios stats. * * @param int $siteid site id. * * @return object|null Database query results or null on failure. */ public function get_last_site_uptime_ratios_stats( $siteid ) { $table_monitors = esc_sql( $this->table_name( 'monitors' ) ); $table_monitor_heartbeat = esc_sql( $this->table_name( 'monitor_heartbeat' ) ); $sql = $this->wpdb->prepare( 'SELECT ' . ' ( SELECT SUM(he24.duration) FROM ' . $table_monitor_heartbeat . ' he24 WHERE ( he24.time >= NOW() - INTERVAL 1 DAY ) AND he24.monitor_id = he.monitor_id AND he24.status = 1 ) AS up24,' . ' ( SELECT SUM(he24.duration) FROM ' . $table_monitor_heartbeat . ' he24 WHERE ( he24.time >= NOW() - INTERVAL 1 DAY ) AND he24.monitor_id = he.monitor_id AND ( he24.status = 0 OR he24.status = 1 ) ) AS total24,' . ' ( SELECT SUM(he7.duration) FROM ' . $table_monitor_heartbeat . ' he7 WHERE ( he7.time >= NOW() - INTERVAL 7 DAY ) AND he7.monitor_id = he.monitor_id AND he7.status = 1 ) AS up7,' . ' ( SELECT SUM(he7.duration) FROM ' . $table_monitor_heartbeat . ' he7 WHERE ( he7.time >= NOW() - INTERVAL 7 DAY ) AND he7.monitor_id = he.monitor_id AND ( he7.status = 0 OR he7.status = 1 ) ) AS total7,' . ' ( SELECT SUM(he30.duration) FROM ' . $table_monitor_heartbeat . ' he30 WHERE ( he30.time >= NOW() - INTERVAL 30 DAY ) AND he30.monitor_id = he.monitor_id AND he30.status = 1 ) AS up30, ' . ' ( SELECT SUM(he30.duration) FROM ' . $table_monitor_heartbeat . ' he30 WHERE ( he30.time >= NOW() - INTERVAL 30 DAY ) AND he30.monitor_id = he.monitor_id AND ( he30.status = 0 OR he30.status = 1 ) ) AS total30 ' . ' FROM ' . $table_monitors . ' mo ' . ' LEFT JOIN ' . $table_monitor_heartbeat . ' he ' . ' ON mo.monitor_id = he.monitor_id ' . ' WHERE mo.wpid = %d LIMIT 1', $siteid ); return $this->wpdb->get_row( $sql, ARRAY_A ); } /** * Get site's reports uptime ratios. * * @param int $siteid site id. * @param array $params params. * * @return array data. */ public function get_site_uptime_ratios_reports_data( $siteid, $params = array() ) { // 'period_days' :. // 'uptimeratiosall' => 365, // Last 365 days. // 'uptimeratios7' => 7. // 'uptimeratios15' => 15 // 'uptimeratios30' => 30. // 'uptimeratios45' => 45. // 'uptimeratios60' => 60. // 'uptimeratios' => from start->end date. $period_days = isset( $params['period_days'] ) ? $params['period_days'] : array(); if ( empty( $period_days ) || empty( $params['start'] ) || empty( $params['end'] ) ) { return array(); } $end_time_period = strtotime( $params['end'] . ' 23:59:59' ); $period_date = array(); foreach ( $period_days as $period => $days ) { if ( 'uptimeratios' !== $period ) { $period_date[ $period ] = array( 'start' => gmdate( 'Y-m-d 00:00:00', $end_time_period - $days * DAY_IN_SECONDS ), 'end' => $params['end'] . ' 23:59:59', ); } } $period_date['uptimeratios'] = array( 'start' => $params['start'] . ' 00:00:01', 'end' => $params['end'] . ' 23:59:59', ); $sql_sub = ''; foreach ( $period_date as $period => $date ) { $as_up = $period; $as_total = 'total' . $period; $_sql = ' ( SELECT SUM(' . $as_up . '.duration) FROM ' . $this->table_name( 'monitor_heartbeat' ) . ' ' . $as_up . ' WHERE ' . $as_up . '.time > "' . $this->escape( $date['start'] ) . '" AND ' . $as_up . '.time <= "' . $this->escape( $date['end'] ) . '" AND ' . $as_up . '.monitor_id = he.monitor_id AND ' . $as_up . '.status = 1 ) AS ' . $as_up . ','; $_sql .= ' ( SELECT SUM(' . $as_total . '.duration) FROM ' . $this->table_name( 'monitor_heartbeat' ) . ' ' . $as_total . ' WHERE ' . $as_total . '.time > "' . $this->escape( $date['start'] ) . '" AND ' . $as_total . '.time <= "' . $this->escape( $date['end'] ) . '" AND ' . $as_total . '.monitor_id = he.monitor_id AND ( ' . $as_total . '.status = 1 OR ' . $as_total . '.status = 0 ) ) AS ' . $as_total . ','; $sql_sub .= $_sql; } $sql_sub = rtrim( $sql_sub, ',' ); $sql = $this->wpdb->prepare( 'SELECT ' . $sql_sub . ' FROM ' . $this->table_name( 'monitors' ) . ' mo ' . ' LEFT JOIN ' . $this->table_name( 'monitor_heartbeat' ) . ' he ' . ' ON mo.monitor_id = he.monitor_id ' . ' WHERE mo.wpid = %d LIMIT 1', $siteid ); $result = $this->wpdb->get_row( $sql, ARRAY_A ); //phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL from wpdb->prepare(). if ( ! is_array( $result ) ) { $result = array(); } $data = array(); foreach ( $period_days as $period => $number ) { $as_up = $period; $as_total = 'total' . $period; $data[ $period ] = isset( $result[ $as_total ] ) && ! empty( $result[ $as_total ] ) ? number_format( $result[ $as_up ] * 100 / $result[ $as_total ], 6 ) : 'N/A'; // prevent divided by zero. } MainWP_Logger::instance()->log_uptime_check( 'Get reports data :: [params=' . print_r( $params, true ) . '] :: [ratios data='. print_r( $data, true ) . ']' ); //phpcs:ignore -- NOSONAR -for debug. return $data; } /** * Get monitor response time stats. * * @param int $siteid site id. * @param array $params params. * array 'start' and 'end' format : 'Y-m-d'. * * @return array Database query results or empty. */ public function get_db_site_response_time_stats_data( $siteid, $params = array() ) { $table_monitors = esc_sql( $this->table_name( 'monitors' ) ); $table_monitor_heartbeat = esc_sql( $this->table_name( 'monitor_heartbeat' ) ); if ( empty( $params['start'] ) || empty( $params['end'] ) ) { return array(); } $group_time = ! empty( $params['group_time_by'] ) ? strtolower( $params['group_time_by'] ) : 'date'; $start_ts = strtotime( $params['start'] ); $end_ts = strtotime( $params['end'] ); $start = gmdate( 'Y-m-d 00:00:00', $start_ts ); $end = gmdate( 'Y-m-d 23:59:59', $end_ts ); $sum_total = ', SUM(he.ping_ms) as resp_total_ms '; if ( 'hour' === $group_time ) { $group_by = ' GROUP BY HOUR(he.time) '; } elseif ( 'get_all' === $group_time ) { $group_by = ''; $sum_total = ', he.ping_ms as resp_total_ms '; } else { $group_by = ' GROUP BY DATE( he.time ) '; } $where = ''; if ( isset( $params['issub'] ) && 0 === (int) $params['issub'] ) { $where = ' AND mo.issub = 0 '; } $sql = $this->wpdb->prepare( 'SELECT he.time as resp_time ' . $sum_total . ' FROM ' . $table_monitors . ' mo ' . ' LEFT JOIN ' . $table_monitor_heartbeat . ' he ' . ' ON mo.monitor_id = he.monitor_id ' . ' WHERE mo.wpid = %d ' . $where . ' AND he.time > %s AND he.time <= %s ' . $group_by . ' ORDER BY resp_time ASC ', $siteid, $start, $end ); $data = $this->wpdb->get_results( $sql, ARRAY_A ); //phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL from wpdb->prepare(). $sql_stats = $this->wpdb->prepare( 'SELECT AVG( he.ping_ms ) AS avg_time_ms, MIN( he.ping_ms ) as min_time_ms, MAX( he.ping_ms ) as max_time_ms FROM ' . $table_monitors . ' mo ' . ' LEFT JOIN ' . $table_monitor_heartbeat . ' he ' . ' ON mo.monitor_id = he.monitor_id ' . ' WHERE mo.wpid = %d AND he.time > %s AND he.time <= %s', $siteid, $start, $end ); $resp_data = $this->wpdb->get_row( $sql_stats, ARRAY_A ); return array( 'resp_time_list' => $data, 'start' => $start, 'end' => $end, 'resp_stats_data' => $resp_data, ); } /** * Get monitoring events stats. * * @param int $siteid site id. * @param array $params params. * * @return object|null Database query results or null on failure. */ public function get_site_monitoring_events_stats( $siteid, $params = array() ) { $table_monitors = esc_sql( $this->table_name( 'monitors' ) ); $table_monitor_heartbeat = esc_sql( $this->table_name( 'monitor_heartbeat' ) ); $start = isset( $params['start'] ) ? $params['start'] . ' 00:00:00' : gmdate( 'Y-m-d 00:00:00', time() - 7 * DAY_IN_SECONDS ); $end = isset( $params['end'] ) ? $params['end'] . ' 23:59:59' : gmdate( 'Y-m-d 23:59:59', time() ); $sql = $this->wpdb->prepare( 'SELECT mo.active,mo.type,mo.keyword,mo.suburl,mo.interval,he.msg,he.status,he.time,he.ping_ms,he.http_code FROM ' . $table_monitors . ' mo ' . ' LEFT JOIN ' . $table_monitor_heartbeat . ' he ' . ' ON mo.monitor_id = he.monitor_id ' . ' WHERE mo.wpid = %d AND he.time > %s AND he.time <= %s ' . ' AND he.importance = 1 ', $siteid, $start, $end ); return $this->wpdb->get_results( $sql, ARRAY_A ); } /** * Get monitor uptime hourly stats by. * * @param int $monitor_id monitor id. * @param string $by by. * @param mixed $value value. * @param string $obj obj. * @return mixed */ public function get_uptime_monitor_stat_hourly_by( $monitor_id, $by, $value = false, $obj = ARRAY_A ) { $table_monitor_stat_hourly = esc_sql( $this->table_name( 'monitor_stat_hourly' ) ); if ( 'timestamp' === $by ) { if ( empty( $value ) ) { return false; } $sql = $this->wpdb->prepare( 'SELECT stho.* FROM ' . $table_monitor_stat_hourly . ' stho WHERE stho.monitor_id = %d AND stho.timestamp = %d', $monitor_id, $value ); return $this->wpdb->get_row( $sql, $obj ); } elseif ( 'last24' === $by ) { if ( empty( $value ) ) { return false; } $sql = $this->wpdb->prepare( 'SELECT stho.* FROM ' . $table_monitor_stat_hourly . ' stho WHERE stho.monitor_id = %d AND stho.timestamp >= %d ORDER BY stho.timestamp ASC ', $monitor_id, $value ); return $this->wpdb->get_results( $sql, $obj ); } return false; } /** * Method remove_outdated_hourly_uptime_stats * * @param int $days days. * @return void */ public function remove_outdated_hourly_uptime_stats( $days = 30 ) { $table_monitor_stat_hourly = esc_sql( $this->table_name( 'monitor_stat_hourly' ) ); $time = time() - $days * DAY_IN_SECONDS; $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $table_monitor_stat_hourly . ' WHERE timestamp < %d', $time ) ); } /** * Update uptime stat hourly. * * @param array $data data. * * @return int|bool Database query results or null on failure. */ public function update_site_uptime_stat_hourly( $data ) { if ( ! is_array( $data ) ) { return false; } if ( isset( $data['stat_hourly_id'] ) ) { $id = $data['stat_hourly_id']; unset( $data['stat_hourly_id'] ); $this->wpdb->update( $this->table_name( 'monitor_stat_hourly' ), $data, array( 'stat_hourly_id' => $id ) ); return $id; } else { $this->wpdb->insert( $this->table_name( 'monitor_stat_hourly' ), $data ); return $this->wpdb->insert_id; } } /** * Delete stats by monitor id. * * @param int $monitorid monitor id. * @return bool */ public function delete_stats( $monitorid ) { if ( empty( $monitorid ) ) { return false; } $table_monitor_stat_hourly = esc_sql( $this->table_name( 'monitor_stat_hourly' ) ); if ( $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . $table_monitor_stat_hourly . ' WHERE monitor_id=%d', $monitorid ) ) ) { return true; } return false; } }