diff --git a/CollectionClass.inc b/CollectionClass.inc index 30035594..27a497d7 100644 --- a/CollectionClass.inc +++ b/CollectionClass.inc @@ -5,6 +5,11 @@ * * Collection Class Class */ + +if (!defined('PHP_VERSION_ID')) { //XXX: This should go elsewhere + $version = explode('.', PHP_VERSION); + define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2])); +} /** * This CLASS caches the streams so once you call a getstream once it will always return @@ -500,10 +505,11 @@ class CollectionClass { */ function showFieldSets($page_number) { module_load_include('inc', 'fedora_repository', 'api/fedora_item'); - module_load_include('inc', 'fedora_repository', 'CollectionManagement'); - module_load_include('inc', 'fedora_repository', 'BatchIngest'); + module_load_include('inc', 'fedora_repository', 'CollectionPolicy'); + //module_load_include('inc', 'fedora_repository', 'BatchIngest'); //Legacy code? global $base_url; global $user; + $tabset = array(); $query = NULL; $item = new Fedora_Item($this->pid); @@ -513,10 +519,7 @@ class CollectionClass { $results = $this->getRelatedItems($this->pid, $query); $collection_items = $this->renderCollection($results, $this->pid, NULL, NULL, $page_number); - $collection_item = new Fedora_Item($this->pid); - // Check the form post to see if we are in the middle of an ingest operation. - $show_ingest_tab = (!empty($_POST['form_id']) && $_POST['form_id'] == 'fedora_repository_ingest_form'); - $add_to_collection = $this->getIngestInterface(); + //$collection_item = new Fedora_Item($this->pid); //XXX: This didn't seem to be used... $show_batch_tab = FALSE; $policy = CollectionPolicy::loadFromCollection($this->pid, TRUE); @@ -527,39 +530,42 @@ class CollectionClass { if (count($content_models) == 1 && $content_models[0]->pid == "islandora:collectionCModel") { $show_batch_tab = FALSE; } - if (!$show_ingest_tab) { - $view_selected = TRUE; - } - if (!$collection_items) { - $view_selected = FALSE; - $add_selected = TRUE; - } - $view_selected = !$show_ingest_tab; - + + // Check the form post to see if we are in the middle of an ingest operation. + $add_selected = ((!empty($_POST['form_id']) && $_POST['form_id'] == 'fedora_repository_ingest_form') || !$collection_items); + $view_selected = !$add_selected; $tabset['view_tab'] = array( '#type' => 'tabpage', - '#title' => 'View', + '#title' => t('View'), '#selected' => $view_selected, '#content' => $collection_items, + '#tab_name' => 'view-tab', ); - $tabset['add_tab'] = array( - '#type' => 'tabpage', - '#title' => t('Add'), - '#selected' => $add_selected, - // This will be the content of the tab. - '#content' => $add_to_collection, - ); - - if ($show_batch_tab && user_access('create batch process')) { + + $add_to_collection = $this->getIngestInterface(); + if (!empty($add_to_collection)) { + $tabset['add_tab'] = array( + '#type' => 'tabpage', + '#title' => t('Add'), + '#selected' => $add_selected, + // This will be the content of the tab. + '#content' => $add_to_collection, + '#tab_name' => 'add-tab', + ); + } + + if ($show_batch_tab && user_access('create batch process')) { //XXX: Is this not put in by the batch module? $tabset['batch_ingest_tab'] = array( // #type and #title are the minimum requirements. '#type' => 'tabpage', '#title' => t('Batch Ingest'), // This will be the content of the tab. '#content' => drupal_get_form('batch_creation_form', $this->pid, $content_models), + '#tab_name' => 'batch-ingest-tab', ); } + return $tabset; } @@ -622,7 +628,7 @@ class CollectionClass { $pageNumber = 1; } - if (!isset($collectionName)) { + if (empty($collectionName)) { $collectionName = variable_get('fedora_repository_name', 'Collection'); } $xslContent = $this->getXslContent($pid, $path); @@ -636,11 +642,23 @@ class CollectionClass { if ($results->length > 0) { try { $proc = new XsltProcessor(); - $proc->setParameter('', 'collectionPid', $collection_pid); - $proc->setParameter('', 'collectionTitle', $collectionName); - $proc->setParameter('', 'baseUrl', $base_url); - $proc->setParameter('', 'path', $base_url . '/' . $path); - $proc->setParameter('', 'hitPage', $pageNumber); + $options = array( //Could make this the return of a hook? + 'collectionPid' => $collection_pid, + 'collectionTitle' => $collectionName, + 'baseUrl' => $base_url, + 'path' => "$base_url/$path", + 'hitPage' => $pageNumber, + ); + + if (defined('PHP_VERSION_ID') && PHP_VERSION_ID >= 50100) { + $proc->setParameter('', $options); + } + else { + foreach ($options as $name => $value) { + $proc->setParameter('', $name, $value); + } + } + $proc->registerPHPFunctions(); $xsl = new DomDocument(); $xsl->loadXML($xslContent); @@ -657,13 +675,13 @@ class CollectionClass { throw new Exception("Invalid XML."); } } catch (Exception $e) { - drupal_set_message(t('@e', array('@e' => check_plain($e->getMessage()))), 'error'); + drupal_set_message(check_plain($e->getMessage()), 'error'); return ''; } } } else { - drupal_set_message(t("No Objects in this collection or bad query.")); + drupal_set_message(t("No objects in this collection (or bad query).")); } return $objectList; } diff --git a/CollectionPolicy.inc b/CollectionPolicy.inc index 9b0af861..71d95a6c 100644 --- a/CollectionPolicy.inc +++ b/CollectionPolicy.inc @@ -44,7 +44,12 @@ class CollectionPolicy extends XMLDatastream { if ($preFetch) { $fedoraItem = new Fedora_Item($pid); - $ds = $fedoraItem->get_datastream_dissemination($dsid); + if (array_key_exists($dsid, $fedoraItem->get_datastreams_list_as_array())) { + $ds = $fedoraItem->get_datastream_dissemination($dsid); + } + else { //No collection policy stream (of the default name, anyway) + return FALSE; + } } else { $ds = NULL; @@ -55,7 +60,6 @@ class CollectionPolicy extends XMLDatastream { $ret = new CollectionPolicy($ds, $pid, $dsid); } } catch (SOAPException $e) { - $ret = FALSE; } return $ret; diff --git a/ConnectionHelper.inc b/ConnectionHelper.inc index 4dce9a0d..a385199c 100644 --- a/ConnectionHelper.inc +++ b/ConnectionHelper.inc @@ -63,11 +63,12 @@ class ConnectionHelper { //anonymous user. We will need an entry in the fedora users.xml file //with the appropriate entry for a username of anonymous password of anonymous try { - $client = new SoapClient($this->_fixURL($url, 'anonymous', 'anonymous'), array( - 'login' => 'anonymous', - 'password' => 'anonymous', - 'exceptions' => $exceptions, - )); + $client = new SoapClient($url, array( + 'login' => 'anonymous', + 'password' => 'anonymous', + 'exceptions' => $exceptions, + 'authentication' => SOAP_AUTHENTICATION_BASIC + )); } catch (SoapFault $e) { drupal_set_message(t('@e', array('@e' => check_plain($e->getMessage())))); return NULL; @@ -75,11 +76,13 @@ class ConnectionHelper { } else { try { - $client = new SoapClient($this->_fixURL($url, $user->name, $user->pass), array( - 'login' => $user->name, - 'password' => $user->pass, - 'exceptions' => TRUE, - )); + $client = new SoapClient($url, array( + 'login' => $user->name, + 'password' => $user->pass, + 'exceptions' => TRUE, + 'authentication' => SOAP_AUTHENTICATION_BASIC, + 'cache_wsdl' => WSDL_CACHE_MEMORY + )); } catch (SoapFault $e) { drupal_set_message(t('@e', array('@e' => check_plain($e->getMessage())))); return NULL; diff --git a/ObjectHelper.inc b/ObjectHelper.inc index 31a0ccd2..3c6ed8dc 100644 --- a/ObjectHelper.inc +++ b/ObjectHelper.inc @@ -138,7 +138,7 @@ class ObjectHelper { curl_setopt($ch, CURLOPT_USERPWD, "$fedoraUser:$fedoraPass"); // There seems to be a bug in Fedora 3.1's REST authentication, removing this line fixes the authorization denied error. // curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0); // return into a variable + curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); // return into a variable curl_setopt($ch, CURLOPT_URL, $url); @@ -150,7 +150,6 @@ class ObjectHelper { fclose($fp); } else { - header("Content-type: $mimeType"); if ($contentSize > 0) { header("Content-length: $contentSize"); @@ -181,12 +180,38 @@ class ObjectHelper { header('Content-Disposition: attachment; filename="' . $suggestedFileName . '"'); } - if ((isset($user) && $user->uid != 0) || $forceSoap || isset($_SERVER['HTTPS'])) { - curl_exec($ch); + curl_setopt($ch, CURLOPT_NOBODY, TRUE); + $curl_out = curl_exec($ch); + if ($curl_out !== FALSE) { + $info = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); + //dd($info, 'effective URL'); + if ($url !== $info) { //Handle redirect streams (the final URL is not the same as the Fedora URL) + + //Add the parameters passed to Drupal, leaving out the 'q' + $query = array(); + parse_str($_SERVER['QUERY_STRING'], $query); + if (isset($query['q'])) { + unset($query['q']); + } + + header('HTTP/1.1 307 Moved Temporarily'); + header('Location: ' . $info . '?' . http_build_query($query)); //Fedora seems to discard the query portion. + } + elseif ((isset($user) && $user->uid != 0) || $forceSoap || isset($_SERVER['HTTPS'])) { //If not anonymous, soap is force or we're using HTTPS + //Have the webserver mediate the transfer (download and restream) + + curl_setopt($ch, CURLOPT_NOBODY, FALSE); + curl_setopt($ch, CURLOPT_HTTPGET, TRUE); //CURLOPT_NOBODY sets it to 'HEAD' + $toReturn = curl_exec($ch); + echo $toReturn; + } + else { + header('Location: ' . $url); + } } else { - header('Location: ' . $url); - } + //Curl error... + } } curl_close($ch); } @@ -929,14 +954,14 @@ class ObjectHelper { } else { $query_string = 'select $parentObject $title $content from <#ri> - where ( $title - and $parentObject $content - and ( $parentObject - or $parentObject - or $parentObject) - and $parentObject ) - minus $content - order by $title desc'; + where ( $title + and $parentObject $content + and ( $parentObject + or $parentObject + or $parentObject) + and $parentObject ) + minus $content + order by $title desc'; $query_string = htmlentities(urlencode($query_string)); $url = variable_get('fedora_repository_url', 'http://localhost:8080/fedora/risearch'); diff --git a/api/fedora_item.inc b/api/fedora_item.inc index 50330d6a..279a3e51 100644 --- a/api/fedora_item.inc +++ b/api/fedora_item.inc @@ -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) { module_load_include('inc', 'fedora_repository', 'MimeClass'); if (!is_file($datastream_file)) { - drupal_set_message("$datastream_file not found
", '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; } + 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)) { // Get mime type from the file extension. $mimetype_helper = new MimeClass(); @@ -214,43 +219,64 @@ class Fedora_Item { /** * Add a relationship string to this object's RELS-EXT. + * * does not support rels-int yet. - * @param type $relationship - * @param type $object - * @param type $namespaceURI + * + * @param string $relationship + * 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(); - - if (empty($ds_list['RELS-EXT'])) { - $this->add_datastream_from_string(' - + $f_prefix = 'info:fedora/'; + if (!array_key_exists('RELS-EXT', $ds_list)) { + $rdf_string = << + - ', 'RELS-EXT', 'Fedora object-to-object relationship metadata', 'text/xml', 'X'); + +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'); - - if (substr($object, 0, 12) != 'info:fedora/') { - $object = "info:fedora/$object"; + + if (!$literal_value && strpos($object, $f_prefix) !== 0) { + $object = $f_prefix . $object; } - $relsextxml = new DomDocument(); + $relsextxml = new DOMDocument(); $relsextxml->loadXML($relsext); $description = $relsextxml->getElementsByTagNameNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'Description'); 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'); + 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); // Create the new relationship node. $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); - $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()); /* $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. + * + * @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 $object */ @@ -300,7 +373,7 @@ class Fedora_Item { break; } - if (substr($object, 0, 12) != 'info:fedora/') { + if (!empty($object) && substr($object, 0, 12) != 'info:fedora/') { $object = "info:fedora/$object"; } @@ -310,17 +383,16 @@ class Fedora_Item { $rels = $relsextxml->getElementsByTagNameNS($namespaceURI, $relationship); if (!empty($rels)) { 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); $modified = TRUE; } } } 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; - //print ($description->dump_node()); } /** @@ -434,7 +506,7 @@ class Fedora_Item { * @param type $as_of_date_time * @return type */ - function get_datastream($dsid, $as_of_date_time = "") { + function get_datastream($dsid, $as_of_date_time = '') { $params = array( 'pid' => $this->pid, 'dsID' => $dsid, @@ -530,7 +602,7 @@ class Fedora_Item { * @return datastream object * 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( 'pid' => $this->pid, 'dsID' => $dsid, @@ -563,7 +635,7 @@ class Fedora_Item { // datastream, instead of returning it as an array, only // the single item will be returned directly. We have to // check for this. - if (count($this->datastreams_list->datastreamDef) >= 2) { + if (count($this->datastreams_list->datastreamDef) > 1) { foreach ($this->datastreams_list->datastreamDef as $ds) { if (!is_object($ds)) { print_r($ds); @@ -644,7 +716,7 @@ class Fedora_Item { try { $relsext = $this->get_datastream_dissemination('RELS-EXT'); } 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; } @@ -668,30 +740,8 @@ class Fedora_Item { } function get_models() { - $relationships = array(); - try { - $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; + //This is/was formerly just a copy/paste jobbie, without the parameter being passable... + return $this->get_relationships(); } /** @@ -790,8 +840,9 @@ class Fedora_Item { * @return type */ function url() { - global $base_url; - return $base_url . '/fedora/repository/' . $this->pid . (!empty($this->objectProfile) ? '/-/' . drupal_urlencode($this->objectProfile->objLabel) : ''); + return url('fedora/repository/' . $this->pid . (!empty($this->objectProfile) ? '/-/' . drupal_urlencode($this->objectProfile->objLabel) : ''), array( + 'absolute' => TRUE + )); } /** @@ -827,9 +878,14 @@ class Fedora_Item { * @param type $foxml * @return Fedora_Item */ - static function ingest_from_FOXML($foxml) { - $params = array('objectXML' => $foxml->saveXML(), 'format' => "info:fedora/fedora-system:FOXML-1.1", 'logMessage' => "Fedora Object Ingested"); + static function ingest_from_FOXML(DOMDocument $foxml) { + $params = array( + 'objectXML' => $foxml->saveXML(), + 'format' => 'info:fedora/fedora-system:FOXML-1.1', + 'logMessage' => 'Fedora Object Ingested' + ); $object = self::soap_call('ingest', $params); + //dd($object, 'Soap return'); return new Fedora_Item($object->objectPID); } @@ -889,6 +945,69 @@ class Fedora_Item { 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 = ''; + 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 * @param type $external_url @@ -976,9 +1095,11 @@ class Fedora_Item { module_load_include('inc', 'fedora_repository', '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_url', 'http://localhost:8080/fedora/services/access?wsdl'); + variable_get('fedora_soap_url', 'http://localhost:8080/fedora/services/access?wsdl') + ); try { $soap_client = self::$connection_helper->getSoapClient($url); 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("PID", $pid); - $root_element->setAttribute("xmlns:foxml", "info:fedora/fedora-system:def/foxml#"); - $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"); + $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"); $foxml->appendChild($root_element); // FOXML object properties section - $object_properties = $foxml->createElement("foxml:objectProperties"); - $state_property = $foxml->createElement("foxml:property"); + $object_properties = $foxml->createElementNS("info:fedora/fedora-system:def/foxml#", "foxml:objectProperties"); + $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("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("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("VALUE", $owner); @@ -1056,7 +1175,6 @@ class Fedora_Item { $object_properties->appendChild($owner_property); $root_element->appendChild($object_properties); $foxml->appendChild($root_element); - return $foxml; } diff --git a/fedora_repository.module b/fedora_repository.module index 06d220c7..abec4b9e 100644 --- a/fedora_repository.module +++ b/fedora_repository.module @@ -146,14 +146,13 @@ function fedora_repository_ingest_form_submit(array $form, array &$form_state) { $form_state['submitted'] = FALSE; return; } - if ($form_state['storage']['xml']) { - if (module_exists('islandora_content_model_forms')) { - module_load_include('inc', 'islandora_content_model_forms', 'IngestObjectMetadataForm'); - $xml_form = new IngestObjectMetadataForm(); - $xml_form->submit($form, $form_state); - } + //ddebug_backtrace(); + if ($form_state['storage']['xml'] && module_exists('islandora_content_model_forms')) { + module_load_include('inc', 'islandora_content_model_forms', 'IngestObjectMetadataForm'); + $xml_form = new IngestObjectMetadataForm(); + $xml_form->submit($form, $form_state); } - elseif ($form_state['clicked_button']['#id'] == 'edit-submit') { + elseif (strpos($form_state['clicked_button']['#id'], 'edit-submit') === 0) { global $base_url; module_load_include('inc', 'fedora_repository', 'CollectionClass'); module_load_include('inc', 'fedora_repository', 'CollectionPolicy'); @@ -188,7 +187,7 @@ function fedora_repository_ingest_form_submit(array $form, array &$form_state) { } if ($redirect) { - $form_state['redirect'] = ($err) ? ' ' : $base_url . "/fedora/repository/{$form_state['values']['collection_pid']}"; + $form_state['redirect'] = ($err) ? ' ' : url("fedora/repository/{$form_state['values']['collection_pid']}"); } } } @@ -205,7 +204,7 @@ function fedora_repository_ingest_form_validate($form, &$form_state) { $form_state['submitted'] = FALSE; return; } - if ($form_state['clicked_button']['#id'] == 'edit-submit' && $form_state['ahah_submission'] != 1) { + if (strpos($form_state['clicked_button']['#id'], 'edit-submit') === 0 && $form_state['ahah_submission'] != 1) { switch ($form_state['storage']['step']) { case 1: $form_state['storage']['step']++; @@ -286,7 +285,8 @@ function fedora_repository_ingest_form(&$form_state, $collection_pid, $collectio $ingestForm = new formClass(); $form_state['storage']['content_model'] = $content_model; $form_state['storage']['collection_pid'] = $collection_pid; - return $ingestForm->createIngestForm($collection_pid, $collection_label, $form_state); + $form = $ingestForm->createIngestForm($collection_pid, $collection_label, $form_state); + return $form; } /** @@ -771,13 +771,6 @@ function fedora_repository_edit_qdc_form(&$form_state, $pid, $dsId = NULL) { $client = $soapHelper->getSoapClient(variable_get('fedora_soap_url', 'http://localhost:8080/fedora/services/access?wsdl')); // Check if there is a custom edit metadata function defined in the content model. - - $breadcrumbs = array(); - $objectHelper = new ObjectHelper(); - $objectHelper->getBreadcrumbs($pid, $breadcrumbs); - drupal_set_breadcrumb(array_reverse($breadcrumbs)); - - $output = ''; if (($cm = ContentModel::loadFromObject($pid)) !== FALSE) { $output = $cm->buildEditMetadataForm($pid, $dsId); @@ -821,7 +814,7 @@ function fedora_repository_edit_qdc_form_validate($form, &$form_state) { function fedora_repository_edit_qdc_form_submit($form, &$form_state) { if ($form_state['storage']['xml']) { module_load_include('inc', 'islandora_content_model_forms', 'EditObjectMetadataForm'); - $xml_form = new EditObjectMetadataForm($form_state); + $xml_form = new EditObjectMetadataForm(); $xml_form->submit($form, $form_state); } else { @@ -1047,6 +1040,7 @@ function fedora_repository_get_items($pid = NULL, $dsId = NULL, $collection = NU /** * fedora repository urlencode string + * FIXME: URL-encoding is not the same as HTML/XML encoding... * @param type $str * @return type */ @@ -1722,7 +1716,7 @@ function fedora_repository_required_fedora_objects() { 'pid' => 'islandora:collectionCModel', 'label' => 'Islandora Collection Content Model', 'dsid' => 'ISLANDORACM', - 'datastream_file' => "$module_path/content_models/COLLECTIONCM.xml", + 'datastream_file' => "./$module_path/content_models/COLLECTIONCM.xml", 'dsversion' => 2, 'cmodel' => 'fedora-system:ContentModel-3.0', ), @@ -1733,11 +1727,11 @@ function fedora_repository_required_fedora_objects() { 'datastreams' => array( array( 'dsid' => 'COLLECTION_POLICY', - 'datastream_file' => "$module_path/collection_policies/COLLECTION-COLLECTION POLICY.xml", + 'datastream_file' => "./$module_path/collection_policies/COLLECTION-COLLECTION POLICY.xml", ), array( 'dsid' => 'TN', - 'datastream_file' => "$module_path/images/Gnome-emblem-photos.png", + 'datastream_file' => "./$module_path/images/Gnome-emblem-photos.png", 'mimetype' => 'image/png', ), ), @@ -2169,56 +2163,68 @@ function fedora_repository_batch_reingest_object($object, &$context) { module_load_include('inc', 'fedora_repository', 'api/fedora_item'); module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); - + if (!empty($object) && is_array($object)) { $pid = $object['pid']; if (!valid_pid($pid)) { return NULL; } -// Does the object exist? If so, purge it. + // Does the object exist? If so, purge it. + //dd("About to test existence of PID: $pid"); $item = new Fedora_Item($pid); if ($item->exists()) { + //dd(' Found'); $item->purge(t('Remove during re-install batch job')); + //dd(' Purged'); } + $new_item = NULL; //Need to have this a couple places... (After trying from FOXML and later for individual DSs) + $datastreams = array(); //Seems like this might be getting messed up due to scope? + // Ingest the object from the source file. if (!empty($object['foxml_file'])) { $foxml_file = $object['foxml_file']; $new_item = Fedora_Item::ingest_from_FOXML_file($foxml_file); if ($new_item->exists()) { -// Batch operation was successful. - $context['message'][] = "$new_item->pid installed."; +// Batch operation was successful; can still add additional DSs, though + $context['message'][] = t('%pid installed.', array('%pid' => $new_item->pid)); } } if (!empty($object['dsid']) && !empty($object['datastream_file'])) { - $datastreams = array( - array( - 'dsid' => $object['dsid'], - 'datastream_file' => $object['datastream_file'], - ) + $datastreams[] = array( + 'dsid' => $object['dsid'], + 'datastream_file' => $object['datastream_file'], ); } elseif (!empty($object['datastreams'])) { $datastreams = $object['datastreams']; } - if (!empty($datastreams) && is_array($datastreams)) { - - $label = !empty($object['label']) ? $object['label'] : ''; - - if (empty($object['foxml_file']) && !isset($new_item)) { - $new_item = Fedora_Item::ingest_new_item($object['pid'], 'A', $label); - } - + $label = !empty($object['label']) ? $object['label'] : ''; + if (!isset($new_item)) { + //dd(' Not found, creating'); + $new_item = Fedora_Item::ingest_new_item($pid, 'A', $label); + //dd(' Created'); + } + elseif (!empty($label)) { + $new_item->modify_object($label); + } + + if (isset($new_item)) { if (!empty($object['cmodel'])) { + //dd(' relating to cmodel'); $new_item->add_relationship('hasModel', $object['cmodel'], FEDORA_MODEL_URI); + //dd(' related to cmodel'); } if (!empty($object['parent'])) { + //dd(' adding parent'); $new_item->add_relationship('isMemberOfCollection', $object['parent']); + //dd(' parent added'); } - foreach ($datastreams as $ds) { + foreach ((array)$datastreams as $ds) { + //dd("trying to add ds: {$ds['dsid']}"); if ($ds['dsid'] == 'DC') { $new_item->modify_datastream_by_value(file_get_contents($ds['datastream_file']), $ds['dsid'], $ds['label'], 'text/xml'); } @@ -2242,22 +2248,17 @@ function fedora_repository_batch_reingest_object($object, &$context) { */ function fedora_repository_get_islandora_datastream_version($item = NULL, $dsid = NULL, $datastream_file = NULL) { $return = NULL; - if (isset($item)) { + if (!empty($item) && !empty($dsid)) { $doc = simplexml_load_string($item->get_datastream_dissemination($dsid)); } - elseif (isset($datastream_file)) { + elseif (!empty($datastream_file)) { $doc = simplexml_load_file($datastream_file); } - - if (!empty($doc)) { - $attrs = $doc->attributes(); - foreach ($attrs as $name => $value) { - if ($name == 'version') { - $return = (int) $value; - break; - } - } + + if (!empty($doc) && $version = (int)$doc->attributes()->version) { + $return = $version; } + return $return; } diff --git a/fedora_repository.solutionpacks.inc b/fedora_repository.solutionpacks.inc index efc7cd9d..b6c40412 100644 --- a/fedora_repository.solutionpacks.inc +++ b/fedora_repository.solutionpacks.inc @@ -110,10 +110,11 @@ function fedora_repository_solution_pack_form(&$form_state, $solution_pack_modul $object_status = 'Missing datastream'; break; } - if (isset($ds['dsversion'])) { + elseif (isset($ds['dsversion'])) { // Check if the datastream is versioned and needs updating. $installed_version = fedora_repository_get_islandora_datastream_version($item, $ds['dsid']); $available_version = fedora_repository_get_islandora_datastream_version(NULL, NULL, $ds['datastream_file']); + if ($available_version > $installed_version) { $needs_update = TRUE; $object_status = 'Out of date'; @@ -165,8 +166,8 @@ function fedora_repository_solution_pack_form_submit($form, &$form_state) { $module_name = $form_state['values']['solution_pack_module']; // This should be replaced with module_invoke - $solution_pack_info = call_user_func($module_name . '_required_fedora_objects'); - //$solution_pack_info = module_invoke($module_name, 'required_fedora_objects'); + //$solution_pack_info = call_user_func($module_name . '_required_fedora_objects'); + $solution_pack_info = module_invoke($module_name, 'required_fedora_objects'); $batch = array( 'title' => t('Installing / updating solution pack objects'), diff --git a/formClass.inc b/formClass.inc index 8512fd61..c1122182 100644 --- a/formClass.inc +++ b/formClass.inc @@ -69,19 +69,13 @@ class formClass { 'type' => MENU_CALLBACK, 'access arguments' => array('view fedora collection'), ); - $repository_title = variable_get('fedora_repository_title', 'Digital repository'); - if (trim($repository_title) != '') { - $respository_title = t($repository_title); - } - else { - $repository_title = NULL; - } $items['fedora/repository'] = array( - 'title' => $repository_title, + 'title' => '', + 'title callback' => 'variable_get', + 'title arguments' => array('fedora_repository_name', 'Digital Repository'), 'page callback' => 'repository_page', 'type' => MENU_NORMAL_ITEM, 'access arguments' => array('view fedora collection'), - // 'access' => TRUE ); $items['fedora/repository/service'] = array( @@ -100,8 +94,6 @@ class formClass { $items['fedora/repository/editmetadata'] = array( 'title' => t('Edit metadata'), 'page callback' => 'fedora_repository_edit_qdc_page', - // 'page arguments' => array(1), - //'type' => MENU_LOCAL_TASK, 'type' => MENU_CALLBACK, 'access arguments' => array('edit fedora meta data') ); @@ -123,7 +115,6 @@ class formClass { $items['fedora/repository/purgeObject'] = array( 'title' => t('Purge object'), 'page callback' => 'fedora_repository_purge_object', - // 'type' => MENU_LOCAL_TASK, 'type' => MENU_CALLBACK, 'access arguments' => array('purge objects and datastreams') ); @@ -131,7 +122,6 @@ class formClass { $items['fedora/repository/addStream'] = array( 'title' => t('Add stream'), 'page callback' => 'add_stream', - // 'type' => MENU_LOCAL_TASK, 'type' => MENU_CALLBACK, 'access arguments' => array('add fedora datastreams') ); @@ -617,6 +607,7 @@ class formClass { $form = new IngestObjectMetadataForm(); return $form->create($collection_pid, $collection_label, $form_state); } catch (Exception $e) { + //dd('An error occured; reverting to QDC form...'); $form_state['storage']['xml'] = FALSE; // An error occured revert back to the QDC Form. } } diff --git a/plugins/FedoraObjectDetailedContent.inc b/plugins/FedoraObjectDetailedContent.inc index 55a3d31c..9283acb2 100644 --- a/plugins/FedoraObjectDetailedContent.inc +++ b/plugins/FedoraObjectDetailedContent.inc @@ -43,6 +43,7 @@ class FedoraObjectDetailedContent { '#type' => 'tabpage', '#title' => t('Object Details'), '#selected' => $details_selected, + '#weight' => 100, //XXX: Make the weight configurable? ); $tabset['fedora_object_details']['tabset'] = array( '#type' => 'tabset', @@ -51,12 +52,28 @@ class FedoraObjectDetailedContent { $ds_list = $objectHelper->get_formatted_datastream_list($this->pid, NULL, $this->item); - - $tabset['fedora_object_details']['tabset']['view'] = array( - '#type' => 'tabpage', - '#title' => t('View'), - '#content' => $dc_html . $ds_list . $purge_form, - ); + $i = 0; + if (fedora_repository_access(OBJECTHELPER :: $VIEW_DETAILED_CONTENT_LIST, $this->pid, $user)) { + $tabset['fedora_object_details']['tabset']['view'] = array( + '#type' => 'tabpage', + '#title' => t('View'), + 'dc' => array( + '#type' => 'markup', + '#value' => $dc_html, //XXX: This could easily be done in Drupal, instead of using an XSL + '#weight' => $i++ + ), + 'list' => array( + '#type' => 'markup', + '#value' => $ds_list, //XXX: The function called here could be cleaned up a fair bit as well... + '#weight' => $i++ + ), + 'purge' => array( + '#type' => 'markup', + '#value' => $purge_form, + '#weight' => $i++ + ) + ); + } if (fedora_repository_access(OBJECTHELPER :: $EDIT_FEDORA_METADATA, $this->pid, $user)) { $editform = drupal_get_form('fedora_repository_edit_qdc_form', $this->pid, 'DC'); @@ -68,7 +85,13 @@ class FedoraObjectDetailedContent { ); } - return $tabset; + $ts = $tabset['fedora_object_details']['tabset']; + if (array_key_exists('view', $ts) || array_key_exists('edit', $ts)) { + return $tabset; + } + else { + return array(); + } } }