Skip to content

Refactor GVI/GVIRecord controllers to action handlers - #10

Draft
stweil with Copilot wants to merge 2 commits into
copilot/gvi-refactor-gvi-controllerfrom
copilot/refactor-gvi-controllers-to-action-classes
Draft

stweil with Copilot wants to merge 2 commits into
copilot/gvi-refactor-gvi-controllerfrom
copilot/refactor-gvi-controllers-to-action-classes

Conversation

Copilot AI commented May 31, 2026

Copy link
Copy Markdown

This aligns GVI and GVIRecord with the Authority/AuthorityRecord action-based dispatch pattern from d1f18a9, replacing legacy MVC controllers with VuFind\Action\... classes while preserving route behavior. The refactor keeps existing GVI static/record routes intact and ports the legacy tag-search special case into the new action flow.

  • GVIRecord migrated to action

    • Added VuFind\Action\GVIRecord\HomeAction (module/VuFind/src/VuFind/Action/GVIRecord/HomeAction.php)
    • Uses AbstractRecordAction
    • Sets GVI-specific defaults in init():
      • $this->sourceId = 'GVI'
      • $this->fallbackDefaultTab = 'Description'
    • action() delegates tab rendering via showTab(...)
  • GVI search/results action base introduced

    • Added VuFind\Action\GVI\AbstractGVISearchAndResultsAction
    • Extends AbstractSearchAndResultsAction
    • Sets $this->searchClassId = 'GVI' in init()
  • GVI Home/Results actions added

    • Added VuFind\Action\GVI\HomeAction with renderHomePage()
    • Added VuFind\Action\GVI\ResultsAction with migrated tag behavior:
      • if type=tag, inject fuzzy=true and forward to Tag/Home
      • otherwise run standard renderSearchResults()
  • Action resolution/config updates

    • Updated VuFind\Action\PluginManager category aliases:
      • added 'Gvirecord' => 'GVIRecord' (requested)
      • added 'Gvi' => 'GVI' to ensure uppercase acronym category resolves correctly
    • Updated module/VuFind/config/module.config.php:
      • removed GVIController / GVIrecordController factories
      • removed controller aliases GVI, gvi, GVIRecord, gvirecord
      • retained gvirecord in $recordRoutes
      • retained GVI/Advanced, GVI/FacetList, GVI/Home, GVI/Results in $staticRoutes
  • Legacy controllers removed

    • Deleted:
      • module/VuFind/src/VuFind/Controller/GVIController.php
      • module/VuFind/src/VuFind/Controller/GVIrecordController.php
// module/VuFind/src/VuFind/Action/GVI/ResultsAction.php
if ($this->getQueryParam('type') == 'tag') {
    $query = $request->getQueryParams();
    $query['fuzzy'] = 'true';
    return $this->getHelper(ForwardHelper::class)->forwardTo(
        $request->withQueryParams($query),
        $response,
        'Tag/Home'
    );
}
return $this->renderSearchResults();
Original prompt

Refactor GVI controllers to action classes

Following the pattern established in commit d1f18a9d46c4849d44f182fdd11a4bcc54b65a72 (which refactored Authority and AuthorityRecord controllers to actions), apply the same refactoring to the GVI controllers.

Changes required

1. Create module/VuFind/src/VuFind/Action/GVIRecord/HomeAction.php

