diff --git a/.github/workflows/generate-package.yml b/.github/workflows/generate-package.yml
index e0d702c..76f8d7a 100644
--- a/.github/workflows/generate-package.yml
+++ b/.github/workflows/generate-package.yml
@@ -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
@@ -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 }}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5657f6e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+vendor
\ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 633bf25..3807210 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -7,3 +7,7 @@ include:
file:
- 'templates/groups/pkp_plugin.yml'
- 'templates/groups/omp/unit_tests.yml'
+
+.unit_test_template:
+ before_script:
+ - composer install
diff --git a/ThothPlugin.inc.php b/ThothPlugin.inc.php
index 47274c4..db1525d 100644
--- a/ThothPlugin.inc.php
+++ b/ThothPlugin.inc.php
@@ -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']);
diff --git a/classes/ThothRegister.inc.php b/classes/ThothRegister.inc.php
index b0f1d0e..ad0a240 100644
--- a/classes/ThothRegister.inc.php
+++ b/classes/ThothRegister.inc.php
@@ -20,6 +20,7 @@
use PKP\security\Role;
import('plugins.generic.thoth.classes.facades.ThothService');
+import('plugins.generic.thoth.classes.ThothValidator');
class ThothRegister
{
@@ -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)) {
@@ -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 = '';
- $noticeMsg = __('plugins.generic.thoth.connectionError');
- $msg = '
' . $warningIconHtml . $noticeMsg . '
';
+ if (!empty($errors)) {
+ $msg = '';
+ $msg .= __('plugins.generic.thoth.register.warning');
+ $msg .= '
';
+ foreach ($errors as $error) {
+ $msg .= '- ' . $error . '
';
+ }
+ $msg .= '
';
$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 = '';
+ // $noticeMsg = __('plugins.generic.thoth.connectionError');
+ // $msg = '' . $warningIconHtml . $noticeMsg . '
';
+
+ // $form->addField(new \PKP\components\forms\FieldHTML('registerNotice', [
+ // 'description' => $msg,
+ // 'groupId' => 'default',
+ // ]));
+
+ // error_log($e->getMessage());
+ // }
+
return false;
}
diff --git a/classes/ThothValidator.inc.php b/classes/ThothValidator.inc.php
new file mode 100644
index 0000000..99950d4
--- /dev/null
+++ b/classes/ThothValidator.inc.php
@@ -0,0 +1,59 @@
+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;
+ }
+}
diff --git a/classes/components/forms/RegisterForm.inc.php b/classes/components/forms/RegisterForm.inc.php
index ccd000b..8ee19a1 100644
--- a/classes/components/forms/RegisterForm.inc.php
+++ b/classes/components/forms/RegisterForm.inc.php
@@ -40,14 +40,18 @@ public function __construct($action, $imprints, $errors)
'pageId' => 'default',
]);
+ $msg = '';
+ $msg .= __('plugins.generic.thoth.register.warning');
+ $msg .= '
';
+
+ $this->addField(new \PKP\components\forms\FieldHTML('registerNotice', [
+ 'description' => $msg,
+ 'groupId' => 'default',
+ ]));
return;
}
diff --git a/classes/services/ThothPublicationService.inc.php b/classes/services/ThothPublicationService.inc.php
index 22cd755..559b511 100644
--- a/classes/services/ThothPublicationService.inc.php
+++ b/classes/services/ThothPublicationService.inc.php
@@ -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)
- );
- }
}
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..84515fe
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,5 @@
+{
+ "require": {
+ "biblys/isbn": "~3.0"
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..2ac77c3
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,78 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "30bd5da4e33de53f4f7c5b93d76d158f",
+ "packages": [
+ {
+ "name": "biblys/isbn",
+ "version": "3.2.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/biblys/isbn.git",
+ "reference": "88decabdccce7eed3f298f826e3365a00f895a05"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/biblys/isbn/zipball/88decabdccce7eed3f298f826e3365a00f895a05",
+ "reference": "88decabdccce7eed3f298f826e3365a00f895a05",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
+ },
+ "require-dev": {
+ "ext-json": "*",
+ "ext-simplexml": "*",
+ "guzzlehttp/guzzle": "^7.0",
+ "phpunit/phpunit": "^6 || ^7 || ^8 || ^11"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "Biblys": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Clement Latzarus",
+ "email": "hello@clemlatz.dev"
+ }
+ ],
+ "description": "A PHP library to convert and validate ISBNs",
+ "homepage": "https://github.com/biblys/isbn",
+ "keywords": [
+ "ISBN",
+ "book",
+ "ean",
+ "gtin"
+ ],
+ "support": {
+ "issues": "https://github.com/biblys/isbn/issues",
+ "source": "https://github.com/biblys/isbn/tree/3.2.9"
+ },
+ "funding": [
+ {
+ "url": "https://liberapay.com/clemlatz",
+ "type": "liberapay"
+ }
+ ],
+ "time": "2022-11-26T00:00:00+00:00"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": [],
+ "platform-dev": [],
+ "plugin-api-version": "2.6.0"
+}
diff --git a/controllers/modal/RegisterHandler.inc.php b/controllers/modal/RegisterHandler.inc.php
index 4488efb..b36a8bc 100644
--- a/controllers/modal/RegisterHandler.inc.php
+++ b/controllers/modal/RegisterHandler.inc.php
@@ -22,6 +22,7 @@
use PKP\security\Role;
import('classes.handler.Handler');
+import('plugins.generic.thoth.classes.ThothValidator');
class RegisterHandler extends Handler
{
@@ -90,6 +91,8 @@ public function register($args, $request)
$thothClient = $plugin->getThothClient($submissionContext->getId());
$publishers = $thothClient->linkedPublishers();
$imprints = $thothClient->imprints(['publishers' => array_column($publishers, 'publisherId')]);
+
+ $errors = array_merge(ThothValidator::validate($this->submission), $errors);
} catch (ThothException $e) {
$errors[] = __('plugins.generic.thoth.connectionError');
error_log($e->getMessage());
diff --git a/locale/en/locale.po b/locale/en/locale.po
index 33eeeb1..7897aeb 100644
--- a/locale/en/locale.po
+++ b/locale/en/locale.po
@@ -48,6 +48,12 @@ msgstr "Register"
msgid "plugins.generic.thoth.register.label"
msgstr "Thoth registration"
+msgid "plugins.generic.thoth.register.warning"
+msgstr "The submission metadata can not be submitted to Thoth because of the following errors:"
+
+msgid "plugins.generic.thoth.validation.isbn"
+msgstr "\"{$isbn}\" of \"{$formatName}\" publication format is not a valid ISBN-13. A valid ISBN-13 must be exactly 17 characters (numbers and hyphens)."
+
msgid "plugins.generic.thoth.register.confirmation"
msgstr "Do you want to register in Thoth the metadata related to this submission?"
diff --git a/locale/es/locale.po b/locale/es/locale.po
index 4a23595..1632c05 100644
--- a/locale/es/locale.po
+++ b/locale/es/locale.po
@@ -48,6 +48,12 @@ msgstr "Registrar"
msgid "plugins.generic.thoth.register.label"
msgstr "Registro en Thoth"
+msgid "plugins.generic.thoth.register.warning"
+msgstr "Los metadatos de envio no pueden ser enviados a Thoth debido a los siguientes errores:"
+
+msgid "plugins.generic.thoth.validation.isbn"
+msgstr "\"{$isbn}\" del formato de publicación \"{$formatName}\" no es un ISBN-13 válido. Un ISBN-13 válido debe tener exactamente 17 caracteres (números y guiones)."
+
msgid "plugins.generic.thoth.register.confirmation"
msgstr "¿Desea registrar en Thoth los metadatos relacionados con este envío?"
diff --git a/locale/pt_BR/locale.po b/locale/pt_BR/locale.po
index 293ec00..4db8476 100644
--- a/locale/pt_BR/locale.po
+++ b/locale/pt_BR/locale.po
@@ -48,6 +48,12 @@ msgstr "Registrar"
msgid "plugins.generic.thoth.register.label"
msgstr "Registro em Thoth"
+msgid "plugins.generic.thoth.register.warning"
+msgstr "Os metadados da submissão não podem ser enviados para Thoth devido aos seguintes erros:"
+
+msgid "plugins.generic.thoth.validation.isbn"
+msgstr "\"{$isbn}\" do formato de publicação \"{$formatName}\" não é um ISBN-13 válido. Um ISBN-13 válido deve ter exatamente 17 caracteres (números e hífens)."
+
msgid "plugins.generic.thoth.register.confirmation"
msgstr "Deseja realmente registrar na Thoth os metadados relacionados a essa submissão?"
diff --git a/tests/classes/ThothValidateTest.php b/tests/classes/ThothValidateTest.php
new file mode 100644
index 0000000..597b847
--- /dev/null
+++ b/tests/classes/ThothValidateTest.php
@@ -0,0 +1,89 @@
+makePartial()
+ ->shouldReceive('getLocalizedName')
+ ->withAnyArgs()
+ ->andReturn('PDF')
+ ->shouldReceive('getIdentificationCodes')
+ ->withAnyArgs()
+ ->andReturn(
+ Mockery::mock(\PKP\db\DAOResultFactory::class)
+ ->makePartial()
+ ->shouldReceive('toArray')
+ ->withAnyArgs()
+ ->andReturn([
+ Mockery::mock(\APP\publicationFormat\IdentificationCode::class)
+ ->makePartial()
+ ->shouldReceive('getCode')
+ ->withAnyArgs()
+ ->andReturn('24')
+ ->shouldReceive('getValue')
+ ->withAnyArgs()
+ ->andReturn('97-83-9-579-61')
+ ->getMock()
+ ])
+ ->getMock()
+ )
+ ->getMock(),
+ Mockery::mock(\APP\publicationFormat\PublicationFormat::class)
+ ->makePartial()
+ ->shouldReceive('getLocalizedName')
+ ->withAnyArgs()
+ ->andReturn('EPUB')
+ ->shouldReceive('getIdentificationCodes')
+ ->withAnyArgs()
+ ->andReturn(
+ Mockery::mock(\PKP\db\DAOResultFactory::class)
+ ->makePartial()
+ ->shouldReceive('toArray')
+ ->withAnyArgs()
+ ->andReturn([
+ Mockery::mock(\APP\publicationFormat\IdentificationCode::class)
+ ->makePartial()
+ ->shouldReceive('getCode')
+ ->withAnyArgs()
+ ->andReturn('15')
+ ->shouldReceive('getValue')
+ ->withAnyArgs()
+ ->andReturn('978395796140')
+ ->getMock()
+ ])
+ ->getMock()
+ )
+ ->getMock(),
+ ];
+
+ $errors = ThothValidator::validateIsbn($publicationFormats);
+
+ $this->assertEquals([
+ '##plugins.generic.thoth.validation.isbn##',
+ '##plugins.generic.thoth.validation.isbn##'
+ ], $errors);
+ }
+}
diff --git a/version.xml b/version.xml
index 4dc3d8e..4a4cacc 100644
--- a/version.xml
+++ b/version.xml
@@ -3,8 +3,8 @@
thoth
plugins.generic
- 0.2.1.5
- 2025-01-15
+ 0.2.2.0
+ 2025-01-18
1
ThothPlugin