Difference between revisions of "Using Internal IDs for Staff Browse Views"

From EPrints Documentation
Jump to: navigation, search
(Added render function for internal ID to help with browse views.)
m
Line 16: Line 16:
  
 
=== Add Internal ID field to User ===
 
=== Add Internal ID field to User ===
1. In your archive's '''cfg/cfg.d/user_fields.pl file ad the following snippet of code at the end:
+
1. In your archive's '''cfg/cfg.d/user_fields.pl''' file ad the following snippet of code at the end:
  
 
  push @{$c->{fields}->{user}},
 
  push @{$c->{fields}->{user}},
Line 71: Line 71:
 
2. Repeat this change with the '''contributors''' and '''editors'' fields.
 
2. Repeat this change with the '''contributors''' and '''editors'' fields.
  
3. Create a file called '''render_internalid''' in '''cfg/cfg.d/ ogf you archive, with the following contents
+
3. Create a file called '''render_internalid''' in '''cfg/cfg.d/''' of you archive, with the following contents:
  
 
  $c->{render_internalid} = sub
 
  $c->{render_internalid} = sub

Revision as of 10:11, 19 June 2017

Scenario

Your institution/organisation has a unique identfiers for your members/staff and you want to be able to use these to create a browse view listing each individuals publication list.

By default EPrints provides a browse view based on the given name and family name of those listed in the Creators field of an EPrints publication. This is not useful for most institutions/organisations for a number of reasons:

  1. Given name and family name is not necessary unique
  2. Some creators will not be members of your institution/organisation and therefore you do not want them listed.
  3. You have an existing ID that you want to be able to use programmatically to link to their EPrints publication list.

Solution

By default, when adding creators to an EPrint, as well as a field for given name and family name there is also a column for Email, this is just labelled as such but is actually named creators_id and therefore can be any unique identifier for the user. However, it is important that the unique identifier used is consistent, (i.e. it is always an email address or another unique identifier used by your institution/organisation). In general, it is best to retain email address as a unique identifier, as you may wish to use this to allow visitors to you repository to contact creators (authors), also you may want to record the email address of creators who are not part of your institution/organisation. Therefore for this solution, we will assume that another unique identifier will be used separate to email address.

Lets assume that your institution/organisation has a public members/staff ID that you want to use. To ensure that this members/staff ID is adding whenever this person is added as a creator, you can use Autocompletion. Autocompletion can be setup to use the users records within EPrints. This assumes that you have generated accounts for all your members/staff. This can often be done using LDAP.

Procedure

N.B. The following instructions assume EPrints has been installed in the directory /opt/eprints3/ some EPrints install will appear under /usr/share/eprints3/ or other locations. Make sure you amend these as appropriate for your instaltion

Add Internal ID field to User

1. In your archive's cfg/cfg.d/user_fields.pl file ad the following snippet of code at the end:

push @{$c->{fields}->{user}},
{
  name => 'internalid',
  type => 'id',
};

2. Run EPrints database update command to add this new field:

/opt/eprints3/bin/epadmin update ARCHIVENAME

3. Assuming the above has been successful add the phrases required for this new field to cfg/lang/en/phrases/local.xml

<epp:phrase id="user_fieldname_internalid">Internal ID</epp:phrase>
<epp:phrase id="user_fieldhelp_internalid">Unique ID used to identify a user, used by <epc:phrase ref="archive_name" /></epp:phrase>

4. Test that EPrints is happy with these changes and if so reload Apache:

/opt/eprints3/bin/epadmin test ARCHIVENAME
apachectl graceful


Add Internal ID to creators/editors/contributors fields for an EPrint

1. Edit your archive's cfg/cfg.d/eprint_fields.pl. Under the field named creators, you will see a block labelled fields. Copy and paste the block that has the sub_name id and copy and paste it just before the end fields block, ensuring to add a comma a comma prior to this. Then modify the sub_name from id to internalid. The creators block should then look something like below:

