17 import(
'classes.plugins.PubIdPlugin');
24 public function register($category, $path, $mainContextId =
null) {
25 $success = parent::register($category, $path, $mainContextId);
26 if (!
Config::getVar(
'general',
'installed') || defined(
'RUNNING_UPGRADE'))
return $success;
27 if ($success && $this->
getEnabled($mainContextId)) {
28 HookRegistry::register(
'Publication::getProperties::summaryProperties', array($this,
'modifyObjectProperties'));
29 HookRegistry::register(
'Publication::getProperties::fullProperties', array($this,
'modifyObjectProperties'));
32 HookRegistry::register(
'Galley::getProperties::summaryProperties', array($this,
'modifyObjectProperties'));
52 return __(
'plugins.pubIds.urn.displayName');
59 return __(
'plugins.pubIds.urn.description');
70 $urn = $pubIdPrefix . $pubIdSuffix;
72 $suffixGenerationStrategy = $this->
getSetting($contextId, $suffixFieldName);
74 if ($suffixGenerationStrategy !=
'customId' && $this->
getSetting($contextId,
'urnCheckNo')) {
98 return 'Uniform Resource Name';
105 $resolverURL = $this->
getSetting($contextId,
'urnResolver');
106 return $resolverURL . $pubId;
120 $templateMgr->addJavaScript(
122 $request->getBaseUrl() . DIRECTORY_SEPARATOR . $this->getPluginPath() . DIRECTORY_SEPARATOR .
'js' . DIRECTORY_SEPARATOR .
'checkNumber.js',
125 'contexts' => [
'publicIdentifiersForm',
'backend'],
141 $this->
import(
'classes.form.URNSettingsForm');
149 return array(
'urnSuffix');
177 $linkActions = array();
178 import(
'lib.pkp.classes.linkAction.request.RemoteActionConfirmationModal');
180 $userVars =
$request->getUserVars();
181 $userVars[
'pubIdPlugIn'] = get_class($this);
183 $linkActions[
'clearPubIdLinkActionURN'] =
new LinkAction(
187 __(
'plugins.pubIds.urn.editor.clearObjectsURN.confirm'),
189 $request->url(
null,
null,
'clearPubId',
null, $userVars),
192 __(
'plugins.pubIds.urn.editor.clearObjectsURN'),
194 __(
'plugins.pubIds.urn.editor.clearObjectsURN')
204 'Submission' =>
'urnPublicationSuffixPattern',
205 'Representation' =>
'urnRepresentationSuffixPattern',
206 'SubmissionFile' =>
'urnSubmissionFileSuffixPattern',
207 'Chapter' =>
'urnChapterSuffixPattern',
215 return array(
'pub-id::other::urn');
222 return (
boolean) $this->
getSetting($contextId,
"enable${pubObjectType}URN");
229 return __(
'plugins.pubIds.urn.editor.urnSuffixCustomIdentifierNotUnique');
248 $props[] =
'pub-id::other::urn';
270 if (get_class($object) ===
'IssueGalley') {
275 if (get_class($object) ===
'Publication' || get_class($object) ===
'ArticleGalley') {
279 if (in_array(
'pub-id::other::urn', $props)) {
281 $values[
'pub-id::other::urn'] = $pubId ? $pubId :
null;
296 if (empty($props[
'pub-id::other::urn'])) {
300 if ($action === VALIDATE_ACTION_ADD) {
301 $submission =
Services::get(
'submission')->get($props[
'submissionId']);
303 $publication =
Services::get(
'publication')->get($props[
'id']);
304 $submission =
Services::get(
'submission')->get($publication->getData(
'submissionId'));
307 $contextId = $submission->getData(
'contextId');
308 $urnPrefix = $this->
getSetting($contextId,
'urnPrefix');
311 if (strpos($props[
'pub-id::other::urn'], $urnPrefix) !== 0) {
312 $urnErrors[] = __(
'plugins.pubIds.urn.editor.missingPrefix', [
'urnPrefix' => $urnPrefix]);
314 if (!$this->
checkDuplicate($props[
'pub-id::other::urn'],
'Publication', $submission->getId(), $contextId)) {
317 if (!empty($urnErrors)) {
318 $errors[
'pub-id::other::urn'] = $urnErrors;
330 if ($form->id !==
'publicationIdentifiers') {
334 if (!$this->
getSetting($form->submissionContext->getId(),
'enablePublicationURN')) {
338 $prefix = $this->
getSetting($form->submissionContext->getId(),
'urnPrefix');
340 $suffixType = $this->
getSetting($form->submissionContext->getId(),
'urnSuffix');
342 if ($suffixType ===
'default') {
344 } elseif ($suffixType ===
'pattern') {
345 $pattern = $this->
getSetting($form->submissionContext->getId(),
'urnPublicationSuffixPattern');
351 'label' => __(
'plugins.pubIds.urn.displayName'),
352 'value' => $form->publication->getData(
'pub-id::other::urn'),
354 'pattern' => $pattern,
355 'contextInitials' => $form->submissionContext->getData(
'acronym', $form->submissionContext->getData(
'primaryLocale')) ??
'',
356 'isPForPress' =>
true,
357 'submissionId' => $form->publication->getData(
'submissionId'),
358 'assignIdLabel' => __(
'plugins.pubIds.urn.editor.urn.assignUrn'),
359 'clearIdLabel' => __(
'plugins.pubIds.urn.editor.clearObjectsURN'),
360 'missingPartsLabel' => __(
'plugins.pubIds.doi.editor.missingParts'),
362 if ($form->publication->getData(
'pub-id::publisher-id')) {
363 $fieldData[
'publisherId'] = $form->publication->getData(
'pub-id::publisher-id');
365 if ($form->publication->getData(
'pages')) {
366 $fieldData[
'pages'] = $form->publication->getData(
'pages');
368 if ($form->publication->getData(
'issueId')) {
369 $issue =
Services::get(
'issue')->get($form->publication->getData(
'issueId'));
371 $fieldData[
'issueNumber'] = $issue->getNumber() ??
'';
372 $fieldData[
'issueVolume'] = $issue->getVolume() ??
'';
373 $fieldData[
'year'] = $issue->getYear() ??
'';
376 $form->addField(
new \
PKP\components\forms\
FieldPubId(
'pub-id::other::urn', $fieldData));
384 $this->
import(
'classes.form.FieldUrn');
385 $form->addField(
new \
Plugins\Generic\URN\
FieldUrn(
'pub-id::other::urn', [
386 'label' => __(
'plugins.pubIds.urn.displayName'),
387 'description' => __(
'plugins.pubIds.urn.editor.urn.description', [
'prefix' => $prefix]),
388 'value' => $form->publication->getData(
'pub-id::other::urn'),
389 'addCheckNumberLabel' => __(
'plugins.pubIds.urn.editor.addCheckNo'),
402 if ($form->id !==
'publish' || !empty($form->errors)) {
406 $submission =
Services::get(
'submission')->get($form->publication->getData(
'submissionId'));
407 $publicationUrnEnabled = $this->
getSetting($submission->getData(
'contextId'),
'enablePublicationURN');
408 $galleyUrnEnabled = $this->
getSetting($submission->getData(
'contextId'),
'enableRepresentationURN');
409 $warningIconHtml =
'<span class="fa fa-exclamation-triangle pkpIcon--inline"></span>';
411 if (!$publicationUrnEnabled && !$galleyUrnEnabled) {
415 }
else if (!$galleyUrnEnabled) {
416 if ($form->publication->getData(
'pub-id::other::urn')) {
417 $msg = __(
'plugins.pubIds.urn.editor.preview.publication', [
'urn' => $form->publication->getData(
'pub-id::other::urn')]);
419 $msg =
'<div class="pkpNotification pkpNotification--warning">' . $warningIconHtml . __(
'plugins.pubIds.urn.editor.preview.publication.none') .
'</div>';
421 $form->addField(
new \
PKP\components\forms\
FieldHTML(
'urn', [
422 'description' => $msg,
423 'groupId' =>
'default',
430 if ($publicationUrnEnabled) {
431 if ($form->publication->getData(
'pub-id::other::urn')) {
432 $urnTableRows[] = [$form->publication->getData(
'pub-id::other::urn'),
'Publication'];
434 $urnTableRows[] = [$warningIconHtml . __(
'submission.status.unassigned'),
'Publication'];
437 if ($galleyUrnEnabled) {
438 foreach ((array) $form->publication->getData(
'galleys') as $galley) {
439 if ($galley->getStoredPubId(
'other::urn')) {
440 $urnTableRows[] = [$galley->getStoredPubId(
'other::urn'), __(
'plugins.pubIds.urn.editor.preview.galleys', [
'galleyLabel' => $galley->getGalleyLabel()])];
442 $urnTableRows[] = [$warningIconHtml . __(
'submission.status.unassigned'),__(
'plugins.pubIds.urn.editor.preview.galleys', [
'galleyLabel' => $galley->getGalleyLabel()])];
446 if (!empty($urnTableRows)) {
447 $table =
'<table class="pkpTable"><thead><tr>' .
448 '<th>' . __(
'plugins.pubIds.urn.displayName') .
'</th>' .
449 '<th>' . __(
'plugins.pubIds.urn.editor.preview.objects') .
'</th>' .
450 '</tr></thead><tbody>';
451 foreach ($urnTableRows as $urnTableRow) {
452 $table .=
'<tr><td>' . $urnTableRow[0] .
'</td><td>' . $urnTableRow[1] .
'</td></tr>';
454 $table .=
'</tbody></table>';
456 $form->addField(
new \
PKP\components\forms\
FieldHTML(
'urn', [
457 'description' => $table,
458 'groupId' =>
'default',
470 $templateMgr = $args[0];
471 $template = $args[1];
473 if ($template !==
'workflow/workflow.tpl') {
477 $templateMgr->addJavaScript(
478 'urn-field-component',
481 'contexts' =>
'backend',
482 'priority' => STYLE_SEQUENCE_LAST,
486 $templateMgr->addStyleSheet(
487 'urn-field-component',
489 .pkpFormField--urn__input {
490 display: inline-block;
493 .pkpFormField--urn__button {
494 margin-left: 0.25rem;
495 height: 2.5rem; // Match input height
499 'contexts' =>
'backend',
501 'priority' => STYLE_SEQUENCE_LAST,
521 $conversionTable = array(
'9' =>
'41',
'8' =>
'9',
'7' =>
'8',
'6' =>
'7',
'5' =>
'6',
'4' =>
'5',
'3' =>
'4',
'2' =>
'3',
'1' =>
'2',
'0' =>
'1',
'a' =>
'18',
'b' =>
'14',
'c' =>
'19',
'd' =>
'15',
'e' =>
'16',
'f' =>
'21',
'g' =>
'22',
'h' =>
'23',
'i' =>
'24',
'j' =>
'25',
'k' =>
'42',
'l' =>
'26',
'm' =>
'27',
'n' =>
'13',
'o' =>
'28',
'p' =>
'29',
'q' =>
'31',
'r' =>
'12',
's' =>
'32',
't' =>
'33',
'u' =>
'11',
'v' =>
'34',
'w' =>
'35',
'x' =>
'36',
'y' =>
'37',
'z' =>
'38',
'-' =>
'39',
':' =>
'17',
'_' =>
'43',
'/' =>
'45',
'.' =>
'47',
'+' =>
'49');
523 for ($i = 0; $i < strlen($urnLower); $i++) {
524 $char = $urnLower[$i];
525 $newURN .= $conversionTable[$char];
528 for ($j = 1; $j <= strlen($newURN); $j++) {
529 $sum = $sum + ($newURN[$j-1] * $j);
531 $lastNumber = $newURN[strlen($newURN)-1];
532 $quot = $sum / $lastNumber;
533 $quotRound = floor($quot);
534 $quotString = (string)$quotRound;
535 return $quotString[strlen($quotString)-1];