From 264bdd3e4a5e5a40aa66dae994621a559e974295 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Mon, 29 Nov 2010 11:37:47 -0400 Subject: [PATCH 1/8] SCORM module functions properly if SCORM player is not enabled. --- plugins/nmlt/scorm.inc | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/plugins/nmlt/scorm.inc b/plugins/nmlt/scorm.inc index 09b05076..13c77f4c 100644 --- a/plugins/nmlt/scorm.inc +++ b/plugins/nmlt/scorm.inc @@ -99,26 +99,28 @@ class SCORMObject { //$result = db_query("SELECT * FROM {content_node_field} nf INNER JOIN {content_node_field_instance} ni ON nf.field_name = ni.field_name WHERE nf.type='field_fedora_pid_reference'"); fedora_pidfield_redirect_to_node($this); - module_load_include('module', 'SCORM', 'SCORM'); - $dest_array = explode('/', urldecode(drupal_get_destination())); - $nid = $dest_array[count($dest_array) - 1]; - $node = node_load($nid); - - $tabset = array(); - - $tabset['my_tabset'] = array( - '#type' => 'tabset', - ); - - $tabset['my_tabset']['first_tab'] = array( + $tabset['my_tabset']['first_tab'] = array( '#type' => 'tabpage', '#title' => t('Description'), ); - $tabset['my_tabset']['second_tab'] = array( - '#type' => 'tabpage', - '#title' => t('Results'), - '#content' => scorm_show_results($node), - ); + if (module_load_include('module', 'SCORM', 'SCORM')) { + $dest_array = explode('/', urldecode(drupal_get_destination())); + $nid = $dest_array[count($dest_array) - 1]; + $node = node_load($nid); + + $tabset = array(); + + $tabset['my_tabset'] = array( + '#type' => 'tabset', + ); + $tabset['my_tabset']['second_tab'] = array( + '#type' => 'tabpage', + '#title' => t('Results'), + '#content' => scorm_show_results($node), + ); + } + + module_load_include('inc', 'fedora_repository', 'ObjectHelper'); $obj = new ObjectHelper(); $tabset['my_tabset']['first_tab']['tabset'] = array( From 796325947276a0880024a06f275582462e51ed1c Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Wed, 1 Dec 2010 14:00:23 -0400 Subject: [PATCH 2/8] Added modifyDatastreamByReference to API. --- api/fedora_item.inc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/api/fedora_item.inc b/api/fedora_item.inc index 01d71cfa..463ba6df 100644 --- a/api/fedora_item.inc +++ b/api/fedora_item.inc @@ -622,6 +622,23 @@ class Fedora_Item { return self::soap_call('modifyObject', $params, $quiet); } + function modify_datastream_by_reference($external_url, $dsid, $label, $mime_type, $force = FALSE, $logMessage = 'Modified by Islandora API',$quiet=FALSE) { + $params = array( + 'pid' => $this->pid, + 'dsID' => $dsid, + 'altIDs' => NULL, + 'dsLabel' => $label, + 'MIMEType' => $mime_type, + 'formatURI' => NULL, + 'dsLocation' => $external_url, + 'checksumType' => 'DISABLED', + 'checksum' => 'none', + 'logMessage' => $logMessage, + 'force' => $force + ); + return self::soap_call('modifyDatastreamByReference', $params, $quiet); + } + function modify_datastream_by_value($content, $dsid, $label, $mime_type, $force = FALSE, $logMessage = 'Modified by Islandora API',$quiet=FALSE) { $params = array( 'pid' => $this->pid, @@ -654,6 +671,7 @@ class Fedora_Item { case 'getNextPID': case 'getRelationships': case 'modifyDatastreamByValue': + case 'modifyDatastreamByReference': case 'purgeDatastream': case 'purgeObject': case 'modifyObject': From 9311a8da7b4101968e7d50b2d225941f605709f2 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Wed, 1 Dec 2010 15:18:29 -0400 Subject: [PATCH 3/8] Added MODS to DC transform to book ingest. --- ilives/book.inc | 28 ++- ilives/fedora_ilives.module | 8 +- ilives/xsl/MODS3-22simpleDC.xsl | 409 ++++++++++++++++++++++++++++++++ 3 files changed, 441 insertions(+), 4 deletions(-) create mode 100644 ilives/xsl/MODS3-22simpleDC.xsl diff --git a/ilives/book.inc b/ilives/book.inc index d05f41d4..086a883a 100644 --- a/ilives/book.inc +++ b/ilives/book.inc @@ -121,10 +121,14 @@ class IslandoraBook { $new_item->add_datastream_from_string($form_values['mods']['mods_record'], 'MODS', 'MODS Metadata', 'text/xml', 'X'); + $dc = transform_mods_to_dc($form_values['mods']['mods_record']); + if ($dc) { + $new_item->modify_datastream_by_value($dc, 'DC', 'Dublin Core XML Metadata', 'text/xml'); + } $new_item->add_relationship('hasModel', $form_values['content_model_pid'], FEDORA_MODEL_URI); $new_item->add_relationship(!empty($form_values['relationship']) ? $form_values['relationship'] : 'isMemberOfCollection', $form_values['collection_pid']); } - + public function buildAddPagesForm($form = array()) { } @@ -248,3 +252,25 @@ function ilives_add_single_page_object($book_pid, $page_file, $page_num = 1, $pa $page_item->add_relationship('isMemberOf', $book_pid); $page_item->add_datastream_from_file($page_file, 'TIFF', 'Archival TIFF', 'image/tiff', 'M'); } + +function transform_mods_to_dc($mods) { + $xp = new XsltProcessor(); + // create a DOM document and load the XSL stylesheet + $xsl = new DomDocument; + $xsl->load(drupal_get_path('module', 'fedora_ilives').'/xsl/MODS3-22simpleDC.xsl'); + + // import the XSL styelsheet into the XSLT process + $xp->importStylesheet($xsl); + + // create a DOM document and load the XML datat + $xml_doc = new DomDocument; + $xml_doc->loadXML($mods); + + // transform the XML into HTML using the XSL file + if ($dc = $xp->transformToXML($xml_doc)) { + return $dc; + } + else { + return FALSE; + } +} \ No newline at end of file diff --git a/ilives/fedora_ilives.module b/ilives/fedora_ilives.module index 1e40ce7b..84a4b4a5 100644 --- a/ilives/fedora_ilives.module +++ b/ilives/fedora_ilives.module @@ -203,9 +203,11 @@ function fedora_ilives_create_book_view($pid, $query = NULL) { $simpleDCxml = simplexml_load_string($dc_xml); $types = $simpleDCxml->xpath('//dc:type'); $ingested = 'false'; - foreach ($types as $type) { - if ($type == 'ingested') { - $ingested = 'true'; + if (!empty($types)) { + foreach ($types as $type) { + if ($type == 'ingested') { + $ingested = 'true'; + } } } diff --git a/ilives/xsl/MODS3-22simpleDC.xsl b/ilives/xsl/MODS3-22simpleDC.xsl new file mode 100644 index 00000000..4a4eff8d --- /dev/null +++ b/ilives/xsl/MODS3-22simpleDC.xsl @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + : + + + + . + + + + . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- + + + + + -- + + + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + + + + + - + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Collection + + + DataSet + + + Service + + + Software + + + Image + + + InteractiveResource + + + MovingImage + + + PhysicalObject + + + Sound + + + StillImage + + + Text + + + Text + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- + + + + + + + + + + + -- + + + + + + + + + + + + + + + + + + + + + + , + + + + , + + + + + ( + + ) + + + ( + + ) + + + + + + + + + - + + + + + - + + + + + + + + + + + + From 4db6df21227e9208e5cfa894bafd7294e63ae366 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Wed, 1 Dec 2010 16:13:32 -0400 Subject: [PATCH 4/8] Added custom PID to ingest form. --- ilives/book.inc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/ilives/book.inc b/ilives/book.inc index 086a883a..f3de4f00 100644 --- a/ilives/book.inc +++ b/ilives/book.inc @@ -21,6 +21,15 @@ class IslandoraBook { // Set #cache to true to create the $form_state cache $form['#cache'] = TRUE; + + // Give the user an option to enter a custom PID + $form['custom_pid'] = array( + '#type' => 'textfield', + '#title' => 'Custom PID', + '#description' => 'If you want to manually specify the PID for the new object, enter it here. '. + 'Leave it blank for an automatically-generated PID.', + ); + // Prompt the user to enter a record ID to be looked up in Evergreen. $form['unapi_url'] = array( '#type' => 'textfield', @@ -90,7 +99,7 @@ class IslandoraBook { return TRUE; } - public function handleIngestForm($form_values, $form, &$form_state) { + public function handleIngestForm($form_values) { /* * process the metadata form * Create fedora object @@ -115,7 +124,8 @@ class IslandoraBook { global $user; $mimetype = new MimeClass(); - $new_item = Fedora_Item::ingest_new_item($form_values['pid'], 'A', $title, + + $new_item = Fedora_Item::ingest_new_item(!empty($form_values['custom_pid']) ? $form_values['custom_pid'] : $form_values['pid'], 'A', $title, $user->name); $new_item->add_datastream_from_string($form_values['mods']['mods_record'], 'MODS', From 76660c06876eca5ff8eb22b783943d2394f10a14 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Wed, 1 Dec 2010 17:47:36 -0400 Subject: [PATCH 5/8] Add PID as a dc:identifier field in DC. --- ilives/book.inc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ilives/book.inc b/ilives/book.inc index f3de4f00..d1ad5055 100644 --- a/ilives/book.inc +++ b/ilives/book.inc @@ -133,7 +133,13 @@ class IslandoraBook { $dc = transform_mods_to_dc($form_values['mods']['mods_record']); if ($dc) { - $new_item->modify_datastream_by_value($dc, 'DC', 'Dublin Core XML Metadata', 'text/xml'); + // Add the PID to a dc:identifier field. + $dc_doc = simplexml_load_string($dc); + $dc_item = $dc_doc->xpath('/srw_dc:dcCollection/srw_dc:dc[1]'); + foreach($dc_item as $node) { + $node->addChild('identifier', $new_item->pid, 'http://purl.org/dc/elements/1.1/'); + } + $new_item->modify_datastream_by_value($dc_doc->saveXML(), 'DC', 'Dublin Core XML Metadata', 'text/xml'); } $new_item->add_relationship('hasModel', $form_values['content_model_pid'], FEDORA_MODEL_URI); $new_item->add_relationship(!empty($form_values['relationship']) ? $form_values['relationship'] : 'isMemberOfCollection', $form_values['collection_pid']); From 2981b09949cbb7963984960209cce314297e8b54 Mon Sep 17 00:00:00 2001 From: mroy Date: Wed, 1 Dec 2010 15:50:23 -0600 Subject: [PATCH 6/8] Updated to also allow searching by process id instead of just process name and collection. Updated to process 500 JMS messages per cron run. --- .../islandora_workflow_client.module | 112 +++++++++++------- 1 file changed, 71 insertions(+), 41 deletions(-) diff --git a/workflow_client/islandora_workflow_client.module b/workflow_client/islandora_workflow_client.module index 5ab2be70..a361f5a8 100644 --- a/workflow_client/islandora_workflow_client.module +++ b/workflow_client/islandora_workflow_client.module @@ -16,44 +16,66 @@ function islandora_workflow_client_menu() function islandora_workflow_client_search_submit($form,&$form_state) { - if (trim($form['collection_pid']['#value']) !== '') - { - drupal_goto('admin/settings/workflow_client/'.$form['process_name']['#value'].'/'.$form['collection_pid']['#value']); - } else - { - drupal_goto('admin/settings/workflow_client/'.$form['process_name']['#value']); + $url ='admin/settings/workflow_client/'.$form['process_name']['#value']; + if (trim($form['process_id']['#value']) !== '') { + $url.='/'.$form['process_id']['#value']; + } else { + $url .= '/-/'; } + + if (trim($form['collection_pid']['#value']) !== '') { + $url.='/'.$form['collection_pid']['#value']; + } else { + $url .= '/-/'; + } + + drupal_goto($url); + } -function islandora_workflow_client_search() +function islandora_workflow_client_search(&$form_state,$terms=null,$process_id=null,$collection=null) { module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); $form = array(); $form['process_name'] = array( '#type' => 'textfield', + '#required'=> TRUE, '#title' => t('Search by Process Name'), + '#default_value' => ($terms!=null?$terms:''), '#description' => t('Returns a list of objects that match the process name(s) entered. Separate multiple names by spaces.'), ); + $form['process_id'] = array( + '#type' => 'textfield', + '#title' => t('Search by Process ID'), + '#default_value' => ($process_id!=null?$process_id:''), + '#description' => t('Returns only objects that match the also match the process id entered. '), + ); + + $form['collection_pid'] = array( '#type' => 'textfield', '#title' => t('Search by Collection PID'), + '#default_value' => ($collection!=null?$collection:''), '#description' => t('Returns only objects that match the also match the collection pid(s) entered. Separate multiple PIDs by spaces.'), ); + $form['submit'] = array('#type' => 'submit', '#value' => t('Search')); return $form; } -function islandora_workflow_client_manage($terms = null, $collection = null, $queue= null, $queueProcess = null) +function islandora_workflow_client_manage($terms = null, $process_id= null, $collection = null, $queue= null, $queueProcess = null) { - if ($collection == 'none') - { + if ($collection == 'none' || $collection == '-') { $collection = null; } + if ($process_id == 'none' || $process_id == '-') { + $process_id = null; + } $output = ''; if (trim($terms) != '') @@ -143,49 +165,57 @@ function islandora_workflow_client_manage($terms = null, $collection = null, $qu $errCount = 0; $waitCount =0; $completeCount = 0; + $display = false; foreach ($pids as $pid) { if ( isset($workflows[$pid]) && $workflows[$pid] !== false ) { + $display = true; $procs = $workflows[$pid]->getProcesses(); $updated = FALSE; foreach ($procs as $id=>$n) { - - if ($name == $n) - { - $proc=$workflows[$pid]->getProcess($id); - if (($queue == 'queue'|| ($queue =='errorQueue' && $proc['state'] == 'error')) && $queueProcess == $n) - { - $workflows[$pid]->setState($id,'waiting'); - $updated=TRUE; - } - - - switch ($proc['state']) - { - case 'completed': - $completeCount++; - break; - case 'waiting': - $waitCount++; - break; - case 'error': - $errCount++; - $errors[]=$proc; - break; + if ($process_id == null || $id == $process_id) + { + if ($name == $n) + { + $proc=$workflows[$pid]->getProcess($id); + if (($queue == 'queue'|| ($queue =='errorQueue' && $proc['state'] == 'error')) && $queueProcess == $n) + { + $workflows[$pid]->setState($id,'waiting'); + $updated=TRUE; + } + + + switch ($proc['state']) + { + case 'completed': + $completeCount++; + break; + case 'waiting': + $waitCount++; + break; + case 'error': + $errCount++; + $errors[]=$proc; + break; + } } } - } - if ($updated) - { - $workflows[$pid]->saveToFedora(); + if ($updated) + { + $workflows[$pid]->saveToFedora(); + } } } } - $rows[]= array($name, $waitCount,$completeCount,$errCount,l('Add All to Queue','admin/settings/workflow_client/'.$terms.'/'.(trim($collection)==''?'none':$collection).'/queue/'.$name).'
'.l('Add Errors to Queue','admin/settings/workflow_client/'.$terms.'/'.(trim($collection)==''?'none':$collection).'/errorQueue/'.$name)); + if ($display) { + $rows[]= array($name, $waitCount,$completeCount,$errCount, + l('Add All to Queue','admin/settings/workflow_client/'.$terms.'/'.(trim($process_id)==''?'none':$process_id).'/'.(trim($collection)==''?'none':$collection).'/queue/'.$name).'
'. + l('Add Errors to Queue','admin/settings/workflow_client/'.$terms.'/'.(trim($process_id)==''?'none':$process_id).'/'.(trim($collection)==''?'none':$collection).'/errorQueue/'.$name)); + } } if ($queue == 'queue' || $queue == 'errorQueue') @@ -193,7 +223,7 @@ function islandora_workflow_client_manage($terms = null, $collection = null, $qu drupal_goto('admin/settings/workflow_client/'.$terms.(trim($collection)==''?'/'.$collection:'')); } - $output.='

Search for "'.$terms.'" '.(trim($collection)!=''?'in collection(s) "'.$collection.'" ':'').'returned Processes:

'; + $output.='

Search for '.($process_id!=null?'process id '.$process_id.' with terms ':'').' "'.$terms.'" '.(trim($collection)!=''?'in collection(s) "'.$collection.'" ':'').'returned Processes:

'; $output.=theme('table',$headers,$rows); if (count ($errors) > 0) @@ -223,7 +253,7 @@ function islandora_workflow_client_manage($terms = null, $collection = null, $qu } } - $output .= drupal_get_form('islandora_workflow_client_search'); + $output .= drupal_get_form('islandora_workflow_client_search',$form,NULL, $terms, $process_id, $collection); return $output; } @@ -239,7 +269,7 @@ function islandora_workflow_client_cron() $queue='/queue/fedora.apim.update'; $con->subscribe($queue); $messagesToSend=array(); - for ($i=0;$i<50;$i++) { + for ($i=0;$i<500;$i++) { $msg = $con->readFrame(); if ($msg != null) { From 65712b26cd24f283a77682b6c5594fd98bda9004 Mon Sep 17 00:00:00 2001 From: mroy Date: Wed, 1 Dec 2010 16:00:07 -0600 Subject: [PATCH 7/8] makeObject redirects to the fedora/get URL instead of buffering through SOAP if user is not logged in (so it can be an anonymous request). The SOAP request is also done if connected over SSL. --- ObjectHelper.inc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ObjectHelper.inc b/ObjectHelper.inc index 9341a6c6..0cb03f00 100644 --- a/ObjectHelper.inc +++ b/ObjectHelper.inc @@ -34,11 +34,12 @@ class ObjectHelper { /** * Grabs a stream from fedora sets the mimetype and returns it. $dsID is the - * datastream id. + * datastream id. If $forceSoap is set, the function will always buffer the datastream from fedora. Otherwise, it will + * try and use a redirect if possible. * @param $pid String * @param $dsID String */ - function makeObject($pid, $dsID, $asAttachment = FALSE, $label = NULL, $filePath=FALSE, $version=NULL) { + function makeObject($pid, $dsID, $asAttachment = FALSE, $label = NULL, $filePath=FALSE, $version=NULL, $forceSoap = FALSE) { global $user; module_load_include('inc','fedora_repository','ContentModel'); if ($pid == NULL || $dsID == NULL) { @@ -163,7 +164,12 @@ class ObjectHelper { header('Content-Disposition: attachment; filename="' . $suggestedFileName . '"'); } - curl_exec($ch); + + if ( (isset($user) && $user->uid != 0) || $forceSoap || isset($_SERVER['HTTPS'])) { + curl_exec($ch); + } else { + header('Location: '.$url); + } } curl_close($ch); } else { From babc48f07b321a82e5b1176be02e05431908fe13 Mon Sep 17 00:00:00 2001 From: mroy Date: Wed, 1 Dec 2010 16:01:00 -0600 Subject: [PATCH 8/8] Added handling of mods_alternative_title(s), mods_area, and mods_caption form field values. --- plugins/ModsFormBuilder.inc | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/plugins/ModsFormBuilder.inc b/plugins/ModsFormBuilder.inc index 597dea14..3c135d6e 100644 --- a/plugins/ModsFormBuilder.inc +++ b/plugins/ModsFormBuilder.inc @@ -385,6 +385,25 @@ class ModsFormBuilder extends FormBuilder { $mods->appendChild($titleinfo); } + if (isset($form_values['mods_alternative_titles']) && trim($form_values['mods_alternative_titles']) != '') { + $titles=preg_split('/\s+\;\s+/',trim($form_values['mods_alternative_titles'])); + foreach ($titles as $t) { + $titleinfo = $dom->createElement('mods:titleInfo'); + $titleinfo->setAttribute('alternative') ; + $title = $dom->createElement('mods:title',$t); + $titleInfo->appendChild($title); + $mods->appendChild($title); + } + } + + if (isset($form_values['mods_alternative_title']) && trim($form_values['mods_alternative_title']) != '') { + $titleinfo = $dom->createElement('mods:titleInfo'); + $titleinfo->setAttribute('alternative') ; + $title = $dom->createElement('mods:title',trim($form_values['mods_alternative_title'])); + $titleInfo->appendChild($title); + $mods->appendChild($title); + } + if (isset($form_values['mods_description']) && trim($form_values['mods_description']) != '') { $abstract = $dom->createElement('mods:abstract', htmlspecialchars(trim($form_values['mods_description']))); $mods->appendChild($abstract); @@ -477,6 +496,12 @@ class ModsFormBuilder extends FormBuilder { $note = $dom->createElement('mods:note', htmlspecialchars(trim($form_values['mods_note']))); $mods->appendChild($note); } + + if (isset($form_values['mods_caption']) && trim($form_values['mods_caption']) != '') { + $note = $dom->createElement('mods:note', htmlspecialchars(trim($form_values['mods_caption']))); + $note->setAttribute('type','caption'); + $mods->appendChild($note); + } if (isset($form_values['mods_format']) && trim($form_values['mods_format']) != '') { $typeOfResource = $dom->createElement('mods:typeOfResource', htmlspecialchars($form_values['mods_format'])); @@ -524,6 +549,13 @@ class ModsFormBuilder extends FormBuilder { $city = $dom->createElement('mods:city', htmlspecialchars($form_values['mods_city'])); $geographic->appendChild($city); } + + if (isset($form_values['mods_area']) && trim($form_values['mods_area']) != '') { + $state = $dom->createElement('mods:area', htmlspecialchars($form_values['mods_area'])); + $geographic->appendChild($state); + } + + $subject->appendChild($geographic); }