@ -103,9 +103,14 @@ class Fedora_Item {
function add_datastream_from_file($datastream_file, $datastream_id, $datastream_label = NULL, $datastream_mimetype = '', $controlGroup = 'M', $logMessage = NULL) {
function add_datastream_from_file($datastream_file, $datastream_id, $datastream_label = NULL, $datastream_mimetype = '', $controlGroup = 'M', $logMessage = NULL) {
module_load_include('inc', 'fedora_repository', 'MimeClass');
module_load_include('inc', 'fedora_repository', 'MimeClass');
if (!is_file($datastream_file)) {
if (!is_file($datastream_file)) {
drupal_set_message("$datastream_file not found< br / > " , 'warning');
drupal_set_message(t('The datastream file %datastream_file could not found! (or is not a regular file...)', array('%datastream_file' => $datastream_file)) , 'warning');
return;
return;
}
}
elseif (!is_readable($datastream_file)) {
drupal_set_message(t('The datastream file %datastream_file could not be read! (likely due to permissions...)', array('%datastream_file' => $datastream_file)), 'warning');
return;
}
if (empty($datastream_mimetype)) {
if (empty($datastream_mimetype)) {
// Get mime type from the file extension.
// Get mime type from the file extension.
$mimetype_helper = new MimeClass();
$mimetype_helper = new MimeClass();
@ -214,43 +219,64 @@ class Fedora_Item {
/**
/**
* Add a relationship string to this object's RELS-EXT.
* Add a relationship string to this object's RELS-EXT.
*
* does not support rels-int yet.
* does not support rels-int yet.
* @param type $relationship
*
* @param type $object
* @param string $relationship
* @param type $namespaceURI
* The predicate/relationship tag to add
* @param string $object
* The object to be related to.
* @param string $namespaceURI
* The predicate namespace.
* @param boolean $literal_value
* Whether or not the object should be added as a URI (FALSE) or a literal (TRUE).
*/
*/
function add_relationship($relationship, $object, $namespaceURI = RELS_EXT_URI) {
function add_relationship($relationship, $object, $namespaceURI = RELS_EXT_URI, $literal_value = FALSE) {
//dd($this, 'The Fedora_Item');
$ds_list = $this->get_datastreams_list_as_array();
$ds_list = $this->get_datastreams_list_as_array();
$f_prefix = 'info:fedora/';
if (empty($ds_list['RELS-EXT'])) {
if (!array_key_exists('RELS-EXT', $ds_list)) {
$this->add_datastream_from_string(' < rdf:RDF xmlns:rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
$rdf_string = < < < RDF
< rdf:Description rdf:about = "info:fedora/' . $this->pid . '" >
< rdf:RDF xmlns:rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
< rdf:Description rdf:about = "$f_prefix{$this->pid}" >
< / rdf:Description >
< / rdf:Description >
< / rdf:RDF > ', 'RELS-EXT', 'Fedora object-to-object relationship metadata', 'text/xml', 'X');
< / rdf:RDF >
RDF;
$this->add_datastream_from_string($rdf_string, 'RELS-EXT', 'Fedora object-to-object relationship metadata', 'application/rdf+xml', 'X');
}
}
$relsext = $this->get_datastream_dissemination('RELS-EXT');
$relsext = $this->get_datastream_dissemination('RELS-EXT');
if (substr($object, 0, 12) != 'info:fedora/' ) {
if (!$literal_value & & strpos($object, $f_prefix) !== 0 ) {
$object = "info:fedora/$object" ;
$object = $f_prefix . $object ;
}
}
$relsextxml = new Dom Document();
$relsextxml = new DOM Document();
$relsextxml->loadXML($relsext);
$relsextxml->loadXML($relsext);
$description = $relsextxml->getElementsByTagNameNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'Description');
$description = $relsextxml->getElementsByTagNameNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'Description');
if ($description->length == 0) {
if ($description->length == 0) {
//XXX: This really shouldn't be done; lower case d doesn't fit the schema. Warn users to fix the data and generators, pending deprecation.
$description = $relsextxml->getElementsByTagNameNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'description');
$description = $relsextxml->getElementsByTagNameNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'description');
if ($description->length > 0) {
drupal_set_message(t('RDF with lower case "d" in "description" encountered. Should be uppercase! PID: %pid', array('%pid' => $this->pid)), 'warning');
}
}
}
$description = $description->item(0);
$description = $description->item(0);
// Create the new relationship node.
// Create the new relationship node.
$newrel = $relsextxml->createElementNS($namespaceURI, $relationship);
$newrel = $relsextxml->createElementNS($namespaceURI, $relationship);
$newrel->setAttribute('rdf:resource', $object);
if ($literal_value) {
$newrel->appendChild($relsextxml->createTextNode($object));
}
else {
$newrel->setAttribute('rdf:resource', $object);
}
$description->appendChild($newrel);
$description->appendChild($newrel);
$this->modify_datastream_by_value($relsextxml->saveXML(), 'RELS-EXT', "Fedora Object-to-Object Relationship Metadata", 'text/xml');
$this->modify_datastream($relsextxml->saveXML(), 'RELS-EXT', "Fedora Object-to-Object Relationship Metadata", 'application/rdf+xml');
//print ($description->dump_node());
//print ($description->dump_node());
/*
/*
$params = array( 'pid' => $this->pid,
$params = array( 'pid' => $this->pid,
@ -264,8 +290,55 @@ class Fedora_Item {
*/
*/
}
}
/**
* Purge/delete relationships string from this object's RELS-EXT.
*
* does not support rels-int yet.
*
* @param string $relationship
* The predicate/relationship tag to delete
* @param string $object
* The object to be related to. (NULL/value for which empty() evaluates to true will remove all relations of the given type, ignoring $literal_value)
* @param string $namespaceURI
* The predicate namespace.
* @param boolean $literal_value
* Whether or not the object should be looked for as a URI (FALSE) or a literal (TRUE).
* @return boolean
* Whether or not this operation has produced any changes in the RELS-EXT
*/
function purge_relationships($relationship, $object, $namespaceURI = RELS_EXT_URI, $literal_value = FALSE) {
$relsext = $this->get_datastream_dissemination('RELS-EXT');
$relsextxml = new DomDocument();
$relsextxml->loadXML($relsext);
$modified = FALSE;
$rels = $relsextxml->getElementsByTagNameNS($namespaceURI, $relationship);
if (!empty($rels)) {
foreach ($rels as $rel) {
if ( //If either no object is specified, or the object matches (in either the literal or URI case), remove this node from it's parent, and mark as changed.
empty($object) ||
(!$literal_value & & $rel->getAttributeNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'resource') == $object) ||
($literal_value & & $rel->textContent == $object)) {
$rel->parentNode->removeChild($rel);
$modified = TRUE;
}
}
}
//Save changes.
if ($modified) {
$this->modify_datastream($relsextxml->saveXML(), 'RELS-EXT', "Fedora Object-to-Object Relationship Metadata", 'text/xml');
}
//Return whether or not we've introduced any changes.
return $modified;
}
/**
/**
* Removes the given relationship from the item's RELS-EXT and re-saves it.
* Removes the given relationship from the item's RELS-EXT and re-saves it.
*
* @deprecated
* Dropped in favour of purge_relationships, which follows the same paradigm as add_relationship. This function tries to figure out the predicate URI based on the prefix/predicate given, which requires specific naming...
* @param string $relationship
* @param string $relationship
* @param string $object
* @param string $object
*/
*/
@ -300,7 +373,7 @@ class Fedora_Item {
break;
break;
}
}
if (substr($object, 0, 12) != 'info:fedora/') {
if (!empty($object) & & substr($object, 0, 12) != 'info:fedora/') {
$object = "info:fedora/$object";
$object = "info:fedora/$object";
}
}
@ -310,17 +383,16 @@ class Fedora_Item {
$rels = $relsextxml->getElementsByTagNameNS($namespaceURI, $relationship);
$rels = $relsextxml->getElementsByTagNameNS($namespaceURI, $relationship);
if (!empty($rels)) {
if (!empty($rels)) {
foreach ($rels as $rel) {
foreach ($rels as $rel) {
if ($rel->getAttributeNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'resource') == $object) {
if (empty($object) || $rel->getAttributeNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'resource') == $object) {
$rel->parentNode->removeChild($rel);
$rel->parentNode->removeChild($rel);
$modified = TRUE;
$modified = TRUE;
}
}
}
}
}
}
if ($modified) {
if ($modified) {
$this->modify_datastream_by_value ($relsextxml->saveXML(), 'RELS-EXT', "Fedora Object-to-Object Relationship Metadata", 'text/xml');
$this->modify_datastream($relsextxml->saveXML(), 'RELS-EXT', "Fedora Object-to-Object Relationship Metadata", 'text/xml');
}
}
return $modified;
return $modified;
//print ($description->dump_node());
}
}
/**
/**
@ -434,7 +506,7 @@ class Fedora_Item {
* @param type $as_of_date_time
* @param type $as_of_date_time
* @return type
* @return type
*/
*/
function get_datastream($dsid, $as_of_date_time = "" ) {
function get_datastream($dsid, $as_of_date_time = '' ) {
$params = array(
$params = array(
'pid' => $this->pid,
'pid' => $this->pid,
'dsID' => $dsid,
'dsID' => $dsid,
@ -530,7 +602,7 @@ class Fedora_Item {
* @return datastream object
* @return datastream object
* get the mimetype size etc. in one shot. instead of iterating throught the datastream list for what we need
* get the mimetype size etc. in one shot. instead of iterating throught the datastream list for what we need
*/
*/
function get_datastream_info($dsid, $as_of_date_time = "" ) {
function get_datastream_info($dsid, $as_of_date_time = '' ) {
$params = array(
$params = array(
'pid' => $this->pid,
'pid' => $this->pid,
'dsID' => $dsid,
'dsID' => $dsid,
@ -563,7 +635,7 @@ class Fedora_Item {
// datastream, instead of returning it as an array, only
// datastream, instead of returning it as an array, only
// the single item will be returned directly. We have to
// the single item will be returned directly. We have to
// check for this.
// check for this.
if (count($this->datastreams_list->datastreamDef) >= 2 ) {
if (count($this->datastreams_list->datastreamDef) > 1 ) {
foreach ($this->datastreams_list->datastreamDef as $ds) {
foreach ($this->datastreams_list->datastreamDef as $ds) {
if (!is_object($ds)) {
if (!is_object($ds)) {
print_r($ds);
print_r($ds);
@ -644,7 +716,7 @@ class Fedora_Item {
try {
try {
$relsext = $this->get_datastream_dissemination('RELS-EXT');
$relsext = $this->get_datastream_dissemination('RELS-EXT');
} catch (exception $e) {
} catch (exception $e) {
drupal_set_message(t("Error retrieving RELS-EXT of object $pid" ), 'error');
drupal_set_message(t('Error retrieving RELS-EXT of object %pid.', array('%pid' => $pid) ), 'error');
return $relationships;
return $relationships;
}
}
@ -668,30 +740,8 @@ class Fedora_Item {
}
}
function get_models() {
function get_models() {
$relationships = array();
//This is/was formerly just a copy/paste jobbie, without the parameter being passable...
try {
return $this->get_relationships();
$relsext = $this->get_datastream_dissemination('RELS-EXT');
} catch (exception $e) {
drupal_set_message(t("Error retrieving RELS-EXT of object $pid"), 'error');
return $relationships;
}
// Parse the RELS-EXT into an associative array.
$relsextxml = new DOMDocument();
$relsextxml->loadXML($relsext);
$relsextxml->normalizeDocument();
$mods = $relsextxml->getElementsByTagNameNS(FEDORA_MODEL_URI, '*');
foreach ($mods as $child) {
if (empty($relationship) || preg_match("/$relationship/", $child->tagName)) {
$relationships[] = array(
'subject' => $this->pid,
'predicate' => $child->tagName,
'object' => substr($child->getAttributeNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'resource'), 12),
);
}
}
return $relationships;
}
}
/**
/**
@ -790,8 +840,9 @@ class Fedora_Item {
* @return type
* @return type
*/
*/
function url() {
function url() {
global $base_url;
return url('fedora/repository/' . $this->pid . (!empty($this->objectProfile) ? '/-/' . drupal_urlencode($this->objectProfile->objLabel) : ''), array(
return $base_url . '/fedora/repository/' . $this->pid . (!empty($this->objectProfile) ? '/-/' . drupal_urlencode($this->objectProfile->objLabel) : '');
'absolute' => TRUE
));
}
}
/**
/**
@ -827,9 +878,14 @@ class Fedora_Item {
* @param type $foxml
* @param type $foxml
* @return Fedora_Item
* @return Fedora_Item
*/
*/
static function ingest_from_FOXML($foxml) {
static function ingest_from_FOXML(DOMDocument $foxml) {
$params = array('objectXML' => $foxml->saveXML(), 'format' => "info:fedora/fedora-system:FOXML-1.1", 'logMessage' => "Fedora Object Ingested");
$params = array(
'objectXML' => $foxml->saveXML(),
'format' => 'info:fedora/fedora-system:FOXML-1.1',
'logMessage' => 'Fedora Object Ingested'
);
$object = self::soap_call('ingest', $params);
$object = self::soap_call('ingest', $params);
//dd($object, 'Soap return');
return new Fedora_Item($object->objectPID);
return new Fedora_Item($object->objectPID);
}
}
@ -889,6 +945,69 @@ class Fedora_Item {
return self::soap_call('modifyObject', $params, $quiet);
return self::soap_call('modifyObject', $params, $quiet);
}
}
/**
* Wrap modify by value and reference
*
* Wrap modify by value and reference, so that the proper one gets called in the correct instance. (value if inline XML, reference otherwise)
*
* First tries to treat the passed in value as a filename, tries using as contents second.
* Coerces the data into what is required, and passes it on to the relevant function.
*
* @param string $filename_or_content
* Either a filename to add, or an string of content.
* @param string $dsid
* The DSID to update
* @param string $label
* A label to withwhich to update the datastream
* @param string $mime_type
* Mimetype for the data being pushed into the datastream
* @param boolean $force
* Dunno, refer to underlying functions/SOAP interface. We just pass it like a chump.
* @param string $logMessage
* A message for the audit log.
* @param boolean $quiet
* Error suppression? Refer to soap_call for usage (just passed along here).
*/
function modify_datastream($filename_or_content, $dsid, $label, $mime_type, $force = FALSE, $logMessage='Modified by Islandora API', $quiet=FALSE) {
//Determine if it's inline xml; if it is, modify by value
if ($this->get_datastream($dsid)->controlGroup === 'X') {
$content = '< null / > ';
if (is_file($filename_or_content) & & is_readable($filename_or_content)) {
$content = file_get_contents($filename_or_content);
}
else {
$content = $filename_or_content;
}
$this->modify_datastream_by_value($content, $dsid, $label, $mime_type, $force, $logMessage);
}
//Otherwise, write to web-accessible temp file and modify by reference.
else {
$file = '';
$created_temp = FALSE;
if (is_file($filename_or_content) & & is_readable($filename_or_content)) {
$file = $filename_or_content;
$original_path = $file;
// Temporarily move file to a web-accessible location.
file_copy($file, file_directory_path());
$created_temp = ($original_path != $file);
}
else {
//Push contents to a web-accessible file
$file = file_save_data($filename_or_content, file_directory_path());
$created_temp = TRUE;
}
$file_url = file_create_url($file);
$this->modify_datastream_by_reference($file_url, $dsid, $label, $mime_type, $force, $logMessage);
if ($created_temp & & is_file($file) & & is_writable($file)) {
file_delete($file);
}
}
}
/**
/**
* Modify datastream by reference
* Modify datastream by reference
* @param type $external_url
* @param type $external_url
@ -976,9 +1095,11 @@ class Fedora_Item {
module_load_include('inc', 'fedora_repository', 'ConnectionHelper');
module_load_include('inc', 'fedora_repository', 'ConnectionHelper');
self::$connection_helper = new ConnectionHelper();
self::$connection_helper = new ConnectionHelper();
}
}
$url = (array_search($function, self::$SoapManagedFunctions) !== FALSE) ?
$url = (
in_array($function, self::$SoapManagedFunctions)?
variable_get('fedora_soap_manage_url', 'http://localhost:8080/fedora/wsdl?api=API-M') :
variable_get('fedora_soap_manage_url', 'http://localhost:8080/fedora/wsdl?api=API-M') :
variable_get('fedora_soap_url', 'http://localhost:8080/fedora/services/access?wsdl');
variable_get('fedora_soap_url', 'http://localhost:8080/fedora/services/access?wsdl')
);
try {
try {
$soap_client = self::$connection_helper->getSoapClient($url);
$soap_client = self::$connection_helper->getSoapClient($url);
if (isset($soap_client)) {
if (isset($soap_client)) {
@ -1029,25 +1150,23 @@ class Fedora_Item {
}
}
}
}
$root_element = $foxml->createElement("foxml:digitalObject");
$root_element = $foxml->createElementNS ("info:fedora/fedora-system:def/foxml#", "foxml:digitalObject");
$root_element->setAttribute("VERSION", "1.1");
$root_element->setAttribute("VERSION", "1.1");
$root_element->setAttribute("PID", $pid);
$root_element->setAttribute("PID", $pid);
$root_element->setAttribute("xmlns:foxml", "info:fedora/fedora-system:def/foxml#");
$root_element->setAttributeNS("http://www.w3.org/2001/XMLSchema-instance", "xsi:schemaLocation", "info:fedora/fedora-system:def/foxml# http://www.fedora.info/definitions/1/0/foxml1-1.xsd");
$root_element->setAttribute("xmlns:xsl", "http://www.w3.org/2001/XMLSchema-instance");
$root_element->setAttribute("xsl:schemaLocation", "info:fedora/fedora-system:def/foxml# http://www.fedora.info/definitions/1/0/foxml1-1.xsd");
$foxml->appendChild($root_element);
$foxml->appendChild($root_element);
// FOXML object properties section
// FOXML object properties section
$object_properties = $foxml->createElement("foxml:objectProperties");
$object_properties = $foxml->createElementNS ("info:fedora/fedora-system:def/foxml#", "foxml:objectProperties");
$state_property = $foxml->createElement("foxml:property");
$state_property = $foxml->createElementNS ("info:fedora/fedora-system:def/foxml#", "foxml:property");
$state_property->setAttribute("NAME", "info:fedora/fedora-system:def/model#state");
$state_property->setAttribute("NAME", "info:fedora/fedora-system:def/model#state");
$state_property->setAttribute("VALUE", $state);
$state_property->setAttribute("VALUE", $state);
$label_property = $foxml->createElement("foxml:property");
$label_property = $foxml->createElementNS ("info:fedora/fedora-system:def/foxml#", "foxml:property");
$label_property->setAttribute("NAME", "info:fedora/fedora-system:def/model#label");
$label_property->setAttribute("NAME", "info:fedora/fedora-system:def/model#label");
$label_property->setAttribute("VALUE", $label);
$label_property->setAttribute("VALUE", $label);
$owner_property = $foxml->createElement("foxml:property");
$owner_property = $foxml->createElementNS ("info:fedora/fedora-system:def/foxml#", "foxml:property");
$owner_property->setAttribute("NAME", "info:fedora/fedora-system:def/model#ownerId");
$owner_property->setAttribute("NAME", "info:fedora/fedora-system:def/model#ownerId");
$owner_property->setAttribute("VALUE", $owner);
$owner_property->setAttribute("VALUE", $owner);
@ -1056,7 +1175,6 @@ class Fedora_Item {
$object_properties->appendChild($owner_property);
$object_properties->appendChild($owner_property);
$root_element->appendChild($object_properties);
$root_element->appendChild($object_properties);
$foxml->appendChild($root_element);
$foxml->appendChild($root_element);
return $foxml;
return $foxml;
}
}