settings = $settings; } /** * Write a log entry. * * @param string $level Log level. * @param string $message Message. * @param array $context Context. * @return void */ public function log( $level, $message, $context = array() ) { if ( ! $this->settings->get( 'logging.enabled', 1 ) ) { return; } $entries = get_option( self::OPTION, array() ); $entries = is_array( $entries ) ? $entries : array(); $entries[] = array( 'time' => current_time( 'mysql' ), 'level' => sanitize_key( $level ), 'message' => sanitize_text_field( $message ), 'context' => $this->sanitize_context( $context ), ); if ( count( $entries ) > 300 ) { $entries = array_slice( $entries, -300 ); } update_option( self::OPTION, $entries, false ); } /** * Read recent logs. * * @param int $limit Max entries. * @return array */ public function recent( $limit = 100 ) { $entries = get_option( self::OPTION, array() ); $entries = is_array( $entries ) ? array_reverse( $entries ) : array(); return array_slice( $entries, 0, max( 1, absint( $limit ) ) ); } /** * Remove old log files. * * @return int Removed files. */ public function prune() { $retention = max( 1, absint( $this->settings->get( 'logging.retention_days', 14 ) ) ); $cutoff = time() - ( DAY_IN_SECONDS * $retention ); $entries = get_option( self::OPTION, array() ); $entries = is_array( $entries ) ? $entries : array(); $kept = array(); foreach ( $entries as $entry ) { $time = isset( $entry['time'] ) ? strtotime( $entry['time'] ) : time(); if ( $time >= $cutoff ) { $kept[] = $entry; } } update_option( self::OPTION, $kept, false ); return count( $entries ) - count( $kept ); } /** * Sanitize context values for database storage. * * @param mixed $context Context. * @return mixed */ private function sanitize_context( $context ) { if ( is_array( $context ) ) { return array_map( array( $this, 'sanitize_context' ), $context ); } if ( is_scalar( $context ) || null === $context ) { return sanitize_text_field( (string) $context ); } return ''; } }