Islandora introduces support for a Fedora repository to be connected to and manipulated using the Tuque PHP library. This library can be accessed using functions included with Islandora, available inside a properly-bootstrapped Drupal environment. It can also be accessed directly outside of an Islandora environment.
Tuque is an API, written and accessible via PHP, that connects with a Fedora repository and mirrors its functionality. Tuque can be used to work with objects inside a Fedora repository, accessing their properties, manipulating them, and working with datastreams.
This guide will highlight methods of working with Fedora and Fedora objects using Tuque both by itself and from a Drupal environment.
Variables repeated often in this guide
From here on out, we're going to be repeating the use of a few specific PHP variables after the guide demonstrates how they are instantiated or constructed:
Variable | PHP Class | Description |
---|
$repository | FedoraRepository | A PHP object representation of the Fedora repository itself. |
$object | FedoraObject | A generic Fedora object. |
$datastream | FedoraDatastream | A generic Fedora object datastream. |
Accessing the Fedora Repository
Connecting to Fedora
Connecting to a Fedora Repository
To connect directly to a Fedora Repository using the tuque library:
...
|
$connection = new RepositoryConnection( |
...
$fedora_url, $username, $password |
...
Code Block |
---|
title | Islandora Only (via module) |
---|
|
$connection = islandora_get_tuque_connection($user) |
Accessing the repository
Code Block |
---|
|
/**
* Assuming our $connection has been instantiated as a new RepositoryConnection object.
*/
$api = new FedoraApi($connection);
$repository = new FedoraRepository($api, |
...
...
...
The IslandoraTuque class provides a simple constructor for Islandora users.
...
Code Block |
---|
title | Islandora only, manually, using the Islandora Tuque wrapper: |
---|
|
/**
* Assuming our $connection has been instantiated as a new RepositoryConnection object.
*/
|
...
module_load_include('inc', 'islandora', 'includes/ |
...
...
...
module_load_include('inc', 'islandora', 'includes/tuque_wrapper');
$api = new IslandoraFedoraApi($connection);
$repository = new |
...
IslandoraFedoraRepository($api, new SimpleCache()); |
Code Block |
---|
title | Islandora only, automatically, using the Islandora module: |
---|
|
/**
* Assuming $connection has been created via islandora_get_tuque_connection().
*/
$repository = $connection->repository; |
Code Block |
---|
language | php |
---|
title | Islandora only, using the IslandoraFedoraObject wrapper: |
---|
|
/**
* This method tends to be the most reliable when working with a single object,
* since it builds on the success of the attempt to load that object.
*/
$pid = 'object:pid';
$object = islandora_object_load($pid);
if ($object) {
$repository = $object->repository;
} |
From here, all Fedora repository functionality supported by Tuque is available to you through $repository
. This functionality is described in the rest of this document.
As of Islandora 7.x, there is a wrapper object, IslandoraFedoraObject
, that handles some errors and fires some hooks in includes/tuque.inc. More error handling is available if one uses the wrapper functions in islandora.module.
Working with existing objects
Loading an object
Method | Code | On Success | On Fail |
---|
Tuque or Islandora, from aFedoraRepository | $object = $this->repository->getObject($pid); | Returns aFedoraObject loaded from the given $pid . | Throws a 'Not Found'RepositoryException . |
Islandora only, from anIslandoraFedoraRepository | $object = $this->repository->getObject($pid); | Returns anIslandoraFedoraObject loaded from the given$pid . | Throws a 'Not Found'RepositoryException . |
Islandora only, using the module itself | $object = islandora_object_load($pid); | Returns anIslandoraFedoraObject loaded from the given$pid . | Returns FALSE |
Because the third method returns FALSE on failure, you can check if the object loaded correctly using !$object
, e.g.:
Code Block |
---|
$object = islandora_object_load($pid);
if (!$object) {
/**
* Logic for object load failure would go here.
*/
return;
}
/**
* Logic for object load success would continue through the rest of the method here.
*/ |
In the case of the other two methods, try
to load the object and catch
the load failure exception, e.g.:
Code Block |
---|
try {
$object = $this->repository->getObject($pid);
}
catch (Exception $e) {
/**
* Logic for object load failure would go here.
*/
}
/**
* Logic for object load success would continue through the rest of the method here.
*/ |
Objects loaded via Tuque (either through Islandora or directly) have the following properties and can be manipulated using the following methods:
Properties
Name | Type | Description |
---|
createdDate | FedoraDate | The object's date of creation. |
forceUpdate | bool | Whether or not Tuque should respect Fedora object locking on this object (FALSE to uphold locking). Defaults to FALSE . |
id | string | The PID of the object. When constructing a new object, this can also be set to a namespace instead, to simply use the next available ID for that namespace. |
label | string | The object's label. |
lastModifiedDate | FedoraDate | When the object was last modified. |
logMessage | string | The log message associated with the creation of the object in Fedora. |
models | array | An array of content model PIDs (e.g. 'islandora:collectionCModel') applied to the object. |
owner | string | The object's owner. |
relationships | FedoraRelsExt | A FedoraRelsExt object allowing for working with the object's relationship metadata. This is described in another section below. |
repository | FedoraRepository | The FedoraRepository object this particular object was loaded from. This functions precisely the same as the $repository created in the "Accessing the repository" section above. |
state | string | The object's state (A/I/D). |
Methods
Name | Description | Parameters | Return Value |
---|
constructDatastream($id, $control_group) | Constructs an empty datastream. Note that this does not ingest a datastream into the object, but merely instantiates one as anAbstractDatastream object. Ingesting is done viaingestDatastream() , described below. | $id - the PID of the object; $control_group - the Fedora control group the datastream will belong to, whether Inline (X)ML, (M)anaged Content, (R)edirect, or (E)xternal Referenced. Defaults to 'M'. | An emptyAbstractDatastream object from the given information. |
count() | The number of datastreams this object contains. | None | The number of datastreams, as anint . |
delete() | Sets the object's state to 'D' (deleted). | None | None |
getDatastream($dsid) | Gets a datastream from the object based on its DSID. $object->getDatastream($dsid) works effectively the same as$object[$dsid] . | $dsid - the datastream identifier for the datastream to be loaded. | AnAbstractDatastream objeect representing the datastream that was gotten, orFALSE on failure. |
getParents() | Gets the IDs of the object's parents using itsisMemberOfCollection and isMemberOf relationships. | None | An array of PIDs of parent objects. |
ingestDatastream(&$abstract_datastream) | Takes a constructed datastream, with the properties you've given it, and ingests it into the object. This should be the last thing you do when creating a new datastream. | Technically takes$abstract_datastream as a parameter, but this should be passed to it by reference after constructing a datastream withconstructDatastream() . | A FedoraDatastream object representing the object that was just ingested. |
purgeDatastream($dsid) | Purges the datastream identified by the given DSID. | $dsid - The datastream identifier of the object. | TRUE on success,FALSE on failure. |
refresh() | Clears the object cache so that fresh information can be requested from Fedora. | None | None |
Purging an object
A loaded object can be purged from the repository using:
Code Block |
---|
$repository->purgeObject($object); |
Working with datastreams
Datastreams can be accessed from a loaded object like so:
Code Block |
---|
|
$datastream = $object['DSID']; |
Code Block |
---|
|
$datastream = islandora_datastream_load($dsid, $object); |
This loads the datastream as a FedoraDatastream
object. From there, it can be manipulated using the following properties and methods:where $dsid
is the datastream identifier as a string
, and $object
is a loaded Fedora object.
Properties
Name | Type | Description |
---|
checksum | string | The datastream's base64-encoded checksum. |
checksumType | string | The type of checksum for this datastream, either DISABLED, MD5, SHA-1, SHA-256, SHA-384, SHA-512. Defaults to DISABLED. |
content | string | The binary content of the datastream, as a string. Can be used to set the content directly if it is an (I)nternal or (M)anaged datastream. |
controlGroup | string | The control group for this datastream , whether Inline (X)ML, (M)anaged Content, (R)edirect, or (E)xternal Referenced.. |
createdDate | FedoraDate | The date the datastream was created. |
forceUpdate | bool | Whether or not Tuque should respect Fedora object locking on this datastream (FALSE to uphold locking). Defaults toFALSE . |
format | string | The format URI of the datastream, if it has one. This is rarely used, but does apply to RELS-EXT. |
id | string | The datastream identifier. |
label | string | The datastream label. |
location | string | A combination of the object ID, the DSID, and the DSID version ID. |
logMessage | string | The log message associated with actions in the Fedora audit datastream. |
mimetype | string | The datastream's mimetype. |
parent | AbstractFedoraObject | The object that the datastream was loaded from. |
relationships | FedoraRelsInt | The relationships that datastream holds internally within the object. |
repository | FedoraRepository | The FedoraRepository object this particular datastream was loaded from. This functions precisely the same as the$repository created in the "Accessing the repository" section above. |
size | int | The size of the datastream, in bytes. This is only available to ingested datastreams, not ones that have been constructed as objects but are yet to be ingested. |
state | string | The state of the datastream (A/I/D). |
url | string | The URL of the datastream, if it is a (R)edirected or (E)xternally-referrenced datastream. |
versionable | bool | Whether or not the datastream is versionable. |
Methods
Name | Description | Parameters | Return Value |
---|
count() | The number of revisions in the datastream's history. | None | An int representing the number of revisions in the datastream history. |
getContent() | Returns the binary content of the datastream. | None | A string representing the contents of the datastream. |
refresh() | Clears the object cache so that fresh information can be requested from Fedora. | None | None |
setContentFromFile($path) | Sets the content of a datastream from the contents of a local file. | $path - the path to the file to be used. | None |
setContentFromString($string) | Sets the content of a datastream from astring . | $string - the string to set the content from. | None |
setContentFromUrl($url) | Attempts to set the content of a datastream from content downloaded using a standatd HTTP request (NOT HTTPS). | $url - the URL to grab the data from. | None |
Iterating over all of an object's datastreams
Since they exist on an object as an array, datastreams can be iterated over using standard array iteration methods, e.g.:
Code Block |
---|
foreach ($object as $datastream) {
strtoupper($datastream->id);
$datastream->label = "new label";
$datastream_content = $datastream->getContent();
} |
Example of creating or updating a datastream
Code Block |
---|
$dsid = 'DSID';
// Before we do anything, check if the datastream exists. If it does, load it; otherwise construct it.
// The easiest way to do this, as opposed to a string of cases or if/then/elses, is the ternary operator, e.g.
// $variable = isThisThingTrueOrFalse($thing) ? setToThisIfTrue() : setToThisIfFalse();
$datastream = isset($object[$dsid]) ? $object[$dsid] : $object->constructDatastream($dsid);
$datastream->label = 'Datastream Label';
$datastream->mimeType = 'datastream/mimetype';
$datastream->setContentFromFile('path/to/file');
// There's no harm in doing this if the datastream is already ingested or if the object is only constructed.
$object->ingestDatastream($datastream);
// If the object IS only constructed, ingesting it here also ingests the datastream.
$repository->ingestObject($object); |
Creating new objects and datastreams
When using Tuque, Fedora objects and datastreams must first be constructed as PHP objects before being ingested into Fedora. Un-ingested, PHP-constructed Fedora objects and datastreams function nearly identically to their ingested counterparts, as far as Tuque is concerned, with only a few exceptions noted in the properties and methods tables below.
Constructing and ingesting an object
Code Block |
---|
title | Constructing and ingesting an object |
---|
|
$object = $repository->constructObject($pid); // $pid may also be a namespace.
/**
* Here, you can manipulate the constructed object using the properties and methods described above.
*/
$repository->ingestObject($object); |
Code Block |
---|
title | Constructing and ingesting a datastream |
---|
|
$datastream = $object->constructDatastream($dsid) // You may also set the $control_group.
/**
* Here, you can manipulate the constructed datastream using the properties and methods described above.
*/
$object->ingestDatastream($dsid, $object); |
Accessing an object's relationships
Once an object is loaded, its relationships can be accessed via the object's relationships
property:
Code Block |
---|
$relationships = $object->relationships; |
From there, the object's relationships can be viewed and manipulated using the following properties and methods:
Properties
Name | Type | Description |
---|
autoCommit | bool | Whether or not changes to the RELS should be automatically committed. WARNING: Probably don't touch this if you're not absolutely sure what you're doing. |
datastream | AbstractFedoraDatastream | The datastream that this relationship is manipulating, if any. |
Methods
Name | Description | Parameters | Return Value |
---|
add($predicate_uri, $predicate, $object, $type) | Adds a relationship to the object. | $predicate_uri - the namespace of the relationship predicate (if this is to be added via XML, use theregisterNamespace() function described below first);$predicate - the predicate tag to be added; $object - the object to add the relationship to (not required if this is called using$object->relationships->add() ); $type - the type of the attribute to add (defaults toRELS_TYPE_URI ). | None |
changeObjectID($id) | Changes the ID referenced in therdf:about attribute. | $id - the new ID to use. | None |
commitRelationships($set_auto_commit) | Forces the committal of any relationships cached while theautoCommit property was set toFALSE (or for whatever other reason). | $set_auto_commit - determines the state of autoCommit after this method is run (defaults to TRUE ). | None |
get($predicate_uri, $predicate, $object, $type) | Queries an object's relationships based on the parameters given. See below for an example of filtering relationships using parameters. | $predicate_uri - the URI to use as the namespace predicate, or NULL for any predicate (defaults to NULL );$predicate - the predicate tag to filter by, or 'NULL' for any tag (defaults toNULL ); $object - the object to filter the relationship by (not required if this is called using$object->relationships->get() ); $type - what typeRELS_TYPE_XXX attribute the retrieved should be (defaults toRELS_TYPE_URI ). | The relationships as anarray . See the note below for an example. |
registerNamespace($alias, $uri) | Registers a namespace to be used by predicate URIs. | $alias - the namespace alias;$uri - the URI to associate with that alias. | None |
remove($predicate_uri, $predicate, $object, $type) | Removes a relationship from the object. | $predicate_uri - the namespace of the relationship predicate to be removed, or NULL to ignore (defaults toNULL ); $predicate - the predicate tag to filter removed results by. or NULL to remove all (defaults to NULL ); $object - the object to add the relationship to (not required if this is called using$object->relationships->remove() ); $type - what typeRELS_TYPE_XXX attribute the removed should be (defaults toRELS_TYPE_URI ). | None |
Example of retrieving a filtered relationship
Code Block |
---|
$object_content_models = $object->relationships->get('info:fedora/fedora-system:def/model#', 'hasModel'); |
This would return an array containing only the object's hasModel
relationships.
Example of a retrieved relationship array
Code Block |
---|
Array
(
[0] => Array
(
|
All interaction with Fedora can now take place through the $repository object. D7 There are some wrapper functions that handle some errors and fire some hooks in islandora.module.
To build a new object:
Create array of ContentModels for the object. This will normally be a single element array:
Code Block |
---|
$content_models = array(array('pid' => 'islandora:collectionCModel')); |
Identify the namespace for the new pid, and identify the collection the object is to be a member of. Tuque will retrieve the next available PID in that namespace.
Code Block |
---|
$namespace = 'test';
$collection_pid = 'islandora:root'; |
Create the object using the factory method.
Code Block |
---|
module_load_include('inc', 'islandora', '/includes/islandora.ingest');
$fedora_object = islandora_ingest_get_object($content_models, $collection_pid, 'isMemberOf', $namespace); |
or create the object directly with tuque:
Code Block |
---|
$fedora_object = $repository->constructObject($namespace); // allow fedora to generate a PID |
or with a specified PID:
Code Block |
---|
$fedora_object = $repository->constructObject($pid); // create an object with the given PID |
Label the object
Code Block |
---|
$fedora_object->label = "my new object"; |
Set the owner
Code Block |
---|
$fedora_object->owner = $username; |
Build datastream
Code Block |
---|
$datastream_id = "TN";
$new_datastream = $fedora_object->constructDatastream($datastream_id); |
or
Code Block |
---|
$datastream_id = "MODS";
$controlGroup = "X";
$new_datastream = $fedora_object->constructDatastream($datastream_id, $controlGroup); |
Set label, mimetype, and content as a minimum. Content may come from url, string, or file
Code Block |
---|
$new_datastream->label = 'MYDSID';
$new_datastream->mimetype = 'something/something';
$new_datastream->setContentFromUrl(URL_TO_CONTENT); |
or
Code Block |
---|
$new_datastream->setContentFromFile(PATH_TO_CONTENT); |
or
Code Block |
---|
$new_datastream->setContentFromString("content"); |
Add datastream to object
Code Block |
---|
$fedora_object->ingestDatastream($new_datastream); |
Manipulate object’s RELS-EXT
Code Block |
---|
$fedora_object->relationships->remove(FEDORA_MODEL_URI, 'hasModel', 'islandora:collectionCModel');
$fedora_object->relationships->add(FEDORA_MODEL_URI, 'hasModel', 'islandora:imageCModel'); |
Ingest object into fedora repository
Code Block |
---|
$new_fedora_object = islandora_ingest_add_object($fedora_object); |
or ingest with existing repository object
Code Block |
---|
$repository->ingestObject($fedora_object); |
Working with existing objects.
Create object to access and manipulate existing Fedora object.
Code Block |
---|
$pid = "test:1";
$fedora_object = islandora_object_load($pid); |
or
Code Block |
---|
$fedora_object = $repository->getObject($pid); |
Object evaluates to FALSE if the Object doesn’t exist.
Code Block |
---|
if (!$fedora_object) {
drupal_set_message("Fedora Object isn't in the repo!");
} |
Purge Object from repository
Code Block |
---|
$fedora_object->repository->purgeObject($pid); |
or
Code Block |
---|
$repository->purgeObject($pid); |
Delete Object from repository
Code Block |
---|
$fedora_object->delete |
Accessing RELS_EXT
Returns an array of associative arrays representing all relationships.
Code Block |
---|
$rels = $fedora_object->relationships->get() |
Each array has two keys, each pointing to its own associative array of values.
...
...
...
isMemberOfCollection
[alias] => fedora |
...
[namespace] => info:fedora/fedora-system:def/ |
...
relations-external#
)
[object] => Array
|
...
...
FALSE
[value] => islandora: |
...
Returns array of relationships filtered by namespace and predicate
...
sp_basic_image_collection
)
)
[1] => Array
(
[predicate] => Array
(
[value] => hasModel
[alias] => fedora-model
[namespace] => info:fedora/fedora-system:def/model# |
...
Datastreams
Get all datastreams as an array
Code Block |
---|
$datastreams = $fedora_object->repository->api->a->listDatastreams($pid); |
Get individual datastream by DSID
Code Block |
---|
$datastream = $fedora_object['dsid']; |
Get properties of Datastream.
Code Block |
---|
$pid = $datastream->id; |
All datastream properties. Not case sensitive.
- label
- controlGroup
- versionable
- state
- mimetype
- format
- size
- checksum
- checksumType
- createdDate
- content
- url
- location
- logMessage
Iterate through datastreams in an object.
Code Block |
---|
foreach($fedora_object as $datastream){
// access individual datastreams.
} |
Properties can be accessed or mutated.
Code Block |
---|
$old_mime = $datastream->mimeType;
$datastream->mimeType = "new/mimetype";
$datastream->content = file_get_contents('http://myexample.com/sample.jpg')); |
Creating or updating a datastream that may or may not exist.
Code Block |
---|
// Create DS or grab it.
if (!isset($fedora_object["JP2"])) {
$jp2_ds = $fedora_object->constructDatastream('JP2', 'M');
}
else { $jp2_ds = $fedora_object["JP2"];
} $jp2_ds->label = 'Derived display JP2.';
$jp2_ds->mimeType = 'image/jp2';
// Don't copy the file. $jp2_ds->setContentFromFile($jp2_file, FALSE);
// May not need to be called if the DS already existed
$fedora_object->ingestDatastream($jp2_ds); |
Access Resource Index
)
[object] => Array
(
[literal] => FALSE
[value] => islandora:sp_basic_image
)
)
) |
Using the Fedora A and M APIs
Tuque can work with the Fedora repository's "Access" and "Manage" API services in much the same way one would using standard Fedora API requests. This functionality is mimicked using an instantiated $repository
's api
property.
Note that the methods above provide a much more PHP-friendly way of performing many of the tasks provided by API-A and API-M. They are nonetheless listed in full below for documentation purposes. When a method in this section and a method above share functionality (e.g. addRelationship()
here versus $repository->relationships->add()
above, or listDatastreams()
here versus foreach ($object as $datastream) { print_r($datastream); }
above), it is always recommended to use the method above, as we cannot predict the composition of the Fedora APIs in the future; if any Fedora functionality changes or is removed, your code may also lose functionality.
Documentation for the current version of each API can be found at:
Each API exists as a PHP object through Tuque, and can be created using:
Code Block |
---|
$api_a = $repository->api->a; // For an Access API.
$api_m = $repository->api->m; // For a Management API. |
From here, the functionality provided by each API mimics the functionality provided by the actual Fedora APIs, where the standard Fedora endpoints can be called as API object methods, e.g.:
Code Block |
---|
$datastreams = $api_a->listDatastreams('islandora:1'); |
The following methods are available for each type of API:
FedoraApiA
All of these return results described in an array.
Method | Description |
---|
describeRepository() | Returns repository information. |
findObjects($type, $query, $max_results, $display_fields) | Finds objects based on the input parameters. |
getDatastreamDissemination($pid, $dsid, $as_of_date_time, $file) | Gets the content of a datastream. |
getDissemination($pid, $sdef_pid, $method, $method_parameters) | Gets a dissemination based on the provided method. |
getObjectHistory($pid) | Gets the history of the specified object. |
getObjectProfile($pid, $as_of_date_time) | Gets the Fedora profile of an object. |
listDatastreams($pid, $as_of_date_time) | Lists an object's datastreams. |
listMethods($pid, $sdef_pid, $as_of_date_time) | Lists the methods that an object can use for dissemination. |
resumeFindObjects($session_token) | Resumes a findObjects() call that returned a resumption token. |
userAttributes() | Authenticates and provides information about a user's Fedora attributes. |
FedoraApiM
All of these return results described in an array.
Method | Description |
---|
addDatastream($pid, $dsid, $type, $file, $params) | Adds a datastream to the object specified. |
addRelationship($pid, $relationship, $is_literal, $datatype) | Adds a relationship to the object specified. |
export($pid, $params) | Exports information about an object. |
getDatastream($pid, $dsid, $params) | Returns information about the specified datastream. |
getDatastreamHistory($pid, $dsid) | Returns the datastream's history information. |
getNextPid($namespace, $numpids) | Gets a new, unused PID, incrementing Fedora's PID counter for that namespace. |
getObjectXml($pid) | Returns the object's FOXML. |
getRelationships($pid, $relationship) | Returns the object's relationships. |
ingest($params) | Ingests an object. |
modifyDatastream($pid, $dsid, $params) | Makes specified modifications to an object's datastream. |
modifyObject($pid, $params) | Makes specified modifications to an object. |
purgeDatastream($pid, $dsid, $params) | Purges the specified datastream. |
purgeObject($pid, $log_message) | Purges the specified object. |
upload($file) | Uploads a file to the server. |
validate($pid, $as_of_date_time) | Validates an object. |
Using the Resource Index
The resource index can be queried from the repository using:
Code Block |
---|
$ri = $repository->ri; |
From there, queries can be made to the resource index. It is generally best to use SPARQL queries for forwards compatibility:
Code Block |
---|
$itql_query_results = $ri->itqlQuery($query, $limit); // For an iTQL query.
$sparql_query_results = $ri->sparqlQuery($query, $limit); // For a SPARQL query. |
Methods
Method | Description | Parameters | Return Value |
---|
itqlQuery($query, $limit) | Executes an iTQL query to the resource index. | $query - a string containing the query parameters; $limit - an int representing the number of hits to return (defaults to -1 for unlimited). | An array containing query results. |
sparqlQuery($query, $limit) | Executes a SparQL query to the resource index. | $query - a string containing the query parameters; $limit - an int representing the number of hits to return (defaults to -1 for unlimited). | An array containing query results. |
...