120 ) { $subject = trim( preg_replace( '/\s+/', ' ', substr( $subject, 0, 120 ) ) ) . '…'; } $key = md5( $source . '|' . $subject ); if ( isset( self::$pending[ $key ] ) ) { return; } self::$pending[ $key ] = [ 'subject' => $subject, 'category' => (string) $category, 'source' => $source, 'url' => self::current_url(), 'seen' => time(), ]; if ( 1 === count( self::$pending ) ) { add_action( 'shutdown', [ __CLASS__, 'flush' ], 99 ); } } public static function flush() { if ( empty( self::$pending ) ) { return; } $stored = get_transient( self::KEY ); $stored = is_array( $stored ) ? $stored : []; $stored = array_merge( $stored, self::$pending ); // Newest wins when the report is full — an old entry has already been // read, and the entries that matter are from the page just loaded. if ( count( $stored ) > self::LIMIT ) { uasort( $stored, function ( $a, $b ) { return $b['seen'] <=> $a['seen']; } ); $stored = array_slice( $stored, 0, self::LIMIT, true ); } set_transient( self::KEY, $stored, DAY_IN_SECONDS ); self::$pending = []; } /** * @return array Entries, newest first. */ public static function get() { $stored = get_transient( self::KEY ); $stored = is_array( $stored ) ? $stored : []; uasort( $stored, function ( $a, $b ) { return $b['seen'] <=> $a['seen']; } ); return array_values( $stored ); } public static function clear() { delete_transient( self::KEY ); } private static function current_url() { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash $path = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; return $path ? substr( $path, 0, 190 ) : ''; } }