insert( Argus_DB::table( 'events' ), array( 'event_type' => $type, 'severity' => $severity, 'ip' => $ip, 'summary' => $summary, 'payload' => wp_json_encode( $payload ), 'created_at' => current_time( 'mysql', true ), ), array( '%s', '%s', '%s', '%s', '%s', '%s' ) ); return (int) $wpdb->insert_id; } public static function recent( $limit = 50, $type = null ) { global $wpdb; $table = Argus_DB::table( 'events' ); if ( $type ) { $rows = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE event_type = %s ORDER BY created_at DESC LIMIT %d", $type, $limit ) // phpcs:ignore ); } else { $rows = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} ORDER BY created_at DESC LIMIT %d", $limit ) // phpcs:ignore ); } foreach ( $rows as &$row ) { $row->payload = json_decode( $row->payload, true ); } return $rows; } public static function counts_since( $since_mysql ) { global $wpdb; $table = Argus_DB::table( 'events' ); return $wpdb->get_results( $wpdb->prepare( "SELECT event_type, severity, COUNT(*) AS cnt FROM {$table} WHERE created_at >= %s GROUP BY event_type, severity", // phpcs:ignore $since_mysql ) ); } const PER_PAGE = 10; public static function paginated( $page = 1, array $filters = array(), $per_page = self::PER_PAGE ) { global $wpdb; $table = Argus_DB::table( 'events' ); $page = max( 1, (int) $page ); $offset = ( $page - 1 ) * $per_page; $where = array( '1=1' ); $args = array(); if ( ! empty( $filters['search'] ) ) { $where[] = 'summary LIKE %s'; $args[] = '%' . $wpdb->esc_like( $filters['search'] ) . '%'; } if ( ! empty( $filters['severity'] ) ) { $where[] = 'severity = %s'; $args[] = $filters['severity']; } if ( ! empty( $filters['type'] ) ) { $where[] = 'event_type = %s'; $args[] = $filters['type']; } if ( ! empty( $filters['since'] ) ) { $where[] = 'created_at >= %s'; $args[] = $filters['since']; } $where_sql = implode( ' AND ', $where ); $count_sql = "SELECT COUNT(*) FROM {$table} WHERE {$where_sql}"; // phpcs:ignore $total = (int) ( $args ? $wpdb->get_var( $wpdb->prepare( $count_sql, $args ) ) : $wpdb->get_var( $count_sql ) ); // phpcs:ignore $list_sql = "SELECT * FROM {$table} WHERE {$where_sql} ORDER BY created_at DESC LIMIT %d OFFSET %d"; // phpcs:ignore $list_args = array_merge( $args, array( $per_page, $offset ) ); $rows = $wpdb->get_results( $wpdb->prepare( $list_sql, $list_args ) ); // phpcs:ignore foreach ( $rows as &$row ) { $row->payload = json_decode( $row->payload, true ); } return array( 'rows' => $rows, 'total' => $total, 'total_pages' => max( 1, (int) ceil( $total / $per_page ) ), 'page' => $page, ); } public static function distinct_types() { global $wpdb; $table = Argus_DB::table( 'events' ); return $wpdb->get_col( "SELECT DISTINCT event_type FROM {$table} ORDER BY event_type ASC" ); // phpcs:ignore } const RETENTION_DAYS_BY_SEVERITY = array( 'info' => 30, 'low' => 90, 'medium' => 365, 'high' => 365, 'critical' => 365, ); public static function prune() { global $wpdb; $table = Argus_DB::table( 'events' ); $retention = apply_filters( 'argus_wpd_event_retention_days', self::RETENTION_DAYS_BY_SEVERITY ); $deleted = 0; foreach ( $retention as $severity => $days ) { $cutoff = gmdate( 'Y-m-d H:i:s', time() - ( (int) $days * DAY_IN_SECONDS ) ); $deleted += (int) $wpdb->query( $wpdb->prepare( "DELETE FROM {$table} WHERE severity = %s AND created_at < %s", $severity, $cutoff ) // phpcs:ignore ); } $max_rows = (int) apply_filters( 'argus_wpd_max_event_rows', self::DEFAULT_MAX_ROWS ); $total = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$table}" ); // phpcs:ignore if ( $total <= $max_rows ) { return $deleted; } $overflow = $total - $max_rows; $deleted += (int) $wpdb->query( $wpdb->prepare( "DELETE FROM {$table} ORDER BY created_at ASC LIMIT %d", // phpcs:ignore $overflow ) ); return $deleted; } }