{
  name => 'creators',
  type => 'compound',
  multiple => 1,
  fields => [
    {
      sub_name => 'name',
      type => 'name',
      hide_honourific => 1,
      hide_lineage => 1,
      family_first => 1,
    },
    {
      sub_name => 'id',
      type => 'text',
      input_cols => 20,
      allow_null => 1,
    },
    {
      sub_name => 'internalid',
      type => 'text',
      input_cols => 10,
      allow_null => 1,
      render_single_value => render_internalid,
    },
  ],
},

2. Repeat this change with the contributors' and editors fields.

3. Create a file called render_internalid in cfg/cfg.d/ of you archive, with the following contents:

$c->{render_internalid} = sub
{
  my( $session, $field, $value, $obj ) = @_;

  $user_ds =  $session->dataset( "user" );
  my $userexp = EPrints::Search->new(
    session => $session,
    dataset => $user_ds 
  );
  $userexp->add_field( $user_ds->get_field( "internalid" ), $value);
  my $results = $userexp->perform_search;
  $user = $results->item( 0 );

  return $field->render_single_value( $session, $session->render_name( $user->get_value('name') ) );
}

4. Run EPrints database update command to add these new subfields:

/opt/eprints3/bin/epadmin update ARCHIVENAME 

5. Assuming the above has been successful add the phrases required for this new field to cfg/lang/en/phrases/local.xml

<epp:phrase id="eprint_fieldname_creators_internalid">Internal ID</epp:phrase>
<epp:phrase id="eprint_fieldhelp_creators_internalid">Unique ID used to identify a user, used by <epc:phrase ref="archive_name" /></epp:phrase>
<epp:phrase id="eprint_fieldname_contributors_internalid">Internal ID</epp:phrase>
<epp:phrase id="eprint_fieldhelp_contributors_internalid">Unique ID used to identify a user, used by <epc:phrase ref="archive_name" /></epp:phrase>
<epp:phrase id="eprint_fieldname_editors_internalid">Internal ID</epp:phrase>
<epp:phrase id="eprint_fieldhelp_editors_internalid">Unique ID used to identify a user, used by <epc:phrase ref="archive_name" /></epp:phrase>

6. Test that EPrints is happy with these changes and if so reload Apache:

/opt/eprints3/bin/epadmin test ARCHIVENAME
apachectl graceful


Add Autocompletion for creators/editors/contributors fields

1. Create a new file in your archive under cgi/users/lookup/staffinternal and edit:

use EPrints;
use strict;

my $session = EPrints::Session->new();

my $content = "text/xml";
$session->send_http_header( content_type=>$content );
my $family = $session->param( "_name_family" );
my $given = $session->param( "_name_given" );
my $id = $session->param( "_id" );
my $internalid = $session->param( "_internalid" );

my $database = $session->get_database;
my $dataset = $session->get_repository->get_dataset( "user" );
my $name_field = $dataset->get_field( "name" );
my $email_field = $dataset->get_field( "email" );
my $internalid_field = $dataset->get_field( "internalid" );

# the field to use as the creator ID
my $id_fieldname = "email";
my $id_field = $dataset->get_field( $id_fieldname );

my @fields = ($name_field->get_sql_names, $id_field->get_sql_names, $internalid_field->get_sql_names);

my $Q_table = $database->quote_identifier($dataset->get_sql_table_name);
my $Q_usertype = $database->quote_identifier( "usertype" );
my $Q_id = $database->quote_identifier( $id_fieldname );
 
my $sql = "SELECT " . join(",", map { $database->quote_identifier($_) } @fields ) .
  " FROM $Q_table " .
  " WHERE $Q_usertype != ".$database->quote_value( "minuser" ) .
  " AND $Q_id IS NOT NULL ";