This replaces module/VuFind/src/VuFind/Controller/GVIrecordController.php.

  • Namespace: VuFind\Action\GVIRecord
  • Class: HomeAction extends AbstractRecordAction (use VuFind\Action\Record\AbstractRecordAction)
  • Implement action(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface that returns $this->showTab($this->getRouteParam('tab') ?? $this->getDefaultTab())
  • Override protected function init(): void to set $this->sourceId = 'GVI' and $this->fallbackDefaultTab = 'Description', then call parent::init()

Model exactly on module/VuFind/src/VuFind/Action/AuthorityRecord/HomeAction.php from that commit.

2. Create module/VuFind/src/VuFind/Action/GVI/AbstractGVISearchAndResultsAction.php

  • Namespace: VuFind\Action\GVI
  • Abstract class: AbstractGVISearchAndResultsAction extends AbstractSearchAndResultsAction (use VuFind\Action\Search\AbstractSearchAndResultsAction)
  • Override protected function init(): void to set $this->searchClassId = 'GVI', then call parent::init()

Model on module/VuFind/src/VuFind/Action/Authority/AbstractAuthoritySearchAndResultsAction.php from that commit.

3. Create module/VuFind/src/VuFind/Action/GVI/HomeAction.php

  • Namespace: VuFind\Action\GVI
  • Class: HomeAction extends AbstractGVISearchAndResultsAction
  • Implement action(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface that returns $this->renderHomePage()

Model on module/VuFind/src/VuFind/Action/Authority/HomeAction.php from that commit (but without the legacy ID redirect logic, since there is none in GVIController).

4. Create module/VuFind/src/VuFind/Action/GVI/ResultsAction.php

  • Namespace: VuFind\Action\GVI
  • Class: ResultsAction extends AbstractGVISearchAndResultsAction
  • Implement action(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
  • Port the tag-redirect logic from the old GVIController::resultsAction():
    • If $this->getQueryParam('type') == 'tag', set fuzzy=true on the query and forward to tag/home action
    • Otherwise, return $this->renderSearchResults()

Look at how AbstractSearchAndResultsAction handles forwarding/redirecting in the existing codebase (e.g. look at Authority/HomeAction.php which uses RedirectHelper) to implement the tag redirect. If forwarding to another action is available, use that; otherwise redirect.

Also look at module/VuFind/src/VuFind/Action/GVI/ directory equivalents like Search2 or Author actions for how ResultsAction is structured.

5. Update module/VuFind/src/VuFind/Action/PluginManager.php

Add 'Gvirecord' => 'GVIRecord' to the $categoryAliases array, following the same pattern as 'Authorityrecord' => 'AuthorityRecord'. Keep entries alphabetically sorted.

6. Update module/VuFind/config/module.config.php

  • Remove 'VuFind\Controller\GVIController' => 'VuFind\Controller\AbstractBaseFactory' from the controllers > factories section
  • Remove 'VuFind\Controller\GVIrecordController' => 'VuFind\Controller\AbstractBaseFactory' from the controllers > factories section
  • Remove the four alias entries for GVI, gvi, GVIRecord, gvirecord from the controllers > aliases section
  • Keep 'gvirecord' => 'GVIRecord' in $recordRoutes (this is a route, not a controller alias — it should remain)
  • Keep the GVI/Advanced, GVI/FacetList, GVI/Home, GVI/Results entries in $staticRoutes (these are now handled by the action system)

7. Delete module/VuFind/src/VuFind/Controller/GVIrecordController.php

Delete this file entirely (it is replaced by Action/GVIRecord/HomeAction.php). To delete it, create the file with empty content is not sufficient — instead, you need to remove it. Since GitHub's API doesn't support deletion directly via file creation, you should verify whether the coding agent can delete files; if not, replace the file content with a note or leave a comment in the PR.

Actually: the coding agent CAN delete files. Please delete both old controller files.

8. Delete module/VuFind/src/VuFind/Controller/GVIController.php

Delete this file entirely (it is replaced by the Action/GVI/ actions).

Reference files to study

  • module/VuFind/src/VuFind/Action/AuthorityRecord/HomeAction.php — template for GVIRecord/HomeAction.php
  • module/VuFind/src/VuFind/Action/Authority/AbstractAuthoritySearchAndResultsAction.php — template for GVI abstract base
  • `module/VuFind/src/VuFind/Action/Authority/HomeAction.php...

This pull request was created from Copilot chat.

Copilot AI changed the title [WIP] Refactor GVI controllers to action classes Refactor GVI/GVIRecord controllers to action handlers May 31, 2026
Copilot finished work on behalf of stweil May 31, 2026 11:52
Copilot AI requested a review from stweil May 31, 2026 11:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants