From ba81f50aa34138ed03a4d007fbe345182c29761b Mon Sep 17 00:00:00 2001
From: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Date: Mon, 17 Jan 2022 17:59:21 +0100
Subject: [PATCH] Bug 29897: Display author's identifiers

This new enhancement add the capability to list the different
identifiers of authors. It is helpful for research publications for
instance.

This patch will add a new "Author identifiers" tab on the detail page
(OPAC) of a bibliographic record, with the list of the authors and their
identifiers.
On the detail page of the authority record, the same identifier list
will be displayed.

Test plan:
Create some authority with
024
  $a source
  $2 number
  $6 link to the source
With the pref turned ON you will be able to see the new information.

Sponsored-by: Orex Digital
---
 Koha/Authority.pm                             | 30 ++++++++++++
 .../bootstrap/en/modules/opac-auth-detail.tt  | 29 +++++++++++-
 .../bootstrap/en/modules/opac-detail.tt       | 32 +++++++++++++
 opac/opac-authoritiesdetail.pl                |  6 +++
 opac/opac-detail.pl                           | 18 +++++++
 t/db_dependent/Koha/Authorities.t             | 47 ++++++++++++++++++-
 6 files changed, 160 insertions(+), 2 deletions(-)

diff --git a/Koha/Authority.pm b/Koha/Authority.pm
index cec6c662f45..0a6d30c6166 100644
--- a/Koha/Authority.pm
+++ b/Koha/Authority.pm
@@ -114,6 +114,36 @@ sub controlled_indicators {
     });
 }
 
+=head3 get_identifiers
+
+    my $identifiers = $author->get_identifiers;
+
+Return a list of identifiers of the authors which are in 024$2$a
+
+=cut
+
+sub get_identifiers {
+    my ( $self, $params ) = @_;
+
+    my $flavour =
+      C4::Context->preference('marcflavour') eq 'UNIMARC'
+      ? 'UNIMARCAUTH'
+      : 'MARC21';
+    my $record =
+      MARC::Record->new_from_xml( $self->marcxml, 'UTF-8', $flavour );
+
+    my @identifiers;
+    for my $field ( $record->field('024') ) {
+        my $sf_2 = $field->subfield('2');
+        my $sf_a = $field->subfield('a');
+        my $sf_6 = $field->subfield('6');
+        next unless $sf_2 && $sf_a;
+        push @identifiers, {source => $sf_2, number => $sf_a, linkage => $sf_6};
+    }
+
+    return \@identifiers;
+}
+
 =head2 Class Methods
 
 =head3 type
diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth-detail.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth-detail.tt
index f0d9fbcc2d5..3131e2a2a72 100644
--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth-detail.tt
+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth-detail.tt
@@ -36,7 +36,13 @@
                             [% INCLUDE 'navigation.inc' %]
                         </div>
                     </div>
-                    <div class="col-lg-10 order-first order-md-first order-lg-2">
+                    [% IF Koha.Preference( 'OPACAuthorIdentifiers' ) && author_identifiers.size %]
+                        <div class="col-lg-5 order-first order-md-first order-lg-2">
+                    [% ELSE %]
+                        <div class="col-lg-10 order-first order-md-first order-lg-2">
+                    [% END %]
+                [% ELSIF Koha.Preference( 'OPACAuthorIdentifiers' ) && author_identifiers.size %]
+                    <div class="col-lg-6 order-first order-md-first order-lg-2">
                 [% ELSE %]
                     <div class="col order-first order-md-first order-lg-2">
                 [% END %]
@@ -159,6 +165,27 @@
                         </div>
                     </div> <!-- / .#userauthdetails -->
                 </div> <!-- / .col-lg-10/12 -->
+                [% IF Koha.Preference( 'OPACAuthorIdentifiers' ) && author_identifiers.size %]
+                    [% IF ( OpacNav || OpacNavBottom ) %]
+                        <div class="col-lg-5 order-lg-3">
+                    [% ELSE %]
+                        <div class="col-lg-6 order-lg-3">
+                    [% END %]
+                        <div class="author_identifier">
+                            <span>Identifiers</span>
+                            <ul>
+                            [% FOR identifier IN author_identifiers %]
+                                <li>
+                                [% SWITCH identifier.source.lower %]
+                                [% CASE 'orcid' %]ORCID: <a href="https://orcid.org/[% identifier.number | url %]">[% identifier.number | html %]</a>
+                                [% CASE %][% identifier.source | html %]: [% identifier.number | html %]
+                                [% END %]
+                                </li>
+                            [% END %]
+                            </ul>
+                        </div>
+                    </div>
+                [% END %]
             </div> <!-- / .row -->
         </div> <!-- / .container-fluid -->
     </div> <!-- / .main -->
diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt
index c226da6dd08..31cfe03cb1e 100644
--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt
+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt
@@ -469,6 +469,10 @@
                             [% IF ( defaulttab == 'media' ) %]<li id="tab_html5media" class="ui-tabs-active">[% ELSE %]<li id="tab_html5media">[% END %]<a href="#html5media">Play media</a></li>
                         [% END %]
 
+                        [% IF Koha.Preference( 'OPACAuthorIdentifiers' ) && author_identifiers.size %]
+                            <li id="tab_author_identifiers"><a href="#author_identifiers">Author identifiers</a></li>
+                        [% END %]
+
                     </ul>
 
                     [% IF ( serialcollection ) %]
