Skip to content

Add admin CSV export for citation data (per-journal and all-journals) - #3

Draft
alexdryden with Copilot wants to merge 4 commits into
mainfrom
copilot/add-citation-data-report
Draft

Add admin CSV export for citation data (per-journal and all-journals)#3
alexdryden with Copilot wants to merge 4 commits into
mainfrom
copilot/add-citation-data-report

Conversation

Copilot AI commented Aug 24, 2026

Copy link
Copy Markdown

Admins have no way to extract citation data in bulk — citations are only surfaced per-article in the frontend widget. This adds a CSV export endpoint usable by journal managers and site admins.

Endpoint

GET /index.php/<journal>/citations/export

  • Journal manager / site admin → exports all published articles with DOIs for the current journal
  • Site admin only → append ?scope=all to export every enabled journal in one file

Export always fetches full citation lists (ignores the showList display setting) from all configured providers (Crossref, Scopus, EuropePMC).

CSV columns

Journal · Article DOI · Article Title · Article Year · Citation Source · Citation DOI · Citation Title · Citation Authors · Citation Journal · Citation Year · Citation Volume · Citation Issue · Citation Pages · Citation Type

UTF-8 with BOM for Excel compatibility.

Plugin UI

Two new action buttons in the Plugin Management page:

  • Export Citations (CSV) — managers + site admins
  • Export All Journals (CSV) — site admins only

Implementation notes

  • export() added directly to CitationsHandler (same page, new op — no routing changes needed)
  • Filename sanitized before injection into Content-Disposition header
  • $settings['provider'] guarded with ?? '' to handle partially configured plugins
  • Single getAllContextMap() call fetches all context names to avoid N+1 queries on the all-journals path

Co-authored-by: alexdryden <47127862+alexdryden@users.noreply.github.com>
Copilot AI changed the title Add CSV export feature for citation data Add admin CSV export for citation data (per-journal and all-journals) Aug 24, 2026
Copilot AI requested a review from alexdryden August 24, 2026 18:38
@alexdryden

Copy link
Copy Markdown

@copilot it looks like you pulled main immediately before the port to feature was implemented. Review all of the changes that went into #2 including reviewing any interface changes to 3.5. Make sure that you have implemented in a way that is compatible with 3.5 and fix the conflict with the new state of main.

Co-authored-by: alexdryden <47127862+alexdryden@users.noreply.github.com>

Copilot AI commented Aug 24, 2026

Copy link
Copy Markdown
Author

@copilot it looks like you pulled main immediately before the port to feature was implemented. Review all of the changes that went into #2 including reviewing any interface changes to 3.5. Make sure t...

