Skip to content

Commit

Permalink
Merge pull request #22 from lepidus/main
Browse files Browse the repository at this point in the history
Feature/added publication format ISBN validation (OMP 3.4.0)
  • Loading branch information
thiagolepidus authored Jan 18, 2025
2 parents c810f6b + b154579 commit c00b7be
Show file tree
Hide file tree
Showing 16 changed files with 363 additions and 63 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/generate-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ jobs:
mkdir $PLUGIN_NAME
shopt -s extglob
cp -r !($PLUGIN_NAME|.git*|.|..|tests) $PLUGIN_NAME
wget -O composer.phar https://getcomposer.org/composer-stable.phar
php composer.phar install -d ${PLUGIN_NAME}
tar -zcvf $PLUGIN_NAME.tar.gz $PLUGIN_NAME
shell: bash
- name: Create the release
Expand All @@ -47,7 +49,7 @@ jobs:
draft: false
prerelease: false
- name: Upload the package as release asset
id: upload-release-asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
vendor
4 changes: 4 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ include:
file:
- 'templates/groups/pkp_plugin.yml'
- 'templates/groups/omp/unit_tests.yml'

.unit_test_template:
before_script:
- composer install
2 changes: 1 addition & 1 deletion ThothPlugin.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function register($category, $path, $mainContextId = null)
$thothRegister = new ThothRegister($this);
HookRegistry::register('Schema::get::submission', [$thothRegister, 'addWorkIdToSchema']);
HookRegistry::register('Schema::get::eventLog', [$thothRegister, 'addReasonToSchema']);
HookRegistry::register('Form::config::before', [$thothRegister, 'addImprintField']);
HookRegistry::register('Form::config::before', [$thothRegister, 'addThothField']);
HookRegistry::register('Publication::validatePublish', [$thothRegister, 'validateRegister']);
HookRegistry::register('TemplateManager::display', [$thothRegister, 'addResources']);
HookRegistry::register('Publication::publish', [$thothRegister, 'registerOnPublish']);
Expand Down
118 changes: 89 additions & 29 deletions classes/ThothRegister.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use PKP\security\Role;

import('plugins.generic.thoth.classes.facades.ThothService');
import('plugins.generic.thoth.classes.ThothValidator');

class ThothRegister
{
Expand Down Expand Up @@ -52,7 +53,7 @@ public function addReasonToSchema($hookName, $args)
return false;
}

public function addImprintField($hookName, $form)
public function addThothField($hookName, $form)
{

if ($form->id !== 'publish' || !empty($form->errors)) {
Expand All @@ -65,48 +66,107 @@ public function addImprintField($hookName, $form)
return;
}

$errors = [];

try {
$thothClient = $this->plugin->getThothClient($submission->getData('contextId'));
$publishers = $thothClient->linkedPublishers();
$imprints = $thothClient->imprints(['publishers' => array_column($publishers, 'publisherId')]);
} catch (ThothException $e) {
$errors[] = __('plugins.generic.thoth.connectionError');
error_log($e->getMessage());
}

$imprintOptions = [];
foreach ($imprints as $imprint) {
$imprintOptions[] = [
'value' => $imprint['imprintId'],
'label' => $imprint['imprintName']
];
}
if (empty($errors)) {
$errors = ThothValidator::validate($submission);
}

$form->addField(new \PKP\components\forms\FieldOptions('registerConfirmation', [
'label' => __('plugins.generic.thoth.register.label'),
'options' => [
['value' => true, 'label' => __('plugins.generic.thoth.register.confirmation')]
],
'value' => false,
'groupId' => 'default',
]))
->addField(new \PKP\components\forms\FieldSelect('imprint', [
'label' => __('plugins.generic.thoth.imprint'),
'options' => $imprintOptions,
'required' => true,
'showWhen' => 'registerConfirmation',
'groupId' => 'default',
'value' => $imprints[0]['imprintId'] ?? null
]));
} catch (ThothException $e) {
$warningIconHtml = '<span class="fa fa-exclamation-triangle pkpIcon--inline"></span>';
$noticeMsg = __('plugins.generic.thoth.connectionError');
$msg = '<div class="pkpNotification pkpNotification--warning">' . $warningIconHtml . $noticeMsg . '</div>';
if (!empty($errors)) {
$msg = '<div class="pkpNotification pkpNotification--warning">';
$msg .= __('plugins.generic.thoth.register.warning');
$msg .= '<ul>';
foreach ($errors as $error) {
$msg .= '<li>' . $error . '</li>';
}
$msg .= '</ul></div>';

$form->addField(new \PKP\components\forms\FieldHTML('registerNotice', [
'description' => $msg,
'groupId' => 'default',
]));

error_log($e->getMessage());
return false;
}

$imprintOptions = [];
foreach ($imprints as $imprint) {
$imprintOptions[] = [
'value' => $imprint['imprintId'],
'label' => $imprint['imprintName']
];
}

$form->addField(new \PKP\components\forms\FieldOptions('registerConfirmation', [
'label' => __('plugins.generic.thoth.register.label'),
'options' => [
['value' => true, 'label' => __('plugins.generic.thoth.register.confirmation')]
],
'value' => false,
'groupId' => 'default',
]))
->addField(new \PKP\components\forms\FieldSelect('imprint', [
'label' => __('plugins.generic.thoth.imprint'),
'options' => $imprintOptions,
'required' => true,
'showWhen' => 'registerConfirmation',
'groupId' => 'default',
'value' => $imprints[0]['imprintId'] ?? null
]));

// return false;

// try {
// $thothClient = $this->plugin->getThothClient($submission->getData('contextId'));
// $publishers = $thothClient->linkedPublishers();
// $imprints = $thothClient->imprints(['publishers' => array_column($publishers, 'publisherId')]);

// $imprintOptions = [];
// foreach ($imprints as $imprint) {
// $imprintOptions[] = [
// 'value' => $imprint['imprintId'],
// 'label' => $imprint['imprintName']
// ];
// }

// $form->addField(new \PKP\components\forms\FieldOptions('registerConfirmation', [
// 'label' => __('plugins.generic.thoth.register.label'),
// 'options' => [
// ['value' => true, 'label' => __('plugins.generic.thoth.register.confirmation')]
// ],
// 'value' => false,
// 'groupId' => 'default',
// ]))
// ->addField(new \PKP\components\forms\FieldSelect('imprint', [
// 'label' => __('plugins.generic.thoth.imprint'),
// 'options' => $imprintOptions,
// 'required' => true,
// 'showWhen' => 'registerConfirmation',
// 'groupId' => 'default',
// 'value' => $imprints[0]['imprintId'] ?? null
// ]));
// } catch (ThothException $e) {
// $warningIconHtml = '<span class="fa fa-exclamation-triangle pkpIcon--inline"></span>';
// $noticeMsg = __('plugins.generic.thoth.connectionError');
// $msg = '<div class="pkpNotification pkpNotification--warning">' . $warningIconHtml . $noticeMsg . '</div>';

// $form->addField(new \PKP\components\forms\FieldHTML('registerNotice', [
// 'description' => $msg,
// 'groupId' => 'default',
// ]));

// error_log($e->getMessage());
// }

return false;
}

