<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://wiki.eprints.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Denics%40free.fr</id>
	<title>EPrints Documentation - User contributions [en-gb]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.eprints.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Denics%40free.fr"/>
	<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/Special:Contributions/Denics@free.fr"/>
	<updated>2026-05-15T18:53:54Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.8</generator>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=Config_Options_by_File&amp;diff=12169</id>
		<title>Config Options by File</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=Config_Options_by_File&amp;diff=12169"/>
		<updated>2016-08-23T07:45:16Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: /* dynamic_template.pl */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Manual]]&lt;br /&gt;
&lt;br /&gt;
== 10_core.pl ==&lt;br /&gt;
* aliases&lt;br /&gt;
* host&lt;br /&gt;
* port&lt;br /&gt;
* securehost&lt;br /&gt;
* securepath&lt;br /&gt;
== 20_baseurls.pl ==&lt;br /&gt;
* base_url&lt;br /&gt;
* perl_url&lt;br /&gt;
* urlpath&lt;br /&gt;
== adminemail.pl ==&lt;br /&gt;
* adminemail&lt;br /&gt;
== branding.pl ==&lt;br /&gt;
* site_logo&lt;br /&gt;
== database.pl ==&lt;br /&gt;
* dbhost&lt;br /&gt;
* dbname&lt;br /&gt;
* dbpass&lt;br /&gt;
* dbuser&lt;br /&gt;
== document_fields_automatic.pl ==&lt;br /&gt;
* set_document_automatic_fields&lt;br /&gt;
== document_fields_default.pl ==&lt;br /&gt;
* set_document_defaults&lt;br /&gt;
== document_upload.pl ==&lt;br /&gt;
* diskspace_error_threshold&lt;br /&gt;
* diskspace_warn_threshold&lt;br /&gt;
* guess_doc_type&lt;br /&gt;
* on_files_modified&lt;br /&gt;
* required_formats&lt;br /&gt;
== document_validate.pl ==&lt;br /&gt;
* validate_document&lt;br /&gt;
== dynamic_template.pl ==&lt;br /&gt;
*[[API:EPrints/Apache/Template#Dynamic_Pins|Dynamic Pins]]&lt;br /&gt;
&lt;br /&gt;
== email.pl ==&lt;br /&gt;
* send_email&lt;br /&gt;
== eprint_fields.pl ==&lt;br /&gt;
* fields&lt;br /&gt;
== eprint_fields_automatic.pl ==&lt;br /&gt;
* set_eprint_automatic_fields&lt;br /&gt;
== eprint_fields_default.pl ==&lt;br /&gt;
* set_eprint_defaults&lt;br /&gt;
== eprint_render.pl ==&lt;br /&gt;
* eprint_render&lt;br /&gt;
== eprint_validate.pl ==&lt;br /&gt;
* validate_eprint&lt;br /&gt;
== eprint_warnings.pl ==&lt;br /&gt;
* eprint_warnings&lt;br /&gt;
== field_property_defaults.pl ==&lt;br /&gt;
* field_defaults&lt;br /&gt;
== field_validate.pl ==&lt;br /&gt;
* validate_field&lt;br /&gt;
== indexing.pl ==&lt;br /&gt;
* extract_words&lt;br /&gt;
* index&lt;br /&gt;
* indexing&lt;br /&gt;
== languages.pl ==&lt;br /&gt;
* defaultlanguage&lt;br /&gt;
* languages&lt;br /&gt;
== log.pl ==&lt;br /&gt;
* log&lt;br /&gt;
* loghandler&lt;br /&gt;
== misc.pl ==&lt;br /&gt;
* allow_user_removal_request&lt;br /&gt;
* cache_maxlife&lt;br /&gt;
* cache_timeout&lt;br /&gt;
* cookie_auth&lt;br /&gt;
* cookie_domain&lt;br /&gt;
* disable_userinfo&lt;br /&gt;
* pin_timeout&lt;br /&gt;
* skip_buffer&lt;br /&gt;
* use_mimetex&lt;br /&gt;
== oai.pl ==&lt;br /&gt;
* oai&lt;br /&gt;
== paths.pl ==&lt;br /&gt;
* config_path&lt;br /&gt;
* documents_path&lt;br /&gt;
* htdocs_path&lt;br /&gt;
== registration.pl ==&lt;br /&gt;
* allow_reset_password&lt;br /&gt;
* allow_web_signup&lt;br /&gt;
* default_user_type&lt;br /&gt;
* signup_style&lt;br /&gt;
* user_registration_fields&lt;br /&gt;
== request_copy.pl ==&lt;br /&gt;
* email_for_doc_request&lt;br /&gt;
== search.pl ==&lt;br /&gt;
* editor_limit_fields&lt;br /&gt;
* issues_search&lt;br /&gt;
* latest_citation&lt;br /&gt;
* latest_tool_modes&lt;br /&gt;
* match_start_of_name&lt;br /&gt;
* search&lt;br /&gt;
== security.pl ==&lt;br /&gt;
* can_request_view_document&lt;br /&gt;
* can_user_view_document&lt;br /&gt;
== session.pl ==&lt;br /&gt;
* session_close&lt;br /&gt;
* session_init&lt;br /&gt;
== sword.pl ==&lt;br /&gt;
* sword&lt;br /&gt;
== urls.pl ==&lt;br /&gt;
* frontpage&lt;br /&gt;
* rewrite_exceptions&lt;br /&gt;
* userhome&lt;br /&gt;
== user_fields.pl ==&lt;br /&gt;
* fields&lt;br /&gt;
== user_fields_automatic.pl ==&lt;br /&gt;
* set_user_automatic_fields&lt;br /&gt;
== user_fields_default.pl ==&lt;br /&gt;
* set_user_defaults&lt;br /&gt;
== user_render.pl ==&lt;br /&gt;
* user_render&lt;br /&gt;
== user_roles.pl ==&lt;br /&gt;
* user_roles&lt;br /&gt;
== user_validate.pl ==&lt;br /&gt;
* validate_user&lt;br /&gt;
== views.pl ==&lt;br /&gt;
* browse_views&lt;br /&gt;
== vlit.pl ==&lt;br /&gt;
* vlit&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=EPrints_Package_Manager&amp;diff=12133</id>
		<title>EPrints Package Manager</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=EPrints_Package_Manager&amp;diff=12133"/>
		<updated>2016-07-14T16:50:23Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: /* EPM Manager Basics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:EPrints Bazaar]]&lt;br /&gt;
&lt;br /&gt;
=The EPrints Package Manager=&lt;br /&gt;
&lt;br /&gt;
This page explains the the core features and aims of the EPrints package manager which will see its debut in EPrints 3.3&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The EPrints Package Manager is basically a cross between a linux package repository and a user friendly GUI store (think fruit flavoured mobile application store). This makes it a highly open platform for developing extensions specific to a single product which has the flexability and functionality of certain closed stores.&lt;br /&gt;
&lt;br /&gt;
The EPM system consists of 2 main parts, EPM repositories and the client side EPM manager which handles packages installed both from an EPM repository as well as those sourced locally. The EPM manager is able to source packages from more than one EPM repository as is defined by the EPM manager configuration file stored relative to each repository. The EPM manager is also responsible for handling the installation, location of upgrades and EPM development of a new EPM compliant package. &lt;br /&gt;
&lt;br /&gt;
In this document we look at each of the feature of the EPM manager, these in turn aid in the development of an EPM package.&lt;br /&gt;
&lt;br /&gt;
==What is an EPM package and what it is not!==&lt;br /&gt;
&lt;br /&gt;
* A EPM package consists of a series of files which can be dropped into the ARCHIVE_ID location at any level.&lt;br /&gt;
* An EPM package is not able to patch existing files and will exit if an existing file is not managed by the package being installed.&lt;br /&gt;
* It is possible to perform other changes to the archive not specified in the EPM by adding a custom configuration screen to the package which can be accessed by users after a successful install, more on this later.&lt;br /&gt;
&lt;br /&gt;
==EPM Manager Basics==&lt;br /&gt;
* Both command line (via tools/epm) and GUI access (via the Admin interface)&lt;br /&gt;
* Basic commands/capabilities. Just download the epm file and run tools/epm from your eprints home.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
** build&lt;br /&gt;
** disable&lt;br /&gt;
** enable&lt;br /&gt;
** install&lt;br /&gt;
** link_cfg&lt;br /&gt;
** link_lib&lt;br /&gt;
** list&lt;br /&gt;
** rebuild&lt;br /&gt;
** uninstall&lt;br /&gt;
** unpack&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example command line&lt;br /&gt;
  perl tools/epm install package.epm&lt;br /&gt;
&lt;br /&gt;
==The EPM Admin GUI==&lt;br /&gt;
&lt;br /&gt;
The EPM admin GUI reflects the command line access and has 4 main tabs which are displayed depending on if there is content to put on them, e.g. the &amp;quot;Installed Packages&amp;quot; tab will not display until you have an EPM installed. The tabs are (in order of display):&lt;br /&gt;
&lt;br /&gt;
===Available Upgrades===&lt;br /&gt;
If a later version of a package is found in an EPM repository to the one you have installed locally, this tab will allow you to install the new version.&lt;br /&gt;
&lt;br /&gt;
===Installed Packages===&lt;br /&gt;
From this tab you can view, remove and configure installed packages. &lt;br /&gt;
&lt;br /&gt;
===Available Packages===&lt;br /&gt;
This tab shows the packages available from the various EPM repositories you have defined. &lt;br /&gt;
&lt;br /&gt;
===Local Packages===&lt;br /&gt;
This tab is the development and advanced administrators tab and allows you to upload a custom package into the EPM manager. Once uploaded these packages are checked for complience to the EPM specification before they can be installed. This also means that this tab is ideal for developmental testing of EPM packages. &lt;br /&gt;
&lt;br /&gt;
==The technical side to the EPM Manager (how it works)==&lt;br /&gt;
&lt;br /&gt;
===Installing &amp;amp; Upgrading===&lt;br /&gt;
These are essentially the same as the EPM Manager will check each file it is attempting to installed to see if it meets the following conditions.&lt;br /&gt;
&lt;br /&gt;
====Before install/upgrade====&lt;br /&gt;
* Make a backup of any previously installed version of this package.&lt;br /&gt;
&lt;br /&gt;
====During install/upgrade====&lt;br /&gt;
* If no file exists at destination install from EPM package, record the installed checksum.&lt;br /&gt;
* If a file exists and is managed by a previous version of this package (by checksum) copy the new one over the top and checksum.&lt;br /&gt;
* If a file exists and is not managed by a previous version of this package (including if it has been changed since the last install), abort and remove files installed to this point, then put back the old files. &lt;br /&gt;
&lt;br /&gt;
====After successful install/upgrade====&lt;br /&gt;
* Attempt to reload the repository, if this fails, abort and rollback as the user may loose the ability to launch the package manager to do this later!&lt;br /&gt;
* Store checksums, spec file and related package files (e.g. package icon) locally overwriting any previous. &lt;br /&gt;
&lt;br /&gt;
===Removing===&lt;br /&gt;
* Make a backup&lt;br /&gt;
* Using the checksums file, attempt to remove all files listed if they match their checksum still.&lt;br /&gt;
* If success, remove package cache, else call a forced install with the backup which will cause it to all be put back how it was.&lt;br /&gt;
&lt;br /&gt;
=TODO=&lt;br /&gt;
* Get postinst/prerm scripts working via a packages configuration screen and define these classes. &lt;br /&gt;
* Add ability to search the EPM repositories to both GUI and command line. &lt;br /&gt;
* Add ability to cache package list as a local dataset which can be searched here rather then centrally.&lt;br /&gt;
* Limit GUI to displaying most popular 20 packages, rest are searched for, this will maintain speed when EPM system gets popular.&lt;br /&gt;
* Add button to local packages tab to allow a custom package to be submitted to the EPrints central EPM repository. In all fairness the button is there but the EPM repository is still under construction.&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=Files/OAI_Harvester_1.02&amp;diff=10481</id>
		<title>Files/OAI Harvester 1.02</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=Files/OAI_Harvester_1.02&amp;diff=10481"/>
		<updated>2012-05-01T13:30:53Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: Redirected page to Files/OAI Harvester for EPrints 3.2+&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Files/OAI Harvester for EPrints 3.2+]]&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=Adding_new_views&amp;diff=10371</id>
		<title>Adding new views</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=Adding_new_views&amp;diff=10371"/>
		<updated>2012-03-23T14:35:40Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: /* Browse by type */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Manual]]&lt;br /&gt;
[[Category:Browse Views]]&lt;br /&gt;
&lt;br /&gt;
{{development}}&lt;br /&gt;
&lt;br /&gt;
Browse views provide a way for visitors to your site to discover relevant content without a specific item in mind (for example, browsing all the content associated with a particular topic). Visitors arriving directly at the page for a specific item in the repository (for example, via a search engine) also use views you have defined to discover related content. &lt;br /&gt;
&lt;br /&gt;
There are two default views in EPrints - '''By Year''' and '''By Subject'''. This guide describes how to add additional views to your repository. &lt;br /&gt;
Instead with this link you can read a [http://wiki.eprints.org/w/Views.pl complete list of all options] avaible for views.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
===The basics===&lt;br /&gt;
&lt;br /&gt;
The views for your repository are defined in the views configuration file:&lt;br /&gt;
&lt;br /&gt;
 /opt/eprints3/archives/ARCHIVEID/cfg/cfg.d/views.pl&lt;br /&gt;
&lt;br /&gt;
Open this file and find the browse_views configuration setting:&lt;br /&gt;
&lt;br /&gt;
 $c-&amp;gt;{browse_views} = [&lt;br /&gt;
        {&lt;br /&gt;
                id =&amp;gt; &amp;quot;year&amp;quot;,&lt;br /&gt;
                fields =&amp;gt; &amp;quot;-date;res=year&amp;quot;,&lt;br /&gt;
                ...&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
                id =&amp;gt; &amp;quot;subjects&amp;quot;,&lt;br /&gt;
                fields =&amp;gt; &amp;quot;subjects&amp;quot;,&lt;br /&gt;
                ...&lt;br /&gt;
        },&lt;br /&gt;
 ];&lt;br /&gt;
&lt;br /&gt;
The views are defined using a special (Perl) syntax: the view definition consists of a pair of curly braces (''note the comma after each closing brace'') enclosing a list of property/value pairs (note ''the comma'' after each line).&lt;br /&gt;
&lt;br /&gt;
The key part of the view definition is the '''fields''' property. This names the metadata field (or fields) that EPrints will use to construct the view. For example, for the '''By Year''' view, EPrints groups the records in the repository according to their '''date''' (note that the '''res=year''' suffix tells EPrints to only consider the year part), and constructs a Web page for each date listing the records. Similarly, the '''Browse by Subjscts''' view, groups the records according to the ''subjects'' they have been assigned to (a record may appear in more than one group!).&lt;br /&gt;
&lt;br /&gt;
Both the '''Browse by Year''' and '''Browse by Subject''' views are constructed using the values of a single field ('''date''' and '''subjects''' respectively).&lt;br /&gt;
&lt;br /&gt;
It is also possible to construct a view using the ''combined'' values of two or more fields (eg. group records by author '''and''' editor), or even using a sequence of two or more fields (eg. group records by journal title '''and then''' by volume number).&lt;br /&gt;
&lt;br /&gt;
===Worked example: browse by organisational structure===&lt;br /&gt;
&lt;br /&gt;
By default, EPrints has a ''divisions'' metadata field which allows authors to associate their deposits with the divisions (units, faculties, schools, departments, institutes, centres..) that were involved in producing their item (for example, the author's department, and the departments of any co-authors). This worked example allows visitors to browse the repository content by division.&lt;br /&gt;
&lt;br /&gt;
Open the views configuration file:&lt;br /&gt;
&lt;br /&gt;
 /opt/eprints3/archives/ARCHIVEID/cfg/cfg.d/views.pl&lt;br /&gt;
&lt;br /&gt;
Add the following definition to the browse_views setting:&lt;br /&gt;
&lt;br /&gt;
 $c-&amp;gt;{browse_views} = [&lt;br /&gt;
        {&lt;br /&gt;
                id =&amp;gt; &amp;quot;year&amp;quot;,&lt;br /&gt;
                ...&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
                id =&amp;gt; &amp;quot;subjects&amp;quot;,&lt;br /&gt;
                ...&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
                id =&amp;gt; &amp;quot;divisions&amp;quot;,&lt;br /&gt;
                fields =&amp;gt; &amp;quot;divisions&amp;quot;,&lt;br /&gt;
                order =&amp;gt; &amp;quot;-date/title&amp;quot;,&lt;br /&gt;
                hideempty =&amp;gt; 1,&lt;br /&gt;
        },&lt;br /&gt;
 ];&lt;br /&gt;
&lt;br /&gt;
Save the file and generate the new view pages (this will also re-generate any existing views defined in the views configuration file):&lt;br /&gt;
&lt;br /&gt;
 bin/generate_views ARCHIVEID --verbose&lt;br /&gt;
&lt;br /&gt;
Open the view page in a Web browser:&lt;br /&gt;
&lt;br /&gt;
 http://your.repository.url/view/&lt;br /&gt;
&lt;br /&gt;
The view page lists all the available views. You should see your new views on the list:&lt;br /&gt;
&lt;br /&gt;
[[Image:View_page2.png|frame|none|The view page lists available views]]&lt;br /&gt;
&lt;br /&gt;
'''Fixing the undefined phrase warning''' The new view may appear on the views page with an ''undefined phrase'' warning (you may also notice a similar warning message when running generate_views):&lt;br /&gt;
&lt;br /&gt;
 [&amp;quot;viewname_eprint_divisions&amp;quot; not defined]&lt;br /&gt;
&lt;br /&gt;
Each view you create needs to be assigned a ''human-readable'' name, which EPrints will use on the view Web pages.&lt;br /&gt;
&lt;br /&gt;
Edit the language-specific phrases file for view names:&lt;br /&gt;
&lt;br /&gt;
 /opt/eprints3/archives/ARCHIVEID/cfg/lang/en/phrases/views.xml&lt;br /&gt;
&lt;br /&gt;
Add an appropriate phrase which describes the new view, for example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;epp:phrase id=&amp;quot;viewname_eprint_divisions&amp;quot;&amp;gt;Division&amp;lt;/epp:phrase&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Save the phrases file and regenerate the view pages:&lt;br /&gt;
&lt;br /&gt;
 bin/generate_views ARCHIVEID --verbose&lt;br /&gt;
&lt;br /&gt;
===Example view definitions===&lt;br /&gt;
&lt;br /&gt;
====Browse by type (3.3.8)====&lt;br /&gt;
&lt;br /&gt;
Every deposit in EPrints has a type (article, book, thesis...). To allow visitors to browse your repository content by type, add the following definition to the browse_views setting:&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
    id=&amp;gt;&amp;quot;doctype&amp;quot;, &lt;br /&gt;
    menus =&amp;gt; [ &lt;br /&gt;
    { &lt;br /&gt;
      fields =&amp;gt; [ &amp;quot;type&amp;quot; ], &lt;br /&gt;
    },], &lt;br /&gt;
    order=&amp;gt;&amp;quot;-date&amp;quot;,&lt;br /&gt;
 },&lt;br /&gt;
&lt;br /&gt;
====Browse by author====&lt;br /&gt;
&lt;br /&gt;
===Example views (combined fields)===&lt;br /&gt;
&lt;br /&gt;
====Browse by author and editor====&lt;br /&gt;
&lt;br /&gt;
===Example views (multiple fields)===&lt;br /&gt;
&lt;br /&gt;
====Browse by journal title, then by volume====&lt;br /&gt;
&lt;br /&gt;
This example lets visitors browse the journals items in your repository have been published in, and then volumes within each journal.&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
        id=&amp;gt;&amp;quot;journal_volume&amp;quot;,&lt;br /&gt;
        fields=&amp;gt;&amp;quot;publication,volume&amp;quot;,&lt;br /&gt;
        order=&amp;gt;&amp;quot;-date/title&amp;quot;,&lt;br /&gt;
        hideempty =&amp;gt; 1,&lt;br /&gt;
 },&lt;br /&gt;
&lt;br /&gt;
[[Image:Browse_by_journal.png|border]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Browse_by_journal_volume.png|border]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Linking in your view===&lt;br /&gt;
&lt;br /&gt;
You now need to add a link to your repository pages which takes visitors directly to your new view, or to the views page from where they can access all available views.&lt;br /&gt;
&lt;br /&gt;
[[Image:Browse_by_navbar.png]]&lt;br /&gt;
&lt;br /&gt;
====Generating CVs etc====&lt;br /&gt;
&lt;br /&gt;
===Linking items back to views===&lt;br /&gt;
===Views as collections===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===New options in EPrints 3.1===&lt;br /&gt;
&lt;br /&gt;
====subfield no longer supported====&lt;br /&gt;
&lt;br /&gt;
The subfield option is no longer supported in EPrints 3.1.&lt;br /&gt;
&lt;br /&gt;
====new_column_at====&lt;br /&gt;
&lt;br /&gt;
This is an array of integers representing the number of items in a view list before another column is added.  For example:&lt;br /&gt;
&lt;br /&gt;
 [ 10 ]&lt;br /&gt;
&lt;br /&gt;
This would have one column of values until there were 11, then there would be 2 columns.&lt;br /&gt;
&lt;br /&gt;
 [ 10, 10 ]&lt;br /&gt;
&lt;br /&gt;
This would have one column if there were ten or less values, two columns if there were between eleven and twenty (ten + ten) values, and three columns for all other cases.&lt;br /&gt;
&lt;br /&gt;
 [ 0, 0 ]&lt;br /&gt;
&lt;br /&gt;
This would always have three columns.&lt;br /&gt;
&lt;br /&gt;
Add one to the number of integers in the array and you get the maximum number of columns.  The value of each integer defines the point at which that column becomes full, and more values cause an 'overflow' into the next column.&lt;br /&gt;
&lt;br /&gt;
====variations====&lt;br /&gt;
&lt;br /&gt;
This controls the various ways in which a browse view can be subheaded.  It consists of a list of strings.  Each string is the name of a non-compound metadata field (or the keyword DEFAULT, for an unsubheaded list), optionally followed by a semi-colon and a comma separated list of options.  E.G:&lt;br /&gt;
&lt;br /&gt;
 variations =&amp;gt; [&lt;br /&gt;
  &amp;quot;creators_name;first_letter&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;,&lt;br /&gt;
  &amp;quot;DEFAULT&amp;quot;&lt;br /&gt;
 ],&lt;br /&gt;
&lt;br /&gt;
See [[views.pl]] for the list of options.&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=EPrints_Control_Format&amp;diff=10370</id>
		<title>EPrints Control Format</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=EPrints_Control_Format&amp;diff=10370"/>
		<updated>2012-03-23T14:16:19Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: /* $index (3.2.0+) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{formats}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= EPrints Control =&lt;br /&gt;
&lt;br /&gt;
== Output Tags ==&lt;br /&gt;
&lt;br /&gt;
=== epc:print ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;epc:print expr='expression' opt='key=value;key2=value2'/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;amp;lt;cite:citation xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;br /&gt;
           xmlns:cite=&amp;quot;http://eprints.org/ep3/citation&amp;quot;&lt;br /&gt;
           xmlns:epc=&amp;quot;http://eprints.org/ep3/control&amp;quot;&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;epc:print expr=&amp;quot;$item.citation('default')&amp;quot; /&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;/cite:citation&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
Outputs the result of the expression in the 'expr' attribute. &lt;br /&gt;
&lt;br /&gt;
Rendering options may be passed in the opt attribute using a key=value form, with semicolons separating multiple options.&lt;br /&gt;
&lt;br /&gt;
Any [[EPScript]] expression can be used. The most simple is just 'eprintid','title','creators' etc. You can also use values from the configuration files by using '$config{base_url}'.&lt;br /&gt;
&lt;br /&gt;
=== Print in attributes using {} ===&lt;br /&gt;
&lt;br /&gt;
Sometimes you may wish to insert a value into an XML attribute. eg. the &amp;quot;href&amp;quot; part of an anchor. Rather than a complicated system, but correct XML, we decide to go for something a bit more readable. Any {} pair in an XML attribute will be treated as a epc:print.&lt;br /&gt;
&lt;br /&gt;
So you can do something like &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;a href=&amp;quot;http://eprints.badger.edu/cgi/myscript.pl?eprintid={eprintid}&amp;quot;&amp;gt;run myscript on this eprint&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== epc:phrase ===&lt;br /&gt;
&lt;br /&gt;
simple:&lt;br /&gt;
 &amp;lt;epc:phrase ref='phraseid' /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with pins:&lt;br /&gt;
 &amp;lt;epc:phrase ref='phraseid'&amp;gt;&lt;br /&gt;
   &amp;lt;epc:param name='somepin'&amp;gt;Content&amp;lt;/epc:param&amp;gt;&lt;br /&gt;
 &amp;lt;/epc:phrase&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Outputs the content of the phrase refered to by 'ref'. Any necessary parameters may be set using the &amp;lt;epc:param&amp;gt; tag, with the contents inserted into the pin with the name corresponding to the name attribute.&lt;br /&gt;
&lt;br /&gt;
== Conditional Tags ==&lt;br /&gt;
&lt;br /&gt;
=== epc:if ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;epc:if test='expr'&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/epc:if&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Outputs any XHTML content and evaluates any EPrints Control structures within the epc:if block if the expression in the test attribute is true.&lt;br /&gt;
&lt;br /&gt;
=== epc:choose, epc:when, epc:otherwise ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;epc:choose&amp;gt;&lt;br /&gt;
   &amp;lt;epc:when test='expr'&amp;gt; &lt;br /&gt;
   ...&lt;br /&gt;
   &amp;lt;/epc:when&amp;gt;&lt;br /&gt;
   &amp;lt;epc:when test='expr2'&amp;gt; &lt;br /&gt;
   ...&lt;br /&gt;
   &amp;lt;/epc:when&amp;gt;&lt;br /&gt;
   &amp;lt;epc:otherwise&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   &amp;lt;/epc:otherwise&amp;gt;&lt;br /&gt;
 &amp;lt;/epc:choose&amp;gt;&lt;br /&gt;
&lt;br /&gt;
epc:choose allows for the construction of a complex conditional. Each epc:when block's 'test' attribute is evaluated, and the content of the block is returned if the result is true. If no expressions return true, the optional epc:otherwise block is returned. Note that no subsequent epc:when blocks are evaluated once the first block to return true is reached.&lt;br /&gt;
&lt;br /&gt;
== Loops ==&lt;br /&gt;
&lt;br /&gt;
Multiple values can be iterated over. For example.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;epc:foreach expr=&amp;quot;creators_name&amp;quot; iterator=&amp;quot;name&amp;quot;&amp;gt;&lt;br /&gt;
    ( &amp;lt;epc:print expr=&amp;quot;$name&amp;quot; /&amp;gt; )&lt;br /&gt;
  &amp;lt;/epc:foreach&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== $index (3.2.0+) ===&lt;br /&gt;
&lt;br /&gt;
Within a foreach block you can use $index to find what iteration of the loop is on. The first value is zero.&lt;br /&gt;
&lt;br /&gt;
This can be used with the modulus &amp;quot;%&amp;quot; to add a strip effect, if wanted, eg.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;table&amp;gt;&lt;br /&gt;
  &amp;lt;epc:foreach expr=&amp;quot;creators_name&amp;quot; iterator=&amp;quot;name&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;epc:if test=&amp;quot;$index % 2&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;tr class='odd'&amp;gt;&amp;lt;td&amp;gt;&amp;lt;epc:print expr=&amp;quot;$name&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;/epc:if&amp;gt;&lt;br /&gt;
    &amp;lt;epc:if test=&amp;quot;!($index % 2)&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;tr class='even'&amp;gt;&amp;lt;td&amp;gt;&amp;lt;epc:print expr=&amp;quot;$name&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;/epc:if&amp;gt;&lt;br /&gt;
  &amp;lt;/epc:foreach&amp;gt;&lt;br /&gt;
  &amp;lt;/table&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== limit (3.2.0+) ===&lt;br /&gt;
&lt;br /&gt;
You can set a limit of how many iterations to process using a &amp;quot;limit&amp;quot; attribute on the epc:foreach element. For example, &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;epc:foreach expr=&amp;quot;creators_name&amp;quot; iterator=&amp;quot;name&amp;quot; limit=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== epc:debug (3.2.0+) ==&lt;br /&gt;
&lt;br /&gt;
The epc:debug element has identical syntax to epc:print, but the result is sent to the error log -- either the command line, or to the apache error log.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;epc:debug expr='expression' opt='key=value;key2=value2'/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== epc:set (3.2.0+) ==&lt;br /&gt;
&lt;br /&gt;
This allows a variable to be set for any print or if elements within the epc:set. This is useful if creating the value has a notable cost which you wish to minimise. &lt;br /&gt;
&lt;br /&gt;
$item.documents() requires some database access, and the results are not cached, so using this speeds things up.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;epc:set name='docs' expr='$item.documents()'&amp;gt;&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=LDAP&amp;diff=10303</id>
		<title>LDAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=LDAP&amp;diff=10303"/>
		<updated>2012-03-14T15:42:20Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: /* LDAP Authentication */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Authentication]]&lt;br /&gt;
&lt;br /&gt;
==LDAP Authentication==&lt;br /&gt;
&lt;br /&gt;
===LDAP and User Roles===&lt;br /&gt;
&lt;br /&gt;
It is recommended that certain user rights are removed when using LDAP for login. The user should not be allowed to change their password or their email address. It is also suggested that the user not be allowed to edit their profile, however I have found certain fields that I would like the user to edit. To set the rights edit the file : &lt;br /&gt;
&lt;br /&gt;
 vi /opt/eprints3/archives/yourarchivename/cfg/cfg.d/user_roles.pl&lt;br /&gt;
&lt;br /&gt;
 ######################################################################&lt;br /&gt;
 #&lt;br /&gt;
 # User Roles&lt;br /&gt;
 #&lt;br /&gt;
 #  Here you can configure which different types of user are &lt;br /&gt;
 #  parts of the system they are allowed to use.&lt;br /&gt;
 #&lt;br /&gt;
 ######################################################################&lt;br /&gt;
 $c-&amp;gt;{user_roles}-&amp;gt;{user} = [qw/&lt;br /&gt;
        general&lt;br /&gt;
        edit-own-record&lt;br /&gt;
        saved-searches&lt;br /&gt;
        deposit&lt;br /&gt;
 /],&lt;br /&gt;
 $c-&amp;gt;{user_roles}-&amp;gt;{editor} = [qw/&lt;br /&gt;
        general&lt;br /&gt;
        edit-own-record&lt;br /&gt;
        saved-searches&lt;br /&gt;
        deposit&lt;br /&gt;
        editor&lt;br /&gt;
        view-status&lt;br /&gt;
        staff-view&lt;br /&gt;
 /],&lt;br /&gt;
 $c-&amp;gt;{user_roles}-&amp;gt;{admin} = [qw/&lt;br /&gt;
        general&lt;br /&gt;
        edit-own-record&lt;br /&gt;
        saved-searches&lt;br /&gt;
        set-password&lt;br /&gt;
        deposit&lt;br /&gt;
        change-email&lt;br /&gt;
        editor&lt;br /&gt;
        view-status&lt;br /&gt;
        staff-view&lt;br /&gt;
        admin&lt;br /&gt;
 /],&lt;br /&gt;
 #$c-&amp;gt;{user_roles}-&amp;gt;{minuser} = [qw/&lt;br /&gt;
 #       saved-searches&lt;br /&gt;
 #       set-password&lt;br /&gt;
 #       change-email&lt;br /&gt;
 #       change-user&lt;br /&gt;
 #       no_edit_own_record&lt;br /&gt;
 #       lock-username-to-email&lt;br /&gt;
 #/];&lt;br /&gt;
&lt;br /&gt;
After editing restart Apache.&lt;br /&gt;
&lt;br /&gt;
===LDAP Authentication with Bulk Import of Users===&lt;br /&gt;
&lt;br /&gt;
This recipe enables authenticating passwords against an LDAP directory for all users (including administrators). The users will need to already exist in EPrints, most likely created by a bulk import from your LDAP server.&lt;br /&gt;
&lt;br /&gt;
The recommendation for EPrints is not to allow users to alter email and passwords, as these changes are not at present written back to the LDAP database.&lt;br /&gt;
&lt;br /&gt;
====LDAP Configuration====&lt;br /&gt;
&lt;br /&gt;
All changes for LDAP authentication can be made in a single file, the file contains useful notes on configuration. Here is an example from my site, I have configured a standard Samba Domain using LDAP for authentication, if you have similar then this config may work for you :&lt;br /&gt;
&lt;br /&gt;
See [[user_login.pl]] for general information on check_user_password.&lt;br /&gt;
&lt;br /&gt;
Edit the file :&lt;br /&gt;
&lt;br /&gt;
 vi /opt/eprints3/archives/yourarchivename/cfg/cfg.d/user_login.pl&lt;br /&gt;