Done. I merged main (which contains PR #2's OJS 3.5 port) into this branch and resolved the conflict in CitationsPlugin.php. The three OJS 3.5 breaking changes from PR #2 are now incorporated alongside the export feature:

  • setPageHandler: uses $params[3] = new CitationsHandler() instead of define('HANDLER_CLASS', ...)
  • getActions: removed the legacy import('lib.pkp.classes.linkAction.request.AjaxModal') call
  • CitationsSettingsForm: uses PKP\notification\Notification::NOTIFICATION_TYPE_SUCCESS instead of PKPNotification::

Merge commit: 81d66e2

@alexdryden

Copy link
Copy Markdown

@copilot Getting https://iopn.library.illinois.edu/journals/uijm/$$$call$$$/ci/export?scope=all and a 404 on export all and similar on export for journal when using the link in the UI. It might be relevant that we are rewriting urls in an .htaccess file:

<IfModule mod_rewrite.c>
   RewriteEngine on
   RewriteBase /journals/
   RewriteCond %{REQUEST_FILENAME} !-d
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteRule ^(.*)$ index.php/$1 [QSA,L]
</IfModule>
in an attempt (I believe) to get a cleaner looking url

Directly calling iopn.library.illinois.edu/journals/jams/citations/export produces a csv, but iopn.library.illinois.edu/journals/jams/citations/export?scope=all produces a 500 error with :

  thrown in /var/www/ojs/plugins/generic/citations/classes/CitationsHandler.php on line 247
[24-Aug-2026 14:47:46 America/Chicago] PHP Fatal error:  Uncaught Error: Call to undefined method APP\core\Application::getContextService() in /var/www/ojs/plugins/generic/citations/classes/CitationsHandler.php:247
Stack trace:
#0 /var/www/ojs/plugins/generic/citations/classes/CitationsHandler.php(91): APP\plugins\generic\citations\classes\CitationsHandler->getAllContextMap()
#1 [internal function]: APP\plugins\generic\citations\classes\CitationsHandler->export()
#2 /var/www/ojs/lib/pkp/classes/core/PKPRouter.php(327): call_user_func()
#3 /var/www/ojs/lib/pkp/classes/core/PKPPageRouter.php(249): PKP\core\PKPRouter->_authorizeInitializeAndCallRequest()
#4 /var/www/ojs/lib/pkp/classes/core/Dispatcher.php(157): PKP\core\PKPPageRouter->route()
#5 /var/www/ojs/lib/pkp/classes/core/PKPApplication.php(429): PKP\core\Dispatcher->dispatch()
#6 /var/www/ojs/index.php(21): PKP\core\PKPApplication->execute()
#7 {main}
  thrown in /var/www/ojs/plugins/generic/citations/classes/CitationsHandler.php on line 247

…or page URLs

Co-authored-by: alexdryden <47127862+alexdryden@users.noreply.github.com>

Copilot AI commented Aug 24, 2026

Copy link
Copy Markdown
Author

@copilot Getting https://iopn.library.illinois.edu/journals/uijm/$$$call$$$/ci/export?scope=all and a 404 on export all and similar on export for journal when using the link in the UI. It might be r...

Fixed in the latest commit. Two issues were addressed:

  1. $$$call$$$ URLsgetActions() runs inside a component handler context, so $router->url() was generating component-style URLs. Replaced with $request->getDispatcher()->url($request, Application::ROUTE_PAGE, ...) which always generates proper page-handler paths regardless of calling context.

  2. 500 on ?scope=allApplication::getContextService() doesn't exist in OJS 3.5. Replaced getAllContextMap() with Repo::journal()->getCollector()->filterByEnabled(true)->getMany(), which is the correct 3.5 API.

@alexdryden

Copy link
Copy Markdown

@copilot do a complete review to make sure all work here is compatible with 3.5 and make sure that any fix is likewise. Getting new error on the get all journals call:

[24-Aug-2026 14:55:40 America/Chicago] PHP Fatal error:  Uncaught Error: Call to undefined method APP\facades\Repo::journal() in /var/www/ojs/plugins/generic/citations/classes/CitationsHandler.php:247
Stack trace:
#0 /var/www/ojs/plugins/generic/citations/classes/CitationsHandler.php(90): APP\plugins\generic\citations\classes\CitationsHandler->getAllContextMap()
#1 [internal function]: APP\plugins\generic\citations\classes\CitationsHandler->export()
#2 /var/www/ojs/lib/pkp/classes/core/PKPRouter.php(327): call_user_func()
#3 /var/www/ojs/lib/pkp/classes/core/PKPPageRouter.php(249): PKP\core\PKPRouter->_authorizeInitializeAndCallRequest()
#4 /var/www/ojs/lib/pkp/classes/core/Dispatcher.php(157): PKP\core\PKPPageRouter->route()
#5 /var/www/ojs/lib/pkp/classes/core/PKPApplication.php(429): PKP\core\Dispatcher->dispatch()
#6 /var/www/ojs/index.php(21): PKP\core\PKPApplication->execute()
#7 {main}
  thrown in /var/www/ojs/plugins/generic/citations/classes/CitationsHandler.php on line 247

….5 compatibility

Co-authored-by: alexdryden <47127862+alexdryden@users.noreply.github.com>

Copilot AI commented Aug 24, 2026

Copy link
Copy Markdown
Author

@copilot do a complete review to make sure all work here is compatible with 3.5 and make sure that any fix is likewise. Getting new error on the get all journals call:

[24-Aug-2026 14:55:40 Amer...

Repo::journal() doesn't exist in OJS 3.5 either — only Repo::submission() is available. Fixed by replacing with DAORegistry::getDAO('JournalDAO')->getAll(true), which iterates over enabled journals via the DAO layer that does exist in 3.5.

I also reviewed the rest of the handler: Repo::submission()->getCollector(), PKPApplication::SITE_CONTEXT_ID, Role::ROLE_ID_*, and PKP\notification\Notification::NOTIFICATION_TYPE_SUCCESS in the settings form are all confirmed valid 3.5 APIs.

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