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')
197 if (is_a($pubObject,
'Issue')) {
199 $linkActions[
'clearIssueObjectsPubIdsLinkActionURN'] =
new LinkAction(
200 'clearObjectsPubIds',
203 __(
'plugins.pubIds.urn.editor.clearIssueObjectsURN.confirm'),
205 $request->url(
null,
null,
'clearIssueObjectsPubIds',
null, $userVars),
208 __(
'plugins.pubIds.urn.editor.clearIssueObjectsURN'),
210 __(
'plugins.pubIds.urn.editor.clearIssueObjectsURN')
222 'Issue' =>
'urnIssueSuffixPattern',
223 'Submission' =>
'urnPublicationSuffixPattern',
224 'Representation' =>
'urnRepresentationSuffixPattern',
232 return array(
'pub-id::other::urn');
239 return (
boolean) $this->
getSetting($contextId,
"enable${pubObjectType}URN");
246 return __(
'plugins.pubIds.urn.editor.urnSuffixCustomIdentifierNotUnique');
265 $props[] =
'pub-id::other::urn';
287 if (get_class($object) ===
'IssueGalley') {
292 if (get_class($object) ===
'Publication' || get_class($object) ===
'ArticleGalley') {
296 if (in_array(
'pub-id::other::urn', $props)) {
298 $values[
'pub-id::other::urn'] = $pubId ? $pubId :
null;
313 if (empty($props[
'pub-id::other::urn'])) {
317 if ($action === VALIDATE_ACTION_ADD) {
318 $submission =
Services::get(
'submission')->get($props[
'submissionId']);
320 $publication =
Services::get(
'publication')->get($props[
'id']);
321 $submission =
Services::get(
'submission')->get($publication->getData(
'submissionId'));
324 $contextId = $submission->getData(
'contextId');
325 $urnPrefix = $this->
getSetting($contextId,
'urnPrefix');
328 if (strpos($props[
'pub-id::other::urn'], $urnPrefix) !== 0) {
329 $urnErrors[] = __(
'plugins.pubIds.urn.editor.missingPrefix', [
'urnPrefix' => $urnPrefix]);
331 if (!$this->
checkDuplicate($props[
'pub-id::other::urn'],
'Publication', $submission->getId(), $contextId)) {
334 if (!empty($urnErrors)) {
335 $errors[
'pub-id::other::urn'] = $urnErrors;
347 if ($form->id !==
'publicationIdentifiers') {
351 if (!$this->
getSetting($form->submissionContext->getId(),
'enablePublicationURN')) {
355 $prefix = $this->
getSetting($form->submissionContext->getId(),
'urnPrefix');
357 $suffixType = $this->
getSetting($form->submissionContext->getId(),
'urnSuffix');
359 if ($suffixType ===
'default') {
360 $pattern =
'%j.v%vi%i.%a';
361 } elseif ($suffixType ===
'pattern') {
362 $pattern = $this->
getSetting($form->submissionContext->getId(),
'urnPublicationSuffixPattern');
368 'label' => __(
'plugins.pubIds.urn.displayName'),
369 'value' => $form->publication->getData(
'pub-id::other::urn'),
371 'pattern' => $pattern,
372 'contextInitials' => $form->submissionContext->getData(
'acronym', $form->submissionContext->getData(
'primaryLocale')) ??
'',
373 'submissionId' => $form->publication->getData(
'submissionId'),
374 'assignId' => __(
'plugins.pubIds.urn.editor.urn.assignUrn'),
375 'clearId' => __(
'plugins.pubIds.urn.editor.clearObjectsURN'),
377 if ($form->publication->getData(
'pub-id::publisher-id')) {
378 $fieldData[
'publisherId'] = $form->publication->getData(
'pub-id::publisher-id');
380 if ($form->publication->getData(
'pages')) {
381 $fieldData[
'pages'] = $form->publication->getData(
'pages');
383 if ($form->publication->getData(
'issueId')) {
384 $issue =
Services::get(
'issue')->get($form->publication->getData(
'issueId'));
386 $fieldData[
'issueNumber'] = $issue->getNumber() ??
'';
387 $fieldData[
'issueVolume'] = $issue->getVolume() ??
'';
388 $fieldData[
'year'] = $issue->getYear() ??
'';
391 if ($suffixType ===
'default') {
392 $fieldData[
'missingPartsLabel'] = __(
'plugins.pubIds.urn.editor.missingIssue');
394 $fieldData[
'missingPartsLabel'] = __(
'plugins.pubIds.urn.editor.missingParts');
396 $form->addField(
new \
PKP\components\forms\
FieldPubId(
'pub-id::other::urn', $fieldData));
404 $this->
import(
'classes.form.FieldUrn');
405 $form->addField(
new \
Plugins\Generic\URN\
FieldUrn(
'pub-id::other::urn', [
406 'label' => __(
'plugins.pubIds.urn.displayName'),
407 'description' => __(
'plugins.pubIds.urn.editor.urn.description', [
'prefix' => $prefix]),
408 'value' => $form->publication->getData(
'pub-id::other::urn'),
421 if ($form->id !==
'publish' || !empty($form->errors)) {
425 $submission =
Services::get(
'submission')->get($form->publication->getData(
'submissionId'));
426 $publicationUrnEnabled = $this->
getSetting($submission->getData(
'contextId'),
'enablePublicationURN');
427 $galleyUrnEnabled = $this->
getSetting($submission->getData(
'contextId'),
'enableRepresentationURN');
428 $warningIconHtml =
'<span class="fa fa-exclamation-triangle pkpIcon--inline"></span>';
430 if (!$publicationUrnEnabled && !$galleyUrnEnabled) {
434 }
else if (!$galleyUrnEnabled) {
435 if ($form->publication->getData(
'pub-id::other::urn')) {
436 $msg = __(
'plugins.pubIds.urn.editor.preview.publication', [
'urn' => $form->publication->getData(
'pub-id::other::urn')]);
438 $msg =
'<div class="pkpNotification pkpNotification--warning">' . $warningIconHtml . __(
'plugins.pubIds.urn.editor.preview.publication.none') .
'</div>';
440 $form->addField(
new \
PKP\components\forms\
FieldHTML(
'urn', [
441 'description' => $msg,
442 'groupId' =>
'default',
449 if ($publicationUrnEnabled) {
450 if ($form->publication->getData(
'pub-id::other::urn')) {
451 $urnTableRows[] = [$form->publication->getData(
'pub-id::other::urn'),
'Publication'];
453 $urnTableRows[] = [$warningIconHtml . __(
'submission.status.unassigned'),
'Publication'];
456 if ($galleyUrnEnabled) {
457 foreach ((array) $form->publication->getData(
'galleys') as $galley) {
458 if ($galley->getStoredPubId(
'other::urn')) {
459 $urnTableRows[] = [$galley->getStoredPubId(
'other::urn'), __(
'plugins.pubIds.urn.editor.preview.galleys', [
'galleyLabel' => $galley->getGalleyLabel()])];
461 $urnTableRows[] = [$warningIconHtml . __(
'submission.status.unassigned'),__(
'plugins.pubIds.urn.editor.preview.galleys', [
'galleyLabel' => $galley->getGalleyLabel()])];
465 if (!empty($urnTableRows)) {
466 $table =
'<table class="pkpTable"><thead><tr>' .
467 '<th>' . __(
'plugins.pubIds.urn.displayName') .
'</th>' .
468 '<th>' . __(
'plugins.pubIds.urn.editor.preview.objects') .
'</th>' .
469 '</tr></thead><tbody>';
470 foreach ($urnTableRows as $urnTableRow) {
471 $table .=
'<tr><td>' . $urnTableRow[0] .
'</td><td>' . $urnTableRow[1] .
'</td></tr>';
473 $table .=
'</tbody></table>';
475 $form->addField(
new \
PKP\components\forms\
FieldHTML(
'urn', [
476 'description' => $table,
477 'groupId' =>
'default',
489 $templateMgr = $args[0];
490 $template = $args[1];
492 if ($template !==
'workflow/workflow.tpl') {
496 $templateMgr->addJavaScript(
497 'urn-field-component',
500 'contexts' =>
'backend',
501 'priority' => STYLE_SEQUENCE_LAST,
505 $templateMgr->addStyleSheet(
506 'urn-field-component',
508 .pkpFormField--urn__input {
509 display: inline-block;
512 .pkpFormField--urn__button {
513 margin-left: 0.25rem;
514 height: 2.5rem; // Match input height
518 'contexts' =>
'backend',
520 'priority' => STYLE_SEQUENCE_LAST,
540 $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');
543 for ($i = 0; $i < strlen($urnLower); $i++) {
544 $char = $urnLower[$i];
545 $newURN .= $conversionTable[$char];
548 for ($j = 1; $j <= strlen($newURN); $j++) {
549 $sum = $sum + ($newURN[$j-1] * $j);
552 $lastNumber = $newURN[strlen($newURN)-1];
553 $quot = $sum / $lastNumber;
554 $quotRound = floor($quot);
555 $quotString = (string)$quotRound;
557 return $quotString[strlen($quotString)-1];