, bytes: int, user: int, users: int[], discarded_by: int, source: string, started: int, finished: int, status: string}> */ public static function all(): array { $stored = get_option( self::OPTION, array() ); $out = array(); foreach ( is_array( $stored ) ? $stored : array() as $entry ) { if ( ! is_array( $entry ) || ! is_string( $entry['check'] ?? null ) ) { continue; } $notes = array(); foreach ( (array) ( $entry['notes'] ?? array() ) as $key => $value ) { if ( is_string( $key ) && is_numeric( $value ) ) { $notes[ $key ] = (int) $value; } } $out[] = array( 'check' => $entry['check'], 'label' => is_string( $entry['label'] ?? null ) ? $entry['label'] : $entry['check'], 'risk' => is_string( $entry['risk'] ?? null ) ? $entry['risk'] : '', 'threshold' => isset( $entry['threshold'] ) && is_numeric( $entry['threshold'] ) ? (int) $entry['threshold'] : null, 'deleted' => (int) ( $entry['deleted'] ?? 0 ), 'skipped' => (int) ( $entry['skipped'] ?? 0 ), 'notes' => $notes, 'bytes' => (int) ( $entry['bytes'] ?? 0 ), 'user' => (int) ( $entry['user'] ?? 0 ), 'users' => array_values( array_unique( array_map( 'intval', array_filter( (array) ( $entry['users'] ?? array() ), 'is_numeric' ) ) ) ), 'discarded_by' => (int) ( $entry['discarded_by'] ?? 0 ), 'source' => in_array( $entry['source'] ?? '', self::SOURCES, true ) ? (string) $entry['source'] : 'manual', 'started' => (int) ( $entry['started'] ?? 0 ), 'finished' => (int) ( $entry['finished'] ?? 0 ), 'status' => in_array( $entry['status'] ?? '', self::STATUSES, true ) ? (string) $entry['status'] : 'done', ); } return array_slice( $out, 0, self::MAX ); } /** * Add an entry (keeps the newest MAX). * * @since 1.0.0 * @param array $entry Entry (see all()). * @return void */ public static function add( array $entry ): void { $list = self::all(); array_unshift( $list, $entry ); $list = array_slice( $list, 0, self::MAX ); update_option( self::OPTION, $list, false ); // Adds it (not autoloaded) when missing. } }