diff --git a/plugins/importexport/onix30/Onix30ExportPlugin.php b/plugins/importexport/onix30/Onix30ExportPlugin.php index 8f70a513cb5..591c29b40ce 100644 --- a/plugins/importexport/onix30/Onix30ExportPlugin.php +++ b/plugins/importexport/onix30/Onix30ExportPlugin.php @@ -3,8 +3,8 @@ /** * @file plugins/importexport/onix30/Onix30ExportPlugin.php * - * Copyright (c) 2014-2021 Simon Fraser University - * Copyright (c) 2003-2021 John Willinsky + * Copyright (c) 2014-2025 Simon Fraser University + * Copyright (c) 2003-2025 John Willinsky * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING. * * @class Onix30ExportPlugin @@ -20,8 +20,12 @@ use APP\core\Request; use APP\template\TemplateManager; use BadMethodCallException; +use Illuminate\Database\Query\JoinClause; +use Illuminate\Support\Collection; +use Illuminate\Support\Facades\DB; use PKP\core\PKPApplication; use PKP\plugins\ImportExportPlugin; +use PKP\plugins\PluginRegistry; use stdClass; class Onix30ExportPlugin extends ImportExportPlugin @@ -198,4 +202,29 @@ public function getAppSpecificDeployment($context, $user) { return new Onix30ExportDeployment($context, $user); } + + /** + * Helper function to retrieve funding data when available. + */ + public function getFundingData(int $contextId, int $submissionId): Collection|false + { + if (!PluginRegistry::getPlugin('generic', 'FundingPlugin')) { + return false; + } + + $fundingData = DB::table('funders AS f') + ->select('f.funder_id', 'f.funder_identification', 'fs.setting_value as funder_name', 'fa.funder_award_id', 'fa.funder_award_number') + ->where('submission_id', $submissionId) + ->where('context_id', $contextId) + ->leftJoin( + 'funder_settings AS fs', + fn (JoinClause $j) => $j->on('f.funder_id', '=', 'fs.funder_id') + ->where('fs.setting_name', '=', 'funderName') + ) + ->leftjoin('funder_awards AS fa', 'f.funder_id', '=', 'fa.funder_id') + ->get() + ->groupBy('funder_id'); + + return $fundingData ?? false; + } } diff --git a/plugins/importexport/onix30/filter/MonographONIX30XmlFilter.php b/plugins/importexport/onix30/filter/MonographONIX30XmlFilter.php index f739cff0cfa..c9135a2ef49 100644 --- a/plugins/importexport/onix30/filter/MonographONIX30XmlFilter.php +++ b/plugins/importexport/onix30/filter/MonographONIX30XmlFilter.php @@ -32,11 +32,11 @@ use PKP\filter\FilterGroup; use PKP\i18n\LocaleConversion; use PKP\plugins\importexport\native\filter\NativeExportFilter; +use PKP\plugins\PluginRegistry; use PKP\userGroup\UserGroup; class MonographONIX30XmlFilter extends NativeExportFilter { - /** */ public DOMDocument $doc; /** @@ -154,7 +154,6 @@ public function createHeaderNode($doc) /** * Create and return a node representing the ONIX Product metadata for this submission. * - * * @throws DOMException * @throws Exception */ @@ -164,6 +163,9 @@ public function createProductNode(DOMDocument $doc, Submission $submission, Publ $deployment = $this->getDeployment(); $context = $deployment->getContext(); + PluginRegistry::loadCategory('importexport'); + $plugin = PluginRegistry::getPlugin('importexport', 'Onix30ExportPlugin'); + /** @var ONIXCodelistItemDAO $onixCodelistItemDao */ $onixCodelistItemDao = DAORegistry::getDAO('ONIXCodelistItemDAO'); @@ -586,6 +588,32 @@ public function createProductNode(DOMDocument $doc, Submission $submission, Publ $websiteNode->appendChild($this->buildTextNode($doc, 'WebsiteLink', $request->url($context->getPath(), 'catalog', 'book', [$submissionBestId]))); + /* --- Funders and awards --- */ + $fundingData = $plugin->getFundingData($context->getId(), $submissionBestId); + if (!$fundingData->isEmpty()) { + foreach ($fundingData as $funder) { + $publisherNode = $doc->createElementNS($deployment->getNamespace(), 'Publisher'); + $publisherNode->appendChild($this->buildTextNode($doc, 'PublishingRole', '16')); // 16 -> Funding body + $publisherIdentifierNode = $doc->createElementNS($deployment->getNamespace(), 'PublisherIdentifier'); + $publisherIdentifierNode->appendChild($this->buildTextNode($doc, 'PublisherIDType', '32')); // 32 -> FundRef DOI + $publisherIdentifierNode->appendChild($this->buildTextNode($doc, 'IDValue', $funder[0]->funder_identification)); + $publisherNode->appendChild($publisherIdentifierNode); + $publisherNode->appendChild($this->buildTextNode($doc, 'PublisherName', $funder[0]->funder_name)); + foreach ($funder as $awards) { + if (isset($awards->funder_award_number)) { + $fundingNode = $doc->createElementNS($deployment->getNamespace(), 'Funding'); + $fundingIdentifierNode = $doc->createElementNS($deployment->getNamespace(), 'FundingIdentifier'); + $fundingIdentifierNode->appendChild($this->buildTextNode($doc, 'FundingIDType', '01')); // 01 -> proprietary + $fundingIdentifierNode->appendChild($this->buildTextNode($doc, 'IDTypeName', 'Award/Grant Number')); + $fundingIdentifierNode->appendChild($this->buildTextNode($doc, 'IDValue', $awards->funder_award_number)); + $fundingNode->appendChild($fundingIdentifierNode); + $publisherNode->appendChild($fundingNode); + } + } + $publishingDetailNode->appendChild($publisherNode); + } + } + /* --- Publishing Dates --- */ $publicationDates = $publicationFormat->getPublicationDates(); @@ -807,7 +835,6 @@ public function createProductNode(DOMDocument $doc, Submission $submission, Publ $supplierWebsiteNode->appendChild($this->buildTextNode($doc, 'WebsiteRole', '29')); // 29 -> Web page for full content $supplierWebsiteNode->appendChild($this->buildTextNode($doc, 'WebsiteLink', $request->url($context->getPath(), 'catalog', 'book', [$submissionBestId]))); } else { // No suppliers specified, use the Press settings instead. - $supplierNode->appendChild($this->buildTextNode($doc, 'SupplierRole', '09')); // Publisher supplying to end customers $supplierNode->appendChild($this->buildTextNode($doc, 'SupplierName', $context->getData('publisher')));