Expand Down
59 changes: 59 additions & 0 deletions classes/ThothValidator.inc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

/**
* @file plugins/generic/thoth/classes/ThothValidator.php
*
* Copyright (c) 2025 Lepidus Tecnologia
* Copyright (c) 2025 Thoth
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class ThothValidator
*
* @ingroup plugins_generic_thoth
*
* @brief Validate submission metadata to Thoth submit
*/

require_once(__DIR__ . '/../vendor/autoload.php');

use Biblys\Isbn\Isbn;

import('plugins.generic.thoth.classes.facades.ThothService');

class ThothValidator
{
public static function validate($submission)
{
$errors = [];

$publicationFormats = Application::getRepresentationDao()
->getApprovedByPublicationId($submission->getData('currentPublicationId'))
->toArray();

$publicationFormats = array_filter($publicationFormats, function ($publicationFormat) {
return $publicationFormat->getIsAvailable();
});

$errors = array_merge($errors, self::validateIsbn($publicationFormats));

return $errors;
}

public static function validateIsbn($publicationFormats)
{
$errors = [];
foreach ($publicationFormats as $publicationFormat) {
try {
$isbn = ThothService::publication()->getIsbnByPublicationFormat($publicationFormat);
Isbn::validateAsIsbn13($isbn);
} catch (Exception $e) {
$errors[] = __('plugins.generic.thoth.validation.isbn', [
'isbn' => $isbn,
'formatName' => $publicationFormat->getLocalizedName()
]);
}
}

return $errors;
}
}
16 changes: 10 additions & 6 deletions classes/components/forms/RegisterForm.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,18 @@ public function __construct($action, $imprints, $errors)
'pageId' => 'default',
]);

$msg = '<div class="pkpNotification pkpNotification--warning">';
$msg .= __('plugins.generic.thoth.register.warning');
$msg .= '<ul>';
foreach ($errors as $error) {
$warningIconHtml = '<span class="fa fa-exclamation-triangle pkpIcon--inline"></span>';
$msg = '<div class="pkpNotification pkpNotification--warning">' . $warningIconHtml . $error . '</div>';
$this->addField(new \PKP\components\forms\FieldHTML('registerNotice', [
'description' => $msg,
'groupId' => 'default',
]));
$msg .= '<li>' . $error . '</li>';
}
$msg .= '</ul></div>';

$this->addField(new \PKP\components\forms\FieldHTML('registerNotice', [
'description' => $msg,
'groupId' => 'default',
]));

return;
}
Expand Down
25 changes: 1 addition & 24 deletions classes/services/ThothPublicationService.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -176,33 +176,10 @@ public function getIsbnByPublicationFormat($publicationFormat)
$identificationCodes = $publicationFormat->getIdentificationCodes()->toArray();
foreach ($identificationCodes as $identificationCode) {
if ($identificationCode->getCode() == '15' || $identificationCode->getCode() == '24') {
$isbn = $identificationCode->getValue();
return $this->convertToIsbn13($isbn);
return $identificationCode->getValue();
}
}

return null;
}

public function convertToIsbn13($isbnString)
{
if (preg_match('/(?=.{17}$)97(?:8|9)([ -])\d{1,5}\1\d{1,7}\1\d{1,6}\1\d$/', $isbnString)) {
return $isbnString;
}

$isbnNumber = preg_replace('/\D/', '', $isbnString);

if (strlen($isbnNumber) != 13) {
return $isbnString;
}

return sprintf(
'%s-%s-%s-%s-%s',
substr($isbnNumber, 0, 3),
substr($isbnNumber, 3, 1),
substr($isbnNumber, 4, 2),
substr($isbnNumber, 6, 6),
substr($isbnNumber, 12, 1)
);
}
}
5 changes: 5 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"require": {
"biblys/isbn": "~3.0"
}
}
78 changes: 78 additions & 0 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit c00b7be

Please sign in to comment.