progress_of( $state, $settings ); $finished_at = $this->iso_time->from_timestamp( $state->finished_at ); return array( 'state' => $state->run_state->value, 'phase' => $state->phase?->value, 'done' => $scan_count->done, 'total' => $scan_count->total, 'eta_seconds' => $this->eta_seconds( $state, $scan_count, $now ), 'parallel' => self::PARALLEL_CHECKS, 'finished_at' => $finished_at, 'posts_count' => $state->posts_count, ); } private function progress_of( ScanState $state, Settings $settings ): ScanCount { if ( ScanRunState::Idle === $state->run_state ) { return new ScanCount( 0, 0 ); } if ( ScanPhase::Reading === $state->phase ) { return new ScanCount( $state->posts_read, $this->checked_posts->total( $settings ) ); } return new ScanCount( $this->scan_links->settled_since( (int) $state->started_at ), $this->scan_links->listed_total() ); } private function eta_seconds( ScanState $state, ScanCount $scan_count, int $now ): int|null { $is_running = ScanRunState::Running === $state->run_state; if ( ! $is_running || 0 === $scan_count->done ) { return null; } $remaining = max( 0, $scan_count->total - $scan_count->done ); $spent_seconds = max( 0, $now - (int) $state->started_at ); $seconds = $remaining * $spent_seconds / $scan_count->done; return (int) ceil( $seconds ); } }