&lt;br /&gt;
 # This function allows you to override the default username/password&lt;br /&gt;
 # authentication. For example, you could apply different authentication rules to &lt;br /&gt;
 # different types of user.&lt;br /&gt;
 #&lt;br /&gt;
 # Example: LDAP Authentication (Quick Start)&lt;br /&gt;
 #&lt;br /&gt;
 # Tip: use the test script to determine your LDAP parameters first!&lt;br /&gt;
 # Tip: remove the set-password priviledge from users and editors in&lt;br /&gt;
 # user_roles.pl. Also consider removing edit-own-record and &lt;br /&gt;
 # change-email.&lt;br /&gt;
 #&lt;br /&gt;
 use Net::LDAP; # IO::Socket::SSL also required&lt;br /&gt;
 use Net::LDAP::Util;&lt;br /&gt;
 &lt;br /&gt;
 $c-&amp;gt;{check_user_password} = sub {&lt;br /&gt;
  my( $repo, $username, $password ) = @_;&lt;br /&gt;
 &lt;br /&gt;
  my $user = $repo-&amp;gt;user_by_username( $username );&lt;br /&gt;
  return unless $user;&lt;br /&gt;
 &lt;br /&gt;
  $username = $user-&amp;gt;value( &amp;quot;username&amp;quot; );&lt;br /&gt;
 &lt;br /&gt;
  my $user_type = $user-&amp;gt;get_type;&lt;br /&gt;
  if( $user_type eq &amp;quot;admin&amp;quot; )&lt;br /&gt;
  {&lt;br /&gt;
   # internal authentication for &amp;quot;admin&amp;quot; type&lt;br /&gt;
   return $repo-&amp;gt;database-&amp;gt;valid_login( $username, $password );&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  # LDAP authentication for &amp;quot;user&amp;quot; and &amp;quot;editor&amp;quot; types&lt;br /&gt;
  #&lt;br /&gt;
  # LDAP hostname (and port if not the default)&lt;br /&gt;
  my $ldap_host = &amp;quot;ldap.yourdomain.ac.uk&amp;quot;;&lt;br /&gt;
  #my $ldap_host = &amp;quot;ldap.host.name:1234&amp;quot;;&lt;br /&gt;
  #my $ldap_host = &amp;quot;ldaps://ldap.host.name&amp;quot;; # if server supports LDAPS&lt;br /&gt;
 &lt;br /&gt;
  # Distinguished name for this user&lt;br /&gt;
  # The distinguished name is a unique name for an LDAP entry.&lt;br /&gt;
  # e.g. &amp;quot;cn=John Smith, ou=staff, dc=eprints, dc=org&amp;quot;&lt;br /&gt;
  # You will need to derive this from the username or user metadata&lt;br /&gt;
  my $ldap_dn = sprintf(&amp;quot;uid=%s,ou=People,dc=example,dc=org&amp;quot;,&lt;br /&gt;
   Net::LDAP::Util::escape_dn_value($username)&lt;br /&gt;
  );&lt;br /&gt;
 &lt;br /&gt;
  my $ldap = Net::LDAP-&amp;gt;new ( $ldap_host, version =&amp;gt; 3 );&lt;br /&gt;
  unless( $ldap )&lt;br /&gt;
  {&lt;br /&gt;
   $repo-&amp;gt;log( &amp;quot;LDAP error: $@&amp;quot; );&lt;br /&gt;
   return;&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  # Start secure connection (not needed if using LDAPS)&lt;br /&gt;
  my $ssl = $ldap-&amp;gt;start_tls( sslversion =&amp;gt; &amp;quot;sslv3&amp;quot; );&lt;br /&gt;
  if( $ssl-&amp;gt;code() )&lt;br /&gt;
  {&lt;br /&gt;
   $repo-&amp;gt;log( &amp;quot;LDAP SSL error: &amp;quot; . $ssl-&amp;gt;error() );&lt;br /&gt;
   return;&lt;br /&gt;
  }&lt;br /&gt;
  # Check password&lt;br /&gt;
  my $mesg = $ldap-&amp;gt;bind( $ldap_dn, password =&amp;gt; $password );&lt;br /&gt;
  if( $mesg-&amp;gt;code() )&lt;br /&gt;
  {&lt;br /&gt;
   return;&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  return $username;&lt;br /&gt;
 }&lt;br /&gt;
 # Advanced LDAP Configuration&lt;br /&gt;
 #&lt;br /&gt;
 # 1. It is also possible to define additional user types, each with a different&lt;br /&gt;
 # authentication mechanism. For example, you could keep the default user, &lt;br /&gt;
 # editor and admin types and add ldapuser, ldapeditor and ldapadmin types with&lt;br /&gt;
 # LDAP authentication - this would suit an arrangement where internal staff are &lt;br /&gt;
 # authenticated against the LDAP server but user accounts can still be granted &lt;br /&gt;
 # to external users.&lt;br /&gt;
 #&lt;br /&gt;
 # 2. Sometimes the distinguished name of the user is not computable from the &lt;br /&gt;
 # username. You may need to use values from the user metadata (e.g. name_given,&lt;br /&gt;
 # name_family):&lt;br /&gt;
 #&lt;br /&gt;
 #       my $name = $user-&amp;gt;get_value( &amp;quot;name&amp;quot; );&lt;br /&gt;
 #       my $ldap_dn = $name-&amp;gt;{family} . &amp;quot;, &amp;quot; . $name-&amp;gt;{given} .&amp;quot;, ou=yourorg, dc=yourdomain&amp;quot;;&lt;br /&gt;
 #&lt;br /&gt;
 # or perform an LDAP lookup to determine it (more complicated):&lt;br /&gt;
 #&lt;br /&gt;
 #       my $base = &amp;quot;ou=yourorg, dc=yourdomain&amp;quot;;&lt;br /&gt;
 #       my $result = $ldap-&amp;gt;search (&lt;br /&gt;
 #               base    =&amp;gt; &amp;quot;$base&amp;quot;,&lt;br /&gt;
 #               scope   =&amp;gt; &amp;quot;sub&amp;quot;,&lt;br /&gt;
 #               filter  =&amp;gt; &amp;quot;cn=$username&amp;quot;,&lt;br /&gt;
 #               attrs   =&amp;gt;  ['DN'],&lt;br /&gt;
 #               sizelimit=&amp;gt;1&lt;br /&gt;
 #       );&lt;br /&gt;
 #&lt;br /&gt;
 #       my $entr = $result-&amp;gt;pop_entry;&lt;br /&gt;
 #       unless( defined $entr )&lt;br /&gt;
 #       {&lt;br /&gt;
 #               return 0;&lt;br /&gt;
 #       }&lt;br /&gt;
 #       my $ldap_dn = $entr-&amp;gt;dn&lt;br /&gt;
 #&lt;br /&gt;
 # Alternatively, you could store the distinguished name as part of the user &lt;br /&gt;
 # metadata when the user account is imported              print STDERR &amp;quot;LDAP SSL error: &amp;quot; . $ssl-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
After editing restart Apache.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====LDAP Import====&lt;br /&gt;
&lt;br /&gt;
You can use the [http://files.eprints.org/27/1/update_users update_users script] and apply the following patch to make it work with eprints3:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--- update_users.orig   2007-04-23 16:22:26.000000000 +0200&lt;br /&gt;
+++ update_users    2007-04-24 21:16:40.000000000 +0200&lt;br /&gt;
@@ -1,6 +1,6 @@&lt;br /&gt;
-#!/usr/bin/perl -w -I/opt/eprints2/perl_lib&lt;br /&gt;
+#!/usr/bin/perl -w -I/opt/eprints3/perl_lib&lt;br /&gt;
&lt;br /&gt;
-use EPrints::User;&lt;br /&gt;
+use EPrints::DataObj::User;&lt;br /&gt;
 use EPrints::Session;&lt;br /&gt;
 use Net::LDAP;&lt;br /&gt;
 use strict;&lt;br /&gt;
@@ -16,6 +16,7 @@&lt;br /&gt;
&lt;br /&gt;
 # Start connection&lt;br /&gt;
 my $ldap = Net::LDAP-&amp;gt;new( &amp;quot;ldap.host.name&amp;quot;, version =&amp;gt; 3 );&lt;br /&gt;
+$ldap-&amp;gt;start_tls();&lt;br /&gt;
 unless( $ldap )&lt;br /&gt;
 {&lt;br /&gt;
    print STDERR &amp;quot;LDAP error: $@\n&amp;quot;;&lt;br /&gt;
@@ -74,7 +75,7 @@&lt;br /&gt;
        # New account&lt;br /&gt;
        if( $forreal )&lt;br /&gt;
        {&lt;br /&gt;
-           $user = EPrints::User::create_user( $session, &amp;quot;ldapuser&amp;quot; );&lt;br /&gt;
+           $user = EPrints::DataObj::User::create( $session, &amp;quot;user&amp;quot; );&lt;br /&gt;
            $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
            print &amp;quot;CREATING: $username\n&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
@@ -118,7 +119,7 @@&lt;br /&gt;
        print &amp;quot;FAMILY = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;sn&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        print &amp;quot;GIVEN = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;givenName&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        print &amp;quot;EMAIL = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;mail&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
-       print &amp;quot;DN = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;distinguishedName&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
+       print &amp;quot;DN = &amp;quot; . $entr-&amp;gt;dn . &amp;quot;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===LDAP Authentication with On-Demand Creation of Users===&lt;br /&gt;
&lt;br /&gt;
Here's an example of a customized &amp;lt;tt&amp;gt;/opt/eprints3/archives/ARCHIVEID/cfg/cfg.d/user_login.pl&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* allowing LDAP accounts to login, using the &amp;quot;Advanced LDAP Configuration&amp;quot; example&lt;br /&gt;
* allowing the local eprints admin account to login w/ database authentication&lt;br /&gt;
* creating eprints accounts for all successfully authenticated LDAP users ''on the fly''&lt;br /&gt;
&lt;br /&gt;
Most of the code is from the default &amp;lt;tt&amp;gt;user_login.pl&amp;lt;/tt&amp;gt; and from the [http://files.eprints.org/27/1/update_users update_users] script (which does not seem to exist anymore, but code &amp;amp; text below seem to have been written by [[User:Sp]] not later than May 7th 2007).&lt;br /&gt;
&lt;br /&gt;
Be sure to only use this over [[HTTPS]]!&lt;br /&gt;
&lt;br /&gt;
 $c-&amp;gt;{check_user_password} = sub {&lt;br /&gt;
    my( $session, $username, $password ) = @_;&lt;br /&gt;
    &lt;br /&gt;
    # LDAP authentication for &amp;quot;user&amp;quot;, &amp;quot;editor&amp;quot; and &amp;quot;admin&amp;quot; types (roles)&lt;br /&gt;
    &lt;br /&gt;
    use Net::LDAP; # IO::Socket::SSL also required&lt;br /&gt;
    &lt;br /&gt;
    # LDAP tunables&lt;br /&gt;
    my $ldap_host = &amp;quot;ldap.example.org&amp;quot;;&lt;br /&gt;
    my $base      = &amp;quot;dc=example,dc=org&amp;quot;;&lt;br /&gt;
    my $dn        = &amp;quot;cn=someProxyAccount,ou=accounts,$base&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    my $ldap      = Net::LDAP-&amp;gt;new ( $ldap_host, version =&amp;gt; 3 );&lt;br /&gt;
    unless( $ldap )&lt;br /&gt;
    {&lt;br /&gt;
        print STDERR &amp;quot;LDAP error: $@\n&amp;quot;;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Start secure connection (not needed if using LDAPS)&lt;br /&gt;
    my $ssl = $ldap-&amp;gt;start_tls();&lt;br /&gt;
    if( $ssl-&amp;gt;code() )&lt;br /&gt;
    {&lt;br /&gt;
        print STDERR &amp;quot;LDAP SSL error: &amp;quot; . $ssl-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Get password for the search-bind-account&lt;br /&gt;
    my $repository = $session-&amp;gt;get_repository;&lt;br /&gt;
    my $id         = $repository-&amp;gt;get_id;&lt;br /&gt;
    my $ldappass   = `cat /opt/eprints3/archives/$id/cfg/ldap.passwd`;&lt;br /&gt;
    chomp($ldappass);&lt;br /&gt;
    &lt;br /&gt;
    my $mesg = $ldap-&amp;gt;bind( $dn, password=&amp;gt;$ldappass );&lt;br /&gt;
    if( $mesg-&amp;gt;code() )&lt;br /&gt;
    {&lt;br /&gt;
        print STDERR &amp;quot;LDAP Bind error: &amp;quot; . $mesg-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Distinguished name (and attribues needed later on) for this user&lt;br /&gt;
    my $result = $ldap-&amp;gt;search (&lt;br /&gt;
        base    =&amp;gt; &amp;quot;$base&amp;quot;,&lt;br /&gt;
        scope   =&amp;gt; &amp;quot;sub&amp;quot;,&lt;br /&gt;
        filter  =&amp;gt; &amp;quot;(&amp;amp;(uid=$username)(objectclass=inetOrgPerson))&amp;quot;,&lt;br /&gt;
        attrs   =&amp;gt;  ['1.1', 'uid', 'sn', 'givenname', 'mail'],&lt;br /&gt;
        sizelimit=&amp;gt;1&lt;br /&gt;
    );&lt;br /&gt;
    my $entr = $result-&amp;gt;pop_entry;&lt;br /&gt;
    unless( defined $entr )&lt;br /&gt;
    {&lt;br /&gt;
        # Allow local EPrints authentication for admins (accounts not found in LDAP)&lt;br /&gt;
        my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
        return 0 unless $user;&lt;br /&gt;
        &lt;br /&gt;
        my $user_type = $user-&amp;gt;get_type;&lt;br /&gt;
        if( $user_type eq &amp;quot;admin&amp;quot; )&lt;br /&gt;
        {&lt;br /&gt;
            # internal authentication for &amp;quot;admin&amp;quot; type&lt;br /&gt;
            return $session-&amp;gt;get_database-&amp;gt;valid_login( $username, $password );&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    my $ldap_dn = $entr-&amp;gt;dn;&lt;br /&gt;
    &lt;br /&gt;
    # Check password&lt;br /&gt;
    my $mesg = $ldap-&amp;gt;bind( $ldap_dn, password =&amp;gt; $password );&lt;br /&gt;
    if( $mesg-&amp;gt;code() )&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Does account already exist?&lt;br /&gt;
    my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
    if( !defined $user )&lt;br /&gt;
    {&lt;br /&gt;
        # New account&lt;br /&gt;
        $user = EPrints::DataObj::User::create( $session, &amp;quot;user&amp;quot; );&lt;br /&gt;
        $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Set metadata&lt;br /&gt;
    my $name = {};&lt;br /&gt;
    $name-&amp;gt;{family} = $entr-&amp;gt;get_value( &amp;quot;sn&amp;quot; );&lt;br /&gt;
    $name-&amp;gt;{given} = $entr-&amp;gt;get_value( &amp;quot;givenName&amp;quot; );&lt;br /&gt;
    $user-&amp;gt;set_value( &amp;quot;name&amp;quot;, $name );&lt;br /&gt;
    $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
    $user-&amp;gt;set_value( &amp;quot;email&amp;quot;, $entr-&amp;gt;get_value( &amp;quot;mail&amp;quot; ) );&lt;br /&gt;
    $user-&amp;gt;commit();&lt;br /&gt;
    &lt;br /&gt;
    $ldap-&amp;gt;unbind if $ldap;&lt;br /&gt;
    &lt;br /&gt;
    return 1;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Things to note====&lt;br /&gt;
&lt;br /&gt;
* This script uses a dedicated proxy account which must exist in your LDAP tree and has appropriate permissions (ACL settings) to search for users and read their &amp;lt;tt&amp;gt;uid,givenname,sn,mail&amp;lt;/tt&amp;gt; attributes.&lt;br /&gt;
* It gets this proxy accounts' password from a file inside the repository configuration. this file needs to have read permissions for the user your webserver runs as (e.g. &amp;lt;tt&amp;gt;www-data&amp;lt;/tt&amp;gt; on Debian).  Use file system permissions to protect this (e.g. &amp;lt;tt&amp;gt;chmod 400 ldap.passwd&amp;lt;/tt&amp;gt;).&lt;br /&gt;
* It changes the flow of &amp;lt;tt&amp;gt;user_login.pl&amp;lt;/tt&amp;gt; a little to only check for local ''admin'' accounts (no users or editors; we have them all in our LDAP tree) and only when no user is found for ldap authentication. This allows you to have your admins in LDAP (if you want) but still use the local admin for &amp;quot;promoting&amp;quot; other users to admins, among other things (which could also be done with a simple SQL &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; directly in the RDBMS). If you don't need the local admin, remove those lines and just &amp;lt;tt&amp;gt;return 0&amp;lt;/tt&amp;gt; since no user was found in LDAP.&lt;br /&gt;
* you could change the default role for generated user accounts from &amp;lt;tt&amp;gt;user&amp;lt;/tt&amp;gt;, if you really wanted.&lt;br /&gt;
&lt;br /&gt;
===Kerberos Authentication on AD with On-Demand Creation of Users using LDAP ===&lt;br /&gt;
&lt;br /&gt;
Tested on 3.3.8&lt;br /&gt;
&lt;br /&gt;
Here's another example of a customized &amp;lt;tt&amp;gt;/opt/eprints3/archives/ARCHIVEID/cfg/cfg.d/user_login.pl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
* allowing LDAP accounts to login, using the following example&lt;br /&gt;
* allowing the local eprints admin account to login w/ database authentication&lt;br /&gt;
* creating eprints accounts for all successfully authenticated LDAP users ''on the fly''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 $c-&amp;gt;{check_user_password} = sub {&lt;br /&gt;
   my( $session, $username, $password ) = @_;&lt;br /&gt;
   &lt;br /&gt;
   # Kerberos authentication for &amp;quot;user&amp;quot;, &amp;quot;editor&amp;quot; and &amp;quot;admin&amp;quot; types (roles)&lt;br /&gt;
   &lt;br /&gt;
   use Net::LDAP; # IO::Socket::SSL also required&lt;br /&gt;
   use Authen::Krb5::Simple;&lt;br /&gt;
   use Authen::SASL;&lt;br /&gt;
   &lt;br /&gt;
   # LDAP tunables&lt;br /&gt;
   my $ldap_host = &amp;quot;ldap.example.org&amp;quot;;&lt;br /&gt;
   my $base      = &amp;quot;OU=people,DC=example,DC=org&amp;quot;;&lt;br /&gt;
   my $proxy_user =&amp;quot;ad_read&amp;quot;;&lt;br /&gt;
   my $dn        = &amp;quot;CN=$proxy_user,$base&amp;quot;;&lt;br /&gt;
   &lt;br /&gt;
   # Kerberos tunables&lt;br /&gt;
   my $krb_host = &amp;quot;example.org&amp;quot;;&lt;br /&gt;
      &lt;br /&gt;
   my $krb 	  = Authen::Krb5::Simple-&amp;gt;new(realm =&amp;gt; $krb_host);&lt;br /&gt;
   unless ( $krb )&lt;br /&gt;
   {&lt;br /&gt;
   	print STDERR &amp;quot;Kerberos error: $@\n&amp;quot;;&lt;br /&gt;
   	return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   my $ldap      = Net::LDAP-&amp;gt;new ( $ldap_host );&lt;br /&gt;
   unless( $ldap )&lt;br /&gt;
   {&lt;br /&gt;
       print STDERR &amp;quot;LDAP error: $@\n&amp;quot;;&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   my $sasl = Authen::SASL-&amp;gt;new(&lt;br /&gt;
          mechanism =&amp;gt; 'GSSAPI', &lt;br /&gt;
          callback =&amp;gt; { user =&amp;gt; 'ad_read' }&lt;br /&gt;
        ) or die &amp;quot;$@&amp;quot;;&lt;br /&gt;
   &lt;br /&gt;
   my $mesg = $ldap-&amp;gt;bind(sasl =&amp;gt; $sasl);&lt;br /&gt;
   &lt;br /&gt;
   if( $mesg-&amp;gt;code() )&lt;br /&gt;
   {&lt;br /&gt;
       print STDERR &amp;quot;LDAP Bind error: &amp;quot; . $mesg-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   # Distinguished name (and attribues needed later on) for this user&lt;br /&gt;
   my $result = $ldap-&amp;gt;search (&lt;br /&gt;
       base    =&amp;gt; &amp;quot;$base&amp;quot;,&lt;br /&gt;
       filter  =&amp;gt; &amp;quot;(&amp;amp;(sAMAccountName=$username))&amp;quot;,&lt;br /&gt;
       attrs   =&amp;gt;  ['1.1', 'uid', 'sn', 'givenname', 'mail', 'department', 'title'],&lt;br /&gt;
       sizelimit=&amp;gt;1&lt;br /&gt;
   );&lt;br /&gt;
   &lt;br /&gt;
   my $entr = $result-&amp;gt;pop_entry;&lt;br /&gt;
   unless( defined $entr )&lt;br /&gt;
   {&lt;br /&gt;
       # Allow local EPrints authentication for admins (accounts not found in LDAP)&lt;br /&gt;
       my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
       return 0 unless $user;&lt;br /&gt;
   &lt;br /&gt;
       my $user_type = $user-&amp;gt;get_type;&lt;br /&gt;
       if( $user_type eq &amp;quot;admin&amp;quot; )&lt;br /&gt;
       {&lt;br /&gt;
           # internal authentication for &amp;quot;admin&amp;quot; type&lt;br /&gt;
           return $session-&amp;gt;get_database-&amp;gt;valid_login( $username, $password );&lt;br /&gt;
       }&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   # Check password&lt;br /&gt;
   if( !$krb-&amp;gt;authenticate( $username, $password ) )&lt;br /&gt;
   {&lt;br /&gt;
   	print STDERR &amp;quot;$username authentication failed: &amp;quot;, $krb-&amp;gt;errstr(), &amp;quot;\n&amp;quot;;&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   # Does account already exist?&lt;br /&gt;
   my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
   if( !defined $user )&lt;br /&gt;
   {&lt;br /&gt;
       # New account&lt;br /&gt;
       $user = EPrints::DataObj::User::create( $session, &amp;quot;user&amp;quot; );&lt;br /&gt;
       $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   # Set metadata&lt;br /&gt;
   my $name = {};&lt;br /&gt;
   $name-&amp;gt;{family} = $entr-&amp;gt;get_value( &amp;quot;sn&amp;quot; );&lt;br /&gt;
   $name-&amp;gt;{given} = $entr-&amp;gt;get_value( &amp;quot;givenName&amp;quot; );&lt;br /&gt;
   $name-&amp;gt;{honourific} = $entr-&amp;gt;get_value( &amp;quot;title&amp;quot;);&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;name&amp;quot;, $name );&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;email&amp;quot;, $entr-&amp;gt;get_value( &amp;quot;mail&amp;quot; ) );&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;dept&amp;quot;, $entr-&amp;gt;get_value(&amp;quot;department&amp;quot;)  );&lt;br /&gt;
   $user-&amp;gt;commit();&lt;br /&gt;
   &lt;br /&gt;
   $ldap-&amp;gt;unbind if $ldap;&lt;br /&gt;
   &lt;br /&gt;
   return 1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
===Possible enhancements===&lt;br /&gt;
&lt;br /&gt;
Currently this script does not remove local eprints accounts from the database: when accounts get deleted from the LDAP database the corresponding local EPrints accounts sit around forever. But since login isn't possible anymore this is not a risk or of high priority.&lt;br /&gt;
&lt;br /&gt;
Depending on your situation it may be enough to run some kind of cleanup script, e.g. once a year, that get's a list of all local EPrints accounts, loops over them and &amp;lt;code&amp;gt;$user-&amp;gt;remove&amp;lt;/code&amp;gt;s all those, which cannot be found in LDAP anymore (except for those where &amp;lt;code&amp;gt;$user_type eq 'admin'&amp;lt;/code&amp;gt;, so you don't risk losing your local admins).&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=LDAP&amp;diff=10302</id>
		<title>LDAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=LDAP&amp;diff=10302"/>
		<updated>2012-03-14T15:40:57Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: /* Kerberos Authentication on AD with On-Demand Creation of Users using LDAP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Authentication]]&lt;br /&gt;
&lt;br /&gt;
==LDAP Authentication==&lt;br /&gt;
&lt;br /&gt;
===LDAP and User Roles===&lt;br /&gt;
&lt;br /&gt;
It is recommended that certain user rights are removed when using LDAP for login. The user should not be allowed to change their password or their email address. It is also suggested that the user not be allowed to edit their profile, however I have found certain fields that I would like the user to edit. To set the rights edit the file : &lt;br /&gt;
&lt;br /&gt;
 vi /opt/eprints3/archives/yourarchivename/cfg/cfg.d/user_roles.pl&lt;br /&gt;
&lt;br /&gt;
 ######################################################################&lt;br /&gt;
 #&lt;br /&gt;
 # User Roles&lt;br /&gt;
 #&lt;br /&gt;
 #  Here you can configure which different types of user are &lt;br /&gt;
 #  parts of the system they are allowed to use.&lt;br /&gt;
 #&lt;br /&gt;
 ######################################################################&lt;br /&gt;
 $c-&amp;gt;{user_roles}-&amp;gt;{user} = [qw/&lt;br /&gt;
        general&lt;br /&gt;
        edit-own-record&lt;br /&gt;
        saved-searches&lt;br /&gt;
        deposit&lt;br /&gt;
 /],&lt;br /&gt;
 $c-&amp;gt;{user_roles}-&amp;gt;{editor} = [qw/&lt;br /&gt;
        general&lt;br /&gt;
        edit-own-record&lt;br /&gt;
        saved-searches&lt;br /&gt;
        deposit&lt;br /&gt;
        editor&lt;br /&gt;
        view-status&lt;br /&gt;
        staff-view&lt;br /&gt;
 /],&lt;br /&gt;
 $c-&amp;gt;{user_roles}-&amp;gt;{admin} = [qw/&lt;br /&gt;
        general&lt;br /&gt;
        edit-own-record&lt;br /&gt;
        saved-searches&lt;br /&gt;
        set-password&lt;br /&gt;
        deposit&lt;br /&gt;
        change-email&lt;br /&gt;
        editor&lt;br /&gt;
        view-status&lt;br /&gt;
        staff-view&lt;br /&gt;
        admin&lt;br /&gt;
 /],&lt;br /&gt;
 #$c-&amp;gt;{user_roles}-&amp;gt;{minuser} = [qw/&lt;br /&gt;
 #       saved-searches&lt;br /&gt;
 #       set-password&lt;br /&gt;
 #       change-email&lt;br /&gt;
 #       change-user&lt;br /&gt;
 #       no_edit_own_record&lt;br /&gt;
 #       lock-username-to-email&lt;br /&gt;
 #/];&lt;br /&gt;
&lt;br /&gt;
After editing restart Apache.&lt;br /&gt;
&lt;br /&gt;
===LDAP Authentication with Bulk Import of Users===&lt;br /&gt;
&lt;br /&gt;
This recipe enables authenticating passwords against an LDAP directory for all users (including administrators). The users will need to already exist in EPrints, most likely created by a bulk import from your LDAP server.&lt;br /&gt;
&lt;br /&gt;
The recommendation for EPrints is not to allow users to alter email and passwords, as these changes are not at present written back to the LDAP database.&lt;br /&gt;
&lt;br /&gt;
====LDAP Configuration====&lt;br /&gt;
&lt;br /&gt;
All changes for LDAP authentication can be made in a single file, the file contains useful notes on configuration. Here is an example from my site, I have configured a standard Samba Domain using LDAP for authentication, if you have similar then this config may work for you :&lt;br /&gt;
&lt;br /&gt;
See [[user_login.pl]] for general information on check_user_password.&lt;br /&gt;
&lt;br /&gt;
Edit the file :&lt;br /&gt;
&lt;br /&gt;
 vi /opt/eprints3/archives/yourarchivename/cfg/cfg.d/user_login.pl&lt;br /&gt;
&lt;br /&gt;
 # This function allows you to override the default username/password&lt;br /&gt;
 # authentication. For example, you could apply different authentication rules to &lt;br /&gt;
 # different types of user.&lt;br /&gt;
 #&lt;br /&gt;
 # Example: LDAP Authentication (Quick Start)&lt;br /&gt;
 #&lt;br /&gt;
 # Tip: use the test script to determine your LDAP parameters first!&lt;br /&gt;
 # Tip: remove the set-password priviledge from users and editors in&lt;br /&gt;
 # user_roles.pl. Also consider removing edit-own-record and &lt;br /&gt;
 # change-email.&lt;br /&gt;
 #&lt;br /&gt;
 use Net::LDAP; # IO::Socket::SSL also required&lt;br /&gt;
 use Net::LDAP::Util;&lt;br /&gt;
 &lt;br /&gt;
 $c-&amp;gt;{check_user_password} = sub {&lt;br /&gt;
  my( $repo, $username, $password ) = @_;&lt;br /&gt;
 &lt;br /&gt;
  my $user = $repo-&amp;gt;user_by_username( $username );&lt;br /&gt;
  return unless $user;&lt;br /&gt;
 &lt;br /&gt;
  $username = $user-&amp;gt;value( &amp;quot;username&amp;quot; );&lt;br /&gt;
 &lt;br /&gt;
  my $user_type = $user-&amp;gt;get_type;&lt;br /&gt;
  if( $user_type eq &amp;quot;admin&amp;quot; )&lt;br /&gt;
  {&lt;br /&gt;
   # internal authentication for &amp;quot;admin&amp;quot; type&lt;br /&gt;
   return $repo-&amp;gt;database-&amp;gt;valid_login( $username, $password );&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  # LDAP authentication for &amp;quot;user&amp;quot; and &amp;quot;editor&amp;quot; types&lt;br /&gt;
  #&lt;br /&gt;
  # LDAP hostname (and port if not the default)&lt;br /&gt;
  my $ldap_host = &amp;quot;ldap.yourdomain.ac.uk&amp;quot;;&lt;br /&gt;
  #my $ldap_host = &amp;quot;ldap.host.name:1234&amp;quot;;&lt;br /&gt;
  #my $ldap_host = &amp;quot;ldaps://ldap.host.name&amp;quot;; # if server supports LDAPS&lt;br /&gt;
 &lt;br /&gt;
  # Distinguished name for this user&lt;br /&gt;
  # The distinguished name is a unique name for an LDAP entry.&lt;br /&gt;
  # e.g. &amp;quot;cn=John Smith, ou=staff, dc=eprints, dc=org&amp;quot;&lt;br /&gt;
  # You will need to derive this from the username or user metadata&lt;br /&gt;
  my $ldap_dn = sprintf(&amp;quot;uid=%s,ou=People,dc=example,dc=org&amp;quot;,&lt;br /&gt;
   Net::LDAP::Util::escape_dn_value($username)&lt;br /&gt;
  );&lt;br /&gt;
 &lt;br /&gt;
  my $ldap = Net::LDAP-&amp;gt;new ( $ldap_host, version =&amp;gt; 3 );&lt;br /&gt;
  unless( $ldap )&lt;br /&gt;
  {&lt;br /&gt;
   $repo-&amp;gt;log( &amp;quot;LDAP error: $@&amp;quot; );&lt;br /&gt;
   return;&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  # Start secure connection (not needed if using LDAPS)&lt;br /&gt;
  my $ssl = $ldap-&amp;gt;start_tls( sslversion =&amp;gt; &amp;quot;sslv3&amp;quot; );&lt;br /&gt;
  if( $ssl-&amp;gt;code() )&lt;br /&gt;
  {&lt;br /&gt;
   $repo-&amp;gt;log( &amp;quot;LDAP SSL error: &amp;quot; . $ssl-&amp;gt;error() );&lt;br /&gt;
   return;&lt;br /&gt;
  }&lt;br /&gt;
  # Check password&lt;br /&gt;
  my $mesg = $ldap-&amp;gt;bind( $ldap_dn, password =&amp;gt; $password );&lt;br /&gt;
  if( $mesg-&amp;gt;code() )&lt;br /&gt;
  {&lt;br /&gt;
   return;&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  return $username;&lt;br /&gt;
 }&lt;br /&gt;
 # Advanced LDAP Configuration&lt;br /&gt;
 #&lt;br /&gt;
 # 1. It is also possible to define additional user types, each with a different&lt;br /&gt;
 # authentication mechanism. For example, you could keep the default user, &lt;br /&gt;
 # editor and admin types and add ldapuser, ldapeditor and ldapadmin types with&lt;br /&gt;
 # LDAP authentication - this would suit an arrangement where internal staff are &lt;br /&gt;
 # authenticated against the LDAP server but user accounts can still be granted &lt;br /&gt;
 # to external users.&lt;br /&gt;
 #&lt;br /&gt;
 # 2. Sometimes the distinguished name of the user is not computable from the &lt;br /&gt;
 # username. You may need to use values from the user metadata (e.g. name_given,&lt;br /&gt;
 # name_family):&lt;br /&gt;
 #&lt;br /&gt;
 #       my $name = $user-&amp;gt;get_value( &amp;quot;name&amp;quot; );&lt;br /&gt;
 #       my $ldap_dn = $name-&amp;gt;{family} . &amp;quot;, &amp;quot; . $name-&amp;gt;{given} .&amp;quot;, ou=yourorg, dc=yourdomain&amp;quot;;&lt;br /&gt;
 #&lt;br /&gt;
 # or perform an LDAP lookup to determine it (more complicated):&lt;br /&gt;
 #&lt;br /&gt;
 #       my $base = &amp;quot;ou=yourorg, dc=yourdomain&amp;quot;;&lt;br /&gt;
 #       my $result = $ldap-&amp;gt;search (&lt;br /&gt;
 #               base    =&amp;gt; &amp;quot;$base&amp;quot;,&lt;br /&gt;
 #               scope   =&amp;gt; &amp;quot;sub&amp;quot;,&lt;br /&gt;
 #               filter  =&amp;gt; &amp;quot;cn=$username&amp;quot;,&lt;br /&gt;
 #               attrs   =&amp;gt;  ['DN'],&lt;br /&gt;
 #               sizelimit=&amp;gt;1&lt;br /&gt;
 #       );&lt;br /&gt;
 #&lt;br /&gt;
 #       my $entr = $result-&amp;gt;pop_entry;&lt;br /&gt;
 #       unless( defined $entr )&lt;br /&gt;
 #       {&lt;br /&gt;
 #               return 0;&lt;br /&gt;
 #       }&lt;br /&gt;
 #       my $ldap_dn = $entr-&amp;gt;dn&lt;br /&gt;
 #&lt;br /&gt;
 # Alternatively, you could store the distinguished name as part of the user &lt;br /&gt;
 # metadata when the user account is imported              print STDERR &amp;quot;LDAP SSL error: &amp;quot; . $ssl-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
After editing restart Apache.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====LDAP Import====&lt;br /&gt;
&lt;br /&gt;
You can use the [http://files.eprints.org/27/1/update_users update_users script] and apply the following patch to make it work with eprints3:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--- update_users.orig   2007-04-23 16:22:26.000000000 +0200&lt;br /&gt;
+++ update_users    2007-04-24 21:16:40.000000000 +0200&lt;br /&gt;
@@ -1,6 +1,6 @@&lt;br /&gt;
-#!/usr/bin/perl -w -I/opt/eprints2/perl_lib&lt;br /&gt;
+#!/usr/bin/perl -w -I/opt/eprints3/perl_lib&lt;br /&gt;
&lt;br /&gt;
-use EPrints::User;&lt;br /&gt;
+use EPrints::DataObj::User;&lt;br /&gt;
 use EPrints::Session;&lt;br /&gt;
 use Net::LDAP;&lt;br /&gt;
 use strict;&lt;br /&gt;
@@ -16,6 +16,7 @@&lt;br /&gt;
&lt;br /&gt;
 # Start connection&lt;br /&gt;
 my $ldap = Net::LDAP-&amp;gt;new( &amp;quot;ldap.host.name&amp;quot;, version =&amp;gt; 3 );&lt;br /&gt;
+$ldap-&amp;gt;start_tls();&lt;br /&gt;
 unless( $ldap )&lt;br /&gt;
 {&lt;br /&gt;
    print STDERR &amp;quot;LDAP error: $@\n&amp;quot;;&lt;br /&gt;
@@ -74,7 +75,7 @@&lt;br /&gt;
        # New account&lt;br /&gt;
        if( $forreal )&lt;br /&gt;
        {&lt;br /&gt;
-           $user = EPrints::User::create_user( $session, &amp;quot;ldapuser&amp;quot; );&lt;br /&gt;
+           $user = EPrints::DataObj::User::create( $session, &amp;quot;user&amp;quot; );&lt;br /&gt;
            $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
            print &amp;quot;CREATING: $username\n&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
@@ -118,7 +119,7 @@&lt;br /&gt;
        print &amp;quot;FAMILY = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;sn&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        print &amp;quot;GIVEN = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;givenName&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        print &amp;quot;EMAIL = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;mail&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
-       print &amp;quot;DN = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;distinguishedName&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
+       print &amp;quot;DN = &amp;quot; . $entr-&amp;gt;dn . &amp;quot;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===LDAP Authentication with On-Demand Creation of Users===&lt;br /&gt;
&lt;br /&gt;
Here's an example of a customized &amp;lt;tt&amp;gt;/opt/eprints3/archives/ARCHIVEID/cfg/cfg.d/user_login.pl&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* allowing LDAP accounts to login, using the &amp;quot;Advanced LDAP Configuration&amp;quot; example&lt;br /&gt;
* allowing the local eprints admin account to login w/ database authentication&lt;br /&gt;
* creating eprints accounts for all successfully authenticated LDAP users ''on the fly''&lt;br /&gt;
&lt;br /&gt;
Most of the code is from the default &amp;lt;tt&amp;gt;user_login.pl&amp;lt;/tt&amp;gt; and from the [http://files.eprints.org/27/1/update_users update_users] script (which does not seem to exist anymore, but code &amp;amp; text below seem to have been written by [[User:Sp]] not later than May 7th 2007).&lt;br /&gt;
&lt;br /&gt;
Be sure to only use this over [[HTTPS]]!&lt;br /&gt;
&lt;br /&gt;
 $c-&amp;gt;{check_user_password} = sub {&lt;br /&gt;
    my( $session, $username, $password ) = @_;&lt;br /&gt;
    &lt;br /&gt;
    # LDAP authentication for &amp;quot;user&amp;quot;, &amp;quot;editor&amp;quot; and &amp;quot;admin&amp;quot; types (roles)&lt;br /&gt;
    &lt;br /&gt;
    use Net::LDAP; # IO::Socket::SSL also required&lt;br /&gt;
    &lt;br /&gt;
    # LDAP tunables&lt;br /&gt;
    my $ldap_host = &amp;quot;ldap.example.org&amp;quot;;&lt;br /&gt;
    my $base      = &amp;quot;dc=example,dc=org&amp;quot;;&lt;br /&gt;
    my $dn        = &amp;quot;cn=someProxyAccount,ou=accounts,$base&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    my $ldap      = Net::LDAP-&amp;gt;new ( $ldap_host, version =&amp;gt; 3 );&lt;br /&gt;
    unless( $ldap )&lt;br /&gt;
    {&lt;br /&gt;
        print STDERR &amp;quot;LDAP error: $@\n&amp;quot;;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Start secure connection (not needed if using LDAPS)&lt;br /&gt;
    my $ssl = $ldap-&amp;gt;start_tls();&lt;br /&gt;
    if( $ssl-&amp;gt;code() )&lt;br /&gt;
    {&lt;br /&gt;
        print STDERR &amp;quot;LDAP SSL error: &amp;quot; . $ssl-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Get password for the search-bind-account&lt;br /&gt;
    my $repository = $session-&amp;gt;get_repository;&lt;br /&gt;
    my $id         = $repository-&amp;gt;get_id;&lt;br /&gt;
    my $ldappass   = `cat /opt/eprints3/archives/$id/cfg/ldap.passwd`;&lt;br /&gt;
    chomp($ldappass);&lt;br /&gt;
    &lt;br /&gt;
    my $mesg = $ldap-&amp;gt;bind( $dn, password=&amp;gt;$ldappass );&lt;br /&gt;
    if( $mesg-&amp;gt;code() )&lt;br /&gt;
    {&lt;br /&gt;
        print STDERR &amp;quot;LDAP Bind error: &amp;quot; . $mesg-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Distinguished name (and attribues needed later on) for this user&lt;br /&gt;
    my $result = $ldap-&amp;gt;search (&lt;br /&gt;
        base    =&amp;gt; &amp;quot;$base&amp;quot;,&lt;br /&gt;
        scope   =&amp;gt; &amp;quot;sub&amp;quot;,&lt;br /&gt;
        filter  =&amp;gt; &amp;quot;(&amp;amp;(uid=$username)(objectclass=inetOrgPerson))&amp;quot;,&lt;br /&gt;
        attrs   =&amp;gt;  ['1.1', 'uid', 'sn', 'givenname', 'mail'],&lt;br /&gt;
        sizelimit=&amp;gt;1&lt;br /&gt;
    );&lt;br /&gt;
    my $entr = $result-&amp;gt;pop_entry;&lt;br /&gt;
    unless( defined $entr )&lt;br /&gt;
    {&lt;br /&gt;
        # Allow local EPrints authentication for admins (accounts not found in LDAP)&lt;br /&gt;
        my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
        return 0 unless $user;&lt;br /&gt;
        &lt;br /&gt;
        my $user_type = $user-&amp;gt;get_type;&lt;br /&gt;
        if( $user_type eq &amp;quot;admin&amp;quot; )&lt;br /&gt;
        {&lt;br /&gt;
            # internal authentication for &amp;quot;admin&amp;quot; type&lt;br /&gt;
            return $session-&amp;gt;get_database-&amp;gt;valid_login( $username, $password );&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    my $ldap_dn = $entr-&amp;gt;dn;&lt;br /&gt;
    &lt;br /&gt;
    # Check password&lt;br /&gt;
    my $mesg = $ldap-&amp;gt;bind( $ldap_dn, password =&amp;gt; $password );&lt;br /&gt;
    if( $mesg-&amp;gt;code() )&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Does account already exist?&lt;br /&gt;
    my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
    if( !defined $user )&lt;br /&gt;
    {&lt;br /&gt;
        # New account&lt;br /&gt;
        $user = EPrints::DataObj::User::create( $session, &amp;quot;user&amp;quot; );&lt;br /&gt;
        $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Set metadata&lt;br /&gt;
    my $name = {};&lt;br /&gt;
    $name-&amp;gt;{family} = $entr-&amp;gt;get_value( &amp;quot;sn&amp;quot; );&lt;br /&gt;
    $name-&amp;gt;{given} = $entr-&amp;gt;get_value( &amp;quot;givenName&amp;quot; );&lt;br /&gt;
    $user-&amp;gt;set_value( &amp;quot;name&amp;quot;, $name );&lt;br /&gt;
    $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
    $user-&amp;gt;set_value( &amp;quot;email&amp;quot;, $entr-&amp;gt;get_value( &amp;quot;mail&amp;quot; ) );&lt;br /&gt;
    $user-&amp;gt;commit();&lt;br /&gt;
    &lt;br /&gt;
    $ldap-&amp;gt;unbind if $ldap;&lt;br /&gt;
    &lt;br /&gt;
    return 1;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Things to note====&lt;br /&gt;
&lt;br /&gt;
* This script uses a dedicated proxy account which must exist in your LDAP tree and has appropriate permissions (ACL settings) to search for users and read their &amp;lt;tt&amp;gt;uid,givenname,sn,mail&amp;lt;/tt&amp;gt; attributes.&lt;br /&gt;
* It gets this proxy accounts' password from a file inside the repository configuration. this file needs to have read permissions for the user your webserver runs as (e.g. &amp;lt;tt&amp;gt;www-data&amp;lt;/tt&amp;gt; on Debian).  Use file system permissions to protect this (e.g. &amp;lt;tt&amp;gt;chmod 400 ldap.passwd&amp;lt;/tt&amp;gt;).&lt;br /&gt;
* It changes the flow of &amp;lt;tt&amp;gt;user_login.pl&amp;lt;/tt&amp;gt; a little to only check for local ''admin'' accounts (no users or editors; we have them all in our LDAP tree) and only when no user is found for ldap authentication. This allows you to have your admins in LDAP (if you want) but still use the local admin for &amp;quot;promoting&amp;quot; other users to admins, among other things (which could also be done with a simple SQL &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; directly in the RDBMS). If you don't need the local admin, remove those lines and just &amp;lt;tt&amp;gt;return 0&amp;lt;/tt&amp;gt; since no user was found in LDAP.&lt;br /&gt;
* you could change the default role for generated user accounts from &amp;lt;tt&amp;gt;user&amp;lt;/tt&amp;gt;, if you really wanted.&lt;br /&gt;
&lt;br /&gt;
===Kerberos Authentication on AD with On-Demand Creation of Users using LDAP ===&lt;br /&gt;
&lt;br /&gt;
Tested on 3.3.8&lt;br /&gt;
&lt;br /&gt;
Here's another example of a customized &amp;lt;tt&amp;gt;/opt/eprints3/archives/ARCHIVEID/cfg/cfg.d/user_login.pl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
* allowing LDAP accounts to login, using the following example&lt;br /&gt;
* allowing the local eprints admin account to login w/ database authentication&lt;br /&gt;
* creating eprints accounts for all successfully authenticated LDAP users ''on the fly''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 $c-&amp;gt;{check_user_password} = sub {&lt;br /&gt;
   my( $session, $username, $password ) = @_;&lt;br /&gt;
   &lt;br /&gt;
   # Kerberos authentication for &amp;quot;user&amp;quot;, &amp;quot;editor&amp;quot; and &amp;quot;admin&amp;quot; types (roles)&lt;br /&gt;
   &lt;br /&gt;
   use Net::LDAP; # IO::Socket::SSL also required&lt;br /&gt;
   use Authen::Krb5::Simple;&lt;br /&gt;
   use Authen::SASL;&lt;br /&gt;
   &lt;br /&gt;
   # LDAP tunables&lt;br /&gt;
   my $ldap_host = &amp;quot;ldap.example.org&amp;quot;;&lt;br /&gt;
   my $base      = &amp;quot;OU=people,DC=example,DC=org&amp;quot;;&lt;br /&gt;
   my $proxy_user =&amp;quot;ad_read&amp;quot;;&lt;br /&gt;
   my $dn        = &amp;quot;CN=$proxy_user,$base&amp;quot;;&lt;br /&gt;
   &lt;br /&gt;
   # Kerberos tunables&lt;br /&gt;
   my $krb_host = &amp;quot;example.org&amp;quot;;&lt;br /&gt;
      &lt;br /&gt;
   my $krb 	  = Authen::Krb5::Simple-&amp;gt;new(realm =&amp;gt; $krb_host);&lt;br /&gt;
   unless ( $krb )&lt;br /&gt;
   {&lt;br /&gt;
   	print STDERR &amp;quot;Kerberos error: $@\n&amp;quot;;&lt;br /&gt;
   	return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   my $ldap      = Net::LDAP-&amp;gt;new ( $ldap_host );&lt;br /&gt;
   unless( $ldap )&lt;br /&gt;
   {&lt;br /&gt;
       print STDERR &amp;quot;LDAP error: $@\n&amp;quot;;&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   my $sasl = Authen::SASL-&amp;gt;new(&lt;br /&gt;
          mechanism =&amp;gt; 'GSSAPI', &lt;br /&gt;
          callback =&amp;gt; { user =&amp;gt; 'ad_read' }&lt;br /&gt;
        ) or die &amp;quot;$@&amp;quot;;&lt;br /&gt;
   &lt;br /&gt;
   my $mesg = $ldap-&amp;gt;bind(sasl =&amp;gt; $sasl);&lt;br /&gt;
   &lt;br /&gt;
   if( $mesg-&amp;gt;code() )&lt;br /&gt;
   {&lt;br /&gt;
       print STDERR &amp;quot;LDAP Bind error: &amp;quot; . $mesg-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   # Distinguished name (and attribues needed later on) for this user&lt;br /&gt;
   my $result = $ldap-&amp;gt;search (&lt;br /&gt;
       base    =&amp;gt; &amp;quot;$base&amp;quot;,&lt;br /&gt;
       filter  =&amp;gt; &amp;quot;(&amp;amp;(sAMAccountName=$username))&amp;quot;,&lt;br /&gt;
       attrs   =&amp;gt;  ['1.1', 'uid', 'sn', 'givenname', 'mail', 'department', 'title'],&lt;br /&gt;
       sizelimit=&amp;gt;1&lt;br /&gt;
   );&lt;br /&gt;
   &lt;br /&gt;
   my $entr = $result-&amp;gt;pop_entry;&lt;br /&gt;
   unless( defined $entr )&lt;br /&gt;
   {&lt;br /&gt;
       # Allow local EPrints authentication for admins (accounts not found in LDAP)&lt;br /&gt;
       my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
       return 0 unless $user;&lt;br /&gt;
   &lt;br /&gt;
       my $user_type = $user-&amp;gt;get_type;&lt;br /&gt;
       if( $user_type eq &amp;quot;admin&amp;quot; )&lt;br /&gt;
       {&lt;br /&gt;
           # internal authentication for &amp;quot;admin&amp;quot; type&lt;br /&gt;
           return $session-&amp;gt;get_database-&amp;gt;valid_login( $username, $password );&lt;br /&gt;
       }&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   # Check password&lt;br /&gt;
   if( !$krb-&amp;gt;authenticate( $username, $password ) )&lt;br /&gt;
   {&lt;br /&gt;
   	print STDERR &amp;quot;$username authentication failed: &amp;quot;, $krb-&amp;gt;errstr(), &amp;quot;\n&amp;quot;;&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   # Does account already exist?&lt;br /&gt;
   my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
   if( !defined $user )&lt;br /&gt;
   {&lt;br /&gt;
       # New account&lt;br /&gt;
       $user = EPrints::DataObj::User::create( $session, &amp;quot;user&amp;quot; );&lt;br /&gt;
       $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   # Set metadata&lt;br /&gt;
   my $name = {};&lt;br /&gt;
   $name-&amp;gt;{family} = $entr-&amp;gt;get_value( &amp;quot;sn&amp;quot; );&lt;br /&gt;
   $name-&amp;gt;{given} = $entr-&amp;gt;get_value( &amp;quot;givenName&amp;quot; );&lt;br /&gt;
   $name-&amp;gt;{honourific} = $entr-&amp;gt;get_value( &amp;quot;title&amp;quot;);&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;name&amp;quot;, $name );&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;email&amp;quot;, $entr-&amp;gt;get_value( &amp;quot;mail&amp;quot; ) );&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;dept&amp;quot;, $entr-&amp;gt;get_value(&amp;quot;department&amp;quot;)  );&lt;br /&gt;
   $user-&amp;gt;commit();&lt;br /&gt;
   &lt;br /&gt;
   $ldap-&amp;gt;unbind if $ldap;&lt;br /&gt;
   &lt;br /&gt;
   return 1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
====Possible enhancements====&lt;br /&gt;
&lt;br /&gt;
Currently this script does not remove local eprints accounts from the database: when accounts get deleted from the LDAP database the corresponding local EPrints accounts sit around forever. But since login isn't possible anymore this is not a risk or of high priority.&lt;br /&gt;
&lt;br /&gt;
Depending on your situation it may be enough to run some kind of cleanup script, e.g. once a year, that get's a list of all local EPrints accounts, loops over them and &amp;lt;code&amp;gt;$user-&amp;gt;remove&amp;lt;/code&amp;gt;s all those, which cannot be found in LDAP anymore (except for those where &amp;lt;code&amp;gt;$user_type eq 'admin'&amp;lt;/code&amp;gt;, so you don't risk losing your local admins).&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=LDAP&amp;diff=10301</id>
		<title>LDAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=LDAP&amp;diff=10301"/>
		<updated>2012-03-14T15:40:15Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: /* Kerberos Authentication on AD with On-Demand Creation of Users using LDAP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Authentication]]&lt;br /&gt;
&lt;br /&gt;
==LDAP Authentication==&lt;br /&gt;
&lt;br /&gt;
===LDAP and User Roles===&lt;br /&gt;
&lt;br /&gt;
It is recommended that certain user rights are removed when using LDAP for login. The user should not be allowed to change their password or their email address. It is also suggested that the user not be allowed to edit their profile, however I have found certain fields that I would like the user to edit. To set the rights edit the file : &lt;br /&gt;
&lt;br /&gt;
 vi /opt/eprints3/archives/yourarchivename/cfg/cfg.d/user_roles.pl&lt;br /&gt;
&lt;br /&gt;
 ######################################################################&lt;br /&gt;
 #&lt;br /&gt;
 # User Roles&lt;br /&gt;
 #&lt;br /&gt;
 #  Here you can configure which different types of user are &lt;br /&gt;
 #  parts of the system they are allowed to use.&lt;br /&gt;
 #&lt;br /&gt;
 ######################################################################&lt;br /&gt;
 $c-&amp;gt;{user_roles}-&amp;gt;{user} = [qw/&lt;br /&gt;
        general&lt;br /&gt;
        edit-own-record&lt;br /&gt;
        saved-searches&lt;br /&gt;
        deposit&lt;br /&gt;
 /],&lt;br /&gt;
 $c-&amp;gt;{user_roles}-&amp;gt;{editor} = [qw/&lt;br /&gt;
        general&lt;br /&gt;
        edit-own-record&lt;br /&gt;
        saved-searches&lt;br /&gt;
        deposit&lt;br /&gt;
        editor&lt;br /&gt;
        view-status&lt;br /&gt;
        staff-view&lt;br /&gt;
 /],&lt;br /&gt;
 $c-&amp;gt;{user_roles}-&amp;gt;{admin} = [qw/&lt;br /&gt;
        general&lt;br /&gt;
        edit-own-record&lt;br /&gt;
        saved-searches&lt;br /&gt;
        set-password&lt;br /&gt;
        deposit&lt;br /&gt;
        change-email&lt;br /&gt;
        editor&lt;br /&gt;
        view-status&lt;br /&gt;
        staff-view&lt;br /&gt;
        admin&lt;br /&gt;
 /],&lt;br /&gt;
 #$c-&amp;gt;{user_roles}-&amp;gt;{minuser} = [qw/&lt;br /&gt;
 #       saved-searches&lt;br /&gt;
 #       set-password&lt;br /&gt;
 #       change-email&lt;br /&gt;
 #       change-user&lt;br /&gt;
 #       no_edit_own_record&lt;br /&gt;
 #       lock-username-to-email&lt;br /&gt;
 #/];&lt;br /&gt;
&lt;br /&gt;
After editing restart Apache.&lt;br /&gt;
&lt;br /&gt;
===LDAP Authentication with Bulk Import of Users===&lt;br /&gt;
&lt;br /&gt;
This recipe enables authenticating passwords against an LDAP directory for all users (including administrators). The users will need to already exist in EPrints, most likely created by a bulk import from your LDAP server.&lt;br /&gt;
&lt;br /&gt;
The recommendation for EPrints is not to allow users to alter email and passwords, as these changes are not at present written back to the LDAP database.&lt;br /&gt;
&lt;br /&gt;
====LDAP Configuration====&lt;br /&gt;
&lt;br /&gt;
All changes for LDAP authentication can be made in a single file, the file contains useful notes on configuration. Here is an example from my site, I have configured a standard Samba Domain using LDAP for authentication, if you have similar then this config may work for you :&lt;br /&gt;
&lt;br /&gt;
See [[user_login.pl]] for general information on check_user_password.&lt;br /&gt;
&lt;br /&gt;
Edit the file :&lt;br /&gt;
&lt;br /&gt;
 vi /opt/eprints3/archives/yourarchivename/cfg/cfg.d/user_login.pl&lt;br /&gt;
&lt;br /&gt;
 # This function allows you to override the default username/password&lt;br /&gt;
 # authentication. For example, you could apply different authentication rules to &lt;br /&gt;
 # different types of user.&lt;br /&gt;
 #&lt;br /&gt;
 # Example: LDAP Authentication (Quick Start)&lt;br /&gt;
 #&lt;br /&gt;
 # Tip: use the test script to determine your LDAP parameters first!&lt;br /&gt;
 # Tip: remove the set-password priviledge from users and editors in&lt;br /&gt;
 # user_roles.pl. Also consider removing edit-own-record and &lt;br /&gt;
 # change-email.&lt;br /&gt;
 #&lt;br /&gt;
 use Net::LDAP; # IO::Socket::SSL also required&lt;br /&gt;
 use Net::LDAP::Util;&lt;br /&gt;
 &lt;br /&gt;
 $c-&amp;gt;{check_user_password} = sub {&lt;br /&gt;
  my( $repo, $username, $password ) = @_;&lt;br /&gt;
 &lt;br /&gt;
  my $user = $repo-&amp;gt;user_by_username( $username );&lt;br /&gt;
  return unless $user;&lt;br /&gt;
 &lt;br /&gt;
  $username = $user-&amp;gt;value( &amp;quot;username&amp;quot; );&lt;br /&gt;
 &lt;br /&gt;
  my $user_type = $user-&amp;gt;get_type;&lt;br /&gt;
  if( $user_type eq &amp;quot;admin&amp;quot; )&lt;br /&gt;
  {&lt;br /&gt;
   # internal authentication for &amp;quot;admin&amp;quot; type&lt;br /&gt;
   return $repo-&amp;gt;database-&amp;gt;valid_login( $username, $password );&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  # LDAP authentication for &amp;quot;user&amp;quot; and &amp;quot;editor&amp;quot; types&lt;br /&gt;
  #&lt;br /&gt;
  # LDAP hostname (and port if not the default)&lt;br /&gt;
  my $ldap_host = &amp;quot;ldap.yourdomain.ac.uk&amp;quot;;&lt;br /&gt;
  #my $ldap_host = &amp;quot;ldap.host.name:1234&amp;quot;;&lt;br /&gt;
  #my $ldap_host = &amp;quot;ldaps://ldap.host.name&amp;quot;; # if server supports LDAPS&lt;br /&gt;
 &lt;br /&gt;
  # Distinguished name for this user&lt;br /&gt;
  # The distinguished name is a unique name for an LDAP entry.&lt;br /&gt;
  # e.g. &amp;quot;cn=John Smith, ou=staff, dc=eprints, dc=org&amp;quot;&lt;br /&gt;
  # You will need to derive this from the username or user metadata&lt;br /&gt;
  my $ldap_dn = sprintf(&amp;quot;uid=%s,ou=People,dc=example,dc=org&amp;quot;,&lt;br /&gt;
   Net::LDAP::Util::escape_dn_value($username)&lt;br /&gt;
  );&lt;br /&gt;
 &lt;br /&gt;
  my $ldap = Net::LDAP-&amp;gt;new ( $ldap_host, version =&amp;gt; 3 );&lt;br /&gt;
  unless( $ldap )&lt;br /&gt;
  {&lt;br /&gt;
   $repo-&amp;gt;log( &amp;quot;LDAP error: $@&amp;quot; );&lt;br /&gt;
   return;&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  # Start secure connection (not needed if using LDAPS)&lt;br /&gt;
  my $ssl = $ldap-&amp;gt;start_tls( sslversion =&amp;gt; &amp;quot;sslv3&amp;quot; );&lt;br /&gt;
  if( $ssl-&amp;gt;code() )&lt;br /&gt;
  {&lt;br /&gt;
   $repo-&amp;gt;log( &amp;quot;LDAP SSL error: &amp;quot; . $ssl-&amp;gt;error() );&lt;br /&gt;
   return;&lt;br /&gt;
  }&lt;br /&gt;
  # Check password&lt;br /&gt;
  my $mesg = $ldap-&amp;gt;bind( $ldap_dn, password =&amp;gt; $password );&lt;br /&gt;
  if( $mesg-&amp;gt;code() )&lt;br /&gt;
  {&lt;br /&gt;
   return;&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  return $username;&lt;br /&gt;
 }&lt;br /&gt;
 # Advanced LDAP Configuration&lt;br /&gt;
 #&lt;br /&gt;
 # 1. It is also possible to define additional user types, each with a different&lt;br /&gt;
 # authentication mechanism. For example, you could keep the default user, &lt;br /&gt;
 # editor and admin types and add ldapuser, ldapeditor and ldapadmin types with&lt;br /&gt;
 # LDAP authentication - this would suit an arrangement where internal staff are &lt;br /&gt;
 # authenticated against the LDAP server but user accounts can still be granted &lt;br /&gt;
 # to external users.&lt;br /&gt;
 #&lt;br /&gt;
 # 2. Sometimes the distinguished name of the user is not computable from the &lt;br /&gt;
 # username. You may need to use values from the user metadata (e.g. name_given,&lt;br /&gt;
 # name_family):&lt;br /&gt;
 #&lt;br /&gt;
 #       my $name = $user-&amp;gt;get_value( &amp;quot;name&amp;quot; );&lt;br /&gt;
 #       my $ldap_dn = $name-&amp;gt;{family} . &amp;quot;, &amp;quot; . $name-&amp;gt;{given} .&amp;quot;, ou=yourorg, dc=yourdomain&amp;quot;;&lt;br /&gt;
 #&lt;br /&gt;
 # or perform an LDAP lookup to determine it (more complicated):&lt;br /&gt;
 #&lt;br /&gt;
 #       my $base = &amp;quot;ou=yourorg, dc=yourdomain&amp;quot;;&lt;br /&gt;
 #       my $result = $ldap-&amp;gt;search (&lt;br /&gt;
 #               base    =&amp;gt; &amp;quot;$base&amp;quot;,&lt;br /&gt;
 #               scope   =&amp;gt; &amp;quot;sub&amp;quot;,&lt;br /&gt;
 #               filter  =&amp;gt; &amp;quot;cn=$username&amp;quot;,&lt;br /&gt;
 #               attrs   =&amp;gt;  ['DN'],&lt;br /&gt;
 #               sizelimit=&amp;gt;1&lt;br /&gt;
 #       );&lt;br /&gt;
 #&lt;br /&gt;
 #       my $entr = $result-&amp;gt;pop_entry;&lt;br /&gt;
 #       unless( defined $entr )&lt;br /&gt;
 #       {&lt;br /&gt;
 #               return 0;&lt;br /&gt;
 #       }&lt;br /&gt;
 #       my $ldap_dn = $entr-&amp;gt;dn&lt;br /&gt;
 #&lt;br /&gt;
 # Alternatively, you could store the distinguished name as part of the user &lt;br /&gt;
 # metadata when the user account is imported              print STDERR &amp;quot;LDAP SSL error: &amp;quot; . $ssl-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
After editing restart Apache.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====LDAP Import====&lt;br /&gt;
&lt;br /&gt;
You can use the [http://files.eprints.org/27/1/update_users update_users script] and apply the following patch to make it work with eprints3:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--- update_users.orig   2007-04-23 16:22:26.000000000 +0200&lt;br /&gt;
+++ update_users    2007-04-24 21:16:40.000000000 +0200&lt;br /&gt;
@@ -1,6 +1,6 @@&lt;br /&gt;
-#!/usr/bin/perl -w -I/opt/eprints2/perl_lib&lt;br /&gt;
+#!/usr/bin/perl -w -I/opt/eprints3/perl_lib&lt;br /&gt;
&lt;br /&gt;
-use EPrints::User;&lt;br /&gt;
+use EPrints::DataObj::User;&lt;br /&gt;
 use EPrints::Session;&lt;br /&gt;
 use Net::LDAP;&lt;br /&gt;
 use strict;&lt;br /&gt;
@@ -16,6 +16,7 @@&lt;br /&gt;
&lt;br /&gt;
 # Start connection&lt;br /&gt;
 my $ldap = Net::LDAP-&amp;gt;new( &amp;quot;ldap.host.name&amp;quot;, version =&amp;gt; 3 );&lt;br /&gt;
+$ldap-&amp;gt;start_tls();&lt;br /&gt;
 unless( $ldap )&lt;br /&gt;
 {&lt;br /&gt;
    print STDERR &amp;quot;LDAP error: $@\n&amp;quot;;&lt;br /&gt;
@@ -74,7 +75,7 @@&lt;br /&gt;
        # New account&lt;br /&gt;
        if( $forreal )&lt;br /&gt;
        {&lt;br /&gt;
-           $user = EPrints::User::create_user( $session, &amp;quot;ldapuser&amp;quot; );&lt;br /&gt;
+           $user = EPrints::DataObj::User::create( $session, &amp;quot;user&amp;quot; );&lt;br /&gt;
            $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
            print &amp;quot;CREATING: $username\n&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
@@ -118,7 +119,7 @@&lt;br /&gt;
        print &amp;quot;FAMILY = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;sn&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        print &amp;quot;GIVEN = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;givenName&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        print &amp;quot;EMAIL = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;mail&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
-       print &amp;quot;DN = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;distinguishedName&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
+       print &amp;quot;DN = &amp;quot; . $entr-&amp;gt;dn . &amp;quot;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===LDAP Authentication with On-Demand Creation of Users===&lt;br /&gt;
&lt;br /&gt;
Here's an example of a customized &amp;lt;tt&amp;gt;/opt/eprints3/archives/ARCHIVEID/cfg/cfg.d/user_login.pl&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* allowing LDAP accounts to login, using the &amp;quot;Advanced LDAP Configuration&amp;quot; example&lt;br /&gt;
* allowing the local eprints admin account to login w/ database authentication&lt;br /&gt;
* creating eprints accounts for all successfully authenticated LDAP users ''on the fly''&lt;br /&gt;
&lt;br /&gt;
Most of the code is from the default &amp;lt;tt&amp;gt;user_login.pl&amp;lt;/tt&amp;gt; and from the [http://files.eprints.org/27/1/update_users update_users] script (which does not seem to exist anymore, but code &amp;amp; text below seem to have been written by [[User:Sp]] not later than May 7th 2007).&lt;br /&gt;
&lt;br /&gt;
Be sure to only use this over [[HTTPS]]!&lt;br /&gt;
&lt;br /&gt;
 $c-&amp;gt;{check_user_password} = sub {&lt;br /&gt;
    my( $session, $username, $password ) = @_;&lt;br /&gt;
    &lt;br /&gt;
    # LDAP authentication for &amp;quot;user&amp;quot;, &amp;quot;editor&amp;quot; and &amp;quot;admin&amp;quot; types (roles)&lt;br /&gt;
    &lt;br /&gt;
    use Net::LDAP; # IO::Socket::SSL also required&lt;br /&gt;
    &lt;br /&gt;
    # LDAP tunables&lt;br /&gt;
    my $ldap_host = &amp;quot;ldap.example.org&amp;quot;;&lt;br /&gt;
    my $base      = &amp;quot;dc=example,dc=org&amp;quot;;&lt;br /&gt;
    my $dn        = &amp;quot;cn=someProxyAccount,ou=accounts,$base&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    my $ldap      = Net::LDAP-&amp;gt;new ( $ldap_host, version =&amp;gt; 3 );&lt;br /&gt;
    unless( $ldap )&lt;br /&gt;
    {&lt;br /&gt;
        print STDERR &amp;quot;LDAP error: $@\n&amp;quot;;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Start secure connection (not needed if using LDAPS)&lt;br /&gt;
    my $ssl = $ldap-&amp;gt;start_tls();&lt;br /&gt;
    if( $ssl-&amp;gt;code() )&lt;br /&gt;
    {&lt;br /&gt;
        print STDERR &amp;quot;LDAP SSL error: &amp;quot; . $ssl-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Get password for the search-bind-account&lt;br /&gt;
    my $repository = $session-&amp;gt;get_repository;&lt;br /&gt;
    my $id         = $repository-&amp;gt;get_id;&lt;br /&gt;
    my $ldappass   = `cat /opt/eprints3/archives/$id/cfg/ldap.passwd`;&lt;br /&gt;
    chomp($ldappass);&lt;br /&gt;
    &lt;br /&gt;
    my $mesg = $ldap-&amp;gt;bind( $dn, password=&amp;gt;$ldappass );&lt;br /&gt;
    if( $mesg-&amp;gt;code() )&lt;br /&gt;
    {&lt;br /&gt;
        print STDERR &amp;quot;LDAP Bind error: &amp;quot; . $mesg-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Distinguished name (and attribues needed later on) for this user&lt;br /&gt;
    my $result = $ldap-&amp;gt;search (&lt;br /&gt;
        base    =&amp;gt; &amp;quot;$base&amp;quot;,&lt;br /&gt;
        scope   =&amp;gt; &amp;quot;sub&amp;quot;,&lt;br /&gt;
        filter  =&amp;gt; &amp;quot;(&amp;amp;(uid=$username)(objectclass=inetOrgPerson))&amp;quot;,&lt;br /&gt;
        attrs   =&amp;gt;  ['1.1', 'uid', 'sn', 'givenname', 'mail'],&lt;br /&gt;
        sizelimit=&amp;gt;1&lt;br /&gt;
    );&lt;br /&gt;
    my $entr = $result-&amp;gt;pop_entry;&lt;br /&gt;
    unless( defined $entr )&lt;br /&gt;
    {&lt;br /&gt;
        # Allow local EPrints authentication for admins (accounts not found in LDAP)&lt;br /&gt;
        my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
        return 0 unless $user;&lt;br /&gt;
        &lt;br /&gt;
        my $user_type = $user-&amp;gt;get_type;&lt;br /&gt;
        if( $user_type eq &amp;quot;admin&amp;quot; )&lt;br /&gt;
        {&lt;br /&gt;
            # internal authentication for &amp;quot;admin&amp;quot; type&lt;br /&gt;
            return $session-&amp;gt;get_database-&amp;gt;valid_login( $username, $password );&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    my $ldap_dn = $entr-&amp;gt;dn;&lt;br /&gt;
    &lt;br /&gt;
    # Check password&lt;br /&gt;
    my $mesg = $ldap-&amp;gt;bind( $ldap_dn, password =&amp;gt; $password );&lt;br /&gt;
    if( $mesg-&amp;gt;code() )&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Does account already exist?&lt;br /&gt;
    my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
    if( !defined $user )&lt;br /&gt;
    {&lt;br /&gt;
        # New account&lt;br /&gt;
        $user = EPrints::DataObj::User::create( $session, &amp;quot;user&amp;quot; );&lt;br /&gt;
        $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Set metadata&lt;br /&gt;
    my $name = {};&lt;br /&gt;
    $name-&amp;gt;{family} = $entr-&amp;gt;get_value( &amp;quot;sn&amp;quot; );&lt;br /&gt;
    $name-&amp;gt;{given} = $entr-&amp;gt;get_value( &amp;quot;givenName&amp;quot; );&lt;br /&gt;
    $user-&amp;gt;set_value( &amp;quot;name&amp;quot;, $name );&lt;br /&gt;
    $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
    $user-&amp;gt;set_value( &amp;quot;email&amp;quot;, $entr-&amp;gt;get_value( &amp;quot;mail&amp;quot; ) );&lt;br /&gt;
    $user-&amp;gt;commit();&lt;br /&gt;
    &lt;br /&gt;
    $ldap-&amp;gt;unbind if $ldap;&lt;br /&gt;
    &lt;br /&gt;
    return 1;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Things to note====&lt;br /&gt;
&lt;br /&gt;
* This script uses a dedicated proxy account which must exist in your LDAP tree and has appropriate permissions (ACL settings) to search for users and read their &amp;lt;tt&amp;gt;uid,givenname,sn,mail&amp;lt;/tt&amp;gt; attributes.&lt;br /&gt;
* It gets this proxy accounts' password from a file inside the repository configuration. this file needs to have read permissions for the user your webserver runs as (e.g. &amp;lt;tt&amp;gt;www-data&amp;lt;/tt&amp;gt; on Debian).  Use file system permissions to protect this (e.g. &amp;lt;tt&amp;gt;chmod 400 ldap.passwd&amp;lt;/tt&amp;gt;).&lt;br /&gt;
* It changes the flow of &amp;lt;tt&amp;gt;user_login.pl&amp;lt;/tt&amp;gt; a little to only check for local ''admin'' accounts (no users or editors; we have them all in our LDAP tree) and only when no user is found for ldap authentication. This allows you to have your admins in LDAP (if you want) but still use the local admin for &amp;quot;promoting&amp;quot; other users to admins, among other things (which could also be done with a simple SQL &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; directly in the RDBMS). If you don't need the local admin, remove those lines and just &amp;lt;tt&amp;gt;return 0&amp;lt;/tt&amp;gt; since no user was found in LDAP.&lt;br /&gt;
* you could change the default role for generated user accounts from &amp;lt;tt&amp;gt;user&amp;lt;/tt&amp;gt;, if you really wanted.&lt;br /&gt;
&lt;br /&gt;
===Kerberos Authentication on AD with On-Demand Creation of Users using LDAP ===&lt;br /&gt;
&lt;br /&gt;
Tested on 3.3.8&lt;br /&gt;
&lt;br /&gt;
Here's another example of a customized &amp;lt;tt&amp;gt;/opt/eprints3/archives/ARCHIVEID/cfg/cfg.d/user_login.pl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
* allowing LDAP accounts to login, using the following example&lt;br /&gt;
* allowing the local eprints admin account to login w/ database authentication&lt;br /&gt;
* creating eprints accounts for all successfully authenticated LDAP users ''on the fly''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 $c-&amp;gt;{check_user_password} = sub {&lt;br /&gt;
   my( $session, $username, $password ) = @_;&lt;br /&gt;
   &lt;br /&gt;
   # Kerberos authentication for &amp;quot;user&amp;quot;, &amp;quot;editor&amp;quot; and &amp;quot;admin&amp;quot; types (roles)&lt;br /&gt;
   &lt;br /&gt;
   use Net::LDAP; # IO::Socket::SSL also required&lt;br /&gt;
   use Authen::Krb5::Simple;&lt;br /&gt;
   use Authen::SASL;&lt;br /&gt;
&lt;br /&gt;
   # LDAP tunables&lt;br /&gt;
   my $ldap_host = &amp;quot;ldap.example.org&amp;quot;;&lt;br /&gt;
   my $base      = &amp;quot;OU=people,DC=example,DC=org&amp;quot;;&lt;br /&gt;
   my $proxy_user =&amp;quot;ad_read&amp;quot;;&lt;br /&gt;
   my $dn        = &amp;quot;CN=$proxy_user,$base&amp;quot;;&lt;br /&gt;
   &lt;br /&gt;
   # Kerberos tunables&lt;br /&gt;
   my $krb_host = &amp;quot;example.org&amp;quot;;&lt;br /&gt;
      &lt;br /&gt;
   my $krb 	  = Authen::Krb5::Simple-&amp;gt;new(realm =&amp;gt; $krb_host);&lt;br /&gt;
   unless ( $krb )&lt;br /&gt;
   {&lt;br /&gt;
	print STDERR &amp;quot;Kerberos error: $@\n&amp;quot;;&lt;br /&gt;
	return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   my $ldap      = Net::LDAP-&amp;gt;new ( $ldap_host );&lt;br /&gt;
   unless( $ldap )&lt;br /&gt;
   {&lt;br /&gt;
       print STDERR &amp;quot;LDAP error: $@\n&amp;quot;;&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   my $sasl = Authen::SASL-&amp;gt;new(&lt;br /&gt;
          mechanism =&amp;gt; 'GSSAPI', &lt;br /&gt;
          callback =&amp;gt; { user =&amp;gt; 'ad_read' }&lt;br /&gt;
        ) or die &amp;quot;$@&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   my $mesg = $ldap-&amp;gt;bind(sasl =&amp;gt; $sasl);&lt;br /&gt;
   &lt;br /&gt;
   if( $mesg-&amp;gt;code() )&lt;br /&gt;
   {&lt;br /&gt;
       print STDERR &amp;quot;LDAP Bind error: &amp;quot; . $mesg-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   # Distinguished name (and attribues needed later on) for this user&lt;br /&gt;
   my $result = $ldap-&amp;gt;search (&lt;br /&gt;
       base    =&amp;gt; &amp;quot;$base&amp;quot;,&lt;br /&gt;
       filter  =&amp;gt; &amp;quot;(&amp;amp;(sAMAccountName=$username))&amp;quot;,&lt;br /&gt;
       attrs   =&amp;gt;  ['1.1', 'uid', 'sn', 'givenname', 'mail', 'department', 'title'],&lt;br /&gt;
       sizelimit=&amp;gt;1&lt;br /&gt;
   );&lt;br /&gt;
   &lt;br /&gt;
   my $entr = $result-&amp;gt;pop_entry;&lt;br /&gt;
   unless( defined $entr )&lt;br /&gt;
   {&lt;br /&gt;
       # Allow local EPrints authentication for admins (accounts not found in LDAP)&lt;br /&gt;
       my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
       return 0 unless $user;&lt;br /&gt;
   &lt;br /&gt;
       my $user_type = $user-&amp;gt;get_type;&lt;br /&gt;
       if( $user_type eq &amp;quot;admin&amp;quot; )&lt;br /&gt;
       {&lt;br /&gt;
           # internal authentication for &amp;quot;admin&amp;quot; type&lt;br /&gt;
           return $session-&amp;gt;get_database-&amp;gt;valid_login( $username, $password );&lt;br /&gt;
       }&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   # Check password&lt;br /&gt;
   if( !$krb-&amp;gt;authenticate( $username, $password ) )&lt;br /&gt;
   {&lt;br /&gt;
   	print STDERR &amp;quot;$username authentication failed: &amp;quot;, $krb-&amp;gt;errstr(), &amp;quot;\n&amp;quot;;&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   # Does account already exist?&lt;br /&gt;
   my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
   if( !defined $user )&lt;br /&gt;
   {&lt;br /&gt;
       # New account&lt;br /&gt;
       $user = EPrints::DataObj::User::create( $session, &amp;quot;user&amp;quot; );&lt;br /&gt;
       $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   # Set metadata&lt;br /&gt;
   my $name = {};&lt;br /&gt;
   $name-&amp;gt;{family} = $entr-&amp;gt;get_value( &amp;quot;sn&amp;quot; );&lt;br /&gt;
   $name-&amp;gt;{given} = $entr-&amp;gt;get_value( &amp;quot;givenName&amp;quot; );&lt;br /&gt;
   $name-&amp;gt;{honourific} = $entr-&amp;gt;get_value( &amp;quot;title&amp;quot;);&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;name&amp;quot;, $name );&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;email&amp;quot;, $entr-&amp;gt;get_value( &amp;quot;mail&amp;quot; ) );&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;dept&amp;quot;, $entr-&amp;gt;get_value(&amp;quot;department&amp;quot;)  );&lt;br /&gt;
   $user-&amp;gt;commit();&lt;br /&gt;
   &lt;br /&gt;
   $ldap-&amp;gt;unbind if $ldap;&lt;br /&gt;
   &lt;br /&gt;
   return 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
====Possible enhancements====&lt;br /&gt;
&lt;br /&gt;
Currently this script does not remove local eprints accounts from the database: when accounts get deleted from the LDAP database the corresponding local EPrints accounts sit around forever. But since login isn't possible anymore this is not a risk or of high priority.&lt;br /&gt;
&lt;br /&gt;
Depending on your situation it may be enough to run some kind of cleanup script, e.g. once a year, that get's a list of all local EPrints accounts, loops over them and &amp;lt;code&amp;gt;$user-&amp;gt;remove&amp;lt;/code&amp;gt;s all those, which cannot be found in LDAP anymore (except for those where &amp;lt;code&amp;gt;$user_type eq 'admin'&amp;lt;/code&amp;gt;, so you don't risk losing your local admins).&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=LDAP&amp;diff=10300</id>
		<title>LDAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=LDAP&amp;diff=10300"/>
		<updated>2012-03-14T15:39:15Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: /* Kerberos Authentication on AD with On-Demand Creation of Users using LDAP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Authentication]]&lt;br /&gt;
&lt;br /&gt;
==LDAP Authentication==&lt;br /&gt;
&lt;br /&gt;
===LDAP and User Roles===&lt;br /&gt;
&lt;br /&gt;
It is recommended that certain user rights are removed when using LDAP for login. The user should not be allowed to change their password or their email address. It is also suggested that the user not be allowed to edit their profile, however I have found certain fields that I would like the user to edit. To set the rights edit the file : &lt;br /&gt;
&lt;br /&gt;
 vi /opt/eprints3/archives/yourarchivename/cfg/cfg.d/user_roles.pl&lt;br /&gt;
&lt;br /&gt;
 ######################################################################&lt;br /&gt;
 #&lt;br /&gt;
 # User Roles&lt;br /&gt;
 #&lt;br /&gt;
 #  Here you can configure which different types of user are &lt;br /&gt;
 #  parts of the system they are allowed to use.&lt;br /&gt;
 #&lt;br /&gt;
 ######################################################################&lt;br /&gt;
 $c-&amp;gt;{user_roles}-&amp;gt;{user} = [qw/&lt;br /&gt;
        general&lt;br /&gt;
        edit-own-record&lt;br /&gt;
        saved-searches&lt;br /&gt;
        deposit&lt;br /&gt;
 /],&lt;br /&gt;
 $c-&amp;gt;{user_roles}-&amp;gt;{editor} = [qw/&lt;br /&gt;
        general&lt;br /&gt;
        edit-own-record&lt;br /&gt;
        saved-searches&lt;br /&gt;
        deposit&lt;br /&gt;
        editor&lt;br /&gt;
        view-status&lt;br /&gt;
        staff-view&lt;br /&gt;
 /],&lt;br /&gt;
 $c-&amp;gt;{user_roles}-&amp;gt;{admin} = [qw/&lt;br /&gt;
        general&lt;br /&gt;
        edit-own-record&lt;br /&gt;
        saved-searches&lt;br /&gt;
        set-password&lt;br /&gt;
        deposit&lt;br /&gt;
        change-email&lt;br /&gt;
        editor&lt;br /&gt;
        view-status&lt;br /&gt;
        staff-view&lt;br /&gt;
        admin&lt;br /&gt;
 /],&lt;br /&gt;
 #$c-&amp;gt;{user_roles}-&amp;gt;{minuser} = [qw/&lt;br /&gt;
 #       saved-searches&lt;br /&gt;
 #       set-password&lt;br /&gt;
 #       change-email&lt;br /&gt;
 #       change-user&lt;br /&gt;
 #       no_edit_own_record&lt;br /&gt;
 #       lock-username-to-email&lt;br /&gt;
 #/];&lt;br /&gt;
&lt;br /&gt;
After editing restart Apache.&lt;br /&gt;
&lt;br /&gt;
===LDAP Authentication with Bulk Import of Users===&lt;br /&gt;
&lt;br /&gt;
This recipe enables authenticating passwords against an LDAP directory for all users (including administrators). The users will need to already exist in EPrints, most likely created by a bulk import from your LDAP server.&lt;br /&gt;
&lt;br /&gt;
The recommendation for EPrints is not to allow users to alter email and passwords, as these changes are not at present written back to the LDAP database.&lt;br /&gt;
&lt;br /&gt;
====LDAP Configuration====&lt;br /&gt;
&lt;br /&gt;
All changes for LDAP authentication can be made in a single file, the file contains useful notes on configuration. Here is an example from my site, I have configured a standard Samba Domain using LDAP for authentication, if you have similar then this config may work for you :&lt;br /&gt;
&lt;br /&gt;
See [[user_login.pl]] for general information on check_user_password.&lt;br /&gt;
&lt;br /&gt;
Edit the file :&lt;br /&gt;
&lt;br /&gt;
 vi /opt/eprints3/archives/yourarchivename/cfg/cfg.d/user_login.pl&lt;br /&gt;
&lt;br /&gt;
 # This function allows you to override the default username/password&lt;br /&gt;
 # authentication. For example, you could apply different authentication rules to &lt;br /&gt;
 # different types of user.&lt;br /&gt;
 #&lt;br /&gt;
 # Example: LDAP Authentication (Quick Start)&lt;br /&gt;
 #&lt;br /&gt;
 # Tip: use the test script to determine your LDAP parameters first!&lt;br /&gt;
 # Tip: remove the set-password priviledge from users and editors in&lt;br /&gt;
 # user_roles.pl. Also consider removing edit-own-record and &lt;br /&gt;
 # change-email.&lt;br /&gt;
 #&lt;br /&gt;
 use Net::LDAP; # IO::Socket::SSL also required&lt;br /&gt;
 use Net::LDAP::Util;&lt;br /&gt;
 &lt;br /&gt;
 $c-&amp;gt;{check_user_password} = sub {&lt;br /&gt;
  my( $repo, $username, $password ) = @_;&lt;br /&gt;
 &lt;br /&gt;
  my $user = $repo-&amp;gt;user_by_username( $username );&lt;br /&gt;
  return unless $user;&lt;br /&gt;
 &lt;br /&gt;
  $username = $user-&amp;gt;value( &amp;quot;username&amp;quot; );&lt;br /&gt;
 &lt;br /&gt;
  my $user_type = $user-&amp;gt;get_type;&lt;br /&gt;
  if( $user_type eq &amp;quot;admin&amp;quot; )&lt;br /&gt;
  {&lt;br /&gt;
   # internal authentication for &amp;quot;admin&amp;quot; type&lt;br /&gt;
   return $repo-&amp;gt;database-&amp;gt;valid_login( $username, $password );&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  # LDAP authentication for &amp;quot;user&amp;quot; and &amp;quot;editor&amp;quot; types&lt;br /&gt;
  #&lt;br /&gt;
  # LDAP hostname (and port if not the default)&lt;br /&gt;
  my $ldap_host = &amp;quot;ldap.yourdomain.ac.uk&amp;quot;;&lt;br /&gt;
  #my $ldap_host = &amp;quot;ldap.host.name:1234&amp;quot;;&lt;br /&gt;
  #my $ldap_host = &amp;quot;ldaps://ldap.host.name&amp;quot;; # if server supports LDAPS&lt;br /&gt;
 &lt;br /&gt;
  # Distinguished name for this user&lt;br /&gt;
  # The distinguished name is a unique name for an LDAP entry.&lt;br /&gt;
  # e.g. &amp;quot;cn=John Smith, ou=staff, dc=eprints, dc=org&amp;quot;&lt;br /&gt;
  # You will need to derive this from the username or user metadata&lt;br /&gt;
  my $ldap_dn = sprintf(&amp;quot;uid=%s,ou=People,dc=example,dc=org&amp;quot;,&lt;br /&gt;
   Net::LDAP::Util::escape_dn_value($username)&lt;br /&gt;
  );&lt;br /&gt;
 &lt;br /&gt;
  my $ldap = Net::LDAP-&amp;gt;new ( $ldap_host, version =&amp;gt; 3 );&lt;br /&gt;
  unless( $ldap )&lt;br /&gt;
  {&lt;br /&gt;
   $repo-&amp;gt;log( &amp;quot;LDAP error: $@&amp;quot; );&lt;br /&gt;
   return;&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  # Start secure connection (not needed if using LDAPS)&lt;br /&gt;
  my $ssl = $ldap-&amp;gt;start_tls( sslversion =&amp;gt; &amp;quot;sslv3&amp;quot; );&lt;br /&gt;
  if( $ssl-&amp;gt;code() )&lt;br /&gt;
  {&lt;br /&gt;
   $repo-&amp;gt;log( &amp;quot;LDAP SSL error: &amp;quot; . $ssl-&amp;gt;error() );&lt;br /&gt;
   return;&lt;br /&gt;
  }&lt;br /&gt;
  # Check password&lt;br /&gt;
  my $mesg = $ldap-&amp;gt;bind( $ldap_dn, password =&amp;gt; $password );&lt;br /&gt;
  if( $mesg-&amp;gt;code() )&lt;br /&gt;
  {&lt;br /&gt;
   return;&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  return $username;&lt;br /&gt;
 }&lt;br /&gt;
 # Advanced LDAP Configuration&lt;br /&gt;
 #&lt;br /&gt;
 # 1. It is also possible to define additional user types, each with a different&lt;br /&gt;
 # authentication mechanism. For example, you could keep the default user, &lt;br /&gt;
 # editor and admin types and add ldapuser, ldapeditor and ldapadmin types with&lt;br /&gt;
 # LDAP authentication - this would suit an arrangement where internal staff are &lt;br /&gt;
 # authenticated against the LDAP server but user accounts can still be granted &lt;br /&gt;
 # to external users.&lt;br /&gt;
 #&lt;br /&gt;
 # 2. Sometimes the distinguished name of the user is not computable from the &lt;br /&gt;
 # username. You may need to use values from the user metadata (e.g. name_given,&lt;br /&gt;
 # name_family):&lt;br /&gt;
 #&lt;br /&gt;
 #       my $name = $user-&amp;gt;get_value( &amp;quot;name&amp;quot; );&lt;br /&gt;
 #       my $ldap_dn = $name-&amp;gt;{family} . &amp;quot;, &amp;quot; . $name-&amp;gt;{given} .&amp;quot;, ou=yourorg, dc=yourdomain&amp;quot;;&lt;br /&gt;
 #&lt;br /&gt;
 # or perform an LDAP lookup to determine it (more complicated):&lt;br /&gt;
 #&lt;br /&gt;
 #       my $base = &amp;quot;ou=yourorg, dc=yourdomain&amp;quot;;&lt;br /&gt;
 #       my $result = $ldap-&amp;gt;search (&lt;br /&gt;
 #               base    =&amp;gt; &amp;quot;$base&amp;quot;,&lt;br /&gt;
 #               scope   =&amp;gt; &amp;quot;sub&amp;quot;,&lt;br /&gt;
 #               filter  =&amp;gt; &amp;quot;cn=$username&amp;quot;,&lt;br /&gt;
 #               attrs   =&amp;gt;  ['DN'],&lt;br /&gt;
 #               sizelimit=&amp;gt;1&lt;br /&gt;
 #       );&lt;br /&gt;
 #&lt;br /&gt;
 #       my $entr = $result-&amp;gt;pop_entry;&lt;br /&gt;
 #       unless( defined $entr )&lt;br /&gt;
 #       {&lt;br /&gt;
 #               return 0;&lt;br /&gt;
 #       }&lt;br /&gt;
 #       my $ldap_dn = $entr-&amp;gt;dn&lt;br /&gt;
 #&lt;br /&gt;
 # Alternatively, you could store the distinguished name as part of the user &lt;br /&gt;
 # metadata when the user account is imported              print STDERR &amp;quot;LDAP SSL error: &amp;quot; . $ssl-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
After editing restart Apache.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====LDAP Import====&lt;br /&gt;
&lt;br /&gt;
You can use the [http://files.eprints.org/27/1/update_users update_users script] and apply the following patch to make it work with eprints3:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--- update_users.orig   2007-04-23 16:22:26.000000000 +0200&lt;br /&gt;
+++ update_users    2007-04-24 21:16:40.000000000 +0200&lt;br /&gt;
@@ -1,6 +1,6 @@&lt;br /&gt;
-#!/usr/bin/perl -w -I/opt/eprints2/perl_lib&lt;br /&gt;
+#!/usr/bin/perl -w -I/opt/eprints3/perl_lib&lt;br /&gt;
&lt;br /&gt;
-use EPrints::User;&lt;br /&gt;
+use EPrints::DataObj::User;&lt;br /&gt;
 use EPrints::Session;&lt;br /&gt;
 use Net::LDAP;&lt;br /&gt;
 use strict;&lt;br /&gt;
@@ -16,6 +16,7 @@&lt;br /&gt;
&lt;br /&gt;
 # Start connection&lt;br /&gt;
 my $ldap = Net::LDAP-&amp;gt;new( &amp;quot;ldap.host.name&amp;quot;, version =&amp;gt; 3 );&lt;br /&gt;
+$ldap-&amp;gt;start_tls();&lt;br /&gt;
 unless( $ldap )&lt;br /&gt;
 {&lt;br /&gt;
    print STDERR &amp;quot;LDAP error: $@\n&amp;quot;;&lt;br /&gt;
@@ -74,7 +75,7 @@&lt;br /&gt;
        # New account&lt;br /&gt;
        if( $forreal )&lt;br /&gt;
        {&lt;br /&gt;
-           $user = EPrints::User::create_user( $session, &amp;quot;ldapuser&amp;quot; );&lt;br /&gt;
+           $user = EPrints::DataObj::User::create( $session, &amp;quot;user&amp;quot; );&lt;br /&gt;
            $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
            print &amp;quot;CREATING: $username\n&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
@@ -118,7 +119,7 @@&lt;br /&gt;
        print &amp;quot;FAMILY = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;sn&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        print &amp;quot;GIVEN = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;givenName&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        print &amp;quot;EMAIL = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;mail&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
-       print &amp;quot;DN = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;distinguishedName&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
+       print &amp;quot;DN = &amp;quot; . $entr-&amp;gt;dn . &amp;quot;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===LDAP Authentication with On-Demand Creation of Users===&lt;br /&gt;
&lt;br /&gt;
Here's an example of a customized &amp;lt;tt&amp;gt;/opt/eprints3/archives/ARCHIVEID/cfg/cfg.d/user_login.pl&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* allowing LDAP accounts to login, using the &amp;quot;Advanced LDAP Configuration&amp;quot; example&lt;br /&gt;
* allowing the local eprints admin account to login w/ database authentication&lt;br /&gt;
* creating eprints accounts for all successfully authenticated LDAP users ''on the fly''&lt;br /&gt;
&lt;br /&gt;
Most of the code is from the default &amp;lt;tt&amp;gt;user_login.pl&amp;lt;/tt&amp;gt; and from the [http://files.eprints.org/27/1/update_users update_users] script (which does not seem to exist anymore, but code &amp;amp; text below seem to have been written by [[User:Sp]] not later than May 7th 2007).&lt;br /&gt;
&lt;br /&gt;
Be sure to only use this over [[HTTPS]]!&lt;br /&gt;
&lt;br /&gt;
 $c-&amp;gt;{check_user_password} = sub {&lt;br /&gt;
    my( $session, $username, $password ) = @_;&lt;br /&gt;
    &lt;br /&gt;
    # LDAP authentication for &amp;quot;user&amp;quot;, &amp;quot;editor&amp;quot; and &amp;quot;admin&amp;quot; types (roles)&lt;br /&gt;
    &lt;br /&gt;
    use Net::LDAP; # IO::Socket::SSL also required&lt;br /&gt;
    &lt;br /&gt;
    # LDAP tunables&lt;br /&gt;
    my $ldap_host = &amp;quot;ldap.example.org&amp;quot;;&lt;br /&gt;
    my $base      = &amp;quot;dc=example,dc=org&amp;quot;;&lt;br /&gt;
    my $dn        = &amp;quot;cn=someProxyAccount,ou=accounts,$base&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    my $ldap      = Net::LDAP-&amp;gt;new ( $ldap_host, version =&amp;gt; 3 );&lt;br /&gt;
    unless( $ldap )&lt;br /&gt;
    {&lt;br /&gt;
        print STDERR &amp;quot;LDAP error: $@\n&amp;quot;;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Start secure connection (not needed if using LDAPS)&lt;br /&gt;
    my $ssl = $ldap-&amp;gt;start_tls();&lt;br /&gt;
    if( $ssl-&amp;gt;code() )&lt;br /&gt;
    {&lt;br /&gt;
        print STDERR &amp;quot;LDAP SSL error: &amp;quot; . $ssl-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Get password for the search-bind-account&lt;br /&gt;
    my $repository = $session-&amp;gt;get_repository;&lt;br /&gt;
    my $id         = $repository-&amp;gt;get_id;&lt;br /&gt;
    my $ldappass   = `cat /opt/eprints3/archives/$id/cfg/ldap.passwd`;&lt;br /&gt;
    chomp($ldappass);&lt;br /&gt;
    &lt;br /&gt;
    my $mesg = $ldap-&amp;gt;bind( $dn, password=&amp;gt;$ldappass );&lt;br /&gt;
    if( $mesg-&amp;gt;code() )&lt;br /&gt;
    {&lt;br /&gt;
        print STDERR &amp;quot;LDAP Bind error: &amp;quot; . $mesg-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Distinguished name (and attribues needed later on) for this user&lt;br /&gt;
    my $result = $ldap-&amp;gt;search (&lt;br /&gt;
        base    =&amp;gt; &amp;quot;$base&amp;quot;,&lt;br /&gt;
        scope   =&amp;gt; &amp;quot;sub&amp;quot;,&lt;br /&gt;
        filter  =&amp;gt; &amp;quot;(&amp;amp;(uid=$username)(objectclass=inetOrgPerson))&amp;quot;,&lt;br /&gt;
        attrs   =&amp;gt;  ['1.1', 'uid', 'sn', 'givenname', 'mail'],&lt;br /&gt;
        sizelimit=&amp;gt;1&lt;br /&gt;
    );&lt;br /&gt;
    my $entr = $result-&amp;gt;pop_entry;&lt;br /&gt;
    unless( defined $entr )&lt;br /&gt;
    {&lt;br /&gt;
        # Allow local EPrints authentication for admins (accounts not found in LDAP)&lt;br /&gt;
        my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
        return 0 unless $user;&lt;br /&gt;
        &lt;br /&gt;
        my $user_type = $user-&amp;gt;get_type;&lt;br /&gt;
        if( $user_type eq &amp;quot;admin&amp;quot; )&lt;br /&gt;
        {&lt;br /&gt;
            # internal authentication for &amp;quot;admin&amp;quot; type&lt;br /&gt;
            return $session-&amp;gt;get_database-&amp;gt;valid_login( $username, $password );&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    my $ldap_dn = $entr-&amp;gt;dn;&lt;br /&gt;
    &lt;br /&gt;
    # Check password&lt;br /&gt;
    my $mesg = $ldap-&amp;gt;bind( $ldap_dn, password =&amp;gt; $password );&lt;br /&gt;
    if( $mesg-&amp;gt;code() )&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Does account already exist?&lt;br /&gt;
    my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
    if( !defined $user )&lt;br /&gt;
    {&lt;br /&gt;
        # New account&lt;br /&gt;
        $user = EPrints::DataObj::User::create( $session, &amp;quot;user&amp;quot; );&lt;br /&gt;
        $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Set metadata&lt;br /&gt;
    my $name = {};&lt;br /&gt;
    $name-&amp;gt;{family} = $entr-&amp;gt;get_value( &amp;quot;sn&amp;quot; );&lt;br /&gt;
    $name-&amp;gt;{given} = $entr-&amp;gt;get_value( &amp;quot;givenName&amp;quot; );&lt;br /&gt;
    $user-&amp;gt;set_value( &amp;quot;name&amp;quot;, $name );&lt;br /&gt;
    $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
    $user-&amp;gt;set_value( &amp;quot;email&amp;quot;, $entr-&amp;gt;get_value( &amp;quot;mail&amp;quot; ) );&lt;br /&gt;
    $user-&amp;gt;commit();&lt;br /&gt;
    &lt;br /&gt;
    $ldap-&amp;gt;unbind if $ldap;&lt;br /&gt;
    &lt;br /&gt;
    return 1;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Things to note====&lt;br /&gt;
&lt;br /&gt;
* This script uses a dedicated proxy account which must exist in your LDAP tree and has appropriate permissions (ACL settings) to search for users and read their &amp;lt;tt&amp;gt;uid,givenname,sn,mail&amp;lt;/tt&amp;gt; attributes.&lt;br /&gt;
* It gets this proxy accounts' password from a file inside the repository configuration. this file needs to have read permissions for the user your webserver runs as (e.g. &amp;lt;tt&amp;gt;www-data&amp;lt;/tt&amp;gt; on Debian).  Use file system permissions to protect this (e.g. &amp;lt;tt&amp;gt;chmod 400 ldap.passwd&amp;lt;/tt&amp;gt;).&lt;br /&gt;
* It changes the flow of &amp;lt;tt&amp;gt;user_login.pl&amp;lt;/tt&amp;gt; a little to only check for local ''admin'' accounts (no users or editors; we have them all in our LDAP tree) and only when no user is found for ldap authentication. This allows you to have your admins in LDAP (if you want) but still use the local admin for &amp;quot;promoting&amp;quot; other users to admins, among other things (which could also be done with a simple SQL &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; directly in the RDBMS). If you don't need the local admin, remove those lines and just &amp;lt;tt&amp;gt;return 0&amp;lt;/tt&amp;gt; since no user was found in LDAP.&lt;br /&gt;
* you could change the default role for generated user accounts from &amp;lt;tt&amp;gt;user&amp;lt;/tt&amp;gt;, if you really wanted.&lt;br /&gt;
&lt;br /&gt;
===Kerberos Authentication on AD with On-Demand Creation of Users using LDAP ===&lt;br /&gt;
&lt;br /&gt;
Tested on 3.3.8&lt;br /&gt;
&lt;br /&gt;
Here's another example of a customized &amp;lt;tt&amp;gt;/opt/eprints3/archives/ARCHIVEID/cfg/cfg.d/user_login.pl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
* allowing LDAP accounts to login, using the following example&lt;br /&gt;
* allowing the local eprints admin account to login w/ database authentication&lt;br /&gt;
* creating eprints accounts for all successfully authenticated LDAP users ''on the fly''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 $c-&amp;gt;{check_user_password} = sub {&lt;br /&gt;
   my( $session, $username, $password ) = @_;&lt;br /&gt;
   &lt;br /&gt;
   # Kerberos authentication for &amp;quot;user&amp;quot;, &amp;quot;editor&amp;quot; and &amp;quot;admin&amp;quot; types (roles)&lt;br /&gt;
   &lt;br /&gt;
   use Net::LDAP; # IO::Socket::SSL also required&lt;br /&gt;
   use Authen::Krb5::Simple;&lt;br /&gt;
   use Authen::SASL;&lt;br /&gt;
   &lt;br /&gt;
   # LDAP tunables&lt;br /&gt;
   my $ldap_host = &amp;quot;ldap.example.org&amp;quot;;&lt;br /&gt;
   my $base      = &amp;quot;OU=people,DC=example,DC=org&amp;quot;;&lt;br /&gt;
   my $proxy_user =&amp;quot;ad_read&amp;quot;;&lt;br /&gt;
   my $dn        = &amp;quot;CN=$proxy_user,$base&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   # Kerberos tunables&lt;br /&gt;
   my $krb_host = &amp;quot;example.org&amp;quot;;&lt;br /&gt;
   &lt;br /&gt;
   my $krb 	  = Authen::Krb5::Simple-&amp;gt;new(realm =&amp;gt; $krb_host);&lt;br /&gt;
   unless ( $krb )&lt;br /&gt;
   {&lt;br /&gt;
	print STDERR &amp;quot;Kerberos error: $@\n&amp;quot;;&lt;br /&gt;
	return 0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   my $ldap      = Net::LDAP-&amp;gt;new ( $ldap_host );&lt;br /&gt;
   unless( $ldap )&lt;br /&gt;
   {&lt;br /&gt;
       print STDERR &amp;quot;LDAP error: $@\n&amp;quot;;&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   my $sasl = Authen::SASL-&amp;gt;new(&lt;br /&gt;
          mechanism =&amp;gt; 'GSSAPI', &lt;br /&gt;
          callback =&amp;gt; { user =&amp;gt; 'ad_read' }&lt;br /&gt;
        ) or die &amp;quot;$@&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   my $mesg = $ldap-&amp;gt;bind(sasl =&amp;gt; $sasl);&lt;br /&gt;
&lt;br /&gt;
   if( $mesg-&amp;gt;code() )&lt;br /&gt;
   {&lt;br /&gt;
       print STDERR &amp;quot;LDAP Bind error: &amp;quot; . $mesg-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   # Distinguished name (and attribues needed later on) for this user&lt;br /&gt;
   my $result = $ldap-&amp;gt;search (&lt;br /&gt;
       base    =&amp;gt; &amp;quot;$base&amp;quot;,&lt;br /&gt;
       filter  =&amp;gt; &amp;quot;(&amp;amp;(sAMAccountName=$username))&amp;quot;,&lt;br /&gt;
       attrs   =&amp;gt;  ['1.1', 'uid', 'sn', 'givenname', 'mail', 'department', 'title'],&lt;br /&gt;
       sizelimit=&amp;gt;1&lt;br /&gt;
   );&lt;br /&gt;
&lt;br /&gt;
   my $entr = $result-&amp;gt;pop_entry;&lt;br /&gt;
   unless( defined $entr )&lt;br /&gt;
   {&lt;br /&gt;
       # Allow local EPrints authentication for admins (accounts not found in LDAP)&lt;br /&gt;
       my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
       return 0 unless $user;&lt;br /&gt;
&lt;br /&gt;
       my $user_type = $user-&amp;gt;get_type;&lt;br /&gt;
       if( $user_type eq &amp;quot;admin&amp;quot; )&lt;br /&gt;
       {&lt;br /&gt;
           # internal authentication for &amp;quot;admin&amp;quot; type&lt;br /&gt;
           return $session-&amp;gt;get_database-&amp;gt;valid_login( $username, $password );&lt;br /&gt;
       }&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
   # Check password&lt;br /&gt;
   if( !$krb-&amp;gt;authenticate( $username, $password ) )&lt;br /&gt;
   {&lt;br /&gt;
	print STDERR &amp;quot;$username authentication failed: &amp;quot;, $krb-&amp;gt;errstr(), &amp;quot;\n&amp;quot;;&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   # Does account already exist?&lt;br /&gt;
   my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
   if( !defined $user )&lt;br /&gt;
   {&lt;br /&gt;
       # New account&lt;br /&gt;
       $user = EPrints::DataObj::User::create( $session, &amp;quot;user&amp;quot; );&lt;br /&gt;
       $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   # Set metadata&lt;br /&gt;
   my $name = {};&lt;br /&gt;
   $name-&amp;gt;{family} = $entr-&amp;gt;get_value( &amp;quot;sn&amp;quot; );&lt;br /&gt;
   $name-&amp;gt;{given} = $entr-&amp;gt;get_value( &amp;quot;givenName&amp;quot; );&lt;br /&gt;
   $name-&amp;gt;{honourific} = $entr-&amp;gt;get_value( &amp;quot;title&amp;quot;);&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;name&amp;quot;, $name );&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;email&amp;quot;, $entr-&amp;gt;get_value( &amp;quot;mail&amp;quot; ) );&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;dept&amp;quot;, $entr-&amp;gt;get_value(&amp;quot;department&amp;quot;)  );&lt;br /&gt;
   $user-&amp;gt;commit();&lt;br /&gt;
   &lt;br /&gt;
   $ldap-&amp;gt;unbind if $ldap;&lt;br /&gt;
   &lt;br /&gt;
   return 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
====Possible enhancements====&lt;br /&gt;
&lt;br /&gt;
Currently this script does not remove local eprints accounts from the database: when accounts get deleted from the LDAP database the corresponding local EPrints accounts sit around forever. But since login isn't possible anymore this is not a risk or of high priority.&lt;br /&gt;
&lt;br /&gt;
Depending on your situation it may be enough to run some kind of cleanup script, e.g. once a year, that get's a list of all local EPrints accounts, loops over them and &amp;lt;code&amp;gt;$user-&amp;gt;remove&amp;lt;/code&amp;gt;s all those, which cannot be found in LDAP anymore (except for those where &amp;lt;code&amp;gt;$user_type eq 'admin'&amp;lt;/code&amp;gt;, so you don't risk losing your local admins).&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=LDAP&amp;diff=10299</id>
		<title>LDAP</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=LDAP&amp;diff=10299"/>
		<updated>2012-03-14T15:38:31Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: /* LDAP Authentication */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Authentication]]&lt;br /&gt;
&lt;br /&gt;
==LDAP Authentication==&lt;br /&gt;
&lt;br /&gt;
===LDAP and User Roles===&lt;br /&gt;
&lt;br /&gt;
It is recommended that certain user rights are removed when using LDAP for login. The user should not be allowed to change their password or their email address. It is also suggested that the user not be allowed to edit their profile, however I have found certain fields that I would like the user to edit. To set the rights edit the file : &lt;br /&gt;
&lt;br /&gt;
 vi /opt/eprints3/archives/yourarchivename/cfg/cfg.d/user_roles.pl&lt;br /&gt;
&lt;br /&gt;
 ######################################################################&lt;br /&gt;
 #&lt;br /&gt;
 # User Roles&lt;br /&gt;
 #&lt;br /&gt;
 #  Here you can configure which different types of user are &lt;br /&gt;
 #  parts of the system they are allowed to use.&lt;br /&gt;
 #&lt;br /&gt;
 ######################################################################&lt;br /&gt;
 $c-&amp;gt;{user_roles}-&amp;gt;{user} = [qw/&lt;br /&gt;
        general&lt;br /&gt;
        edit-own-record&lt;br /&gt;
        saved-searches&lt;br /&gt;
        deposit&lt;br /&gt;
 /],&lt;br /&gt;
 $c-&amp;gt;{user_roles}-&amp;gt;{editor} = [qw/&lt;br /&gt;
        general&lt;br /&gt;
        edit-own-record&lt;br /&gt;
        saved-searches&lt;br /&gt;
        deposit&lt;br /&gt;
        editor&lt;br /&gt;
        view-status&lt;br /&gt;
        staff-view&lt;br /&gt;
 /],&lt;br /&gt;
 $c-&amp;gt;{user_roles}-&amp;gt;{admin} = [qw/&lt;br /&gt;
        general&lt;br /&gt;
        edit-own-record&lt;br /&gt;
        saved-searches&lt;br /&gt;
        set-password&lt;br /&gt;
        deposit&lt;br /&gt;
        change-email&lt;br /&gt;
        editor&lt;br /&gt;
        view-status&lt;br /&gt;
        staff-view&lt;br /&gt;
        admin&lt;br /&gt;
 /],&lt;br /&gt;
 #$c-&amp;gt;{user_roles}-&amp;gt;{minuser} = [qw/&lt;br /&gt;
 #       saved-searches&lt;br /&gt;
 #       set-password&lt;br /&gt;
 #       change-email&lt;br /&gt;
 #       change-user&lt;br /&gt;
 #       no_edit_own_record&lt;br /&gt;
 #       lock-username-to-email&lt;br /&gt;
 #/];&lt;br /&gt;
&lt;br /&gt;
After editing restart Apache.&lt;br /&gt;
&lt;br /&gt;
===LDAP Authentication with Bulk Import of Users===&lt;br /&gt;
&lt;br /&gt;
This recipe enables authenticating passwords against an LDAP directory for all users (including administrators). The users will need to already exist in EPrints, most likely created by a bulk import from your LDAP server.&lt;br /&gt;
&lt;br /&gt;
The recommendation for EPrints is not to allow users to alter email and passwords, as these changes are not at present written back to the LDAP database.&lt;br /&gt;
&lt;br /&gt;
====LDAP Configuration====&lt;br /&gt;
&lt;br /&gt;
All changes for LDAP authentication can be made in a single file, the file contains useful notes on configuration. Here is an example from my site, I have configured a standard Samba Domain using LDAP for authentication, if you have similar then this config may work for you :&lt;br /&gt;
&lt;br /&gt;
See [[user_login.pl]] for general information on check_user_password.&lt;br /&gt;
&lt;br /&gt;
Edit the file :&lt;br /&gt;
&lt;br /&gt;
 vi /opt/eprints3/archives/yourarchivename/cfg/cfg.d/user_login.pl&lt;br /&gt;
&lt;br /&gt;
 # This function allows you to override the default username/password&lt;br /&gt;
 # authentication. For example, you could apply different authentication rules to &lt;br /&gt;
 # different types of user.&lt;br /&gt;
 #&lt;br /&gt;
 # Example: LDAP Authentication (Quick Start)&lt;br /&gt;
 #&lt;br /&gt;
 # Tip: use the test script to determine your LDAP parameters first!&lt;br /&gt;
 # Tip: remove the set-password priviledge from users and editors in&lt;br /&gt;
 # user_roles.pl. Also consider removing edit-own-record and &lt;br /&gt;
 # change-email.&lt;br /&gt;
 #&lt;br /&gt;
 use Net::LDAP; # IO::Socket::SSL also required&lt;br /&gt;
 use Net::LDAP::Util;&lt;br /&gt;
 &lt;br /&gt;
 $c-&amp;gt;{check_user_password} = sub {&lt;br /&gt;
  my( $repo, $username, $password ) = @_;&lt;br /&gt;
 &lt;br /&gt;
  my $user = $repo-&amp;gt;user_by_username( $username );&lt;br /&gt;
  return unless $user;&lt;br /&gt;
 &lt;br /&gt;
  $username = $user-&amp;gt;value( &amp;quot;username&amp;quot; );&lt;br /&gt;
 &lt;br /&gt;
  my $user_type = $user-&amp;gt;get_type;&lt;br /&gt;
  if( $user_type eq &amp;quot;admin&amp;quot; )&lt;br /&gt;
  {&lt;br /&gt;
   # internal authentication for &amp;quot;admin&amp;quot; type&lt;br /&gt;
   return $repo-&amp;gt;database-&amp;gt;valid_login( $username, $password );&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  # LDAP authentication for &amp;quot;user&amp;quot; and &amp;quot;editor&amp;quot; types&lt;br /&gt;
  #&lt;br /&gt;
  # LDAP hostname (and port if not the default)&lt;br /&gt;
  my $ldap_host = &amp;quot;ldap.yourdomain.ac.uk&amp;quot;;&lt;br /&gt;
  #my $ldap_host = &amp;quot;ldap.host.name:1234&amp;quot;;&lt;br /&gt;
  #my $ldap_host = &amp;quot;ldaps://ldap.host.name&amp;quot;; # if server supports LDAPS&lt;br /&gt;
 &lt;br /&gt;
  # Distinguished name for this user&lt;br /&gt;
  # The distinguished name is a unique name for an LDAP entry.&lt;br /&gt;
  # e.g. &amp;quot;cn=John Smith, ou=staff, dc=eprints, dc=org&amp;quot;&lt;br /&gt;
  # You will need to derive this from the username or user metadata&lt;br /&gt;
  my $ldap_dn = sprintf(&amp;quot;uid=%s,ou=People,dc=example,dc=org&amp;quot;,&lt;br /&gt;
   Net::LDAP::Util::escape_dn_value($username)&lt;br /&gt;
  );&lt;br /&gt;
 &lt;br /&gt;
  my $ldap = Net::LDAP-&amp;gt;new ( $ldap_host, version =&amp;gt; 3 );&lt;br /&gt;
  unless( $ldap )&lt;br /&gt;
  {&lt;br /&gt;
   $repo-&amp;gt;log( &amp;quot;LDAP error: $@&amp;quot; );&lt;br /&gt;
   return;&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  # Start secure connection (not needed if using LDAPS)&lt;br /&gt;
  my $ssl = $ldap-&amp;gt;start_tls( sslversion =&amp;gt; &amp;quot;sslv3&amp;quot; );&lt;br /&gt;
  if( $ssl-&amp;gt;code() )&lt;br /&gt;
  {&lt;br /&gt;
   $repo-&amp;gt;log( &amp;quot;LDAP SSL error: &amp;quot; . $ssl-&amp;gt;error() );&lt;br /&gt;
   return;&lt;br /&gt;
  }&lt;br /&gt;
  # Check password&lt;br /&gt;
  my $mesg = $ldap-&amp;gt;bind( $ldap_dn, password =&amp;gt; $password );&lt;br /&gt;
  if( $mesg-&amp;gt;code() )&lt;br /&gt;
  {&lt;br /&gt;
   return;&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  return $username;&lt;br /&gt;
 }&lt;br /&gt;
 # Advanced LDAP Configuration&lt;br /&gt;
 #&lt;br /&gt;
 # 1. It is also possible to define additional user types, each with a different&lt;br /&gt;
 # authentication mechanism. For example, you could keep the default user, &lt;br /&gt;
 # editor and admin types and add ldapuser, ldapeditor and ldapadmin types with&lt;br /&gt;
 # LDAP authentication - this would suit an arrangement where internal staff are &lt;br /&gt;
 # authenticated against the LDAP server but user accounts can still be granted &lt;br /&gt;
 # to external users.&lt;br /&gt;
 #&lt;br /&gt;
 # 2. Sometimes the distinguished name of the user is not computable from the &lt;br /&gt;
 # username. You may need to use values from the user metadata (e.g. name_given,&lt;br /&gt;
 # name_family):&lt;br /&gt;
 #&lt;br /&gt;
 #       my $name = $user-&amp;gt;get_value( &amp;quot;name&amp;quot; );&lt;br /&gt;
 #       my $ldap_dn = $name-&amp;gt;{family} . &amp;quot;, &amp;quot; . $name-&amp;gt;{given} .&amp;quot;, ou=yourorg, dc=yourdomain&amp;quot;;&lt;br /&gt;
 #&lt;br /&gt;
 # or perform an LDAP lookup to determine it (more complicated):&lt;br /&gt;
 #&lt;br /&gt;
 #       my $base = &amp;quot;ou=yourorg, dc=yourdomain&amp;quot;;&lt;br /&gt;
 #       my $result = $ldap-&amp;gt;search (&lt;br /&gt;
 #               base    =&amp;gt; &amp;quot;$base&amp;quot;,&lt;br /&gt;
 #               scope   =&amp;gt; &amp;quot;sub&amp;quot;,&lt;br /&gt;
 #               filter  =&amp;gt; &amp;quot;cn=$username&amp;quot;,&lt;br /&gt;
 #               attrs   =&amp;gt;  ['DN'],&lt;br /&gt;
 #               sizelimit=&amp;gt;1&lt;br /&gt;
 #       );&lt;br /&gt;
 #&lt;br /&gt;
 #       my $entr = $result-&amp;gt;pop_entry;&lt;br /&gt;
 #       unless( defined $entr )&lt;br /&gt;
 #       {&lt;br /&gt;
 #               return 0;&lt;br /&gt;
 #       }&lt;br /&gt;
 #       my $ldap_dn = $entr-&amp;gt;dn&lt;br /&gt;
 #&lt;br /&gt;
 # Alternatively, you could store the distinguished name as part of the user &lt;br /&gt;
 # metadata when the user account is imported              print STDERR &amp;quot;LDAP SSL error: &amp;quot; . $ssl-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
After editing restart Apache.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====LDAP Import====&lt;br /&gt;
&lt;br /&gt;
You can use the [http://files.eprints.org/27/1/update_users update_users script] and apply the following patch to make it work with eprints3:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--- update_users.orig   2007-04-23 16:22:26.000000000 +0200&lt;br /&gt;
+++ update_users    2007-04-24 21:16:40.000000000 +0200&lt;br /&gt;
@@ -1,6 +1,6 @@&lt;br /&gt;
-#!/usr/bin/perl -w -I/opt/eprints2/perl_lib&lt;br /&gt;
+#!/usr/bin/perl -w -I/opt/eprints3/perl_lib&lt;br /&gt;
&lt;br /&gt;
-use EPrints::User;&lt;br /&gt;
+use EPrints::DataObj::User;&lt;br /&gt;
 use EPrints::Session;&lt;br /&gt;
 use Net::LDAP;&lt;br /&gt;
 use strict;&lt;br /&gt;
@@ -16,6 +16,7 @@&lt;br /&gt;
&lt;br /&gt;
 # Start connection&lt;br /&gt;
 my $ldap = Net::LDAP-&amp;gt;new( &amp;quot;ldap.host.name&amp;quot;, version =&amp;gt; 3 );&lt;br /&gt;
+$ldap-&amp;gt;start_tls();&lt;br /&gt;
 unless( $ldap )&lt;br /&gt;
 {&lt;br /&gt;
    print STDERR &amp;quot;LDAP error: $@\n&amp;quot;;&lt;br /&gt;
@@ -74,7 +75,7 @@&lt;br /&gt;
        # New account&lt;br /&gt;
        if( $forreal )&lt;br /&gt;
        {&lt;br /&gt;
-           $user = EPrints::User::create_user( $session, &amp;quot;ldapuser&amp;quot; );&lt;br /&gt;
+           $user = EPrints::DataObj::User::create( $session, &amp;quot;user&amp;quot; );&lt;br /&gt;
            $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
            print &amp;quot;CREATING: $username\n&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
@@ -118,7 +119,7 @@&lt;br /&gt;
        print &amp;quot;FAMILY = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;sn&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        print &amp;quot;GIVEN = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;givenName&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        print &amp;quot;EMAIL = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;mail&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
-       print &amp;quot;DN = &amp;quot; . $entr-&amp;gt;get_value( &amp;quot;distinguishedName&amp;quot; ) . &amp;quot;\n&amp;quot;;&lt;br /&gt;
+       print &amp;quot;DN = &amp;quot; . $entr-&amp;gt;dn . &amp;quot;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===LDAP Authentication with On-Demand Creation of Users===&lt;br /&gt;
&lt;br /&gt;
Here's an example of a customized &amp;lt;tt&amp;gt;/opt/eprints3/archives/ARCHIVEID/cfg/cfg.d/user_login.pl&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* allowing LDAP accounts to login, using the &amp;quot;Advanced LDAP Configuration&amp;quot; example&lt;br /&gt;
* allowing the local eprints admin account to login w/ database authentication&lt;br /&gt;
* creating eprints accounts for all successfully authenticated LDAP users ''on the fly''&lt;br /&gt;
&lt;br /&gt;
Most of the code is from the default &amp;lt;tt&amp;gt;user_login.pl&amp;lt;/tt&amp;gt; and from the [http://files.eprints.org/27/1/update_users update_users] script (which does not seem to exist anymore, but code &amp;amp; text below seem to have been written by [[User:Sp]] not later than May 7th 2007).&lt;br /&gt;
&lt;br /&gt;
Be sure to only use this over [[HTTPS]]!&lt;br /&gt;
&lt;br /&gt;
 $c-&amp;gt;{check_user_password} = sub {&lt;br /&gt;
    my( $session, $username, $password ) = @_;&lt;br /&gt;
    &lt;br /&gt;
    # LDAP authentication for &amp;quot;user&amp;quot;, &amp;quot;editor&amp;quot; and &amp;quot;admin&amp;quot; types (roles)&lt;br /&gt;
    &lt;br /&gt;
    use Net::LDAP; # IO::Socket::SSL also required&lt;br /&gt;
    &lt;br /&gt;
    # LDAP tunables&lt;br /&gt;
    my $ldap_host = &amp;quot;ldap.example.org&amp;quot;;&lt;br /&gt;
    my $base      = &amp;quot;dc=example,dc=org&amp;quot;;&lt;br /&gt;
    my $dn        = &amp;quot;cn=someProxyAccount,ou=accounts,$base&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    my $ldap      = Net::LDAP-&amp;gt;new ( $ldap_host, version =&amp;gt; 3 );&lt;br /&gt;
    unless( $ldap )&lt;br /&gt;
    {&lt;br /&gt;
        print STDERR &amp;quot;LDAP error: $@\n&amp;quot;;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Start secure connection (not needed if using LDAPS)&lt;br /&gt;
    my $ssl = $ldap-&amp;gt;start_tls();&lt;br /&gt;
    if( $ssl-&amp;gt;code() )&lt;br /&gt;
    {&lt;br /&gt;
        print STDERR &amp;quot;LDAP SSL error: &amp;quot; . $ssl-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Get password for the search-bind-account&lt;br /&gt;
    my $repository = $session-&amp;gt;get_repository;&lt;br /&gt;
    my $id         = $repository-&amp;gt;get_id;&lt;br /&gt;
    my $ldappass   = `cat /opt/eprints3/archives/$id/cfg/ldap.passwd`;&lt;br /&gt;
    chomp($ldappass);&lt;br /&gt;
    &lt;br /&gt;
    my $mesg = $ldap-&amp;gt;bind( $dn, password=&amp;gt;$ldappass );&lt;br /&gt;
    if( $mesg-&amp;gt;code() )&lt;br /&gt;
    {&lt;br /&gt;
        print STDERR &amp;quot;LDAP Bind error: &amp;quot; . $mesg-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Distinguished name (and attribues needed later on) for this user&lt;br /&gt;
    my $result = $ldap-&amp;gt;search (&lt;br /&gt;
        base    =&amp;gt; &amp;quot;$base&amp;quot;,&lt;br /&gt;
        scope   =&amp;gt; &amp;quot;sub&amp;quot;,&lt;br /&gt;
        filter  =&amp;gt; &amp;quot;(&amp;amp;(uid=$username)(objectclass=inetOrgPerson))&amp;quot;,&lt;br /&gt;
        attrs   =&amp;gt;  ['1.1', 'uid', 'sn', 'givenname', 'mail'],&lt;br /&gt;
        sizelimit=&amp;gt;1&lt;br /&gt;
    );&lt;br /&gt;
    my $entr = $result-&amp;gt;pop_entry;&lt;br /&gt;
    unless( defined $entr )&lt;br /&gt;
    {&lt;br /&gt;
        # Allow local EPrints authentication for admins (accounts not found in LDAP)&lt;br /&gt;
        my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
        return 0 unless $user;&lt;br /&gt;
        &lt;br /&gt;
        my $user_type = $user-&amp;gt;get_type;&lt;br /&gt;
        if( $user_type eq &amp;quot;admin&amp;quot; )&lt;br /&gt;
        {&lt;br /&gt;
            # internal authentication for &amp;quot;admin&amp;quot; type&lt;br /&gt;
            return $session-&amp;gt;get_database-&amp;gt;valid_login( $username, $password );&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    my $ldap_dn = $entr-&amp;gt;dn;&lt;br /&gt;
    &lt;br /&gt;
    # Check password&lt;br /&gt;
    my $mesg = $ldap-&amp;gt;bind( $ldap_dn, password =&amp;gt; $password );&lt;br /&gt;
    if( $mesg-&amp;gt;code() )&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Does account already exist?&lt;br /&gt;
    my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
    if( !defined $user )&lt;br /&gt;
    {&lt;br /&gt;
        # New account&lt;br /&gt;
        $user = EPrints::DataObj::User::create( $session, &amp;quot;user&amp;quot; );&lt;br /&gt;
        $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Set metadata&lt;br /&gt;
    my $name = {};&lt;br /&gt;
    $name-&amp;gt;{family} = $entr-&amp;gt;get_value( &amp;quot;sn&amp;quot; );&lt;br /&gt;
    $name-&amp;gt;{given} = $entr-&amp;gt;get_value( &amp;quot;givenName&amp;quot; );&lt;br /&gt;
    $user-&amp;gt;set_value( &amp;quot;name&amp;quot;, $name );&lt;br /&gt;
    $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
    $user-&amp;gt;set_value( &amp;quot;email&amp;quot;, $entr-&amp;gt;get_value( &amp;quot;mail&amp;quot; ) );&lt;br /&gt;
    $user-&amp;gt;commit();&lt;br /&gt;
    &lt;br /&gt;
    $ldap-&amp;gt;unbind if $ldap;&lt;br /&gt;
    &lt;br /&gt;
    return 1;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
====Things to note====&lt;br /&gt;
&lt;br /&gt;
* This script uses a dedicated proxy account which must exist in your LDAP tree and has appropriate permissions (ACL settings) to search for users and read their &amp;lt;tt&amp;gt;uid,givenname,sn,mail&amp;lt;/tt&amp;gt; attributes.&lt;br /&gt;
* It gets this proxy accounts' password from a file inside the repository configuration. this file needs to have read permissions for the user your webserver runs as (e.g. &amp;lt;tt&amp;gt;www-data&amp;lt;/tt&amp;gt; on Debian).  Use file system permissions to protect this (e.g. &amp;lt;tt&amp;gt;chmod 400 ldap.passwd&amp;lt;/tt&amp;gt;).&lt;br /&gt;
* It changes the flow of &amp;lt;tt&amp;gt;user_login.pl&amp;lt;/tt&amp;gt; a little to only check for local ''admin'' accounts (no users or editors; we have them all in our LDAP tree) and only when no user is found for ldap authentication. This allows you to have your admins in LDAP (if you want) but still use the local admin for &amp;quot;promoting&amp;quot; other users to admins, among other things (which could also be done with a simple SQL &amp;lt;code&amp;gt;update&amp;lt;/code&amp;gt; directly in the RDBMS). If you don't need the local admin, remove those lines and just &amp;lt;tt&amp;gt;return 0&amp;lt;/tt&amp;gt; since no user was found in LDAP.&lt;br /&gt;
* you could change the default role for generated user accounts from &amp;lt;tt&amp;gt;user&amp;lt;/tt&amp;gt;, if you really wanted.&lt;br /&gt;
&lt;br /&gt;
===Kerberos Authentication on AD with On-Demand Creation of Users using LDAP ===&lt;br /&gt;
&lt;br /&gt;
Tested on 3.3.8&lt;br /&gt;
&lt;br /&gt;
Here's another example of a customized &amp;lt;tt&amp;gt;/opt/eprints3/archives/ARCHIVEID/cfg/cfg.d/user_login.pl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
* allowing LDAP accounts to login, using the following example&lt;br /&gt;
* allowing the local eprints admin account to login w/ database authentication&lt;br /&gt;
* creating eprints accounts for all successfully authenticated LDAP users ''on the fly''&lt;br /&gt;
&lt;br /&gt;
$c-&amp;gt;{check_user_password} = sub {&lt;br /&gt;
   my( $session, $username, $password ) = @_;&lt;br /&gt;
   &lt;br /&gt;
   # Kerberos authentication for &amp;quot;user&amp;quot;, &amp;quot;editor&amp;quot; and &amp;quot;admin&amp;quot; types (roles)&lt;br /&gt;
   &lt;br /&gt;
   use Net::LDAP; # IO::Socket::SSL also required&lt;br /&gt;
   use Authen::Krb5::Simple;&lt;br /&gt;
   use Authen::SASL;&lt;br /&gt;
   &lt;br /&gt;
   # LDAP tunables&lt;br /&gt;
   my $ldap_host = &amp;quot;ldap.example.org&amp;quot;;&lt;br /&gt;
   my $base      = &amp;quot;OU=people,DC=example,DC=org&amp;quot;;&lt;br /&gt;
   my $proxy_user =&amp;quot;ad_read&amp;quot;;&lt;br /&gt;
   my $dn        = &amp;quot;CN=$proxy_user,$base&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   # Kerberos tunables&lt;br /&gt;
   my $krb_host = &amp;quot;example.org&amp;quot;;&lt;br /&gt;
   &lt;br /&gt;
   my $krb 	  = Authen::Krb5::Simple-&amp;gt;new(realm =&amp;gt; $krb_host);&lt;br /&gt;
   unless ( $krb )&lt;br /&gt;
   {&lt;br /&gt;
	print STDERR &amp;quot;Kerberos error: $@\n&amp;quot;;&lt;br /&gt;
	return 0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   my $ldap      = Net::LDAP-&amp;gt;new ( $ldap_host );&lt;br /&gt;
   unless( $ldap )&lt;br /&gt;
   {&lt;br /&gt;
       print STDERR &amp;quot;LDAP error: $@\n&amp;quot;;&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   my $sasl = Authen::SASL-&amp;gt;new(&lt;br /&gt;
          mechanism =&amp;gt; 'GSSAPI', &lt;br /&gt;
          callback =&amp;gt; { user =&amp;gt; 'ad_read' }&lt;br /&gt;
        ) or die &amp;quot;$@&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   my $mesg = $ldap-&amp;gt;bind(sasl =&amp;gt; $sasl);&lt;br /&gt;
&lt;br /&gt;
   if( $mesg-&amp;gt;code() )&lt;br /&gt;
   {&lt;br /&gt;
       print STDERR &amp;quot;LDAP Bind error: &amp;quot; . $mesg-&amp;gt;error() . &amp;quot;\n&amp;quot;;&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   # Distinguished name (and attribues needed later on) for this user&lt;br /&gt;
   my $result = $ldap-&amp;gt;search (&lt;br /&gt;
       base    =&amp;gt; &amp;quot;$base&amp;quot;,&lt;br /&gt;
       filter  =&amp;gt; &amp;quot;(&amp;amp;(sAMAccountName=$username))&amp;quot;,&lt;br /&gt;
       attrs   =&amp;gt;  ['1.1', 'uid', 'sn', 'givenname', 'mail', 'department', 'title'],&lt;br /&gt;
       sizelimit=&amp;gt;1&lt;br /&gt;
   );&lt;br /&gt;
&lt;br /&gt;
   my $entr = $result-&amp;gt;pop_entry;&lt;br /&gt;
   unless( defined $entr )&lt;br /&gt;
   {&lt;br /&gt;
       # Allow local EPrints authentication for admins (accounts not found in LDAP)&lt;br /&gt;
       my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
       return 0 unless $user;&lt;br /&gt;
&lt;br /&gt;
       my $user_type = $user-&amp;gt;get_type;&lt;br /&gt;
       if( $user_type eq &amp;quot;admin&amp;quot; )&lt;br /&gt;
       {&lt;br /&gt;
           # internal authentication for &amp;quot;admin&amp;quot; type&lt;br /&gt;
           return $session-&amp;gt;get_database-&amp;gt;valid_login( $username, $password );&lt;br /&gt;
       }&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
   # Check password&lt;br /&gt;
   if( !$krb-&amp;gt;authenticate( $username, $password ) )&lt;br /&gt;
   {&lt;br /&gt;
	print STDERR &amp;quot;$username authentication failed: &amp;quot;, $krb-&amp;gt;errstr(), &amp;quot;\n&amp;quot;;&lt;br /&gt;
       return 0;&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   # Does account already exist?&lt;br /&gt;
   my $user = EPrints::DataObj::User::user_with_username( $session, $username );&lt;br /&gt;
   if( !defined $user )&lt;br /&gt;
   {&lt;br /&gt;
       # New account&lt;br /&gt;
       $user = EPrints::DataObj::User::create( $session, &amp;quot;user&amp;quot; );&lt;br /&gt;
       $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   # Set metadata&lt;br /&gt;
   my $name = {};&lt;br /&gt;
   $name-&amp;gt;{family} = $entr-&amp;gt;get_value( &amp;quot;sn&amp;quot; );&lt;br /&gt;
   $name-&amp;gt;{given} = $entr-&amp;gt;get_value( &amp;quot;givenName&amp;quot; );&lt;br /&gt;
   $name-&amp;gt;{honourific} = $entr-&amp;gt;get_value( &amp;quot;title&amp;quot;);&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;name&amp;quot;, $name );&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;username&amp;quot;, $username );&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;email&amp;quot;, $entr-&amp;gt;get_value( &amp;quot;mail&amp;quot; ) );&lt;br /&gt;
   $user-&amp;gt;set_value( &amp;quot;dept&amp;quot;, $entr-&amp;gt;get_value(&amp;quot;department&amp;quot;)  );&lt;br /&gt;
   $user-&amp;gt;commit();&lt;br /&gt;
   &lt;br /&gt;
   $ldap-&amp;gt;unbind if $ldap;&lt;br /&gt;
   &lt;br /&gt;
   return 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
====Possible enhancements====&lt;br /&gt;
&lt;br /&gt;
Currently this script does not remove local eprints accounts from the database: when accounts get deleted from the LDAP database the corresponding local EPrints accounts sit around forever. But since login isn't possible anymore this is not a risk or of high priority.&lt;br /&gt;
&lt;br /&gt;
Depending on your situation it may be enough to run some kind of cleanup script, e.g. once a year, that get's a list of all local EPrints accounts, loops over them and &amp;lt;code&amp;gt;$user-&amp;gt;remove&amp;lt;/code&amp;gt;s all those, which cannot be found in LDAP anymore (except for those where &amp;lt;code&amp;gt;$user_type eq 'admin'&amp;lt;/code&amp;gt;, so you don't risk losing your local admins).&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=IRStats&amp;diff=10292</id>
		<title>IRStats</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=IRStats&amp;diff=10292"/>
		<updated>2012-03-07T17:30:03Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:IRStats]]&lt;br /&gt;
IRStats is a flexible statistics package which allows easy processing of accesses to fulltext documents of eprints. It can be downloaded from the [http://files.eprints.org/722/ Eprints File repository]. For more detailed information, please see the [[IRStats Technical Documentation]], though it is now somewhat out of date.&lt;br /&gt;
&lt;br /&gt;
== The front end ==&lt;br /&gt;
&lt;br /&gt;
===The Query Form===&lt;br /&gt;
&lt;br /&gt;
The main interface to IRStats is found at the following URL (given a repository base URL of myrepository.ac.uk):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
myrepository.ac.uk/cgi/irstats.cgi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will be presented with a form allowing you to select the parameters with which to generate a report.&lt;br /&gt;
&lt;br /&gt;
===Advanced Report Generation (get_view2 params)===&lt;br /&gt;
&lt;br /&gt;
The following will help if you wish to create queries by setting the CGI parameters by hand.&lt;br /&gt;
&lt;br /&gt;
There are three fundamental parameters that IRStats uses.  There are:&lt;br /&gt;
* A Date Range (actually 6 parameters for day, month and year for both start and end dates)&lt;br /&gt;
* A Set of EPrints&lt;br /&gt;
* A View&lt;br /&gt;
&lt;br /&gt;
However, in order to add functionality, the get_view2 page will convert a larger number of parameters into these three.  The following table shows all parameters and values, with square brackets denoting variables.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Parameter&lt;br /&gt;
! Possible Values&lt;br /&gt;
! Notes&lt;br /&gt;
|- &lt;br /&gt;
| IRS_datechoice || period, range || Controls whether the 6 date range parameters or the single period parameter is used.&lt;br /&gt;
|-&lt;br /&gt;
| period || -[X]m, Q[Z][YYYY] || Used when IRS_datechoice=period.&amp;lt;br/&amp;gt;Where m and Q are literal characters, X is a positive integer, Z is an integer in the range 1 to 4 and YYYY is a four digit year.&amp;lt;br/&amp;gt;Examples: &amp;lt;dl&amp;gt;&amp;lt;dt&amp;gt;-4m&amp;lt;dd&amp;gt;Go back exactly four months from today's date&amp;lt;dt&amp;gt;Q32004&amp;lt;dd&amp;gt;Quarter 3, 2004&amp;lt;/dl&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| start_day, start_month, start_year, end_day, end_month, end_year || integers (1-31, 1-12, four digit respectively) || Used when IRS_datechoice=range.&amp;lt;br/&amp;gt; Note that if a day value is higher than the highest day in the chosen month, it will be treated as the highest day -- e.g. start_day=31&amp;amp;start_month=02 is seen as valid and equivalent to February 28th.  Note that start_day=99 is also valid! &lt;br /&gt;
|-&lt;br /&gt;
| IRS_epchoice || All, EPrint, [set_id] || Controls whether stats will be generated on all eprints, a single eprints, or a set of eprints.  The 'All' option is the only one that does not require extra parameters.  Note that 'set_id' is the id of a valid set as defined in the IRStats configuration.&lt;br /&gt;
|-&lt;br /&gt;
| eprint || [eprintid] || Used when IRS_epchoice=EPrint.&amp;lt;br/&amp;gt;Any valid eprint ID (integer).&lt;br /&gt;
|-&lt;br /&gt;
| [set_id]s || [set_id]_[set_member_code] || Used when IRS_epchoice=[set_id].&amp;lt;br/&amp;gt;  Best described through example: &amp;lt;dl&amp;gt;&amp;lt;dt&amp;gt;IRS_epchoice=divisions&amp;amp;divisionss=divisions_art&amp;lt;dd&amp;gt;Will generate a report on the art department, given a standard EPrints repository and IRStats config, where the subject id 'art' exists in the divisions tree in EPrints.&lt;br /&gt;
|-&lt;br /&gt;
| view || [view classname] || The classname of the IRStats::View perl module.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===The Dashboard Form===&lt;br /&gt;
&lt;br /&gt;
A dashboard is a collection of reports on a single item or set of items (e.g. all items by John Smith).  To access the form to generate a report, go to the url:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
myrepository.ac.uk/cgi/irstats.cgi?page=db&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The configuration file ==&lt;br /&gt;
&lt;br /&gt;
Documentation to follow.&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=IRStats&amp;diff=10291</id>
		<title>IRStats</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=IRStats&amp;diff=10291"/>
		<updated>2012-03-07T17:29:49Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:IRStats]]&lt;br /&gt;
IRStats is a flexible statistics package which allows easy processing of accesses to fulltext documents of eprints. It can be downloaded from the [http://files.eprints.org/722/ | Eprints File repository]. For more detailed information, please see the [[IRStats Technical Documentation]], though it is now somewhat out of date.&lt;br /&gt;
&lt;br /&gt;
== The front end ==&lt;br /&gt;
&lt;br /&gt;
===The Query Form===&lt;br /&gt;
&lt;br /&gt;
The main interface to IRStats is found at the following URL (given a repository base URL of myrepository.ac.uk):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
myrepository.ac.uk/cgi/irstats.cgi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will be presented with a form allowing you to select the parameters with which to generate a report.&lt;br /&gt;
&lt;br /&gt;
===Advanced Report Generation (get_view2 params)===&lt;br /&gt;
&lt;br /&gt;
The following will help if you wish to create queries by setting the CGI parameters by hand.&lt;br /&gt;
&lt;br /&gt;
There are three fundamental parameters that IRStats uses.  There are:&lt;br /&gt;
* A Date Range (actually 6 parameters for day, month and year for both start and end dates)&lt;br /&gt;
* A Set of EPrints&lt;br /&gt;
* A View&lt;br /&gt;
&lt;br /&gt;
However, in order to add functionality, the get_view2 page will convert a larger number of parameters into these three.  The following table shows all parameters and values, with square brackets denoting variables.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Parameter&lt;br /&gt;
! Possible Values&lt;br /&gt;
! Notes&lt;br /&gt;
|- &lt;br /&gt;
| IRS_datechoice || period, range || Controls whether the 6 date range parameters or the single period parameter is used.&lt;br /&gt;
|-&lt;br /&gt;
| period || -[X]m, Q[Z][YYYY] || Used when IRS_datechoice=period.&amp;lt;br/&amp;gt;Where m and Q are literal characters, X is a positive integer, Z is an integer in the range 1 to 4 and YYYY is a four digit year.&amp;lt;br/&amp;gt;Examples: &amp;lt;dl&amp;gt;&amp;lt;dt&amp;gt;-4m&amp;lt;dd&amp;gt;Go back exactly four months from today's date&amp;lt;dt&amp;gt;Q32004&amp;lt;dd&amp;gt;Quarter 3, 2004&amp;lt;/dl&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| start_day, start_month, start_year, end_day, end_month, end_year || integers (1-31, 1-12, four digit respectively) || Used when IRS_datechoice=range.&amp;lt;br/&amp;gt; Note that if a day value is higher than the highest day in the chosen month, it will be treated as the highest day -- e.g. start_day=31&amp;amp;start_month=02 is seen as valid and equivalent to February 28th.  Note that start_day=99 is also valid! &lt;br /&gt;
|-&lt;br /&gt;
| IRS_epchoice || All, EPrint, [set_id] || Controls whether stats will be generated on all eprints, a single eprints, or a set of eprints.  The 'All' option is the only one that does not require extra parameters.  Note that 'set_id' is the id of a valid set as defined in the IRStats configuration.&lt;br /&gt;
|-&lt;br /&gt;
| eprint || [eprintid] || Used when IRS_epchoice=EPrint.&amp;lt;br/&amp;gt;Any valid eprint ID (integer).&lt;br /&gt;
|-&lt;br /&gt;
| [set_id]s || [set_id]_[set_member_code] || Used when IRS_epchoice=[set_id].&amp;lt;br/&amp;gt;  Best described through example: &amp;lt;dl&amp;gt;&amp;lt;dt&amp;gt;IRS_epchoice=divisions&amp;amp;divisionss=divisions_art&amp;lt;dd&amp;gt;Will generate a report on the art department, given a standard EPrints repository and IRStats config, where the subject id 'art' exists in the divisions tree in EPrints.&lt;br /&gt;
|-&lt;br /&gt;
| view || [view classname] || The classname of the IRStats::View perl module.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===The Dashboard Form===&lt;br /&gt;
&lt;br /&gt;
A dashboard is a collection of reports on a single item or set of items (e.g. all items by John Smith).  To access the form to generate a report, go to the url:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
myrepository.ac.uk/cgi/irstats.cgi?page=db&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The configuration file ==&lt;br /&gt;
&lt;br /&gt;
Documentation to follow.&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=IRStats&amp;diff=10290</id>
		<title>IRStats</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=IRStats&amp;diff=10290"/>
		<updated>2012-03-07T17:29:04Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:IRStats]]&lt;br /&gt;
IRStats is a flexible statistics package which allows easy processing of accesses to fulltext documents of eprints. It can be downloaded from the [[ http://files.eprints.org/722/ | Eprints File repository]]. For more detailed information, please see the [[IRStats Technical Documentation]], though it is now somewhat out of date.&lt;br /&gt;
&lt;br /&gt;
== The front end ==&lt;br /&gt;
&lt;br /&gt;
===The Query Form===&lt;br /&gt;
&lt;br /&gt;
The main interface to IRStats is found at the following URL (given a repository base URL of myrepository.ac.uk):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
myrepository.ac.uk/cgi/irstats.cgi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will be presented with a form allowing you to select the parameters with which to generate a report.&lt;br /&gt;
&lt;br /&gt;
===Advanced Report Generation (get_view2 params)===&lt;br /&gt;
&lt;br /&gt;
The following will help if you wish to create queries by setting the CGI parameters by hand.&lt;br /&gt;
&lt;br /&gt;
There are three fundamental parameters that IRStats uses.  There are:&lt;br /&gt;
* A Date Range (actually 6 parameters for day, month and year for both start and end dates)&lt;br /&gt;
* A Set of EPrints&lt;br /&gt;
* A View&lt;br /&gt;
&lt;br /&gt;
However, in order to add functionality, the get_view2 page will convert a larger number of parameters into these three.  The following table shows all parameters and values, with square brackets denoting variables.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Parameter&lt;br /&gt;
! Possible Values&lt;br /&gt;
! Notes&lt;br /&gt;
|- &lt;br /&gt;
| IRS_datechoice || period, range || Controls whether the 6 date range parameters or the single period parameter is used.&lt;br /&gt;
|-&lt;br /&gt;
| period || -[X]m, Q[Z][YYYY] || Used when IRS_datechoice=period.&amp;lt;br/&amp;gt;Where m and Q are literal characters, X is a positive integer, Z is an integer in the range 1 to 4 and YYYY is a four digit year.&amp;lt;br/&amp;gt;Examples: &amp;lt;dl&amp;gt;&amp;lt;dt&amp;gt;-4m&amp;lt;dd&amp;gt;Go back exactly four months from today's date&amp;lt;dt&amp;gt;Q32004&amp;lt;dd&amp;gt;Quarter 3, 2004&amp;lt;/dl&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| start_day, start_month, start_year, end_day, end_month, end_year || integers (1-31, 1-12, four digit respectively) || Used when IRS_datechoice=range.&amp;lt;br/&amp;gt; Note that if a day value is higher than the highest day in the chosen month, it will be treated as the highest day -- e.g. start_day=31&amp;amp;start_month=02 is seen as valid and equivalent to February 28th.  Note that start_day=99 is also valid! &lt;br /&gt;
|-&lt;br /&gt;
| IRS_epchoice || All, EPrint, [set_id] || Controls whether stats will be generated on all eprints, a single eprints, or a set of eprints.  The 'All' option is the only one that does not require extra parameters.  Note that 'set_id' is the id of a valid set as defined in the IRStats configuration.&lt;br /&gt;
|-&lt;br /&gt;
| eprint || [eprintid] || Used when IRS_epchoice=EPrint.&amp;lt;br/&amp;gt;Any valid eprint ID (integer).&lt;br /&gt;
|-&lt;br /&gt;
| [set_id]s || [set_id]_[set_member_code] || Used when IRS_epchoice=[set_id].&amp;lt;br/&amp;gt;  Best described through example: &amp;lt;dl&amp;gt;&amp;lt;dt&amp;gt;IRS_epchoice=divisions&amp;amp;divisionss=divisions_art&amp;lt;dd&amp;gt;Will generate a report on the art department, given a standard EPrints repository and IRStats config, where the subject id 'art' exists in the divisions tree in EPrints.&lt;br /&gt;
|-&lt;br /&gt;
| view || [view classname] || The classname of the IRStats::View perl module.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===The Dashboard Form===&lt;br /&gt;
&lt;br /&gt;
A dashboard is a collection of reports on a single item or set of items (e.g. all items by John Smith).  To access the form to generate a report, go to the url:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
myrepository.ac.uk/cgi/irstats.cgi?page=db&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The configuration file ==&lt;br /&gt;
&lt;br /&gt;
Documentation to follow.&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=IRStats&amp;diff=10289</id>
		<title>IRStats</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=IRStats&amp;diff=10289"/>
		<updated>2012-03-07T17:28:46Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:IRStats]]&lt;br /&gt;
IRStats is a flexible statistics package which allows easy processing of accesses to fulltext documents of eprints. It can be downloaded from the [[Eprints File repository | http://files.eprints.org/722/]]. For more detailed information, please see the [[IRStats Technical Documentation]], though it is now somewhat out of date.&lt;br /&gt;
&lt;br /&gt;
== The front end ==&lt;br /&gt;
&lt;br /&gt;
===The Query Form===&lt;br /&gt;
&lt;br /&gt;
The main interface to IRStats is found at the following URL (given a repository base URL of myrepository.ac.uk):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
myrepository.ac.uk/cgi/irstats.cgi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will be presented with a form allowing you to select the parameters with which to generate a report.&lt;br /&gt;
&lt;br /&gt;
===Advanced Report Generation (get_view2 params)===&lt;br /&gt;
&lt;br /&gt;
The following will help if you wish to create queries by setting the CGI parameters by hand.&lt;br /&gt;
&lt;br /&gt;
There are three fundamental parameters that IRStats uses.  There are:&lt;br /&gt;
* A Date Range (actually 6 parameters for day, month and year for both start and end dates)&lt;br /&gt;
* A Set of EPrints&lt;br /&gt;
* A View&lt;br /&gt;
&lt;br /&gt;
However, in order to add functionality, the get_view2 page will convert a larger number of parameters into these three.  The following table shows all parameters and values, with square brackets denoting variables.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Parameter&lt;br /&gt;
! Possible Values&lt;br /&gt;
! Notes&lt;br /&gt;
|- &lt;br /&gt;
| IRS_datechoice || period, range || Controls whether the 6 date range parameters or the single period parameter is used.&lt;br /&gt;
|-&lt;br /&gt;
| period || -[X]m, Q[Z][YYYY] || Used when IRS_datechoice=period.&amp;lt;br/&amp;gt;Where m and Q are literal characters, X is a positive integer, Z is an integer in the range 1 to 4 and YYYY is a four digit year.&amp;lt;br/&amp;gt;Examples: &amp;lt;dl&amp;gt;&amp;lt;dt&amp;gt;-4m&amp;lt;dd&amp;gt;Go back exactly four months from today's date&amp;lt;dt&amp;gt;Q32004&amp;lt;dd&amp;gt;Quarter 3, 2004&amp;lt;/dl&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| start_day, start_month, start_year, end_day, end_month, end_year || integers (1-31, 1-12, four digit respectively) || Used when IRS_datechoice=range.&amp;lt;br/&amp;gt; Note that if a day value is higher than the highest day in the chosen month, it will be treated as the highest day -- e.g. start_day=31&amp;amp;start_month=02 is seen as valid and equivalent to February 28th.  Note that start_day=99 is also valid! &lt;br /&gt;
|-&lt;br /&gt;
| IRS_epchoice || All, EPrint, [set_id] || Controls whether stats will be generated on all eprints, a single eprints, or a set of eprints.  The 'All' option is the only one that does not require extra parameters.  Note that 'set_id' is the id of a valid set as defined in the IRStats configuration.&lt;br /&gt;
|-&lt;br /&gt;
| eprint || [eprintid] || Used when IRS_epchoice=EPrint.&amp;lt;br/&amp;gt;Any valid eprint ID (integer).&lt;br /&gt;
|-&lt;br /&gt;
| [set_id]s || [set_id]_[set_member_code] || Used when IRS_epchoice=[set_id].&amp;lt;br/&amp;gt;  Best described through example: &amp;lt;dl&amp;gt;&amp;lt;dt&amp;gt;IRS_epchoice=divisions&amp;amp;divisionss=divisions_art&amp;lt;dd&amp;gt;Will generate a report on the art department, given a standard EPrints repository and IRStats config, where the subject id 'art' exists in the divisions tree in EPrints.&lt;br /&gt;
|-&lt;br /&gt;
| view || [view classname] || The classname of the IRStats::View perl module.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===The Dashboard Form===&lt;br /&gt;
&lt;br /&gt;
A dashboard is a collection of reports on a single item or set of items (e.g. all items by John Smith).  To access the form to generate a report, go to the url:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
myrepository.ac.uk/cgi/irstats.cgi?page=db&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The configuration file ==&lt;br /&gt;
&lt;br /&gt;
Documentation to follow.&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=IRStats&amp;diff=10288</id>
		<title>IRStats</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=IRStats&amp;diff=10288"/>
		<updated>2012-03-07T17:28:17Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:IRStats]]&lt;br /&gt;
IRStats is a flexible statistics package which allows easy processing of accesses to fulltext documents of eprints. It can be downloaded from eprints file repository [[http://files.eprints.org/722/]]. For more detailed information, please see the [[IRStats Technical Documentation]], though it is now somewhat out of date.&lt;br /&gt;
&lt;br /&gt;
== The front end ==&lt;br /&gt;
&lt;br /&gt;
===The Query Form===&lt;br /&gt;
&lt;br /&gt;
The main interface to IRStats is found at the following URL (given a repository base URL of myrepository.ac.uk):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
myrepository.ac.uk/cgi/irstats.cgi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will be presented with a form allowing you to select the parameters with which to generate a report.&lt;br /&gt;
&lt;br /&gt;
===Advanced Report Generation (get_view2 params)===&lt;br /&gt;
&lt;br /&gt;
The following will help if you wish to create queries by setting the CGI parameters by hand.&lt;br /&gt;
&lt;br /&gt;
There are three fundamental parameters that IRStats uses.  There are:&lt;br /&gt;
* A Date Range (actually 6 parameters for day, month and year for both start and end dates)&lt;br /&gt;
* A Set of EPrints&lt;br /&gt;
* A View&lt;br /&gt;
&lt;br /&gt;
However, in order to add functionality, the get_view2 page will convert a larger number of parameters into these three.  The following table shows all parameters and values, with square brackets denoting variables.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Parameter&lt;br /&gt;
! Possible Values&lt;br /&gt;
! Notes&lt;br /&gt;
|- &lt;br /&gt;
| IRS_datechoice || period, range || Controls whether the 6 date range parameters or the single period parameter is used.&lt;br /&gt;
|-&lt;br /&gt;
| period || -[X]m, Q[Z][YYYY] || Used when IRS_datechoice=period.&amp;lt;br/&amp;gt;Where m and Q are literal characters, X is a positive integer, Z is an integer in the range 1 to 4 and YYYY is a four digit year.&amp;lt;br/&amp;gt;Examples: &amp;lt;dl&amp;gt;&amp;lt;dt&amp;gt;-4m&amp;lt;dd&amp;gt;Go back exactly four months from today's date&amp;lt;dt&amp;gt;Q32004&amp;lt;dd&amp;gt;Quarter 3, 2004&amp;lt;/dl&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| start_day, start_month, start_year, end_day, end_month, end_year || integers (1-31, 1-12, four digit respectively) || Used when IRS_datechoice=range.&amp;lt;br/&amp;gt; Note that if a day value is higher than the highest day in the chosen month, it will be treated as the highest day -- e.g. start_day=31&amp;amp;start_month=02 is seen as valid and equivalent to February 28th.  Note that start_day=99 is also valid! &lt;br /&gt;
|-&lt;br /&gt;
| IRS_epchoice || All, EPrint, [set_id] || Controls whether stats will be generated on all eprints, a single eprints, or a set of eprints.  The 'All' option is the only one that does not require extra parameters.  Note that 'set_id' is the id of a valid set as defined in the IRStats configuration.&lt;br /&gt;
|-&lt;br /&gt;
| eprint || [eprintid] || Used when IRS_epchoice=EPrint.&amp;lt;br/&amp;gt;Any valid eprint ID (integer).&lt;br /&gt;
|-&lt;br /&gt;
| [set_id]s || [set_id]_[set_member_code] || Used when IRS_epchoice=[set_id].&amp;lt;br/&amp;gt;  Best described through example: &amp;lt;dl&amp;gt;&amp;lt;dt&amp;gt;IRS_epchoice=divisions&amp;amp;divisionss=divisions_art&amp;lt;dd&amp;gt;Will generate a report on the art department, given a standard EPrints repository and IRStats config, where the subject id 'art' exists in the divisions tree in EPrints.&lt;br /&gt;
|-&lt;br /&gt;
| view || [view classname] || The classname of the IRStats::View perl module.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===The Dashboard Form===&lt;br /&gt;
&lt;br /&gt;
A dashboard is a collection of reports on a single item or set of items (e.g. all items by John Smith).  To access the form to generate a report, go to the url:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
myrepository.ac.uk/cgi/irstats.cgi?page=db&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The configuration file ==&lt;br /&gt;
&lt;br /&gt;
Documentation to follow.&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=How_to_add_a_subdirectory_that_runs_PHP_scripts&amp;diff=10286</id>
		<title>How to add a subdirectory that runs PHP scripts</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=How_to_add_a_subdirectory_that_runs_PHP_scripts&amp;diff=10286"/>
		<updated>2012-03-07T15:17:02Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Howto]]&lt;br /&gt;
In this example, we are adding a 'blog' directory, perhaps to host wordpress.&lt;br /&gt;
&lt;br /&gt;
===Edit (or create) [eprint install dir]/archives/[archive]/cfg/cfg.d/[[20_baseurls.pl]]===&lt;br /&gt;
&lt;br /&gt;
Amend this line to include the directory you want to make an exception for.  &lt;br /&gt;
&lt;br /&gt;
Here we are adding the directory /blog/ to the array.&lt;br /&gt;
 $c-&amp;gt;{[[rewrite_exceptions]]} = [ '/cgi/', '/archive/', ''''/blog/''''];&lt;br /&gt;
&lt;br /&gt;
Save and close.&lt;br /&gt;
&lt;br /&gt;
===Edit: [eprint install dir]/archives/[archive]/cfg/[[apachevhost.conf]]===&lt;br /&gt;
&lt;br /&gt;
And add the following.&lt;br /&gt;
&lt;br /&gt;
   Alias /blog/ /path/to/blog/&lt;br /&gt;
   &amp;lt;Location &amp;quot;/blog&amp;quot;&amp;gt;&lt;br /&gt;
      AddHandler php5-script php&lt;br /&gt;
      DirectoryIndex index.php&lt;br /&gt;
   &amp;lt;/Location&amp;gt; &lt;br /&gt;
   &amp;lt;Directory /path/to/blog&amp;gt;&lt;br /&gt;
      Order allow,deny&lt;br /&gt;
      Allow from all&lt;br /&gt;
   &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Restart Apache===&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/apache2 force-reload&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=User:Denics@free.fr&amp;diff=10232</id>
		<title>User:Denics@free.fr</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=User:Denics@free.fr&amp;diff=10232"/>
		<updated>2011-12-22T17:09:36Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: Created page with 'Ciao!'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ciao!&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=How_to&amp;diff=10152</id>
		<title>How to</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=How_to&amp;diff=10152"/>
		<updated>2011-12-10T11:53:02Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: /* Using an external search engine */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Howto]]&lt;br /&gt;
==HOW TO: Set up a Complex Custom View==&lt;br /&gt;
Simple instructions are in the ArchiveConfig.pm section.&lt;br /&gt;
&lt;br /&gt;
Example situation: On my main website www.foobars.ac.uk I have a page per research project, of which we have hundreds. Each project has a short unique id code, eg. &amp;quot;manticore&amp;quot;. I have a field in my eprints archive (eprints.foobars.ac.uk) which is configured:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { name=&amp;gt;&amp;quot;projectcodes&amp;quot;, type=&amp;gt;&amp;quot;text&amp;quot;, multiple=&amp;gt;1 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
I add the following browse view:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { id=&amp;gt;&amp;quot;by_project&amp;quot;, allow_null=&amp;gt;0, fields=&amp;gt;&amp;quot;projectcodes&amp;quot;, &lt;br /&gt;
 order=&amp;gt;&amp;quot;-year/title&amp;quot; }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This will generate a page http://eprints.foobars.ac.uk/views/by_project/manticore.html with a list of all papers in that project, we can link to that URL!&lt;br /&gt;
&lt;br /&gt;
===Making the Field link to the Browse Page===&lt;br /&gt;
If you want a subject to link the subject browse page of that value, add the '''browse_link''' property to the field (and regenerate the abstracts if you want).&lt;br /&gt;
&lt;br /&gt;
If you remove the browse view you should remove the browse_link or it will be a broken link.&lt;br /&gt;
&lt;br /&gt;
Values rendered inside citations which are used to link to the main record will not link into the browse view for obvious reasons.&lt;br /&gt;
&lt;br /&gt;
===Including a view in another page===&lt;br /&gt;
If you change that to:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { id=&amp;gt;&amp;quot;by_project&amp;quot;, allow_null=&amp;gt;0, fields=&amp;gt;&amp;quot;projectcodes&amp;quot;, &lt;br /&gt;
 order=&amp;gt;&amp;quot;-year/title&amp;quot;, noindex=&amp;gt;1, nolink=&amp;gt;1, nohtml=&amp;gt;1, include=&amp;gt;1 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This will generate a view which is NOT listed on the /view/ page and it will not skip making the .html file and make a .include file per value. This will only contain the &amp;quot;count&amp;quot; of items and the XHTML of their citations. This can be used as part of a page on the http://www.foobaars.ac.uk/ site; either by using php and capturing it on-the-fly using &amp;lt;tt&amp;gt;readfile&amp;lt;/tt&amp;gt; or scripting it with perl or NFS exporting the filesystem onto the main server (or just doing it all on one computer) and using server side includes to place it in a page.&lt;br /&gt;
&lt;br /&gt;
===Customising the way each item is cited===&lt;br /&gt;
I want to list the project papers in a strict format in a table with 4 columns: title, author(s), year and an icon which links to the document abstract page...&lt;br /&gt;
&lt;br /&gt;
I add some ''more'' options to the browse view:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { id=&amp;gt;&amp;quot;by_project&amp;quot;, allow_null=&amp;gt;0, fields=&amp;gt;&amp;quot;projectcodes&amp;quot;, &lt;br /&gt;
 order=&amp;gt;&amp;quot;-year/title&amp;quot;, noindex=&amp;gt;1, nolink=&amp;gt;1, nohtml=&amp;gt;1, include=&amp;gt;1,&lt;br /&gt;
 nocount=&amp;gt;1, citation=&amp;gt;&amp;quot;project_table&amp;quot; }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now I add a new citation to the citations config file:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;ep:citation type=&amp;quot;project_table&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;amp;title;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;amp;authors;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&amp;amp;year;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;ep:linkhere&amp;gt;&amp;lt;img &lt;br /&gt;
 src=&amp;quot;http://www.foobars.ac.uk/images/paperlink.png&amp;quot; alt=&amp;quot;view&amp;quot; width=&amp;quot;32&amp;quot; &lt;br /&gt;
 height=&amp;quot;64&amp;quot; border=&amp;quot;0&amp;quot; /&amp;gt;&amp;lt;/ep:linkhere&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/ep:citation&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
That should generate for the manticore project, in the &amp;quot;.include&amp;quot; file (I've cut the contents of the &amp;quot;img&amp;quot; tag for readability:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Making Stuff&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Guy, A.&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;a &lt;br /&gt;
 href=&amp;quot;http://eprints.foobar.ac.uk/archive/00000923/&amp;quot;&amp;gt;&amp;lt;img ... /&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
 &amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Eating Food&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Herring, Walter and Chips, Bob&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;br /&gt;
 2000&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;a href=&amp;quot;http://eprints.foobar.ac.uk/archive/00000445/&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;img ... /&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===A &amp;quot;CV&amp;quot; page - a list of all of Alices records===&lt;br /&gt;
This is where the authors and editors field having an ID comes in handy.&lt;br /&gt;
&lt;br /&gt;
Say we use local username to identify people in the &amp;quot;Person ID&amp;quot; fields, we can now set up a view:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { id=&amp;gt;&amp;quot;by_person&amp;quot;, allow_null=&amp;gt;0, fields=&amp;gt;&amp;quot;authors.id/editors.id&amp;quot;, &lt;br /&gt;
 order=&amp;gt;&amp;quot;-year/title&amp;quot;, noindex=&amp;gt;1, include=&amp;gt;1 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This will generate both .html pages and .include pages. An member of your organisation can get a list of their records either by linking to &amp;lt;tt&amp;gt;/views/by_person/alice.html&amp;lt;/tt&amp;gt; (where alice is their username) or by snarfing the URL &amp;lt;tt&amp;gt;/views/by_person/alice.include&amp;lt;/tt&amp;gt; into his own homepage.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Fields==&lt;br /&gt;
===Add a new Field&lt;br /&gt;
This convers adding a new field to a new system, not a live system. It is possible to add a new field to a live system but invloves SQL hacking.&lt;br /&gt;
&lt;br /&gt;
In this example we add a new &amp;quot;set&amp;quot; field called &amp;quot;local&amp;quot; which will have 3 options &amp;quot;yes&amp;quot;,&amp;quot;no&amp;quot; and &amp;quot;partial&amp;quot; - this will indicate if the item in question was produced in our organisation or not.&lt;br /&gt;
&lt;br /&gt;
; Add the Field to ArchiveMetafieldConfig.pm : Add the field to the appropriate part of ArchiveMetafieldConfig.pm (the &amp;quot;eprint&amp;quot; section in our example)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { name =&amp;gt; &amp;quot;local&amp;quot;, type =&amp;gt; &amp;quot;set&amp;quot;, input_rows =&amp;gt; 1, &lt;br /&gt;
    options =&amp;gt; [ &amp;quot;yes&amp;quot;, &amp;quot;no&amp;quot;, &amp;quot;partial&amp;quot; ] }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
input_rows being set to one will make it appear as a pull-down menu.&lt;br /&gt;
; Add the Field to metadata-types.xml : If you want the user to be able to edit this field for any or all types of eprint/user then you need to add it to each appropriate type in metadata-types.xml (this can be changed on a live system without any serious consequencies).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;field name=&amp;quot;local&amp;quot; required=&amp;quot;yes&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; Add the Field Information to the Archive Phrase File(s) : Normally we just need to add fieldname and fieldhelp, but this is an option field so we need to add names for each option. If we run the archive in more than one language then we add this to each phrase file (but in the appropriate language).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldname_local&amp;quot;&amp;gt;Produced Locally&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldhelp_local&amp;quot;&amp;gt;Please indicate if this item was &lt;br /&gt;
produces in the foo organisation, or not.&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldopt_local_yes&amp;quot;&amp;gt;produced locally&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldopt_local_no&amp;quot;&amp;gt;not produced locally&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldopt_local_partial&amp;quot;&amp;gt;only partially produced &lt;br /&gt;
locally&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Other things you may wish to change after adding a new field====&lt;br /&gt;
; Add it to the citations file : This is optional, only do this if you want it to appear in the citated forms.&lt;br /&gt;
In our example case we only want this to appear when citing technical reports, so we change that entry to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;ep:citation type=&amp;quot;eprint_techreport&amp;quot;&amp;gt;&amp;lt;ep:linkhere&amp;gt;&amp;lt;span &lt;br /&gt;
 class=&amp;quot;citation&amp;quot;&amp;gt;&amp;amp;authors; &amp;lt;ep:ifset name=&amp;quot;year&amp;quot;&amp;gt;(&amp;amp;year;) &lt;br /&gt;
 &amp;lt;/ep:ifset&amp;gt;&amp;amp;title;. Technical Report&amp;lt;ep:ifset name=&amp;quot;reportno&amp;quot;&amp;gt; &lt;br /&gt;
 &amp;amp;reportno;&amp;lt;/ep:ifset&amp;gt;&amp;lt;ep:ifset name=&amp;quot;department&amp;quot;&amp;gt;, &amp;amp;department;&lt;br /&gt;
 &amp;lt;/ep:ifset&amp;gt;&amp;lt;ep:ifset name=&amp;quot;institution&amp;quot;&amp;gt;, &amp;amp;institution;&amp;lt;/ep:ifset&amp;gt;. &lt;br /&gt;
 &amp;amp;local;.&amp;lt;/span&amp;gt;&amp;lt;/ep:linkhere&amp;gt;&amp;lt;/ep:citation&amp;gt; &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
All we've done is add &amp;lt;tt&amp;gt;&amp;amp;local;.&amp;lt;/tt&amp;gt; to the end. It's not inside &amp;lt;tt&amp;gt; &amp;lt;ep:ifset name=&amp;quot;local&amp;quot;&amp;gt; &amp;lt;/tt&amp;gt; as it is a required field and will (should) always be set.&lt;br /&gt;
; Add it to the the Abstract (or View-User) page. : This is also optional. If you want it to appear on the web page for this item then edit ArchiveRenderConfig.pm and select the appropriate function, either eprint_render or user_render.&lt;br /&gt;
In our example we only want to mention items if an item was not produced locally. We'll add it below the documents and above the abstract...&lt;br /&gt;
Single language example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 if( $eprint-&amp;gt;get_value( &amp;quot;local&amp;quot; ) ne &amp;quot;yes&amp;quot; )&lt;br /&gt;
 {&lt;br /&gt;
      # don't need to &amp;quot;my $p&amp;quot; as it's done earlier.&lt;br /&gt;
      $p = $session-&amp;gt;make_element( &amp;quot;p&amp;quot; );&lt;br /&gt;
      $p-&amp;gt;appendChild( $session-&amp;gt;make_text( &amp;quot;This item was &amp;quot; ) );&lt;br /&gt;
      $p-&amp;gt;appendChild( $eprint-&amp;gt;render_value( &amp;quot;local&amp;quot; ) );&lt;br /&gt;
      $p-&amp;gt;appendChild( $session-&amp;gt;make_text( &amp;quot;.&amp;quot; ) );&lt;br /&gt;
&lt;br /&gt;
      # Append our new paragraph to the page.&lt;br /&gt;
      $page-&amp;gt;appendChild( $p );&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Multiple-language example:&lt;br /&gt;
If you want to make it handle more than language then we'll need to use the archive phrase file - we would add something like this to each languages file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;page:itemnotlocal&amp;quot;&amp;gt;&amp;lt;p&amp;gt;This item was &amp;lt;pin ref=&amp;quot;status&amp;quot; /&amp;gt;.&amp;lt;/p&amp;gt;&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
And to the ArchiveRenderConfig.pm file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 if( $eprint-&amp;gt;get_value( &amp;quot;local&amp;quot; ) ne &amp;quot;yes&amp;quot; )&lt;br /&gt;
 {&lt;br /&gt;
      my $localmsg = $session-&amp;gt;html_phrase(&lt;br /&gt;
             &amp;quot;page:itemnotlocal&amp;quot;,&lt;br /&gt;
             status=&amp;gt;$eprint-&amp;gt;render_value( &amp;quot;local&amp;quot; ) );&lt;br /&gt;
      $page-&amp;gt;appendChild( $localmsg );&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
You may prefer to use this method even if you are only using a single language.&lt;br /&gt;
; Add extra Validation Routines : If you need to validate this field in a special way, add code into ArchiveValidateConfig.pm&lt;br /&gt;
; Add it to the OAI metadata (eprints only) : If this field can be rendered into Dublin Core (or other metadata formats you are using) then add it to the appropriate place in the ArchiveOAIConfig.pm file.&lt;br /&gt;
; Add a browse view (eprints only) : If you want to be able to browse this values items. See elsewhere in the docs for how to do this.&lt;br /&gt;
&lt;br /&gt;
If you add a field you will need to run erase_archive and create_tables before you will see a change. EPrints will fail to run if you change the fields and do rebuild the tables.&lt;br /&gt;
&lt;br /&gt;
===HOW TO: Remove a Field===&lt;br /&gt;
The quick answer is to say &amp;quot;the opposite of adding one&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
; Remove the Field to metadata-types.xml : Removing it from here will mean that nobody can enter values for that field. Which is possibly enough, and means you can put it back later.&lt;br /&gt;
; Remove the Field to ArchiveMetafieldConfig.pm : This will remove it from the database ( and require a rebuild as with adding a field ).&lt;br /&gt;
; Remove it from the phrase file(s) : This is optional, unused phrases are just ignored.&lt;br /&gt;
; Remove it from the citations file : If it's used there.&lt;br /&gt;
; Remove it from the the Abstract (or View-User) page. : If it's used there.&lt;br /&gt;
; Remove extra Validation Routines : In the unlikely event you added some validation which looks at this field.&lt;br /&gt;
; Remove it from the OAI metadata (eprints only) : If it's being used. Fields used to generate the default dublincore are: title, authors, subjects, abstract, year and month. It also uses &amp;quot;type&amp;quot; which is a system field so you can't remove it!&lt;br /&gt;
; Remove it from browse views (eprints only) : If it's used there.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: EPrint types==&lt;br /&gt;
===Add a new eprint type===&lt;br /&gt;
Add the eprint type to '''metadata-types.xml'''. Some fields should probably be &amp;quot;required&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Add the name of the type to the phrase file.&lt;br /&gt;
&lt;br /&gt;
Add a citation for this type to the citations file.&lt;br /&gt;
&lt;br /&gt;
===Remove an eprint type===&lt;br /&gt;
Remove it from metadata-types.xml&lt;br /&gt;
&lt;br /&gt;
You can remove it from the phrase file &amp;amp; citations but it won't hurt to leave it there.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Add a new document type==&lt;br /&gt;
Add it to '''metadata-types.xml'''. This does not need any fields.&lt;br /&gt;
&lt;br /&gt;
Add the name of the document type to the phrase file.&lt;br /&gt;
&lt;br /&gt;
Add a citation for this document to the citations file.&lt;br /&gt;
&lt;br /&gt;
If you want this to be one of the must-have-one-of document types then add it's id to the list in ArchiveConfig.pm&lt;br /&gt;
&lt;br /&gt;
If you want to do something &amp;quot;clever&amp;quot; on the abstract page then edit the ArchiveRenderConfig.pm file. If you don't then it will use the citiation you created to render it in the list, as with PDF, HTML etc.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Add a Discussion Forum for Each EPrint==&lt;br /&gt;
The UK Open University (open.ac.uk) have set up a service which allows you to create a discussion for every EPrint in your archive.&lt;br /&gt;
&lt;br /&gt;
The really easy way to do this is to use their discussion server. If you want to run your own d3e server the software is available from http://d3e.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
===Using d3eprints.open.ac.uk===&lt;br /&gt;
Just add the following code to the ArchiveRenderConfig.pm file just before the &amp;lt;tt&amp;gt;if( $has_multiple_versions )&amp;lt;/tt&amp;gt; bit.&lt;br /&gt;
&lt;br /&gt;
Please note that this code is not internationalised.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
        #####################################&lt;br /&gt;
        # Begin D3Eprints links&lt;br /&gt;
&lt;br /&gt;
        my $ol = $session-&amp;gt;make_element( &amp;quot;ol&amp;quot; );&lt;br /&gt;
        my $li = $session-&amp;gt;make_element( &amp;quot;li&amp;quot; );&lt;br /&gt;
        $a = $session-&amp;gt;render_link(&lt;br /&gt;
                EPrints::Utils::url_escape(&lt;br /&gt;
                        &amp;quot;http://d3eprints.open.ac.uk/disc.php?url=&amp;quot;.$eprint-&amp;gt;get_url ),&lt;br /&gt;
                &amp;quot;_top&amp;quot; );&lt;br /&gt;
        $a-&amp;gt;appendChild( $session-&amp;gt;make_text(&lt;br /&gt;
                &amp;quot;View public discussion of this document&amp;quot; ) );&lt;br /&gt;
        $li-&amp;gt;appendChild( $a );&lt;br /&gt;
        $ol-&amp;gt;appendChild( $li );&lt;br /&gt;
&lt;br /&gt;
        $li = $session-&amp;gt;make_element( &amp;quot;li&amp;quot; );&lt;br /&gt;
        $a = $session-&amp;gt;render_link(&lt;br /&gt;
                EPrints::Utils::url_escape(&lt;br /&gt;
                        &amp;quot;http://d3eprints.open.ac.uk/private/disc.php?url=&amp;quot;.&lt;br /&gt;
                                $eprint-&amp;gt;get_url ),&lt;br /&gt;
                &amp;quot;_top&amp;quot; );&lt;br /&gt;
        $a-&amp;gt;appendChild( $session-&amp;gt;make_text(&lt;br /&gt;
                &amp;quot;Create private discussion of this document&amp;quot; ) );&lt;br /&gt;
        $li-&amp;gt;appendChild( $a );&lt;br /&gt;
        $ol-&amp;gt;appendChild( $li );&lt;br /&gt;
&lt;br /&gt;
        $table-&amp;gt;appendChild( _render_row(&lt;br /&gt;
                $session,&lt;br /&gt;
                $session-&amp;gt;make_text( &amp;quot;D3Eprints discussion&amp;quot; ),&lt;br /&gt;
                $ol ) );&lt;br /&gt;
&lt;br /&gt;
        # End of D3Eprints links&lt;br /&gt;
        #####################################&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
==HOW TO: Website Integration==&lt;br /&gt;
===Make the latest additions to your archive appear on your main website===&lt;br /&gt;
The contents of the &amp;quot;latest&amp;quot; page - /perl/latest - can be included via a cron tab using wget and a server side include or using something like PHP's command to do:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 readfile( &amp;quot;http://eprints.foo.org/perl/latest?mainonly=yes&amp;quot; );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The &amp;quot;mainonly=yes&amp;quot; flag is a hack which supresses the template of any eprints page in the /perl/ area so that it can be included, but it is most useful for &amp;quot;latest&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
WARNING: If you have a script which imports 1000 records in one night then latest isn't currently bright enough to truncate the list so your homepage could get kinda messy.&lt;br /&gt;
&lt;br /&gt;
===RSS into HTML===&lt;br /&gt;
If you want to turn any search into a dynamically generated list of references with a link back to the EPrints page, then use this.  This solution uses PHP.  So, you will need PHP enabled on the server.&lt;br /&gt;
&lt;br /&gt;
'''Dependency:''' This code depends on [http://magpierss.sourceforge.net/ MagpieRSS].&lt;br /&gt;
&lt;br /&gt;
'''Original Context:''' It was developed for use in a [http://www.terminalfour.com/ Terminal4 'SiteManager'] template, but can be used with almost no modification.&lt;br /&gt;
&lt;br /&gt;
The code implements local caching of the generated HTML in a text file which is never more than an hour old, unless there is a problem with the server whereupon the last good cached version is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 require_once('D:/website/[path to]/magpierss/rss_fetch.inc');&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;//set some variables here:&amp;lt;/span&amp;gt;&lt;br /&gt;
 $anchor = '&amp;lt;t4 type=&amp;quot;meta&amp;quot; meta=&amp;quot;html_anchor&amp;quot; /&amp;gt;';&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;# All items in Terminal4's cms have an anchor - we like break it apart to get the Unique id, to name the cache file.&amp;lt;/span&amp;gt;&lt;br /&gt;
 $TTL = 3600;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;# Time to live - one hour only.&amp;lt;/span&amp;gt;&lt;br /&gt;
 $feed = '&amp;lt;t4 type=&amp;quot;content&amp;quot; name=&amp;quot;RSS_Feed_URL&amp;quot; output=&amp;quot;normal&amp;quot; modifiers=&amp;quot;&amp;quot;  /&amp;gt;';&lt;br /&gt;
 $uniqueID = explode(&amp;quot;\&amp;quot;&amp;quot;, $anchor);&lt;br /&gt;
 $filename = &amp;quot;./&amp;quot; . str_replace('.', '-', $uniqueID[1]) . &amp;quot;.txt&amp;quot;;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;#filename of cache - generated from unique id in T4 content management system.&amp;lt;/span&amp;gt;&lt;br /&gt;
 $max_items = &amp;lt;t4 type=&amp;quot;content&amp;quot; name=&amp;quot;MaxNumberToShow&amp;quot; output=&amp;quot;normal&amp;quot; modifiers=&amp;quot;&amp;quot;  /&amp;gt;;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;# $max_items = 30; // this is set in EPrints as well, will not exceed Eprints' own internal limit.&amp;lt;/span&amp;gt;&lt;br /&gt;
 $with_summaries = '&amp;lt;t4 type=&amp;quot;content&amp;quot; name=&amp;quot;ShowSummary&amp;quot; output=&amp;quot;normal&amp;quot; modifiers=&amp;quot;&amp;quot;  /&amp;gt;'; # could be 'yes' or 'no'&lt;br /&gt;
 $age = 0;&lt;br /&gt;
 if(file_exists($filename)){&lt;br /&gt;
 	$age = time() - filemtime($filename); &lt;br /&gt;
 }else{&lt;br /&gt;
 	$fh = fopen($filename, &amp;quot;w&amp;quot;);&lt;br /&gt;
 	fwrite($fh, $news_feed);&lt;br /&gt;
 	fclose($fh);&lt;br /&gt;
 	$age = $TTL;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function getFromCache($f){	&lt;br /&gt;
 	$fh = fopen($f, &amp;quot;r&amp;quot;);&lt;br /&gt;
 	$size = filesize($f);&lt;br /&gt;
 	$data = fread($fh, $size);&lt;br /&gt;
 	print $data;&lt;br /&gt;
 	fclose($fh);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 if($age &amp;gt;= $TTL){ &lt;br /&gt;
 	if($rss = fetch_rss($feed)){&lt;br /&gt;
 		$items = array_slice($rss-&amp;gt;items, 0);&lt;br /&gt;
 		$find = array(&amp;quot;/^\.?/&amp;quot;);&lt;br /&gt;
 		$replace = array(&amp;quot; &amp;quot;);&lt;br /&gt;
 		$news_feed = &amp;quot;&amp;amp;lt;ul class=\&amp;quot;rss_list\&amp;quot;&amp;gt;\n&amp;quot;;&lt;br /&gt;
 			foreach ($items as $item ){&lt;br /&gt;
 				if($count &amp;amp;lt; $max_items){&lt;br /&gt;
 					$news_feed .= &amp;quot;\t&amp;amp;lt;li class=\&amp;quot;rss_item\&amp;quot;&amp;gt;\n&amp;quot;;&lt;br /&gt;
 					$news_feed .= &amp;quot;\t\t&amp;amp;lt;span class=\&amp;quot;rss_title\&amp;quot;&amp;gt;&amp;amp;lt;a href=\&amp;quot;&amp;quot; . $item['link'] . &amp;quot;\&amp;quot; target=\&amp;quot;_blank\&amp;quot;&amp;gt;&amp;quot;;&lt;br /&gt;
 					$news_feed .= $item['title'] . &amp;quot;&amp;amp;lt;/a&amp;gt;&amp;amp;lt;/span&amp;gt;\n\t\t&amp;amp;lt;br /&amp;gt;\n&amp;quot;;&lt;br /&gt;
 					if($with_summaries == 'yes'){&lt;br /&gt;
 						$news_feed .= &amp;quot;\t\t&amp;amp;lt;span class=\&amp;quot;rss_summary\&amp;quot;&amp;gt;\n\t\t\t&amp;quot;;&lt;br /&gt;
 						$news_feed .= str_replace(($item['title'] . &amp;quot;.&amp;quot;), &amp;quot;&amp;quot;, htmlentities($item['summary'])) . &amp;quot;&amp;amp;lt;br/&amp;gt;\n\t\t&amp;amp;lt;/span&amp;gt;\n&amp;quot;;&lt;br /&gt;
 					}&lt;br /&gt;
 					$news_feed .= &amp;quot;\t\t&amp;amp;lt;br /&amp;gt;\n\t&amp;lt;/li&amp;gt;\n&amp;quot;;&lt;br /&gt;
 					$count += 1;&lt;br /&gt;
 				}&lt;br /&gt;
 			}&lt;br /&gt;
 		$news_feed .= &amp;quot;&amp;amp;lt;/ul&amp;gt;\n\n&amp;quot;;&lt;br /&gt;
 		echo $news_feed;&lt;br /&gt;
 		$fh = fopen($filename, &amp;quot;w&amp;quot;);&lt;br /&gt;
 		fwrite($fh, $news_feed);&lt;br /&gt;
 		fclose($fh);&lt;br /&gt;
 	}else{&lt;br /&gt;
 		getFromCache($filename);&lt;br /&gt;
 	}&lt;br /&gt;
 }else{&lt;br /&gt;
 	getFromCache($filename);&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;# David Kane, Waterford Institute of Technology&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Add full text searching==&lt;br /&gt;
EPrints does not support this natively but there are several options.&lt;br /&gt;
&lt;br /&gt;
===htdig, or similar software===&lt;br /&gt;
There is plenty of software which will provide a full text search of a website. To add non-eprints cgi scripts to your site create a directory in the cgi dir:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 mkdir /opt/eprints2/cgi/local&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and place your scripts in there, they will have URLs under &amp;lt;tt&amp;gt;http://yoursite.com/perl/&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using an external search engine===&lt;br /&gt;
This is very easy, but will only index public documents. Any search engine will work, but Google is a good choice. Google provide a site-search service which allows you to register with them and then have a form which searches your site using google and adds your logo and colourscheme to the results.&lt;br /&gt;
&lt;br /&gt;
A really easy solution is to just make a form which links to our &amp;quot;google_site&amp;quot; script which just adds &amp;quot;site:yoursite.com&amp;quot; to the google request to limit the search results. The HTML for this would be something like:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;form action=&amp;quot;/perl/google_site&amp;quot;&amp;gt;&lt;br /&gt;
 Use Google to search this site:&lt;br /&gt;
 &amp;lt;input name=&amp;quot;q&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;submit&amp;quot; name=&amp;quot;go&amp;quot; value=&amp;quot;Search&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other search engines; see their documentation for how to make a form to search only your site.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Make the referencetext field link to the items referenced==&lt;br /&gt;
This should have been in the 2.2 docs but I didn't have time. Check the latest version of the documentation at software.eprints.org, if it's not there then bug me at support@eprints.org&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Make the password controlled parts of the site use HTTPS==&lt;br /&gt;
This should have been in the 2.2 docs but I didn't have time. Check the latest version of the documentation at software.eprints.org, if it's not there then bug me at support@eprints.org&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Customise the way the the search results are formatted==&lt;br /&gt;
This should have been in the 2.2 docs but I didn't have time. Check the latest version of the documentation at software.eprints.org, if it's not there then bug me at support@eprints.org&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Reset your EPrints admin password [3.3]==&lt;br /&gt;
&lt;br /&gt;
To directly reset your password, log into phpMyAdmin and execute the following mySQL statement:&lt;br /&gt;
&lt;br /&gt;
 UPDATE user SET password = encrypt('newpassword') WHERE userid = 1;&lt;br /&gt;
This will effectively reset the EPrint admin password for user 1. Note that you can use this to reset the password of any user, although this is typically unnecessary as you should be able to simply log in as admin user (user 1), under which you have the ability to reset any user's password.&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=How_to&amp;diff=10151</id>
		<title>How to</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=How_to&amp;diff=10151"/>
		<updated>2011-12-10T11:26:26Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: /* Using an external search engine */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Howto]]&lt;br /&gt;
==HOW TO: Set up a Complex Custom View==&lt;br /&gt;
Simple instructions are in the ArchiveConfig.pm section.&lt;br /&gt;
&lt;br /&gt;
Example situation: On my main website www.foobars.ac.uk I have a page per research project, of which we have hundreds. Each project has a short unique id code, eg. &amp;quot;manticore&amp;quot;. I have a field in my eprints archive (eprints.foobars.ac.uk) which is configured:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { name=&amp;gt;&amp;quot;projectcodes&amp;quot;, type=&amp;gt;&amp;quot;text&amp;quot;, multiple=&amp;gt;1 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
I add the following browse view:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { id=&amp;gt;&amp;quot;by_project&amp;quot;, allow_null=&amp;gt;0, fields=&amp;gt;&amp;quot;projectcodes&amp;quot;, &lt;br /&gt;
 order=&amp;gt;&amp;quot;-year/title&amp;quot; }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This will generate a page http://eprints.foobars.ac.uk/views/by_project/manticore.html with a list of all papers in that project, we can link to that URL!&lt;br /&gt;
&lt;br /&gt;
===Making the Field link to the Browse Page===&lt;br /&gt;
If you want a subject to link the subject browse page of that value, add the '''browse_link''' property to the field (and regenerate the abstracts if you want).&lt;br /&gt;
&lt;br /&gt;
If you remove the browse view you should remove the browse_link or it will be a broken link.&lt;br /&gt;
&lt;br /&gt;
Values rendered inside citations which are used to link to the main record will not link into the browse view for obvious reasons.&lt;br /&gt;
&lt;br /&gt;
===Including a view in another page===&lt;br /&gt;
If you change that to:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { id=&amp;gt;&amp;quot;by_project&amp;quot;, allow_null=&amp;gt;0, fields=&amp;gt;&amp;quot;projectcodes&amp;quot;, &lt;br /&gt;
 order=&amp;gt;&amp;quot;-year/title&amp;quot;, noindex=&amp;gt;1, nolink=&amp;gt;1, nohtml=&amp;gt;1, include=&amp;gt;1 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This will generate a view which is NOT listed on the /view/ page and it will not skip making the .html file and make a .include file per value. This will only contain the &amp;quot;count&amp;quot; of items and the XHTML of their citations. This can be used as part of a page on the http://www.foobaars.ac.uk/ site; either by using php and capturing it on-the-fly using &amp;lt;tt&amp;gt;readfile&amp;lt;/tt&amp;gt; or scripting it with perl or NFS exporting the filesystem onto the main server (or just doing it all on one computer) and using server side includes to place it in a page.&lt;br /&gt;
&lt;br /&gt;
===Customising the way each item is cited===&lt;br /&gt;
I want to list the project papers in a strict format in a table with 4 columns: title, author(s), year and an icon which links to the document abstract page...&lt;br /&gt;
&lt;br /&gt;
I add some ''more'' options to the browse view:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { id=&amp;gt;&amp;quot;by_project&amp;quot;, allow_null=&amp;gt;0, fields=&amp;gt;&amp;quot;projectcodes&amp;quot;, &lt;br /&gt;
 order=&amp;gt;&amp;quot;-year/title&amp;quot;, noindex=&amp;gt;1, nolink=&amp;gt;1, nohtml=&amp;gt;1, include=&amp;gt;1,&lt;br /&gt;
 nocount=&amp;gt;1, citation=&amp;gt;&amp;quot;project_table&amp;quot; }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now I add a new citation to the citations config file:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;ep:citation type=&amp;quot;project_table&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;amp;title;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;amp;authors;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&amp;amp;year;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;ep:linkhere&amp;gt;&amp;lt;img &lt;br /&gt;
 src=&amp;quot;http://www.foobars.ac.uk/images/paperlink.png&amp;quot; alt=&amp;quot;view&amp;quot; width=&amp;quot;32&amp;quot; &lt;br /&gt;
 height=&amp;quot;64&amp;quot; border=&amp;quot;0&amp;quot; /&amp;gt;&amp;lt;/ep:linkhere&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/ep:citation&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
That should generate for the manticore project, in the &amp;quot;.include&amp;quot; file (I've cut the contents of the &amp;quot;img&amp;quot; tag for readability:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Making Stuff&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Guy, A.&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;a &lt;br /&gt;
 href=&amp;quot;http://eprints.foobar.ac.uk/archive/00000923/&amp;quot;&amp;gt;&amp;lt;img ... /&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
 &amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Eating Food&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Herring, Walter and Chips, Bob&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;br /&gt;
 2000&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;a href=&amp;quot;http://eprints.foobar.ac.uk/archive/00000445/&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;img ... /&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===A &amp;quot;CV&amp;quot; page - a list of all of Alices records===&lt;br /&gt;
This is where the authors and editors field having an ID comes in handy.&lt;br /&gt;
&lt;br /&gt;
Say we use local username to identify people in the &amp;quot;Person ID&amp;quot; fields, we can now set up a view:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { id=&amp;gt;&amp;quot;by_person&amp;quot;, allow_null=&amp;gt;0, fields=&amp;gt;&amp;quot;authors.id/editors.id&amp;quot;, &lt;br /&gt;
 order=&amp;gt;&amp;quot;-year/title&amp;quot;, noindex=&amp;gt;1, include=&amp;gt;1 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This will generate both .html pages and .include pages. An member of your organisation can get a list of their records either by linking to &amp;lt;tt&amp;gt;/views/by_person/alice.html&amp;lt;/tt&amp;gt; (where alice is their username) or by snarfing the URL &amp;lt;tt&amp;gt;/views/by_person/alice.include&amp;lt;/tt&amp;gt; into his own homepage.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Fields==&lt;br /&gt;
===Add a new Field&lt;br /&gt;
This convers adding a new field to a new system, not a live system. It is possible to add a new field to a live system but invloves SQL hacking.&lt;br /&gt;
&lt;br /&gt;
In this example we add a new &amp;quot;set&amp;quot; field called &amp;quot;local&amp;quot; which will have 3 options &amp;quot;yes&amp;quot;,&amp;quot;no&amp;quot; and &amp;quot;partial&amp;quot; - this will indicate if the item in question was produced in our organisation or not.&lt;br /&gt;
&lt;br /&gt;
; Add the Field to ArchiveMetafieldConfig.pm : Add the field to the appropriate part of ArchiveMetafieldConfig.pm (the &amp;quot;eprint&amp;quot; section in our example)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { name =&amp;gt; &amp;quot;local&amp;quot;, type =&amp;gt; &amp;quot;set&amp;quot;, input_rows =&amp;gt; 1, &lt;br /&gt;
    options =&amp;gt; [ &amp;quot;yes&amp;quot;, &amp;quot;no&amp;quot;, &amp;quot;partial&amp;quot; ] }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
input_rows being set to one will make it appear as a pull-down menu.&lt;br /&gt;
; Add the Field to metadata-types.xml : If you want the user to be able to edit this field for any or all types of eprint/user then you need to add it to each appropriate type in metadata-types.xml (this can be changed on a live system without any serious consequencies).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;field name=&amp;quot;local&amp;quot; required=&amp;quot;yes&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; Add the Field Information to the Archive Phrase File(s) : Normally we just need to add fieldname and fieldhelp, but this is an option field so we need to add names for each option. If we run the archive in more than one language then we add this to each phrase file (but in the appropriate language).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldname_local&amp;quot;&amp;gt;Produced Locally&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldhelp_local&amp;quot;&amp;gt;Please indicate if this item was &lt;br /&gt;
produces in the foo organisation, or not.&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldopt_local_yes&amp;quot;&amp;gt;produced locally&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldopt_local_no&amp;quot;&amp;gt;not produced locally&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldopt_local_partial&amp;quot;&amp;gt;only partially produced &lt;br /&gt;
locally&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Other things you may wish to change after adding a new field====&lt;br /&gt;
; Add it to the citations file : This is optional, only do this if you want it to appear in the citated forms.&lt;br /&gt;
In our example case we only want this to appear when citing technical reports, so we change that entry to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;ep:citation type=&amp;quot;eprint_techreport&amp;quot;&amp;gt;&amp;lt;ep:linkhere&amp;gt;&amp;lt;span &lt;br /&gt;
 class=&amp;quot;citation&amp;quot;&amp;gt;&amp;amp;authors; &amp;lt;ep:ifset name=&amp;quot;year&amp;quot;&amp;gt;(&amp;amp;year;) &lt;br /&gt;
 &amp;lt;/ep:ifset&amp;gt;&amp;amp;title;. Technical Report&amp;lt;ep:ifset name=&amp;quot;reportno&amp;quot;&amp;gt; &lt;br /&gt;
 &amp;amp;reportno;&amp;lt;/ep:ifset&amp;gt;&amp;lt;ep:ifset name=&amp;quot;department&amp;quot;&amp;gt;, &amp;amp;department;&lt;br /&gt;
 &amp;lt;/ep:ifset&amp;gt;&amp;lt;ep:ifset name=&amp;quot;institution&amp;quot;&amp;gt;, &amp;amp;institution;&amp;lt;/ep:ifset&amp;gt;. &lt;br /&gt;
 &amp;amp;local;.&amp;lt;/span&amp;gt;&amp;lt;/ep:linkhere&amp;gt;&amp;lt;/ep:citation&amp;gt; &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
All we've done is add &amp;lt;tt&amp;gt;&amp;amp;local;.&amp;lt;/tt&amp;gt; to the end. It's not inside &amp;lt;tt&amp;gt; &amp;lt;ep:ifset name=&amp;quot;local&amp;quot;&amp;gt; &amp;lt;/tt&amp;gt; as it is a required field and will (should) always be set.&lt;br /&gt;
; Add it to the the Abstract (or View-User) page. : This is also optional. If you want it to appear on the web page for this item then edit ArchiveRenderConfig.pm and select the appropriate function, either eprint_render or user_render.&lt;br /&gt;
In our example we only want to mention items if an item was not produced locally. We'll add it below the documents and above the abstract...&lt;br /&gt;
Single language example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 if( $eprint-&amp;gt;get_value( &amp;quot;local&amp;quot; ) ne &amp;quot;yes&amp;quot; )&lt;br /&gt;
 {&lt;br /&gt;
      # don't need to &amp;quot;my $p&amp;quot; as it's done earlier.&lt;br /&gt;
      $p = $session-&amp;gt;make_element( &amp;quot;p&amp;quot; );&lt;br /&gt;
      $p-&amp;gt;appendChild( $session-&amp;gt;make_text( &amp;quot;This item was &amp;quot; ) );&lt;br /&gt;
      $p-&amp;gt;appendChild( $eprint-&amp;gt;render_value( &amp;quot;local&amp;quot; ) );&lt;br /&gt;
      $p-&amp;gt;appendChild( $session-&amp;gt;make_text( &amp;quot;.&amp;quot; ) );&lt;br /&gt;
&lt;br /&gt;
      # Append our new paragraph to the page.&lt;br /&gt;
      $page-&amp;gt;appendChild( $p );&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Multiple-language example:&lt;br /&gt;
If you want to make it handle more than language then we'll need to use the archive phrase file - we would add something like this to each languages file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;page:itemnotlocal&amp;quot;&amp;gt;&amp;lt;p&amp;gt;This item was &amp;lt;pin ref=&amp;quot;status&amp;quot; /&amp;gt;.&amp;lt;/p&amp;gt;&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
And to the ArchiveRenderConfig.pm file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 if( $eprint-&amp;gt;get_value( &amp;quot;local&amp;quot; ) ne &amp;quot;yes&amp;quot; )&lt;br /&gt;
 {&lt;br /&gt;
      my $localmsg = $session-&amp;gt;html_phrase(&lt;br /&gt;
             &amp;quot;page:itemnotlocal&amp;quot;,&lt;br /&gt;
             status=&amp;gt;$eprint-&amp;gt;render_value( &amp;quot;local&amp;quot; ) );&lt;br /&gt;
      $page-&amp;gt;appendChild( $localmsg );&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
You may prefer to use this method even if you are only using a single language.&lt;br /&gt;
; Add extra Validation Routines : If you need to validate this field in a special way, add code into ArchiveValidateConfig.pm&lt;br /&gt;
; Add it to the OAI metadata (eprints only) : If this field can be rendered into Dublin Core (or other metadata formats you are using) then add it to the appropriate place in the ArchiveOAIConfig.pm file.&lt;br /&gt;
; Add a browse view (eprints only) : If you want to be able to browse this values items. See elsewhere in the docs for how to do this.&lt;br /&gt;
&lt;br /&gt;
If you add a field you will need to run erase_archive and create_tables before you will see a change. EPrints will fail to run if you change the fields and do rebuild the tables.&lt;br /&gt;
&lt;br /&gt;
===HOW TO: Remove a Field===&lt;br /&gt;
The quick answer is to say &amp;quot;the opposite of adding one&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
; Remove the Field to metadata-types.xml : Removing it from here will mean that nobody can enter values for that field. Which is possibly enough, and means you can put it back later.&lt;br /&gt;
; Remove the Field to ArchiveMetafieldConfig.pm : This will remove it from the database ( and require a rebuild as with adding a field ).&lt;br /&gt;
; Remove it from the phrase file(s) : This is optional, unused phrases are just ignored.&lt;br /&gt;
; Remove it from the citations file : If it's used there.&lt;br /&gt;
; Remove it from the the Abstract (or View-User) page. : If it's used there.&lt;br /&gt;
; Remove extra Validation Routines : In the unlikely event you added some validation which looks at this field.&lt;br /&gt;
; Remove it from the OAI metadata (eprints only) : If it's being used. Fields used to generate the default dublincore are: title, authors, subjects, abstract, year and month. It also uses &amp;quot;type&amp;quot; which is a system field so you can't remove it!&lt;br /&gt;
; Remove it from browse views (eprints only) : If it's used there.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: EPrint types==&lt;br /&gt;
===Add a new eprint type===&lt;br /&gt;
Add the eprint type to '''metadata-types.xml'''. Some fields should probably be &amp;quot;required&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Add the name of the type to the phrase file.&lt;br /&gt;
&lt;br /&gt;
Add a citation for this type to the citations file.&lt;br /&gt;
&lt;br /&gt;
===Remove an eprint type===&lt;br /&gt;
Remove it from metadata-types.xml&lt;br /&gt;
&lt;br /&gt;
You can remove it from the phrase file &amp;amp; citations but it won't hurt to leave it there.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Add a new document type==&lt;br /&gt;
Add it to '''metadata-types.xml'''. This does not need any fields.&lt;br /&gt;
&lt;br /&gt;
Add the name of the document type to the phrase file.&lt;br /&gt;
&lt;br /&gt;
Add a citation for this document to the citations file.&lt;br /&gt;
&lt;br /&gt;
If you want this to be one of the must-have-one-of document types then add it's id to the list in ArchiveConfig.pm&lt;br /&gt;
&lt;br /&gt;
If you want to do something &amp;quot;clever&amp;quot; on the abstract page then edit the ArchiveRenderConfig.pm file. If you don't then it will use the citiation you created to render it in the list, as with PDF, HTML etc.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Add a Discussion Forum for Each EPrint==&lt;br /&gt;
The UK Open University (open.ac.uk) have set up a service which allows you to create a discussion for every EPrint in your archive.&lt;br /&gt;
&lt;br /&gt;
The really easy way to do this is to use their discussion server. If you want to run your own d3e server the software is available from http://d3e.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
===Using d3eprints.open.ac.uk===&lt;br /&gt;
Just add the following code to the ArchiveRenderConfig.pm file just before the &amp;lt;tt&amp;gt;if( $has_multiple_versions )&amp;lt;/tt&amp;gt; bit.&lt;br /&gt;
&lt;br /&gt;
Please note that this code is not internationalised.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
        #####################################&lt;br /&gt;
        # Begin D3Eprints links&lt;br /&gt;
&lt;br /&gt;
        my $ol = $session-&amp;gt;make_element( &amp;quot;ol&amp;quot; );&lt;br /&gt;
        my $li = $session-&amp;gt;make_element( &amp;quot;li&amp;quot; );&lt;br /&gt;
        $a = $session-&amp;gt;render_link(&lt;br /&gt;
                EPrints::Utils::url_escape(&lt;br /&gt;
                        &amp;quot;http://d3eprints.open.ac.uk/disc.php?url=&amp;quot;.$eprint-&amp;gt;get_url ),&lt;br /&gt;
                &amp;quot;_top&amp;quot; );&lt;br /&gt;
        $a-&amp;gt;appendChild( $session-&amp;gt;make_text(&lt;br /&gt;
                &amp;quot;View public discussion of this document&amp;quot; ) );&lt;br /&gt;
        $li-&amp;gt;appendChild( $a );&lt;br /&gt;
        $ol-&amp;gt;appendChild( $li );&lt;br /&gt;
&lt;br /&gt;
        $li = $session-&amp;gt;make_element( &amp;quot;li&amp;quot; );&lt;br /&gt;
        $a = $session-&amp;gt;render_link(&lt;br /&gt;
                EPrints::Utils::url_escape(&lt;br /&gt;
                        &amp;quot;http://d3eprints.open.ac.uk/private/disc.php?url=&amp;quot;.&lt;br /&gt;
                                $eprint-&amp;gt;get_url ),&lt;br /&gt;
                &amp;quot;_top&amp;quot; );&lt;br /&gt;
        $a-&amp;gt;appendChild( $session-&amp;gt;make_text(&lt;br /&gt;
                &amp;quot;Create private discussion of this document&amp;quot; ) );&lt;br /&gt;
        $li-&amp;gt;appendChild( $a );&lt;br /&gt;
        $ol-&amp;gt;appendChild( $li );&lt;br /&gt;
&lt;br /&gt;
        $table-&amp;gt;appendChild( _render_row(&lt;br /&gt;
                $session,&lt;br /&gt;
                $session-&amp;gt;make_text( &amp;quot;D3Eprints discussion&amp;quot; ),&lt;br /&gt;
                $ol ) );&lt;br /&gt;
&lt;br /&gt;
        # End of D3Eprints links&lt;br /&gt;
        #####################################&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
==HOW TO: Website Integration==&lt;br /&gt;
===Make the latest additions to your archive appear on your main website===&lt;br /&gt;
The contents of the &amp;quot;latest&amp;quot; page - /perl/latest - can be included via a cron tab using wget and a server side include or using something like PHP's command to do:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 readfile( &amp;quot;http://eprints.foo.org/perl/latest?mainonly=yes&amp;quot; );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The &amp;quot;mainonly=yes&amp;quot; flag is a hack which supresses the template of any eprints page in the /perl/ area so that it can be included, but it is most useful for &amp;quot;latest&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
WARNING: If you have a script which imports 1000 records in one night then latest isn't currently bright enough to truncate the list so your homepage could get kinda messy.&lt;br /&gt;
&lt;br /&gt;
===RSS into HTML===&lt;br /&gt;
If you want to turn any search into a dynamically generated list of references with a link back to the EPrints page, then use this.  This solution uses PHP.  So, you will need PHP enabled on the server.&lt;br /&gt;
&lt;br /&gt;
'''Dependency:''' This code depends on [http://magpierss.sourceforge.net/ MagpieRSS].&lt;br /&gt;
&lt;br /&gt;
'''Original Context:''' It was developed for use in a [http://www.terminalfour.com/ Terminal4 'SiteManager'] template, but can be used with almost no modification.&lt;br /&gt;
&lt;br /&gt;
The code implements local caching of the generated HTML in a text file which is never more than an hour old, unless there is a problem with the server whereupon the last good cached version is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 require_once('D:/website/[path to]/magpierss/rss_fetch.inc');&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;//set some variables here:&amp;lt;/span&amp;gt;&lt;br /&gt;
 $anchor = '&amp;lt;t4 type=&amp;quot;meta&amp;quot; meta=&amp;quot;html_anchor&amp;quot; /&amp;gt;';&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;# All items in Terminal4's cms have an anchor - we like break it apart to get the Unique id, to name the cache file.&amp;lt;/span&amp;gt;&lt;br /&gt;
 $TTL = 3600;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;# Time to live - one hour only.&amp;lt;/span&amp;gt;&lt;br /&gt;
 $feed = '&amp;lt;t4 type=&amp;quot;content&amp;quot; name=&amp;quot;RSS_Feed_URL&amp;quot; output=&amp;quot;normal&amp;quot; modifiers=&amp;quot;&amp;quot;  /&amp;gt;';&lt;br /&gt;
 $uniqueID = explode(&amp;quot;\&amp;quot;&amp;quot;, $anchor);&lt;br /&gt;
 $filename = &amp;quot;./&amp;quot; . str_replace('.', '-', $uniqueID[1]) . &amp;quot;.txt&amp;quot;;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;#filename of cache - generated from unique id in T4 content management system.&amp;lt;/span&amp;gt;&lt;br /&gt;
 $max_items = &amp;lt;t4 type=&amp;quot;content&amp;quot; name=&amp;quot;MaxNumberToShow&amp;quot; output=&amp;quot;normal&amp;quot; modifiers=&amp;quot;&amp;quot;  /&amp;gt;;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;# $max_items = 30; // this is set in EPrints as well, will not exceed Eprints' own internal limit.&amp;lt;/span&amp;gt;&lt;br /&gt;
 $with_summaries = '&amp;lt;t4 type=&amp;quot;content&amp;quot; name=&amp;quot;ShowSummary&amp;quot; output=&amp;quot;normal&amp;quot; modifiers=&amp;quot;&amp;quot;  /&amp;gt;'; # could be 'yes' or 'no'&lt;br /&gt;
 $age = 0;&lt;br /&gt;
 if(file_exists($filename)){&lt;br /&gt;
 	$age = time() - filemtime($filename); &lt;br /&gt;
 }else{&lt;br /&gt;
 	$fh = fopen($filename, &amp;quot;w&amp;quot;);&lt;br /&gt;
 	fwrite($fh, $news_feed);&lt;br /&gt;
 	fclose($fh);&lt;br /&gt;
 	$age = $TTL;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function getFromCache($f){	&lt;br /&gt;
 	$fh = fopen($f, &amp;quot;r&amp;quot;);&lt;br /&gt;
 	$size = filesize($f);&lt;br /&gt;
 	$data = fread($fh, $size);&lt;br /&gt;
 	print $data;&lt;br /&gt;
 	fclose($fh);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 if($age &amp;gt;= $TTL){ &lt;br /&gt;
 	if($rss = fetch_rss($feed)){&lt;br /&gt;
 		$items = array_slice($rss-&amp;gt;items, 0);&lt;br /&gt;
 		$find = array(&amp;quot;/^\.?/&amp;quot;);&lt;br /&gt;
 		$replace = array(&amp;quot; &amp;quot;);&lt;br /&gt;
 		$news_feed = &amp;quot;&amp;amp;lt;ul class=\&amp;quot;rss_list\&amp;quot;&amp;gt;\n&amp;quot;;&lt;br /&gt;
 			foreach ($items as $item ){&lt;br /&gt;
 				if($count &amp;amp;lt; $max_items){&lt;br /&gt;
 					$news_feed .= &amp;quot;\t&amp;amp;lt;li class=\&amp;quot;rss_item\&amp;quot;&amp;gt;\n&amp;quot;;&lt;br /&gt;
 					$news_feed .= &amp;quot;\t\t&amp;amp;lt;span class=\&amp;quot;rss_title\&amp;quot;&amp;gt;&amp;amp;lt;a href=\&amp;quot;&amp;quot; . $item['link'] . &amp;quot;\&amp;quot; target=\&amp;quot;_blank\&amp;quot;&amp;gt;&amp;quot;;&lt;br /&gt;
 					$news_feed .= $item['title'] . &amp;quot;&amp;amp;lt;/a&amp;gt;&amp;amp;lt;/span&amp;gt;\n\t\t&amp;amp;lt;br /&amp;gt;\n&amp;quot;;&lt;br /&gt;
 					if($with_summaries == 'yes'){&lt;br /&gt;
 						$news_feed .= &amp;quot;\t\t&amp;amp;lt;span class=\&amp;quot;rss_summary\&amp;quot;&amp;gt;\n\t\t\t&amp;quot;;&lt;br /&gt;
 						$news_feed .= str_replace(($item['title'] . &amp;quot;.&amp;quot;), &amp;quot;&amp;quot;, htmlentities($item['summary'])) . &amp;quot;&amp;amp;lt;br/&amp;gt;\n\t\t&amp;amp;lt;/span&amp;gt;\n&amp;quot;;&lt;br /&gt;
 					}&lt;br /&gt;
 					$news_feed .= &amp;quot;\t\t&amp;amp;lt;br /&amp;gt;\n\t&amp;lt;/li&amp;gt;\n&amp;quot;;&lt;br /&gt;
 					$count += 1;&lt;br /&gt;
 				}&lt;br /&gt;
 			}&lt;br /&gt;
 		$news_feed .= &amp;quot;&amp;amp;lt;/ul&amp;gt;\n\n&amp;quot;;&lt;br /&gt;
 		echo $news_feed;&lt;br /&gt;
 		$fh = fopen($filename, &amp;quot;w&amp;quot;);&lt;br /&gt;
 		fwrite($fh, $news_feed);&lt;br /&gt;
 		fclose($fh);&lt;br /&gt;
 	}else{&lt;br /&gt;
 		getFromCache($filename);&lt;br /&gt;
 	}&lt;br /&gt;
 }else{&lt;br /&gt;
 	getFromCache($filename);&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;# David Kane, Waterford Institute of Technology&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Add full text searching==&lt;br /&gt;
EPrints does not support this natively but there are several options.&lt;br /&gt;
&lt;br /&gt;
===htdig, or similar software===&lt;br /&gt;
There is plenty of software which will provide a full text search of a website. To add non-eprints cgi scripts to your site create a directory in the cgi dir:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 mkdir /opt/eprints2/cgi/local&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and place your scripts in there, they will have URLs under &amp;lt;tt&amp;gt;http://yoursite.com/perl/&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using an external search engine===&lt;br /&gt;
This is very easy, but will only index public documents. Any search engine will work, but Google is a good choice. Google provide a site-search service which allows you to register with them and then have a form which searches your site using google and adds your logo and colourscheme to the results.&lt;br /&gt;
&lt;br /&gt;
A really easy solution is to just make a form which links to our &amp;quot;google_site&amp;quot; script which just adds &amp;quot;site:yoursite.com&amp;quot; to the google request to limit the search results. The HTML for this would be something like:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;form action=&amp;quot;/perl/google_site&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;Use Google to search this site:&lt;br /&gt;
 &amp;lt;input name=&amp;quot;q&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;submit&amp;quot; name=&amp;quot;go&amp;quot; value=&amp;quot;Search&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/form&amp;gt;&lt;br /&gt;
 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other search engines; see their documentation for how to make a form to search only your site.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Make the referencetext field link to the items referenced==&lt;br /&gt;
This should have been in the 2.2 docs but I didn't have time. Check the latest version of the documentation at software.eprints.org, if it's not there then bug me at support@eprints.org&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Make the password controlled parts of the site use HTTPS==&lt;br /&gt;
This should have been in the 2.2 docs but I didn't have time. Check the latest version of the documentation at software.eprints.org, if it's not there then bug me at support@eprints.org&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Customise the way the the search results are formatted==&lt;br /&gt;
This should have been in the 2.2 docs but I didn't have time. Check the latest version of the documentation at software.eprints.org, if it's not there then bug me at support@eprints.org&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Reset your EPrints admin password [3.3]==&lt;br /&gt;
&lt;br /&gt;
To directly reset your password, log into phpMyAdmin and execute the following mySQL statement:&lt;br /&gt;
&lt;br /&gt;
 UPDATE user SET password = encrypt('newpassword') WHERE userid = 1;&lt;br /&gt;
This will effectively reset the EPrint admin password for user 1. Note that you can use this to reset the password of any user, although this is typically unnecessary as you should be able to simply log in as admin user (user 1), under which you have the ability to reset any user's password.&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=How_to&amp;diff=10150</id>
		<title>How to</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=How_to&amp;diff=10150"/>
		<updated>2011-12-10T11:25:52Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: /* Using an external search engine */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Howto]]&lt;br /&gt;
==HOW TO: Set up a Complex Custom View==&lt;br /&gt;
Simple instructions are in the ArchiveConfig.pm section.&lt;br /&gt;
&lt;br /&gt;
Example situation: On my main website www.foobars.ac.uk I have a page per research project, of which we have hundreds. Each project has a short unique id code, eg. &amp;quot;manticore&amp;quot;. I have a field in my eprints archive (eprints.foobars.ac.uk) which is configured:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { name=&amp;gt;&amp;quot;projectcodes&amp;quot;, type=&amp;gt;&amp;quot;text&amp;quot;, multiple=&amp;gt;1 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
I add the following browse view:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { id=&amp;gt;&amp;quot;by_project&amp;quot;, allow_null=&amp;gt;0, fields=&amp;gt;&amp;quot;projectcodes&amp;quot;, &lt;br /&gt;
 order=&amp;gt;&amp;quot;-year/title&amp;quot; }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This will generate a page http://eprints.foobars.ac.uk/views/by_project/manticore.html with a list of all papers in that project, we can link to that URL!&lt;br /&gt;
&lt;br /&gt;
===Making the Field link to the Browse Page===&lt;br /&gt;
If you want a subject to link the subject browse page of that value, add the '''browse_link''' property to the field (and regenerate the abstracts if you want).&lt;br /&gt;
&lt;br /&gt;
If you remove the browse view you should remove the browse_link or it will be a broken link.&lt;br /&gt;
&lt;br /&gt;
Values rendered inside citations which are used to link to the main record will not link into the browse view for obvious reasons.&lt;br /&gt;
&lt;br /&gt;
===Including a view in another page===&lt;br /&gt;
If you change that to:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { id=&amp;gt;&amp;quot;by_project&amp;quot;, allow_null=&amp;gt;0, fields=&amp;gt;&amp;quot;projectcodes&amp;quot;, &lt;br /&gt;
 order=&amp;gt;&amp;quot;-year/title&amp;quot;, noindex=&amp;gt;1, nolink=&amp;gt;1, nohtml=&amp;gt;1, include=&amp;gt;1 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This will generate a view which is NOT listed on the /view/ page and it will not skip making the .html file and make a .include file per value. This will only contain the &amp;quot;count&amp;quot; of items and the XHTML of their citations. This can be used as part of a page on the http://www.foobaars.ac.uk/ site; either by using php and capturing it on-the-fly using &amp;lt;tt&amp;gt;readfile&amp;lt;/tt&amp;gt; or scripting it with perl or NFS exporting the filesystem onto the main server (or just doing it all on one computer) and using server side includes to place it in a page.&lt;br /&gt;
&lt;br /&gt;
===Customising the way each item is cited===&lt;br /&gt;
I want to list the project papers in a strict format in a table with 4 columns: title, author(s), year and an icon which links to the document abstract page...&lt;br /&gt;
&lt;br /&gt;
I add some ''more'' options to the browse view:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { id=&amp;gt;&amp;quot;by_project&amp;quot;, allow_null=&amp;gt;0, fields=&amp;gt;&amp;quot;projectcodes&amp;quot;, &lt;br /&gt;
 order=&amp;gt;&amp;quot;-year/title&amp;quot;, noindex=&amp;gt;1, nolink=&amp;gt;1, nohtml=&amp;gt;1, include=&amp;gt;1,&lt;br /&gt;
 nocount=&amp;gt;1, citation=&amp;gt;&amp;quot;project_table&amp;quot; }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now I add a new citation to the citations config file:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;ep:citation type=&amp;quot;project_table&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;amp;title;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;amp;authors;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&amp;amp;year;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;ep:linkhere&amp;gt;&amp;lt;img &lt;br /&gt;
 src=&amp;quot;http://www.foobars.ac.uk/images/paperlink.png&amp;quot; alt=&amp;quot;view&amp;quot; width=&amp;quot;32&amp;quot; &lt;br /&gt;
 height=&amp;quot;64&amp;quot; border=&amp;quot;0&amp;quot; /&amp;gt;&amp;lt;/ep:linkhere&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/ep:citation&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
That should generate for the manticore project, in the &amp;quot;.include&amp;quot; file (I've cut the contents of the &amp;quot;img&amp;quot; tag for readability:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Making Stuff&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Guy, A.&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;a &lt;br /&gt;
 href=&amp;quot;http://eprints.foobar.ac.uk/archive/00000923/&amp;quot;&amp;gt;&amp;lt;img ... /&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
 &amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Eating Food&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Herring, Walter and Chips, Bob&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;br /&gt;
 2000&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;a href=&amp;quot;http://eprints.foobar.ac.uk/archive/00000445/&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;img ... /&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===A &amp;quot;CV&amp;quot; page - a list of all of Alices records===&lt;br /&gt;
This is where the authors and editors field having an ID comes in handy.&lt;br /&gt;
&lt;br /&gt;
Say we use local username to identify people in the &amp;quot;Person ID&amp;quot; fields, we can now set up a view:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { id=&amp;gt;&amp;quot;by_person&amp;quot;, allow_null=&amp;gt;0, fields=&amp;gt;&amp;quot;authors.id/editors.id&amp;quot;, &lt;br /&gt;
 order=&amp;gt;&amp;quot;-year/title&amp;quot;, noindex=&amp;gt;1, include=&amp;gt;1 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This will generate both .html pages and .include pages. An member of your organisation can get a list of their records either by linking to &amp;lt;tt&amp;gt;/views/by_person/alice.html&amp;lt;/tt&amp;gt; (where alice is their username) or by snarfing the URL &amp;lt;tt&amp;gt;/views/by_person/alice.include&amp;lt;/tt&amp;gt; into his own homepage.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Fields==&lt;br /&gt;
===Add a new Field&lt;br /&gt;
This convers adding a new field to a new system, not a live system. It is possible to add a new field to a live system but invloves SQL hacking.&lt;br /&gt;
&lt;br /&gt;
In this example we add a new &amp;quot;set&amp;quot; field called &amp;quot;local&amp;quot; which will have 3 options &amp;quot;yes&amp;quot;,&amp;quot;no&amp;quot; and &amp;quot;partial&amp;quot; - this will indicate if the item in question was produced in our organisation or not.&lt;br /&gt;
&lt;br /&gt;
; Add the Field to ArchiveMetafieldConfig.pm : Add the field to the appropriate part of ArchiveMetafieldConfig.pm (the &amp;quot;eprint&amp;quot; section in our example)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { name =&amp;gt; &amp;quot;local&amp;quot;, type =&amp;gt; &amp;quot;set&amp;quot;, input_rows =&amp;gt; 1, &lt;br /&gt;
    options =&amp;gt; [ &amp;quot;yes&amp;quot;, &amp;quot;no&amp;quot;, &amp;quot;partial&amp;quot; ] }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
input_rows being set to one will make it appear as a pull-down menu.&lt;br /&gt;
; Add the Field to metadata-types.xml : If you want the user to be able to edit this field for any or all types of eprint/user then you need to add it to each appropriate type in metadata-types.xml (this can be changed on a live system without any serious consequencies).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;field name=&amp;quot;local&amp;quot; required=&amp;quot;yes&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; Add the Field Information to the Archive Phrase File(s) : Normally we just need to add fieldname and fieldhelp, but this is an option field so we need to add names for each option. If we run the archive in more than one language then we add this to each phrase file (but in the appropriate language).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldname_local&amp;quot;&amp;gt;Produced Locally&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldhelp_local&amp;quot;&amp;gt;Please indicate if this item was &lt;br /&gt;
produces in the foo organisation, or not.&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldopt_local_yes&amp;quot;&amp;gt;produced locally&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldopt_local_no&amp;quot;&amp;gt;not produced locally&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldopt_local_partial&amp;quot;&amp;gt;only partially produced &lt;br /&gt;
locally&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Other things you may wish to change after adding a new field====&lt;br /&gt;
; Add it to the citations file : This is optional, only do this if you want it to appear in the citated forms.&lt;br /&gt;
In our example case we only want this to appear when citing technical reports, so we change that entry to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;ep:citation type=&amp;quot;eprint_techreport&amp;quot;&amp;gt;&amp;lt;ep:linkhere&amp;gt;&amp;lt;span &lt;br /&gt;
 class=&amp;quot;citation&amp;quot;&amp;gt;&amp;amp;authors; &amp;lt;ep:ifset name=&amp;quot;year&amp;quot;&amp;gt;(&amp;amp;year;) &lt;br /&gt;
 &amp;lt;/ep:ifset&amp;gt;&amp;amp;title;. Technical Report&amp;lt;ep:ifset name=&amp;quot;reportno&amp;quot;&amp;gt; &lt;br /&gt;
 &amp;amp;reportno;&amp;lt;/ep:ifset&amp;gt;&amp;lt;ep:ifset name=&amp;quot;department&amp;quot;&amp;gt;, &amp;amp;department;&lt;br /&gt;
 &amp;lt;/ep:ifset&amp;gt;&amp;lt;ep:ifset name=&amp;quot;institution&amp;quot;&amp;gt;, &amp;amp;institution;&amp;lt;/ep:ifset&amp;gt;. &lt;br /&gt;
 &amp;amp;local;.&amp;lt;/span&amp;gt;&amp;lt;/ep:linkhere&amp;gt;&amp;lt;/ep:citation&amp;gt; &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
All we've done is add &amp;lt;tt&amp;gt;&amp;amp;local;.&amp;lt;/tt&amp;gt; to the end. It's not inside &amp;lt;tt&amp;gt; &amp;lt;ep:ifset name=&amp;quot;local&amp;quot;&amp;gt; &amp;lt;/tt&amp;gt; as it is a required field and will (should) always be set.&lt;br /&gt;
; Add it to the the Abstract (or View-User) page. : This is also optional. If you want it to appear on the web page for this item then edit ArchiveRenderConfig.pm and select the appropriate function, either eprint_render or user_render.&lt;br /&gt;
In our example we only want to mention items if an item was not produced locally. We'll add it below the documents and above the abstract...&lt;br /&gt;
Single language example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 if( $eprint-&amp;gt;get_value( &amp;quot;local&amp;quot; ) ne &amp;quot;yes&amp;quot; )&lt;br /&gt;
 {&lt;br /&gt;
      # don't need to &amp;quot;my $p&amp;quot; as it's done earlier.&lt;br /&gt;
      $p = $session-&amp;gt;make_element( &amp;quot;p&amp;quot; );&lt;br /&gt;
      $p-&amp;gt;appendChild( $session-&amp;gt;make_text( &amp;quot;This item was &amp;quot; ) );&lt;br /&gt;
      $p-&amp;gt;appendChild( $eprint-&amp;gt;render_value( &amp;quot;local&amp;quot; ) );&lt;br /&gt;
      $p-&amp;gt;appendChild( $session-&amp;gt;make_text( &amp;quot;.&amp;quot; ) );&lt;br /&gt;
&lt;br /&gt;
      # Append our new paragraph to the page.&lt;br /&gt;
      $page-&amp;gt;appendChild( $p );&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Multiple-language example:&lt;br /&gt;
If you want to make it handle more than language then we'll need to use the archive phrase file - we would add something like this to each languages file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;page:itemnotlocal&amp;quot;&amp;gt;&amp;lt;p&amp;gt;This item was &amp;lt;pin ref=&amp;quot;status&amp;quot; /&amp;gt;.&amp;lt;/p&amp;gt;&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
And to the ArchiveRenderConfig.pm file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 if( $eprint-&amp;gt;get_value( &amp;quot;local&amp;quot; ) ne &amp;quot;yes&amp;quot; )&lt;br /&gt;
 {&lt;br /&gt;
      my $localmsg = $session-&amp;gt;html_phrase(&lt;br /&gt;
             &amp;quot;page:itemnotlocal&amp;quot;,&lt;br /&gt;
             status=&amp;gt;$eprint-&amp;gt;render_value( &amp;quot;local&amp;quot; ) );&lt;br /&gt;
      $page-&amp;gt;appendChild( $localmsg );&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
You may prefer to use this method even if you are only using a single language.&lt;br /&gt;
; Add extra Validation Routines : If you need to validate this field in a special way, add code into ArchiveValidateConfig.pm&lt;br /&gt;
; Add it to the OAI metadata (eprints only) : If this field can be rendered into Dublin Core (or other metadata formats you are using) then add it to the appropriate place in the ArchiveOAIConfig.pm file.&lt;br /&gt;
; Add a browse view (eprints only) : If you want to be able to browse this values items. See elsewhere in the docs for how to do this.&lt;br /&gt;
&lt;br /&gt;
If you add a field you will need to run erase_archive and create_tables before you will see a change. EPrints will fail to run if you change the fields and do rebuild the tables.&lt;br /&gt;
&lt;br /&gt;
===HOW TO: Remove a Field===&lt;br /&gt;
The quick answer is to say &amp;quot;the opposite of adding one&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
; Remove the Field to metadata-types.xml : Removing it from here will mean that nobody can enter values for that field. Which is possibly enough, and means you can put it back later.&lt;br /&gt;
; Remove the Field to ArchiveMetafieldConfig.pm : This will remove it from the database ( and require a rebuild as with adding a field ).&lt;br /&gt;
; Remove it from the phrase file(s) : This is optional, unused phrases are just ignored.&lt;br /&gt;
; Remove it from the citations file : If it's used there.&lt;br /&gt;
; Remove it from the the Abstract (or View-User) page. : If it's used there.&lt;br /&gt;
; Remove extra Validation Routines : In the unlikely event you added some validation which looks at this field.&lt;br /&gt;
; Remove it from the OAI metadata (eprints only) : If it's being used. Fields used to generate the default dublincore are: title, authors, subjects, abstract, year and month. It also uses &amp;quot;type&amp;quot; which is a system field so you can't remove it!&lt;br /&gt;
; Remove it from browse views (eprints only) : If it's used there.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: EPrint types==&lt;br /&gt;
===Add a new eprint type===&lt;br /&gt;
Add the eprint type to '''metadata-types.xml'''. Some fields should probably be &amp;quot;required&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Add the name of the type to the phrase file.&lt;br /&gt;
&lt;br /&gt;
Add a citation for this type to the citations file.&lt;br /&gt;
&lt;br /&gt;
===Remove an eprint type===&lt;br /&gt;
Remove it from metadata-types.xml&lt;br /&gt;
&lt;br /&gt;
You can remove it from the phrase file &amp;amp; citations but it won't hurt to leave it there.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Add a new document type==&lt;br /&gt;
Add it to '''metadata-types.xml'''. This does not need any fields.&lt;br /&gt;
&lt;br /&gt;
Add the name of the document type to the phrase file.&lt;br /&gt;
&lt;br /&gt;
Add a citation for this document to the citations file.&lt;br /&gt;
&lt;br /&gt;
If you want this to be one of the must-have-one-of document types then add it's id to the list in ArchiveConfig.pm&lt;br /&gt;
&lt;br /&gt;
If you want to do something &amp;quot;clever&amp;quot; on the abstract page then edit the ArchiveRenderConfig.pm file. If you don't then it will use the citiation you created to render it in the list, as with PDF, HTML etc.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Add a Discussion Forum for Each EPrint==&lt;br /&gt;
The UK Open University (open.ac.uk) have set up a service which allows you to create a discussion for every EPrint in your archive.&lt;br /&gt;
&lt;br /&gt;
The really easy way to do this is to use their discussion server. If you want to run your own d3e server the software is available from http://d3e.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
===Using d3eprints.open.ac.uk===&lt;br /&gt;
Just add the following code to the ArchiveRenderConfig.pm file just before the &amp;lt;tt&amp;gt;if( $has_multiple_versions )&amp;lt;/tt&amp;gt; bit.&lt;br /&gt;
&lt;br /&gt;
Please note that this code is not internationalised.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
        #####################################&lt;br /&gt;
        # Begin D3Eprints links&lt;br /&gt;
&lt;br /&gt;
        my $ol = $session-&amp;gt;make_element( &amp;quot;ol&amp;quot; );&lt;br /&gt;
        my $li = $session-&amp;gt;make_element( &amp;quot;li&amp;quot; );&lt;br /&gt;
        $a = $session-&amp;gt;render_link(&lt;br /&gt;
                EPrints::Utils::url_escape(&lt;br /&gt;
                        &amp;quot;http://d3eprints.open.ac.uk/disc.php?url=&amp;quot;.$eprint-&amp;gt;get_url ),&lt;br /&gt;
                &amp;quot;_top&amp;quot; );&lt;br /&gt;
        $a-&amp;gt;appendChild( $session-&amp;gt;make_text(&lt;br /&gt;
                &amp;quot;View public discussion of this document&amp;quot; ) );&lt;br /&gt;
        $li-&amp;gt;appendChild( $a );&lt;br /&gt;
        $ol-&amp;gt;appendChild( $li );&lt;br /&gt;
&lt;br /&gt;
        $li = $session-&amp;gt;make_element( &amp;quot;li&amp;quot; );&lt;br /&gt;
        $a = $session-&amp;gt;render_link(&lt;br /&gt;
                EPrints::Utils::url_escape(&lt;br /&gt;
                        &amp;quot;http://d3eprints.open.ac.uk/private/disc.php?url=&amp;quot;.&lt;br /&gt;
                                $eprint-&amp;gt;get_url ),&lt;br /&gt;
                &amp;quot;_top&amp;quot; );&lt;br /&gt;
        $a-&amp;gt;appendChild( $session-&amp;gt;make_text(&lt;br /&gt;
                &amp;quot;Create private discussion of this document&amp;quot; ) );&lt;br /&gt;
        $li-&amp;gt;appendChild( $a );&lt;br /&gt;
        $ol-&amp;gt;appendChild( $li );&lt;br /&gt;
&lt;br /&gt;
        $table-&amp;gt;appendChild( _render_row(&lt;br /&gt;
                $session,&lt;br /&gt;
                $session-&amp;gt;make_text( &amp;quot;D3Eprints discussion&amp;quot; ),&lt;br /&gt;
                $ol ) );&lt;br /&gt;
&lt;br /&gt;
        # End of D3Eprints links&lt;br /&gt;
        #####################################&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
==HOW TO: Website Integration==&lt;br /&gt;
===Make the latest additions to your archive appear on your main website===&lt;br /&gt;
The contents of the &amp;quot;latest&amp;quot; page - /perl/latest - can be included via a cron tab using wget and a server side include or using something like PHP's command to do:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 readfile( &amp;quot;http://eprints.foo.org/perl/latest?mainonly=yes&amp;quot; );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The &amp;quot;mainonly=yes&amp;quot; flag is a hack which supresses the template of any eprints page in the /perl/ area so that it can be included, but it is most useful for &amp;quot;latest&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
WARNING: If you have a script which imports 1000 records in one night then latest isn't currently bright enough to truncate the list so your homepage could get kinda messy.&lt;br /&gt;
&lt;br /&gt;
===RSS into HTML===&lt;br /&gt;
If you want to turn any search into a dynamically generated list of references with a link back to the EPrints page, then use this.  This solution uses PHP.  So, you will need PHP enabled on the server.&lt;br /&gt;
&lt;br /&gt;
'''Dependency:''' This code depends on [http://magpierss.sourceforge.net/ MagpieRSS].&lt;br /&gt;
&lt;br /&gt;
'''Original Context:''' It was developed for use in a [http://www.terminalfour.com/ Terminal4 'SiteManager'] template, but can be used with almost no modification.&lt;br /&gt;
&lt;br /&gt;
The code implements local caching of the generated HTML in a text file which is never more than an hour old, unless there is a problem with the server whereupon the last good cached version is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 require_once('D:/website/[path to]/magpierss/rss_fetch.inc');&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;//set some variables here:&amp;lt;/span&amp;gt;&lt;br /&gt;
 $anchor = '&amp;lt;t4 type=&amp;quot;meta&amp;quot; meta=&amp;quot;html_anchor&amp;quot; /&amp;gt;';&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;# All items in Terminal4's cms have an anchor - we like break it apart to get the Unique id, to name the cache file.&amp;lt;/span&amp;gt;&lt;br /&gt;
 $TTL = 3600;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;# Time to live - one hour only.&amp;lt;/span&amp;gt;&lt;br /&gt;
 $feed = '&amp;lt;t4 type=&amp;quot;content&amp;quot; name=&amp;quot;RSS_Feed_URL&amp;quot; output=&amp;quot;normal&amp;quot; modifiers=&amp;quot;&amp;quot;  /&amp;gt;';&lt;br /&gt;
 $uniqueID = explode(&amp;quot;\&amp;quot;&amp;quot;, $anchor);&lt;br /&gt;
 $filename = &amp;quot;./&amp;quot; . str_replace('.', '-', $uniqueID[1]) . &amp;quot;.txt&amp;quot;;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;#filename of cache - generated from unique id in T4 content management system.&amp;lt;/span&amp;gt;&lt;br /&gt;
 $max_items = &amp;lt;t4 type=&amp;quot;content&amp;quot; name=&amp;quot;MaxNumberToShow&amp;quot; output=&amp;quot;normal&amp;quot; modifiers=&amp;quot;&amp;quot;  /&amp;gt;;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;# $max_items = 30; // this is set in EPrints as well, will not exceed Eprints' own internal limit.&amp;lt;/span&amp;gt;&lt;br /&gt;
 $with_summaries = '&amp;lt;t4 type=&amp;quot;content&amp;quot; name=&amp;quot;ShowSummary&amp;quot; output=&amp;quot;normal&amp;quot; modifiers=&amp;quot;&amp;quot;  /&amp;gt;'; # could be 'yes' or 'no'&lt;br /&gt;
 $age = 0;&lt;br /&gt;
 if(file_exists($filename)){&lt;br /&gt;
 	$age = time() - filemtime($filename); &lt;br /&gt;
 }else{&lt;br /&gt;
 	$fh = fopen($filename, &amp;quot;w&amp;quot;);&lt;br /&gt;
 	fwrite($fh, $news_feed);&lt;br /&gt;
 	fclose($fh);&lt;br /&gt;
 	$age = $TTL;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function getFromCache($f){	&lt;br /&gt;
 	$fh = fopen($f, &amp;quot;r&amp;quot;);&lt;br /&gt;
 	$size = filesize($f);&lt;br /&gt;
 	$data = fread($fh, $size);&lt;br /&gt;
 	print $data;&lt;br /&gt;
 	fclose($fh);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 if($age &amp;gt;= $TTL){ &lt;br /&gt;
 	if($rss = fetch_rss($feed)){&lt;br /&gt;
 		$items = array_slice($rss-&amp;gt;items, 0);&lt;br /&gt;
 		$find = array(&amp;quot;/^\.?/&amp;quot;);&lt;br /&gt;
 		$replace = array(&amp;quot; &amp;quot;);&lt;br /&gt;
 		$news_feed = &amp;quot;&amp;amp;lt;ul class=\&amp;quot;rss_list\&amp;quot;&amp;gt;\n&amp;quot;;&lt;br /&gt;
 			foreach ($items as $item ){&lt;br /&gt;
 				if($count &amp;amp;lt; $max_items){&lt;br /&gt;
 					$news_feed .= &amp;quot;\t&amp;amp;lt;li class=\&amp;quot;rss_item\&amp;quot;&amp;gt;\n&amp;quot;;&lt;br /&gt;
 					$news_feed .= &amp;quot;\t\t&amp;amp;lt;span class=\&amp;quot;rss_title\&amp;quot;&amp;gt;&amp;amp;lt;a href=\&amp;quot;&amp;quot; . $item['link'] . &amp;quot;\&amp;quot; target=\&amp;quot;_blank\&amp;quot;&amp;gt;&amp;quot;;&lt;br /&gt;
 					$news_feed .= $item['title'] . &amp;quot;&amp;amp;lt;/a&amp;gt;&amp;amp;lt;/span&amp;gt;\n\t\t&amp;amp;lt;br /&amp;gt;\n&amp;quot;;&lt;br /&gt;
 					if($with_summaries == 'yes'){&lt;br /&gt;
 						$news_feed .= &amp;quot;\t\t&amp;amp;lt;span class=\&amp;quot;rss_summary\&amp;quot;&amp;gt;\n\t\t\t&amp;quot;;&lt;br /&gt;
 						$news_feed .= str_replace(($item['title'] . &amp;quot;.&amp;quot;), &amp;quot;&amp;quot;, htmlentities($item['summary'])) . &amp;quot;&amp;amp;lt;br/&amp;gt;\n\t\t&amp;amp;lt;/span&amp;gt;\n&amp;quot;;&lt;br /&gt;
 					}&lt;br /&gt;
 					$news_feed .= &amp;quot;\t\t&amp;amp;lt;br /&amp;gt;\n\t&amp;lt;/li&amp;gt;\n&amp;quot;;&lt;br /&gt;
 					$count += 1;&lt;br /&gt;
 				}&lt;br /&gt;
 			}&lt;br /&gt;
 		$news_feed .= &amp;quot;&amp;amp;lt;/ul&amp;gt;\n\n&amp;quot;;&lt;br /&gt;
 		echo $news_feed;&lt;br /&gt;
 		$fh = fopen($filename, &amp;quot;w&amp;quot;);&lt;br /&gt;
 		fwrite($fh, $news_feed);&lt;br /&gt;
 		fclose($fh);&lt;br /&gt;
 	}else{&lt;br /&gt;
 		getFromCache($filename);&lt;br /&gt;
 	}&lt;br /&gt;
 }else{&lt;br /&gt;
 	getFromCache($filename);&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;# David Kane, Waterford Institute of Technology&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Add full text searching==&lt;br /&gt;
EPrints does not support this natively but there are several options.&lt;br /&gt;
&lt;br /&gt;
===htdig, or similar software===&lt;br /&gt;
There is plenty of software which will provide a full text search of a website. To add non-eprints cgi scripts to your site create a directory in the cgi dir:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 mkdir /opt/eprints2/cgi/local&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and place your scripts in there, they will have URLs under &amp;lt;tt&amp;gt;http://yoursite.com/perl/&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using an external search engine===&lt;br /&gt;
This is very easy, but will only index public documents. Any search engine will work, but Google is a good choice. Google provide a site-search service which allows you to register with them and then have a form which searches your site using google and adds your logo and colourscheme to the results.&lt;br /&gt;
&lt;br /&gt;
A really easy solution is to just make a form which links to our &amp;quot;google_site&amp;quot; script which just adds &amp;quot;site:yoursite.com&amp;quot; to the google request to limit the search results. The HTML for this would be something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;form action=&amp;quot;/perl/google_site&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;Use Google to search this site:&lt;br /&gt;
 &amp;lt;input name=&amp;quot;q&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;submit&amp;quot; name=&amp;quot;go&amp;quot; value=&amp;quot;Search&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For other search engines; see their documentation for how to make a form to search only your site.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Make the referencetext field link to the items referenced==&lt;br /&gt;
This should have been in the 2.2 docs but I didn't have time. Check the latest version of the documentation at software.eprints.org, if it's not there then bug me at support@eprints.org&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Make the password controlled parts of the site use HTTPS==&lt;br /&gt;
This should have been in the 2.2 docs but I didn't have time. Check the latest version of the documentation at software.eprints.org, if it's not there then bug me at support@eprints.org&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Customise the way the the search results are formatted==&lt;br /&gt;
This should have been in the 2.2 docs but I didn't have time. Check the latest version of the documentation at software.eprints.org, if it's not there then bug me at support@eprints.org&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Reset your EPrints admin password [3.3]==&lt;br /&gt;
&lt;br /&gt;
To directly reset your password, log into phpMyAdmin and execute the following mySQL statement:&lt;br /&gt;
&lt;br /&gt;
 UPDATE user SET password = encrypt('newpassword') WHERE userid = 1;&lt;br /&gt;
This will effectively reset the EPrint admin password for user 1. Note that you can use this to reset the password of any user, although this is typically unnecessary as you should be able to simply log in as admin user (user 1), under which you have the ability to reset any user's password.&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=How_to&amp;diff=10149</id>
		<title>How to</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=How_to&amp;diff=10149"/>
		<updated>2011-12-10T11:25:08Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Howto]]&lt;br /&gt;
==HOW TO: Set up a Complex Custom View==&lt;br /&gt;
Simple instructions are in the ArchiveConfig.pm section.&lt;br /&gt;
&lt;br /&gt;
Example situation: On my main website www.foobars.ac.uk I have a page per research project, of which we have hundreds. Each project has a short unique id code, eg. &amp;quot;manticore&amp;quot;. I have a field in my eprints archive (eprints.foobars.ac.uk) which is configured:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { name=&amp;gt;&amp;quot;projectcodes&amp;quot;, type=&amp;gt;&amp;quot;text&amp;quot;, multiple=&amp;gt;1 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
I add the following browse view:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { id=&amp;gt;&amp;quot;by_project&amp;quot;, allow_null=&amp;gt;0, fields=&amp;gt;&amp;quot;projectcodes&amp;quot;, &lt;br /&gt;
 order=&amp;gt;&amp;quot;-year/title&amp;quot; }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This will generate a page http://eprints.foobars.ac.uk/views/by_project/manticore.html with a list of all papers in that project, we can link to that URL!&lt;br /&gt;
&lt;br /&gt;
===Making the Field link to the Browse Page===&lt;br /&gt;
If you want a subject to link the subject browse page of that value, add the '''browse_link''' property to the field (and regenerate the abstracts if you want).&lt;br /&gt;
&lt;br /&gt;
If you remove the browse view you should remove the browse_link or it will be a broken link.&lt;br /&gt;
&lt;br /&gt;
Values rendered inside citations which are used to link to the main record will not link into the browse view for obvious reasons.&lt;br /&gt;
&lt;br /&gt;
===Including a view in another page===&lt;br /&gt;
If you change that to:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { id=&amp;gt;&amp;quot;by_project&amp;quot;, allow_null=&amp;gt;0, fields=&amp;gt;&amp;quot;projectcodes&amp;quot;, &lt;br /&gt;
 order=&amp;gt;&amp;quot;-year/title&amp;quot;, noindex=&amp;gt;1, nolink=&amp;gt;1, nohtml=&amp;gt;1, include=&amp;gt;1 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This will generate a view which is NOT listed on the /view/ page and it will not skip making the .html file and make a .include file per value. This will only contain the &amp;quot;count&amp;quot; of items and the XHTML of their citations. This can be used as part of a page on the http://www.foobaars.ac.uk/ site; either by using php and capturing it on-the-fly using &amp;lt;tt&amp;gt;readfile&amp;lt;/tt&amp;gt; or scripting it with perl or NFS exporting the filesystem onto the main server (or just doing it all on one computer) and using server side includes to place it in a page.&lt;br /&gt;
&lt;br /&gt;
===Customising the way each item is cited===&lt;br /&gt;
I want to list the project papers in a strict format in a table with 4 columns: title, author(s), year and an icon which links to the document abstract page...&lt;br /&gt;
&lt;br /&gt;
I add some ''more'' options to the browse view:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { id=&amp;gt;&amp;quot;by_project&amp;quot;, allow_null=&amp;gt;0, fields=&amp;gt;&amp;quot;projectcodes&amp;quot;, &lt;br /&gt;
 order=&amp;gt;&amp;quot;-year/title&amp;quot;, noindex=&amp;gt;1, nolink=&amp;gt;1, nohtml=&amp;gt;1, include=&amp;gt;1,&lt;br /&gt;
 nocount=&amp;gt;1, citation=&amp;gt;&amp;quot;project_table&amp;quot; }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Now I add a new citation to the citations config file:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;ep:citation type=&amp;quot;project_table&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;amp;title;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;amp;authors;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&amp;amp;year;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;ep:linkhere&amp;gt;&amp;lt;img &lt;br /&gt;
 src=&amp;quot;http://www.foobars.ac.uk/images/paperlink.png&amp;quot; alt=&amp;quot;view&amp;quot; width=&amp;quot;32&amp;quot; &lt;br /&gt;
 height=&amp;quot;64&amp;quot; border=&amp;quot;0&amp;quot; /&amp;gt;&amp;lt;/ep:linkhere&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/ep:citation&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
That should generate for the manticore project, in the &amp;quot;.include&amp;quot; file (I've cut the contents of the &amp;quot;img&amp;quot; tag for readability:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Making Stuff&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Guy, A.&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;a &lt;br /&gt;
 href=&amp;quot;http://eprints.foobar.ac.uk/archive/00000923/&amp;quot;&amp;gt;&amp;lt;img ... /&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
 &amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Eating Food&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Herring, Walter and Chips, Bob&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;br /&gt;
 2000&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;a href=&amp;quot;http://eprints.foobar.ac.uk/archive/00000445/&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;img ... /&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===A &amp;quot;CV&amp;quot; page - a list of all of Alices records===&lt;br /&gt;
This is where the authors and editors field having an ID comes in handy.&lt;br /&gt;
&lt;br /&gt;
Say we use local username to identify people in the &amp;quot;Person ID&amp;quot; fields, we can now set up a view:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { id=&amp;gt;&amp;quot;by_person&amp;quot;, allow_null=&amp;gt;0, fields=&amp;gt;&amp;quot;authors.id/editors.id&amp;quot;, &lt;br /&gt;
 order=&amp;gt;&amp;quot;-year/title&amp;quot;, noindex=&amp;gt;1, include=&amp;gt;1 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This will generate both .html pages and .include pages. An member of your organisation can get a list of their records either by linking to &amp;lt;tt&amp;gt;/views/by_person/alice.html&amp;lt;/tt&amp;gt; (where alice is their username) or by snarfing the URL &amp;lt;tt&amp;gt;/views/by_person/alice.include&amp;lt;/tt&amp;gt; into his own homepage.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Fields==&lt;br /&gt;
===Add a new Field&lt;br /&gt;
This convers adding a new field to a new system, not a live system. It is possible to add a new field to a live system but invloves SQL hacking.&lt;br /&gt;
&lt;br /&gt;
In this example we add a new &amp;quot;set&amp;quot; field called &amp;quot;local&amp;quot; which will have 3 options &amp;quot;yes&amp;quot;,&amp;quot;no&amp;quot; and &amp;quot;partial&amp;quot; - this will indicate if the item in question was produced in our organisation or not.&lt;br /&gt;
&lt;br /&gt;
; Add the Field to ArchiveMetafieldConfig.pm : Add the field to the appropriate part of ArchiveMetafieldConfig.pm (the &amp;quot;eprint&amp;quot; section in our example)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 { name =&amp;gt; &amp;quot;local&amp;quot;, type =&amp;gt; &amp;quot;set&amp;quot;, input_rows =&amp;gt; 1, &lt;br /&gt;
    options =&amp;gt; [ &amp;quot;yes&amp;quot;, &amp;quot;no&amp;quot;, &amp;quot;partial&amp;quot; ] }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
input_rows being set to one will make it appear as a pull-down menu.&lt;br /&gt;
; Add the Field to metadata-types.xml : If you want the user to be able to edit this field for any or all types of eprint/user then you need to add it to each appropriate type in metadata-types.xml (this can be changed on a live system without any serious consequencies).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;field name=&amp;quot;local&amp;quot; required=&amp;quot;yes&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; Add the Field Information to the Archive Phrase File(s) : Normally we just need to add fieldname and fieldhelp, but this is an option field so we need to add names for each option. If we run the archive in more than one language then we add this to each phrase file (but in the appropriate language).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldname_local&amp;quot;&amp;gt;Produced Locally&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldhelp_local&amp;quot;&amp;gt;Please indicate if this item was &lt;br /&gt;
produces in the foo organisation, or not.&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldopt_local_yes&amp;quot;&amp;gt;produced locally&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldopt_local_no&amp;quot;&amp;gt;not produced locally&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;eprint_fieldopt_local_partial&amp;quot;&amp;gt;only partially produced &lt;br /&gt;
locally&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Other things you may wish to change after adding a new field====&lt;br /&gt;
; Add it to the citations file : This is optional, only do this if you want it to appear in the citated forms.&lt;br /&gt;
In our example case we only want this to appear when citing technical reports, so we change that entry to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;ep:citation type=&amp;quot;eprint_techreport&amp;quot;&amp;gt;&amp;lt;ep:linkhere&amp;gt;&amp;lt;span &lt;br /&gt;
 class=&amp;quot;citation&amp;quot;&amp;gt;&amp;amp;authors; &amp;lt;ep:ifset name=&amp;quot;year&amp;quot;&amp;gt;(&amp;amp;year;) &lt;br /&gt;
 &amp;lt;/ep:ifset&amp;gt;&amp;amp;title;. Technical Report&amp;lt;ep:ifset name=&amp;quot;reportno&amp;quot;&amp;gt; &lt;br /&gt;
 &amp;amp;reportno;&amp;lt;/ep:ifset&amp;gt;&amp;lt;ep:ifset name=&amp;quot;department&amp;quot;&amp;gt;, &amp;amp;department;&lt;br /&gt;
 &amp;lt;/ep:ifset&amp;gt;&amp;lt;ep:ifset name=&amp;quot;institution&amp;quot;&amp;gt;, &amp;amp;institution;&amp;lt;/ep:ifset&amp;gt;. &lt;br /&gt;
 &amp;amp;local;.&amp;lt;/span&amp;gt;&amp;lt;/ep:linkhere&amp;gt;&amp;lt;/ep:citation&amp;gt; &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
All we've done is add &amp;lt;tt&amp;gt;&amp;amp;local;.&amp;lt;/tt&amp;gt; to the end. It's not inside &amp;lt;tt&amp;gt; &amp;lt;ep:ifset name=&amp;quot;local&amp;quot;&amp;gt; &amp;lt;/tt&amp;gt; as it is a required field and will (should) always be set.&lt;br /&gt;
; Add it to the the Abstract (or View-User) page. : This is also optional. If you want it to appear on the web page for this item then edit ArchiveRenderConfig.pm and select the appropriate function, either eprint_render or user_render.&lt;br /&gt;
In our example we only want to mention items if an item was not produced locally. We'll add it below the documents and above the abstract...&lt;br /&gt;
Single language example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 if( $eprint-&amp;gt;get_value( &amp;quot;local&amp;quot; ) ne &amp;quot;yes&amp;quot; )&lt;br /&gt;
 {&lt;br /&gt;
      # don't need to &amp;quot;my $p&amp;quot; as it's done earlier.&lt;br /&gt;
      $p = $session-&amp;gt;make_element( &amp;quot;p&amp;quot; );&lt;br /&gt;
      $p-&amp;gt;appendChild( $session-&amp;gt;make_text( &amp;quot;This item was &amp;quot; ) );&lt;br /&gt;
      $p-&amp;gt;appendChild( $eprint-&amp;gt;render_value( &amp;quot;local&amp;quot; ) );&lt;br /&gt;
      $p-&amp;gt;appendChild( $session-&amp;gt;make_text( &amp;quot;.&amp;quot; ) );&lt;br /&gt;
&lt;br /&gt;
      # Append our new paragraph to the page.&lt;br /&gt;
      $page-&amp;gt;appendChild( $p );&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Multiple-language example:&lt;br /&gt;
If you want to make it handle more than language then we'll need to use the archive phrase file - we would add something like this to each languages file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;ep:phrase ref=&amp;quot;page:itemnotlocal&amp;quot;&amp;gt;&amp;lt;p&amp;gt;This item was &amp;lt;pin ref=&amp;quot;status&amp;quot; /&amp;gt;.&amp;lt;/p&amp;gt;&amp;lt;/ep:phrase&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
And to the ArchiveRenderConfig.pm file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 if( $eprint-&amp;gt;get_value( &amp;quot;local&amp;quot; ) ne &amp;quot;yes&amp;quot; )&lt;br /&gt;
 {&lt;br /&gt;
      my $localmsg = $session-&amp;gt;html_phrase(&lt;br /&gt;
             &amp;quot;page:itemnotlocal&amp;quot;,&lt;br /&gt;
             status=&amp;gt;$eprint-&amp;gt;render_value( &amp;quot;local&amp;quot; ) );&lt;br /&gt;
      $page-&amp;gt;appendChild( $localmsg );&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
You may prefer to use this method even if you are only using a single language.&lt;br /&gt;
; Add extra Validation Routines : If you need to validate this field in a special way, add code into ArchiveValidateConfig.pm&lt;br /&gt;
; Add it to the OAI metadata (eprints only) : If this field can be rendered into Dublin Core (or other metadata formats you are using) then add it to the appropriate place in the ArchiveOAIConfig.pm file.&lt;br /&gt;
; Add a browse view (eprints only) : If you want to be able to browse this values items. See elsewhere in the docs for how to do this.&lt;br /&gt;
&lt;br /&gt;
If you add a field you will need to run erase_archive and create_tables before you will see a change. EPrints will fail to run if you change the fields and do rebuild the tables.&lt;br /&gt;
&lt;br /&gt;
===HOW TO: Remove a Field===&lt;br /&gt;
The quick answer is to say &amp;quot;the opposite of adding one&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
; Remove the Field to metadata-types.xml : Removing it from here will mean that nobody can enter values for that field. Which is possibly enough, and means you can put it back later.&lt;br /&gt;
; Remove the Field to ArchiveMetafieldConfig.pm : This will remove it from the database ( and require a rebuild as with adding a field ).&lt;br /&gt;
; Remove it from the phrase file(s) : This is optional, unused phrases are just ignored.&lt;br /&gt;
; Remove it from the citations file : If it's used there.&lt;br /&gt;
; Remove it from the the Abstract (or View-User) page. : If it's used there.&lt;br /&gt;
; Remove extra Validation Routines : In the unlikely event you added some validation which looks at this field.&lt;br /&gt;
; Remove it from the OAI metadata (eprints only) : If it's being used. Fields used to generate the default dublincore are: title, authors, subjects, abstract, year and month. It also uses &amp;quot;type&amp;quot; which is a system field so you can't remove it!&lt;br /&gt;
; Remove it from browse views (eprints only) : If it's used there.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: EPrint types==&lt;br /&gt;
===Add a new eprint type===&lt;br /&gt;
Add the eprint type to '''metadata-types.xml'''. Some fields should probably be &amp;quot;required&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Add the name of the type to the phrase file.&lt;br /&gt;
&lt;br /&gt;
Add a citation for this type to the citations file.&lt;br /&gt;
&lt;br /&gt;
===Remove an eprint type===&lt;br /&gt;
Remove it from metadata-types.xml&lt;br /&gt;
&lt;br /&gt;
You can remove it from the phrase file &amp;amp; citations but it won't hurt to leave it there.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Add a new document type==&lt;br /&gt;
Add it to '''metadata-types.xml'''. This does not need any fields.&lt;br /&gt;
&lt;br /&gt;
Add the name of the document type to the phrase file.&lt;br /&gt;
&lt;br /&gt;
Add a citation for this document to the citations file.&lt;br /&gt;
&lt;br /&gt;
If you want this to be one of the must-have-one-of document types then add it's id to the list in ArchiveConfig.pm&lt;br /&gt;
&lt;br /&gt;
If you want to do something &amp;quot;clever&amp;quot; on the abstract page then edit the ArchiveRenderConfig.pm file. If you don't then it will use the citiation you created to render it in the list, as with PDF, HTML etc.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Add a Discussion Forum for Each EPrint==&lt;br /&gt;
The UK Open University (open.ac.uk) have set up a service which allows you to create a discussion for every EPrint in your archive.&lt;br /&gt;
&lt;br /&gt;
The really easy way to do this is to use their discussion server. If you want to run your own d3e server the software is available from http://d3e.sourceforge.net/&lt;br /&gt;
&lt;br /&gt;
===Using d3eprints.open.ac.uk===&lt;br /&gt;
Just add the following code to the ArchiveRenderConfig.pm file just before the &amp;lt;tt&amp;gt;if( $has_multiple_versions )&amp;lt;/tt&amp;gt; bit.&lt;br /&gt;
&lt;br /&gt;
Please note that this code is not internationalised.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
        #####################################&lt;br /&gt;
        # Begin D3Eprints links&lt;br /&gt;
&lt;br /&gt;
        my $ol = $session-&amp;gt;make_element( &amp;quot;ol&amp;quot; );&lt;br /&gt;
        my $li = $session-&amp;gt;make_element( &amp;quot;li&amp;quot; );&lt;br /&gt;
        $a = $session-&amp;gt;render_link(&lt;br /&gt;
                EPrints::Utils::url_escape(&lt;br /&gt;
                        &amp;quot;http://d3eprints.open.ac.uk/disc.php?url=&amp;quot;.$eprint-&amp;gt;get_url ),&lt;br /&gt;
                &amp;quot;_top&amp;quot; );&lt;br /&gt;
        $a-&amp;gt;appendChild( $session-&amp;gt;make_text(&lt;br /&gt;
                &amp;quot;View public discussion of this document&amp;quot; ) );&lt;br /&gt;
        $li-&amp;gt;appendChild( $a );&lt;br /&gt;
        $ol-&amp;gt;appendChild( $li );&lt;br /&gt;
&lt;br /&gt;
        $li = $session-&amp;gt;make_element( &amp;quot;li&amp;quot; );&lt;br /&gt;
        $a = $session-&amp;gt;render_link(&lt;br /&gt;
                EPrints::Utils::url_escape(&lt;br /&gt;
                        &amp;quot;http://d3eprints.open.ac.uk/private/disc.php?url=&amp;quot;.&lt;br /&gt;
                                $eprint-&amp;gt;get_url ),&lt;br /&gt;
                &amp;quot;_top&amp;quot; );&lt;br /&gt;
        $a-&amp;gt;appendChild( $session-&amp;gt;make_text(&lt;br /&gt;
                &amp;quot;Create private discussion of this document&amp;quot; ) );&lt;br /&gt;
        $li-&amp;gt;appendChild( $a );&lt;br /&gt;
        $ol-&amp;gt;appendChild( $li );&lt;br /&gt;
&lt;br /&gt;
        $table-&amp;gt;appendChild( _render_row(&lt;br /&gt;
                $session,&lt;br /&gt;
                $session-&amp;gt;make_text( &amp;quot;D3Eprints discussion&amp;quot; ),&lt;br /&gt;
                $ol ) );&lt;br /&gt;
&lt;br /&gt;
        # End of D3Eprints links&lt;br /&gt;
        #####################################&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
==HOW TO: Website Integration==&lt;br /&gt;
===Make the latest additions to your archive appear on your main website===&lt;br /&gt;
The contents of the &amp;quot;latest&amp;quot; page - /perl/latest - can be included via a cron tab using wget and a server side include or using something like PHP's command to do:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 readfile( &amp;quot;http://eprints.foo.org/perl/latest?mainonly=yes&amp;quot; );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The &amp;quot;mainonly=yes&amp;quot; flag is a hack which supresses the template of any eprints page in the /perl/ area so that it can be included, but it is most useful for &amp;quot;latest&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
WARNING: If you have a script which imports 1000 records in one night then latest isn't currently bright enough to truncate the list so your homepage could get kinda messy.&lt;br /&gt;
&lt;br /&gt;
===RSS into HTML===&lt;br /&gt;
If you want to turn any search into a dynamically generated list of references with a link back to the EPrints page, then use this.  This solution uses PHP.  So, you will need PHP enabled on the server.&lt;br /&gt;
&lt;br /&gt;
'''Dependency:''' This code depends on [http://magpierss.sourceforge.net/ MagpieRSS].&lt;br /&gt;
&lt;br /&gt;
'''Original Context:''' It was developed for use in a [http://www.terminalfour.com/ Terminal4 'SiteManager'] template, but can be used with almost no modification.&lt;br /&gt;
&lt;br /&gt;
The code implements local caching of the generated HTML in a text file which is never more than an hour old, unless there is a problem with the server whereupon the last good cached version is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 require_once('D:/website/[path to]/magpierss/rss_fetch.inc');&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;//set some variables here:&amp;lt;/span&amp;gt;&lt;br /&gt;
 $anchor = '&amp;lt;t4 type=&amp;quot;meta&amp;quot; meta=&amp;quot;html_anchor&amp;quot; /&amp;gt;';&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;# All items in Terminal4's cms have an anchor - we like break it apart to get the Unique id, to name the cache file.&amp;lt;/span&amp;gt;&lt;br /&gt;
 $TTL = 3600;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;# Time to live - one hour only.&amp;lt;/span&amp;gt;&lt;br /&gt;
 $feed = '&amp;lt;t4 type=&amp;quot;content&amp;quot; name=&amp;quot;RSS_Feed_URL&amp;quot; output=&amp;quot;normal&amp;quot; modifiers=&amp;quot;&amp;quot;  /&amp;gt;';&lt;br /&gt;
 $uniqueID = explode(&amp;quot;\&amp;quot;&amp;quot;, $anchor);&lt;br /&gt;
 $filename = &amp;quot;./&amp;quot; . str_replace('.', '-', $uniqueID[1]) . &amp;quot;.txt&amp;quot;;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;#filename of cache - generated from unique id in T4 content management system.&amp;lt;/span&amp;gt;&lt;br /&gt;
 $max_items = &amp;lt;t4 type=&amp;quot;content&amp;quot; name=&amp;quot;MaxNumberToShow&amp;quot; output=&amp;quot;normal&amp;quot; modifiers=&amp;quot;&amp;quot;  /&amp;gt;;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;# $max_items = 30; // this is set in EPrints as well, will not exceed Eprints' own internal limit.&amp;lt;/span&amp;gt;&lt;br /&gt;
 $with_summaries = '&amp;lt;t4 type=&amp;quot;content&amp;quot; name=&amp;quot;ShowSummary&amp;quot; output=&amp;quot;normal&amp;quot; modifiers=&amp;quot;&amp;quot;  /&amp;gt;'; # could be 'yes' or 'no'&lt;br /&gt;
 $age = 0;&lt;br /&gt;
 if(file_exists($filename)){&lt;br /&gt;
 	$age = time() - filemtime($filename); &lt;br /&gt;
 }else{&lt;br /&gt;
 	$fh = fopen($filename, &amp;quot;w&amp;quot;);&lt;br /&gt;
 	fwrite($fh, $news_feed);&lt;br /&gt;
 	fclose($fh);&lt;br /&gt;
 	$age = $TTL;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function getFromCache($f){	&lt;br /&gt;
 	$fh = fopen($f, &amp;quot;r&amp;quot;);&lt;br /&gt;
 	$size = filesize($f);&lt;br /&gt;
 	$data = fread($fh, $size);&lt;br /&gt;
 	print $data;&lt;br /&gt;
 	fclose($fh);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 if($age &amp;gt;= $TTL){ &lt;br /&gt;
 	if($rss = fetch_rss($feed)){&lt;br /&gt;
 		$items = array_slice($rss-&amp;gt;items, 0);&lt;br /&gt;
 		$find = array(&amp;quot;/^\.?/&amp;quot;);&lt;br /&gt;
 		$replace = array(&amp;quot; &amp;quot;);&lt;br /&gt;
 		$news_feed = &amp;quot;&amp;amp;lt;ul class=\&amp;quot;rss_list\&amp;quot;&amp;gt;\n&amp;quot;;&lt;br /&gt;
 			foreach ($items as $item ){&lt;br /&gt;
 				if($count &amp;amp;lt; $max_items){&lt;br /&gt;
 					$news_feed .= &amp;quot;\t&amp;amp;lt;li class=\&amp;quot;rss_item\&amp;quot;&amp;gt;\n&amp;quot;;&lt;br /&gt;
 					$news_feed .= &amp;quot;\t\t&amp;amp;lt;span class=\&amp;quot;rss_title\&amp;quot;&amp;gt;&amp;amp;lt;a href=\&amp;quot;&amp;quot; . $item['link'] . &amp;quot;\&amp;quot; target=\&amp;quot;_blank\&amp;quot;&amp;gt;&amp;quot;;&lt;br /&gt;
 					$news_feed .= $item['title'] . &amp;quot;&amp;amp;lt;/a&amp;gt;&amp;amp;lt;/span&amp;gt;\n\t\t&amp;amp;lt;br /&amp;gt;\n&amp;quot;;&lt;br /&gt;
 					if($with_summaries == 'yes'){&lt;br /&gt;
 						$news_feed .= &amp;quot;\t\t&amp;amp;lt;span class=\&amp;quot;rss_summary\&amp;quot;&amp;gt;\n\t\t\t&amp;quot;;&lt;br /&gt;
 						$news_feed .= str_replace(($item['title'] . &amp;quot;.&amp;quot;), &amp;quot;&amp;quot;, htmlentities($item['summary'])) . &amp;quot;&amp;amp;lt;br/&amp;gt;\n\t\t&amp;amp;lt;/span&amp;gt;\n&amp;quot;;&lt;br /&gt;
 					}&lt;br /&gt;
 					$news_feed .= &amp;quot;\t\t&amp;amp;lt;br /&amp;gt;\n\t&amp;lt;/li&amp;gt;\n&amp;quot;;&lt;br /&gt;
 					$count += 1;&lt;br /&gt;
 				}&lt;br /&gt;
 			}&lt;br /&gt;
 		$news_feed .= &amp;quot;&amp;amp;lt;/ul&amp;gt;\n\n&amp;quot;;&lt;br /&gt;
 		echo $news_feed;&lt;br /&gt;
 		$fh = fopen($filename, &amp;quot;w&amp;quot;);&lt;br /&gt;
 		fwrite($fh, $news_feed);&lt;br /&gt;
 		fclose($fh);&lt;br /&gt;
 	}else{&lt;br /&gt;
 		getFromCache($filename);&lt;br /&gt;
 	}&lt;br /&gt;
 }else{&lt;br /&gt;
 	getFromCache($filename);&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: green; font-weight: bold&amp;quot;&amp;gt;# David Kane, Waterford Institute of Technology&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Add full text searching==&lt;br /&gt;
EPrints does not support this natively but there are several options.&lt;br /&gt;
&lt;br /&gt;
===htdig, or similar software===&lt;br /&gt;
There is plenty of software which will provide a full text search of a website. To add non-eprints cgi scripts to your site create a directory in the cgi dir:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 mkdir /opt/eprints2/cgi/local&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and place your scripts in there, they will have URLs under &amp;lt;tt&amp;gt;http://yoursite.com/perl/&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using an external search engine===&lt;br /&gt;
This is very easy, but will only index public documents. Any search engine will work, but Google is a good choice. Google provide a site-search service which allows you to register with them and then have a form which searches your site using google and adds your logo and colourscheme to the results.&lt;br /&gt;
&lt;br /&gt;
A really easy solution is to just make a form which links to our &amp;quot;google_site&amp;quot; script which just adds &amp;quot;site:yoursite.com&amp;quot; to the google request to limit the search results. The HTML for this would be something like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 &amp;lt;form action=&amp;quot;/perl/google_site&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;Use Google to search this site:&lt;br /&gt;
 &amp;lt;input name=&amp;quot;q&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;submit&amp;quot; name=&amp;quot;go&amp;quot; value=&amp;quot;Search&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
For other search engines; see their documentation for how to make a form to search only your site.&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Make the referencetext field link to the items referenced==&lt;br /&gt;
This should have been in the 2.2 docs but I didn't have time. Check the latest version of the documentation at software.eprints.org, if it's not there then bug me at support@eprints.org&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Make the password controlled parts of the site use HTTPS==&lt;br /&gt;
This should have been in the 2.2 docs but I didn't have time. Check the latest version of the documentation at software.eprints.org, if it's not there then bug me at support@eprints.org&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Customise the way the the search results are formatted==&lt;br /&gt;
This should have been in the 2.2 docs but I didn't have time. Check the latest version of the documentation at software.eprints.org, if it's not there then bug me at support@eprints.org&lt;br /&gt;
&lt;br /&gt;
==HOW TO: Reset your EPrints admin password [3.3]==&lt;br /&gt;
&lt;br /&gt;
To directly reset your password, log into phpMyAdmin and execute the following mySQL statement:&lt;br /&gt;
&lt;br /&gt;
 UPDATE user SET password = encrypt('newpassword') WHERE userid = 1;&lt;br /&gt;
This will effectively reset the EPrint admin password for user 1. Note that you can use this to reset the password of any user, although this is typically unnecessary as you should be able to simply log in as admin user (user 1), under which you have the ability to reset any user's password.&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=Files/OAI_Harvester_for_EPrints_3.2%2B&amp;diff=9898</id>
		<title>Files/OAI Harvester for EPrints 3.2+</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=Files/OAI_Harvester_for_EPrints_3.2%2B&amp;diff=9898"/>
		<updated>2011-07-06T09:38:21Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: /* OAI Harvester for EPrints 3.2+ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Keeps your repository in-sync with another repository via OAI-PMH.&lt;br /&gt;
&lt;br /&gt;
Note that these modules contain only the abstract classes, you will need to write your own module which translate whatever XML format you're harvesting to EPrints data structure. An example is provided under &amp;lt;code&amp;gt;cfg/plugins/EPrints/Plugin/Import/OAIPMH/Stub.pm.stub&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
* As ''root'' user:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
cpan HTTP::OAI&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* As ''eprints'' user:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
cp -rf bin/ cfg/ ./archives/ARCHIVEID/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
check the perl declaration in file ''./archives/ARCHIVEID/bin/oai/harvest'' and change it accordingly&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./bin/epadmin update_database_structure ARCHIVEID&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* As ''root'' user:&lt;br /&gt;
&lt;br /&gt;
Restart Web Server.&lt;br /&gt;
&lt;br /&gt;
=== Usage ===&lt;br /&gt;
* Create a module which transforms XML as explained in the intro of this file. Say you created a DC importer called OAIPMH::OAI_DC.&lt;br /&gt;
* Edit the configuration file ''cfg/cfg.d/oai_harvester.pl'' and create a new configuration for the service you want to harvest (an example is provided in that file) eg:&lt;br /&gt;
 $c-&amp;gt;{oai_harvester}-&amp;gt;{service_name} = {&lt;br /&gt;
      url =&amp;gt; 'http://oaiserver.com/oai',&lt;br /&gt;
      set =&amp;gt; 'that_set'&lt;br /&gt;
      default_values =&amp;gt; sub {&lt;br /&gt;
           my( $session, $epdata, $header ) = @_;&lt;br /&gt;
           $epdata-&amp;gt;{userid} = 1234;	# user '1234' will own all imported publications&lt;br /&gt;
           $epdata-&amp;gt;{eprint_status} = 'archive';	# imported publications will go straight to the live archive&lt;br /&gt;
           # etc...&lt;br /&gt;
      },&lt;br /&gt;
 };&lt;br /&gt;
* Run (or setup in cron) bin/oai/harvest periodically:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
bin/oai/harvest ARCHIVEID --plugin=OAIPMH::OAI_DC --conf=service_name&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's it!&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.eprints.org/w/index.php?title=Files/OAI_Harvester_for_EPrints_3.2%2B&amp;diff=9897</id>
		<title>Files/OAI Harvester for EPrints 3.2+</title>
		<link rel="alternate" type="text/html" href="https://wiki.eprints.org/w/index.php?title=Files/OAI_Harvester_for_EPrints_3.2%2B&amp;diff=9897"/>
		<updated>2011-07-06T09:38:03Z</updated>

		<summary type="html">&lt;p&gt;Denics@free.fr: Created page with '== OAI Harvester for EPrints 3.2+ == Keeps your repository in-sync with another repository via OAI-PMH.  Note that these modules contain only the abstract classes, you will need …'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== OAI Harvester for EPrints 3.2+ ==&lt;br /&gt;
Keeps your repository in-sync with another repository via OAI-PMH.&lt;br /&gt;
&lt;br /&gt;
Note that these modules contain only the abstract classes, you will need to write your own module which translate whatever XML format you're harvesting to EPrints data structure. An example is provided under &amp;lt;code&amp;gt;cfg/plugins/EPrints/Plugin/Import/OAIPMH/Stub.pm.stub&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
* As ''root'' user:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
cpan HTTP::OAI&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* As ''eprints'' user:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
cp -rf bin/ cfg/ ./archives/ARCHIVEID/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
check the perl declaration in file ''./archives/ARCHIVEID/bin/oai/harvest'' and change it accordingly&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
./bin/epadmin update_database_structure ARCHIVEID&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* As ''root'' user:&lt;br /&gt;
&lt;br /&gt;
Restart Web Server.&lt;br /&gt;
&lt;br /&gt;
=== Usage ===&lt;br /&gt;
* Create a module which transforms XML as explained in the intro of this file. Say you created a DC importer called OAIPMH::OAI_DC.&lt;br /&gt;
* Edit the configuration file ''cfg/cfg.d/oai_harvester.pl'' and create a new configuration for the service you want to harvest (an example is provided in that file) eg:&lt;br /&gt;
 $c-&amp;gt;{oai_harvester}-&amp;gt;{service_name} = {&lt;br /&gt;
      url =&amp;gt; 'http://oaiserver.com/oai',&lt;br /&gt;
      set =&amp;gt; 'that_set'&lt;br /&gt;
      default_values =&amp;gt; sub {&lt;br /&gt;
           my( $session, $epdata, $header ) = @_;&lt;br /&gt;
           $epdata-&amp;gt;{userid} = 1234;	# user '1234' will own all imported publications&lt;br /&gt;
           $epdata-&amp;gt;{eprint_status} = 'archive';	# imported publications will go straight to the live archive&lt;br /&gt;
           # etc...&lt;br /&gt;
      },&lt;br /&gt;
 };&lt;br /&gt;
* Run (or setup in cron) bin/oai/harvest periodically:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
bin/oai/harvest ARCHIVEID --plugin=OAIPMH::OAI_DC --conf=service_name&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's it!&lt;/div&gt;</summary>
		<author><name>Denics@free.fr</name></author>
		
	</entry>
</feed>