How to control eprint workflow based on a user field

From EPrints Documentation
Jump to: navigation, search

NOTE: This has been written based on my experience of an EPrints 3.3.10 install.

What I was trying to achieve

We have many 'collections'. Each EPrint belongs to one collection.

Users can only deposit items into specific collections.

How do I control the EPrint workflow to only show the collections that a user can deposit into?

How I did it

Configuration of metafields

  • Create a namedset with the collections in it:

~/archives/ARCHIVEID/cfg/namedsets/collections

# A list of collections - remember to add the relevant phrases!
library
art_gallery
university_newspapers
lab_equipment
  • Add the metafield to both the eprint and the user. This can be done in a few different ways, this is one:

Edit ~/archives/ARCHIVEID/cfg/cfg.d/eprint_fields.pl, adding:

{
        name => 'collection',
        type => 'namedset',
        set_name => "collections",
},

Edit ~/archives/ARCHIVEID/cfg/cfg.d/user_fields.pl, adding:

{
        name => 'collection',
        type => 'namedset',
        set_name => "collections",
        multiple => 1, #Allows a user to have rights to more than one collection
},

Add to user workflow

Edit ~/archives/ARCHIVEID/cfg/workflows/user/default.xml. We only want admin staff to be able to assign collections, so the field is added to the 'usertype' stage:

  <stage name="usertype">
      <component><field ref="usertype"/></component>
      <component><field ref="username"/></component>
      <component><field ref="collection"/></component>
      <component><field ref="roles"/></component>
  </stage>

This allows one or more collections to be assigned to a user.

Add to EPrint workflow

To render only the collections that have been assigned to a user, we need to get the 'collection's from the owning user, join them into a comma-separated string and use that as the 'options' for the eprint collection field.

<component><field ref="collection" options="{join($item{userid}.as_item(){collection},',')}"/></component>

We could also have used $current_user - which would be OK if the $current_user will have rights to more collections than the owning user.

Update database and restart webserver

Update the database how you normally do it (web interface or commandline) and reload the server config. Test it works :o)

Adding a default

If a user has no collections assigned in their profile, what should happen? We could either:

  • always set a default collection in user_fields_default.pl
  • use eprint_fields_default.pl to set a default collection for the eprint.
$c->{set_eprint_defaults} = sub
{
  my( $data, $repository ) = @_;
 
  my $user = $repository->current_user();
 
  if( defined $user && $user->is_set( "collection" ) )
  {
    my $collections = $user->get_value( "collection" );
    if( scalar @$collections == 1 ){
      $data->{collection} = @$collections[0];
      #We may also want to set some default metadata on items in this collection?
      #Do it here - as we know we've got one collection!
      if( $data->{collection} eq 'university_newspapers' ){
        $data->{type} = "newspaper";
        ...
      }
    }
  }
}

If a user only has access to one collection, the value should be set automatically and the field not shown in the workflow.

  <flow>
    <epc:choose>
      <epc:when test="$STAFF_ONLY = 'TRUE'">
        <!-- Allow editors to choose any collection -->
        <stage ref="collection"/>
      </epc:when>
      <epc:otherwise test="length( $item{userid}.as_item(){collection} ) gt 1">
        <!-- If someone has access to more than one collection, offer their collections -->
        <stage ref="collection"/>
      </epc:otherwise>
    </epc:choose>
    ...
  </flow>
 
  <stage name="collection">
    <epc:if test="$STAFF_ONLY = 'TRUE'">
        <component><field ref="collection" required="yes" /></component>
    </epc:if>
    <epc:if test="$STAFF_ONLY != 'TRUE'">
        <component><field ref="collection" required="yes" options="{join($item{userid}.as_item(){collection},',')}"/></component>
    </epc:if>
  </stage>