@@ -927,6 +931,34 @@
                             </div><!-- / #images -->
                         [% END # / IF OPACLocalCoverImages && localimages.size %]
 
+                        [% IF Koha.Preference( 'OPACAuthorIdentifiers' ) && author_identifiers.size %]
+                            <div id="author_identifiers">
+                                [% FOR author IN author_identifiers %]
+                                    <div class="author_identifier">
+                                        <span class="author_name"><a href="/cgi-bin/koha/opac-authoritiesdetail.pl?authid=[% author.authid | uri %]">[% author.name | html %]</a></span>
+                                        <ul>
+                                        [% FOR identifier IN author.identifiers %]
+                                            <li>
+                                            [% SWITCH identifier.source.lower %]
+                                            [% CASE 'orcid' %]ORCID:
+                                            [% CASE 'scopus' %]ScopusID:
+                                            [% CASE 'loop' %]loop:
+                                            [% CASE 'rid' %]Publons:
+                                            [% CASE %][% identifier.source | html %]:
+                                            [% END %]
+                                            [% IF identifier.linkage %]
+                                                <a href="[% identifier.linkage | uri %]">[% identifier.number | html %]</a>
+                                            [% ELSE %]
+                                                [% identifier.number | html %]
+                                            [% END %]
+                                            </li>
+                                        [% END %]
+                                        </ul>
+                                    </div>
+                                [% END %]
+                            </div>
+                        [% END %]
+
                 </div> <!-- / #bibliodescriptions -->
 
                 [% IF ( NovelistSelectProfile && NovelistSelectView == 'below' && ( normalized_isbn || normalized_upc ) ) %]
diff --git a/opac/opac-authoritiesdetail.pl b/opac/opac-authoritiesdetail.pl
index ed0a1c70144..e6d41f7bd59 100755
--- a/opac/opac-authoritiesdetail.pl
+++ b/opac/opac-authoritiesdetail.pl
@@ -168,6 +168,12 @@ if ($show_marc) {
 } else {
     my $summary = BuildSummary($record, $authid, $authtypecode);
     $template->{VARS}->{'summary'} = $summary;
+
+    if ( C4::Context->preference('OPACAuthorIdentifiers') ) {
+        my $authority = Koha::Authorities->find($authid);
+        my $identifiers = $authority->get_identifiers;
+        $template->param( author_identifiers => $identifiers );
+    }
 }
 
 output_html_with_http_headers $query, $cookie, $template->output;
diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl
index 1c705db7345..f455706b775 100755
--- a/opac/opac-detail.pl
+++ b/opac/opac-detail.pl
@@ -1234,4 +1234,22 @@ $template->param(
     'OpacLocationBranchToDisplay' => C4::Context->preference('OpacLocationBranchToDisplay'),
 );
 
+if ( C4::Context->preference('OPACAuthorIdentifiers') ) {
+    my @author_identifiers;
+    for my $author ( @{ $biblio->get_marc_authors } ) {
+        my $authid    = $author->{authoritylink};
+        my $authority = Koha::Authorities->find($authid);
+        next unless $authority;
+        my $identifiers = $authority->get_identifiers;
+        next unless $identifiers && @$identifiers;
+        my ($name) =
+          map  { $_->{value} }
+          grep { $_->{code} eq 'a' ? $_ : () }
+          @{ $author->{MARCAUTHOR_SUBFIELDS_LOOP} };
+        push @author_identifiers,
+          { authid => $authid, name => $name, identifiers => $identifiers };
+    }
+    $template->param( author_identifiers => \@author_identifiers );
+}
+
 output_html_with_http_headers $query, $cookie, $template->output;
diff --git a/t/db_dependent/Koha/Authorities.t b/t/db_dependent/Koha/Authorities.t
index 04ad663e28f..a9c507df837 100755
--- a/t/db_dependent/Koha/Authorities.t
+++ b/t/db_dependent/Koha/Authorities.t
@@ -19,7 +19,7 @@
 
 use Modern::Perl;
 
-use Test::More tests => 7;
+use Test::More tests => 8;
 use MARC::Field;
 use MARC::File::XML;
 use MARC::Record;
@@ -242,4 +242,49 @@ sub few_marc_records {
     return [ $marc ];
 }
 
+subtest 'get_identifiers' => sub {
+    plan tests => 1;
+
+    t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' );
+    my $record = MARC::Record->new();
+    $record->add_fields(
+        [
+            '100', ' ', ' ',
+            a => 'Lastname, Firstname',
+            b => 'b',
+            c => 'c',
+            i => 'i'
+        ],
+        [
+            '024', '', '',
+            a => '0000-0002-1234-5678',
+            2 => 'orcid',
+            6 => 'https://orcid.org/0000-0002-1234-5678'
+        ],
+        [
+            '024', '', '',
+            a => '01234567890',
+            2 => 'scopus',
+            6 => 'https://www.scopus.com/authid/detail.uri?authorId=01234567890'
+        ],
+    );
+    my $authid = C4::AuthoritiesMarc::AddAuthority($record, undef, 'PERSO_NAME');
+    my $authority = Koha::Authorities->find($authid);
+    is_deeply(
+        $authority->get_identifiers,
+        [
+            {
+                source  => 'orcid',
+                number  => '0000-0002-1234-5678',
+                linkage => 'https://orcid.org/0000-0002-1234-5678'
+            },
+            {
+                source => 'scopus',
+                number => '01234567890',
+                linkage => 'https://www.scopus.com/authid/detail.uri?authorId=01234567890'
+            }
+        ]
+    );
+};
+
 $schema->storage->txn_rollback;
-- 
2.25.1