dashboards = $dashboards; $this->refresher = $refresher; } /** * Hooks the handlers. */ public function register(): void { add_action( 'admin_post_pulsecast_refresh', array( $this, 'handle_refresh' ) ); add_action( 'admin_post_pulsecast_reset_link', array( $this, 'handle_reset_link' ) ); } /** * Handles the "Refresh feeds now" link. */ public function handle_refresh(): void { $id = $this->authorize( 'pulsecast_refresh_' ); Dashboard_Screen::notify( ...$this->refresh_dashboard( $id ) ); $this->back( $id ); } /** * Handles the "Create a new link" link. */ public function handle_reset_link(): void { $id = $this->authorize( 'pulsecast_reset_link_' ); Dashboard_Screen::notify( ...$this->reset_link( $id ) ); $this->back( $id ); } /** * Refreshes a dashboard's feeds now and describes the outcome. * * @param int $id Dashboard ID. * @return array{0:string,1:string} Notice type and message. */ public function refresh_dashboard( int $id ): array { $dashboard = $this->dashboards->find( $id ); if ( null === $dashboard || array() === $dashboard->feeds ) { return array( 'warning', __( 'This dashboard has no feeds to refresh.', 'feedmarquee' ) ); } $results = $this->refresher->refresh_urls( array_column( $dashboard->feeds, 'url' ) ); if ( null === $results ) { return array( 'warning', __( 'A refresh is already running. Try again in a moment.', 'feedmarquee' ) ); } $failed = array_filter( $results, static fn( string $error ): bool => '' !== $error ); if ( array() === $failed ) { /* translators: %d: number of feeds. */ return array( 'success', sprintf( _n( 'Refreshed %d feed.', 'Refreshed %d feeds.', count( $results ), 'feedmarquee' ), count( $results ) ) ); } $message = ''; foreach ( $failed as $url => $error ) { /* translators: 1: feed address, 2: explanation. */ $message .= sprintf( __( '%1$s: %2$s', 'feedmarquee' ), $url, Messages::feed_error( $error ) ) . ' '; } return array( 'error', trim( $message ) ); } /** * Replaces a dashboard's public key and describes the outcome. * * @param int $id Dashboard ID. * @return array{0:string,1:string} Notice type and message. */ public function reset_link( int $id ): array { if ( null === $this->dashboards->regenerate_key( $id ) ) { return array( 'error', __( 'The link could not be changed.', 'feedmarquee' ) ); } return array( 'success', __( 'A new display link was created. The old link no longer works.', 'feedmarquee' ) ); } /** * Checks the nonce and capability, and returns the dashboard ID. * * @param string $nonce_prefix Nonce action prefix; the dashboard ID is appended. */ private function authorize( string $nonce_prefix ): int { $id = isset( $_GET['dashboard'] ) ? absint( $_GET['dashboard'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Verified on the next line. check_admin_referer( $nonce_prefix . $id ); if ( 0 === $id || ! current_user_can( 'edit_post', $id ) ) { wp_die( esc_html__( 'You are not allowed to do that.', 'feedmarquee' ), '', array( 'response' => 403 ) ); } return $id; } /** * Returns to the dashboard's edit screen. * * @param int $id Dashboard ID. */ private function back( int $id ): void { wp_safe_redirect( (string) get_edit_post_link( $id, 'url' ) ); exit; } }