if( EPrints::Utils::is_set( $family ) )
{
  $sql .= " AND ".$database->quote_identifier("name_family").$database->sql_LIKE().$database->quote_value(EPrints::Database::prep_like_value($family).'%');
}
if( EPrints::Utils::is_set( $given ) )
{
  $sql .= " AND ".$database->quote_identifier("name_given").$database->sql_LIKE().$database->quote_value(EPrints::Database::prep_like_value($given).'%');
}
if( EPrints::Utils::is_set( $id ) )
{
  $sql .= " AND ".$database->quote_identifier($id_field->get_name).$database->sql_LIKE().$database->quote_value(EPrints::Database::prep_like_value($id).'%');
}
if( EPrints::Utils::is_set( $internalid ) )
{
  $sql .= " AND ".$database->quote_identifier($internalid_field->get_name).$database->sql_LIKE().$database->quote_value(EPrints::Database::prep_like_value($internalid).'%'); 
}

$sql .= " ORDER BY " .
  $database->quote_identifier("name_family").",".
  $database->quote_identifier("name_given");

my @rows;

my $sth = $session->get_database->prepare_select( $sql, 'limit' => 40 );
$session->get_database->execute( $sth , $sql );
while( my @row = $sth->fetchrow_array )
{
  my $name = $name_field->value_from_sql_row( $session, \@row );
  my $email = $email_field->value_from_sql_row( $session, \@row );
  my $id = $id_field->value_from_sql_row( $session, \@row );
  my $internalid = $internalid_field->value_from_sql_row( $session, \@row );

  my $item = {};
  push @rows, $item;

  my $frag = $session->make_doc_fragment;
  $frag->appendChild( $name_field->render_single_value( $session, $name ) );
  if ( EPrints::Utils::is_set( $internalid ) ) 
  {
    $frag->appendChild( $session->make_text( " [" ) );
    $frag->appendChild( $email_field->render_single_value( $session, $internalid ) );
    $frag->appendChild( $session->make_text( "]" ) );
  }
  if ( EPrints::Utils::is_set( $email ) ) 
  {
    $frag->appendChild( $session->make_text( " (" ) );
    $frag->appendChild( $email_field->render_single_value( $session, $email ) );
    $frag->appendChild( $session->make_text( ")" ) );
  }
  
  $item->{xhtml} = $frag;
  $item->{values} = [
    "for:value:relative:_name_family" => $name->{family},
    "for:value:relative:_name_given" => $name->{given},
    "for:value:relative:_name_honourific" => $name->{honourific},
    "for:value:relative:_name_lineage" => $name->{lineage},
    "for:value:relative:_internalid" => $internalid,
    "for:value:relative:_id" => $id,
  ];
}

$sth->finish();
my $ul = EPrints::Extras::render_lookup_list( $session, \@rows );
$session->send_http_header( content_type => "text/xml; charset=UTF-8" );
binmode(STDOUT,":utf8");
print <<END;
<?xml version="1.0" encoding="UTF-8" ?>

END
print EPrints::XML::to_string( $ul, "utf-8", 1 );
EPrints::XML::dispose( $ul );
$session->terminate;


Create Browse View based on Internal IDs

1. Edit your archives cfg/cfg.d/views.pl and add the following code snippet at the end of the file:

push @{ $c->{browse_views} }, (
{
  id => "creators_internalid",
  allow_null => 0,
  hideempty => 1,
  menus => [
    {
      fields => [ "creators_internalid", "contributors_internalid", "editors_internalid"  ],
      new_column_at => [1, 1],
      mode => "sections",
      open_first_section => 1,
      group_range_function => "EPrints::Update::Views::cluster_ranges_30",
      grouping_function => "EPrints::Update::Views::group_by_a_to_z",
    },
  ],
  order => "-date/title",
  variations => [
    "type",
    "date;truncate=4,reverse",
    "DEFAULT",
  ],
});

2. Test that EPrints is happy with these changes and if so reload Apache:

/opt/eprints3/bin/epadmin test ARCHIVENAME
apachectl graceful

3. Request the path /views/creators_internalid under your repository's hostname in a web browser (e.g. http://example.eprints.org/views/creators_internalid).