Difference between revisions of "Altering the 'Request a copy' function"
(→Method A: Editing the 'requester' citation) |
(→Method A: Editing the 'requester' citation (For EPrints v3.3.12 and above)) |
||
Line 69: | Line 69: | ||
There are two ways this can be achieved - depending on your version of EPrints. | There are two ways this can be achieved - depending on your version of EPrints. | ||
− | === Method A: Editing the 'requester' citation ( | + | === Method A: Editing the 'requester' citation (EPrints v3.3.12 and above?) === |
If you are using a recent version of EPrints, and the file <code>[EPRINTS_ROOT]/lib/citations/request/requester.xml</code> exists, there is a simple way to include the new fields in the email to the contact_email address. Your version of EPrints uses a citation to include some information from the request dataobject in the request email. | If you are using a recent version of EPrints, and the file <code>[EPRINTS_ROOT]/lib/citations/request/requester.xml</code> exists, there is a simple way to include the new fields in the email to the contact_email address. Your version of EPrints uses a citation to include some information from the request dataobject in the request email. |
Revision as of 08:47, 6 August 2018
The Request a copy function allows for some restricted items to be requested by a visitor to the repository.
If you want someone requesting an item to provide more information that the default email address and reason, you can add additional fields to the request form using the methods outlined below.
Contents
Adding additional fields to the request dataset
The 'requests' are dataobjects - very similar to an eprint, or a user, so you can add fields in the same way.
Add configuration for new fields
In a config file e.g. [EPRINTS_ROOT]/archives/[ARCHIVE_ID]/cfg/cfg.d/z_request_fields.pl
## Additional fields for 'Request a copy'
push @{$c->{fields}->{request}},
{
name => "contact_num",
type => "text",
},
{
name => "id_num",
type => "text",
};
After adding this file, test the config is OK (avoid syntax errors):
> [EPRINTS_ROOT]/bin/epadmin test [ARCHIVE_ID]
Add phrases for new fields
Add the phrases to e.g. [EPRINTS_ROOT]/archives/[ARCHIVE_ID]/cfg/lang/en/phrases/z_request_fields.xml
:
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE phrases SYSTEM "entities.dtd">
<epp:phrases xmlns="http://www.w3.org/1999/xhtml" xmlns:epp="http://eprints.org/ep3/phrase" xmlns:epc="http://eprints.org/ep3/control">
<epp:phrase id="request_fieldname_contact_num">Contact number</epp:phrase>
<epp:phrase id="request_fieldhelp_contact_num">A number that we can contact you on to discuss your request if necessary </epp:phrase>
<epp:phrase id="request_fieldname_id_num">ID number</epp:phrase>
<epp:phrase id="request_fieldhelp_id_num">The identification number from your staff/student card</epp:phrase>
</epp:phrases>
Then run:
> [EPRINTS_ROOT]/bin/epadmin update [ARCHIVE_ID]
This will add the columns to the database.
Adding fields to the workflow
By default the workflow is in the global configuration. It can be customised by copying the default request workflow to the repository config:
> mkdir [EPRINTS_ROOT]/archives/[ARCHIVE_ID]/cfg/workflows/request > cp [EPRINTS_ROOT]/lib/workflows/request/default.xml [EPRINTS_ROOT]/archives/[ARCHIVE_ID]/cfg/workflows/request
Reload Apache
Test the config again:
> [EPRINTS_ROOT]/bin/epadmin test [ARCHIVE_ID]
Restart Apache (this command depends on which operating system you use - you may need to do something slightly different!) > sudo service httpd graceful
This should have added the fields to the 'Request a copy' workflow.
Altering the email sent to the contact_email
address
There are two ways this can be achieved - depending on your version of EPrints.
Method A: Editing the 'requester' citation (EPrints v3.3.12 and above?)
If you are using a recent version of EPrints, and the file [EPRINTS_ROOT]/lib/citations/request/requester.xml
exists, there is a simple way to include the new fields in the email to the contact_email address. Your version of EPrints uses a citation to include some information from the request dataobject in the request email.
Copy requester citation to local configuration
By default the request/requester citation is defined in the global configuration. Don't edit that version (as it will be overwritten when EPrints is upgraded). Make a copy:
> mkdir [EPRINTS_ROOT]/archives/[ARCHIVE_ID]/cfg/citations/request/ > cp [EPRINTS_ROOT]/lib/citations/reuqest/requester.xml [EPRINTS_ROOT]/archives/[ARCHIVE_ID]/cfg/citations/request/
Edit requester citation
Add the new fields to the requester citation:
<?xml version="1.0" ?>
<cite:citation xmlns="http://www.w3.org/1999/xhtml" xmlns:cite="http://eprints.org/ep3/citation" xmlns:epc="http://eprints.org/ep3/control">
<epc:print expr="requester_email"/>
<epc:if test="contact_num"><br /><epc:phrase ref="request_fieldname_contact_num" />: <epc:print expr="contact_num"/></epc:if>
<epc:if test="id_num"><br /><epc:phrase ref="request_fieldname_id_num" />: <epc:print expr="id_num"/></epc:if>
</cite:citation>
Test the config, restart Apache
Run the epadmin test
to check everything is OK, and then restart Apache.
EPrints will pick up changes within an existing XML file when you edit it, but it will not detect a new XML file (such as the local requester.xml citation) by default - so a restart (or a reload) is needed.
Method B: Overriding EPrints::Plugin::Screen::Public::RequestCopy
If your version of EPrints doesn't have the above file, or you need to do something more complex than just adding the fields, follow these instructions!
The screen that processes the request being made (not the response to the request) is EPrints::Plugin::Screen::Public::RequestCopy
.
To include the additional data in the email sent to the contact_email address, we need to change the way this behaves - specifying the additional details to be added.
The correct 'EPrints' way to do this for a plugin is outlined here: https://wiki.eprints.org/w/Instructions_for_local_plugins
Understand how the current script works
Take a look at EPrints::Plugin::Screen::Public::RequestCopy
and try to understand it (a bit at least).
Work out which of the methods you need to work differently.
Make a local copy of the plugin
mkdir -p [EPRINTS_ROOT]/archives/[ARCHIVE_ID]/cfg/plugins/EPrints/Plugins/Screen/Public/RequestCopy/ cp [EPRINTS_ROOT]/perl_lib/EPrints/Plugins/Screen/Public/RequestCopy.pm [EPRINTS_ROOT]/archives/[ARCHIVE_ID]/cfg/plugins/EPrints/Plugins/Screen/Public/RequestCopy/LocalRequestCopy.pm
Edit the local copy of the plugin
The package name and 'isa' need to be updated as this is a subclass of the existing plugin.
Any methods that you don't need to change can also be removed (as they'll be inherited from the main RequestCopy module).
PLEASE NOTE the example code below may have been taken from a different version of EPrints to the one you are running. DO NOT just copy and paste it. Please follow the process above to take a copy of RequestCopy from your server, and edit it!
The changes are indicated with ### INSERTED CODE ###
comments.
#################################
# Example taken from https://github.com/eprints/eprints/blob/v3.3.16/perl_lib/EPrints/Plugin/Screen/Public/RequestCopy.pm
#################################
package EPrints::Plugin::Screen::Public::RequestCopy::LocalRequestCopy;
@ISA = ( 'EPrints::Plugin::Screen::Public::RequestCopy' );
use strict;
sub action_request
{
my( $self ) = @_;
my $session = $self->{session};
my $request = $self->{processor}->{dataobj};
my $rc = $self->workflow->update_from_form( $self->{processor} );
return if !$rc; # validation failed
my $email = $request->value( "requester_email" );
my $use_pin_security = $session->config( 'use_request_copy_pin_security' );
my $eprint = $self->{processor}->{eprint};
my $doc = $self->{processor}->{document};
my $contact_email = $self->{processor}->{contact_email};
my $user = EPrints::DataObj::User::user_with_email( $session, $contact_email );
if( defined $user )
{
$request->set_value( "userid", $user->id );
}
$request = $self->{processor}->{dataset}->create_dataobj( $request->get_data );
my $history_data = {
datasetid=>"request",
objectid=>$request->get_id,
action=>"create",
};
if( defined $self->{processor}->{user} )
{
$history_data->{userid} = $self->{processor}->{user}->get_id;
}
else
{
$history_data->{actor} = $email;
}
# Log request creation event
my $history_ds = $session->dataset( "history" );
$history_ds->create_object( $session, $history_data );
# Send request email
my $subject = $session->phrase( "request/request_email:subject", eprint => $eprint->get_value( "title" ) );
my $mail = $session->make_element( "mail" );
$mail->appendChild( $session->html_phrase(
"request/request_email:body",
eprint => $eprint->render_citation_link_staff,
document => defined $doc ? $doc->render_value( "main" ) : $session->make_doc_fragment,
requester => $request->render_citation( "requester" ),
### INSERTED CODE ###
# this checks whether the value is set, and returns either the rendered value, or an empty document fragment
# the pins for a phrase must be XML fragments - not scalar values.
# The corresponding phrase (request/request_email:body) must also be updated to expect the new data.
contact_num => $request->is_set( "contact_num" ) ? $request->render_value( "contact_num" ) : $session->make_doc_fragment,
id_num => $request->is_set( "id_num" ) ? $request->render_value( "id_num" ) : $session->make_doc_fragment,
### END INSERTED CODE ###
reason => $request->is_set( "reason" ) ? $request->render_value( "reason" )
: $session->html_phrase( "Plugin/Screen/EPrint/RequestRemoval:reason" ) ) );
my $result;
if( ( defined $user || $use_pin_security ) && defined $doc )
{
# Contact is a registered user or it doesn't matter
# because we're using the pin security model, and
# EPrints holds the requested document
# Send email to contact with accept/reject links
my $url;
if ( $use_pin_security )
{
# Handle the response via a non-authenticated CGI script
$url = $session->get_url( host => 1, path => "cgi", "respond_to_doc_request" );
$url->query_form(
pin => $request->get_value( 'pin' ),
);
}
else
{
# Handle the response via cgi/users/home which is authenticated
$url = $session->get_url( host => 1, path => "cgi", "users/home" );
$url->query_form(
screen => "Request::Respond",
requestid => $request->id,
);
}
$mail->appendChild( $session->html_phrase( "request/request_email:links",
accept => $session->render_link( "$url&action=accept" ),
reject => $session->render_link( "$url&action=reject" ) ) );
my $to_name;
if ( defined $user )
{
$to_name = EPrints::Utils::tree_to_utf8( $user->render_description );
}
else
{
$to_name = $contact_email;
}
$result = EPrints::Email::send_mail(
session => $session,
langid => $session->get_langid,
to_name => $to_name,
to_email => $contact_email,
subject => $subject,
message => $mail,
sig => $session->html_phrase( "mail_sig" ),
cc_list => EPrints::Utils::is_set( $session->config( "request_copy_cc" ) ) ? $session->config( "request_copy_cc" ) : [],
);
}
else
{
# Contact is non-registered user or EPrints holds no documents
# Send email to contact with 'replyto'
$result = EPrints::Email::send_mail(
session => $session,
langid => $session->get_langid,
to_name => defined $user ? EPrints::Utils::tree_to_utf8( $user->render_description ) : "",
to_email => $contact_email,
subject => $subject,
message => $mail,
sig => $session->html_phrase( "mail_sig" ),
replyto_email => $email,
cc_list => EPrints::Utils::is_set( $session->config( "request_copy_cc" ) ) ? $session->config( "request_copy_cc" ) : [],
);
}
if( !$result )
{
$self->{processor}->add_message( "error", $session->html_phrase( "general:email_failed" ) );
return;
}
# Send acknowledgement to requester
$mail = $session->make_element( "mail" );
$mail->appendChild( $session->html_phrase(
"request/ack_email:body",
document => defined $doc ? $doc->render_value( "main" ) : $session->make_doc_fragment,
eprint => $eprint->render_citation_link ) );
$result = EPrints::Email::send_mail(
session => $session,
langid => $session->get_langid,
to_email => $email,
subject => $session->phrase( "request/ack_email:subject", eprint=>$eprint->get_value( "title" ) ),
message => $mail,
sig => $session->html_phrase( "mail_sig" )
);
if( !$result )
{
$self->{processor}->add_message( "error", $session->html_phrase( "general:email_failed" ) );
return;
}
$self->{processor}->add_message( "message", $session->html_phrase( "request/ack_page", link => $session->render_link( $eprint->get_url ) ) );
$self->{processor}->{request_sent} = 1;
}
1;
Add phrase
The changes to the perl module add two new pins to the phrase. We have to update a local copy of the phrase and add places for these pins to be inserted.
In the file [EPRINTS_ROOT]/lib/lang/en/phrases/system.xml
locate the phrase request/request_email:body
(see: https://github.com/eprints/eprints/blob/v3.3.16/lib/lang/en/phrases/system.xml#L3422-L3431)
Copy this phrase into an XML phrase file e.g. [EPRINTS_ROOT]/archives/[ARCHIVE_ID]/cfg/lang/en/phrases/z_request_fields.xml
- used above.
Edit the phrase, defining places for the new pins to appear:
<epp:phrase id="request/request_email:body">
<p>This item has been requested from <epc:phrase ref="archive_name" /> by <epc:pin name="requester"/>.</p>
<p>Contact number: <epc:pin name="contact_num"/><br />
ID number: <epc:pin name="id_num"/></p>
<p>Please can you respond.</p>
<p><epc:pin name="eprint"/><br/><epc:pin name="document"/></p>
<p>The following reason was given:</p>
<epc:pin name="reason"/>
<p>Please consider removing restrictions or uploading the full text to the archive so that it will be available immediately to future searchers.</p>
</epp:phrase>
Enable plugin (map)
Finally, we have to tell EPrints to use our new plugin in place of the existing one.
Read the details in [EPRINTS_ROOT]/archives/[ARCHIVE_ID]/cfg/cfg.d/plugins.pl
.
Once you understand what need to be done, add the plugin enabling code in a suitable configuration file e.g. [EPRINTS_ROOT]/archives/[ARCHIVE_ID]/cfg/cfg.d/z_request_fields.pl
.
$c->{plugin_alias_map}->{"Screen::Public::RequestCopy"} = "Screen::Public::RequestCopy::LocalRequestCopy";
$c->{plugin_alias_map}->{"Screen::Public::RequestCopy::LocalRequestCopy"} = undef;
# If this doesn't seem to work, try uncommenting this:
# $c->{plugins}->{"Screen::Public::RequestCopy::LocalRequestCopy"}->{params}->{disable} = 0;
Test everything and restart apache
Using the same procedure as after adding the fields.
If the epadmin test
returns no errors, restart Apache, and try requesting something!