Add CSV export to RA Management search results#521
Open
kayjoosten wants to merge 2 commits into
Open
Conversation
If applied, this commit will let RAA users export the current RA Management search results as a CSV file, and rename the blank Role filter option to a descriptive label. Why is this change needed? Prior to this change, the RA Management page had no export option, unlike the existing Tokens (Second Factors) page. Institution admins had no way to get an offline copy of their RA(A) listing. The Role filter dropdown also had an unlabeled blank option between "RA" and "RAA", which was unclear to users. How does it address the issue? This change adds an Export button next to Search, following the same button-group pattern used on the Tokens page. Since RA listings have no unpaginated export endpoint in the middleware client (unlike Second Factors), RaListingService::export() pages through the existing paginated search results and aggregates them before handing off to the new RaListingExport service, which streams the results as CSV via fputcsv. The exported filename is derived from the active role filter: ra_export_YYYY-MM-DD, raa_export_YYYY-MM-DD, or ra-raa-export_YYYY-MM-DD when no role filter is set. The Role filter's blank option now shows a "RA/RAA" placeholder instead of being empty. The export action keeps its own ROLE_RAA authorization check independent of the search action, so it stays protected even if the search page's access level changes later. Institution-scoping and existing authorization boundaries are unchanged. Links / references: #498
If applied, this commit will make the CI QA pipeline pass for the RA Management CSV export feature. Why is this change needed? Prior to this change, CI's phpstan step failed on the new export code: an untyped/uninitialized $actorId property, a stale baseline entry for a booleanAnd.leftAlwaysTrue error that the buildQuery() refactor already fixed by making its $roleAtInstitution parameter nullable, unchecked resource|false returns from fopen() in RaListingExport, a missing iterable value type on getColumnNames(), and a new getClickedButton() call on FormInterface that needed the same baseline treatment already used for the equivalent Second Factors export form. How does it address the issue? This change adds a `@var string` docblock to ExportRaListingCommand::$actorId (matching the existing ExportRaSecondFactorsCommand convention), removes the now-stale booleanAnd.leftAlwaysTrue baseline entry for RaListingService, adds a baseline entry for RaManagementController's getClickedButton() call mirroring SecondFactorController's, guards the fopen() result in RaListingExport before using it, and adds a `@return string[]` docblock to getColumnNames().
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
RaListingService::export()pages through the existing paginated middleware search (no unpaginated export endpoint exists for RA listings) and streams the aggregated results as CSV via a newRaListingExportservice.ra_export_YYYY-MM-DD,raa_export_YYYY-MM-DD, orra-raa-export_YYYY-MM-DDwhen unfiltered.export()keeps its ownROLE_RAAauthorization check, independent ofmanage().Test plan
php -lon all changed/new PHP filesservices.ymlExportRaListingCommand::fromSearchCommand,RaListingService::export,RaListingExport::export(not yet added)Closes #498