$data ) { if ( ! in_array( $file, $active_plugins, true ) ) { continue; } if ( isset( $update_data->response[ $file ] ) ) { $outdated[] = $data['Name']; } } if ( empty( $outdated ) ) { return array(); } return array( $this->make_result( array( 'id' => 'plugins_outdated', 'title' => sprintf( /* translators: %d: Number of active plugins needing updates. */ _n( '%d plugin needs updating', '%d plugins need updating', count( $outdated ), 'aipatch-security-scanner' ), count( $outdated ) ), 'description' => sprintf( /* translators: %s: Comma-separated list of outdated plugin names. */ __( 'Outdated plugins: %s', 'aipatch-security-scanner' ), implode( ', ', array_map( 'esc_html', array_slice( $outdated, 0, 10 ) ) ) ), 'severity' => count( $outdated ) > 3 ? 'high' : 'medium', 'confidence' => 'high', 'category' => 'plugins', 'why_it_matters' => __( 'Outdated plugins are one of the most common entry points for attackers. Updates often include security patches.', 'aipatch-security-scanner' ), 'recommendation' => __( 'Update all plugins from Dashboard → Updates, or enable auto-updates for trusted plugins.', 'aipatch-security-scanner' ), 'dismissible' => false, 'evidence' => sprintf( 'Outdated: %s', implode( ', ', array_slice( $outdated, 0, 10 ) ) ), 'meta' => array( 'outdated_count' => count( $outdated ), 'names' => $outdated ), ) ), ); } }