From d36fdd291ce6d346f75e4414409b73241c286ac8 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Tue, 12 Jul 2011 14:14:25 -0300 Subject: [PATCH 01/27] Fix Headers for FlowPlayer FlowPlayer requires the "Content-Length" header to be returned in order to work properly, but it wasn't getting returned in the header when a user was not logged in. A slight change to the semantics, and opening up of the getDatastream API-M method via XACML seems to work. --- ObjectHelper.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ObjectHelper.inc b/ObjectHelper.inc index 0f8be1bb..4a12240b 100644 --- a/ObjectHelper.inc +++ b/ObjectHelper.inc @@ -94,13 +94,13 @@ class ObjectHelper { if ((!isset($user)) || $user->uid == 0) { $fedoraUser = 'anonymous'; $fedoraPass = 'anonymous'; - $contentSize = 0; } else { $fedoraUser = $user->name; $fedoraPass = $user->pass; - $dataStreamInfo = $item->get_datastream_info($dsID); - $contentSize = $dataStreamInfo->datastream->size; } + + $dataStreamInfo = $item->get_datastream_info($dsID); + $contentSize = $dataStreamInfo->datastream->size; if (function_exists("curl_init")) { if (!isset($mimeType)) { From 5aefe46f85709cd5218a5f139616dc925f57b90c Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Tue, 24 Apr 2012 14:19:47 -0300 Subject: [PATCH 02/27] Use wrapping modify_datastream wrapper in replace datastream callback. --- fedora_repository.module | 45 +++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/fedora_repository.module b/fedora_repository.module index e83d91f5..208e028e 100644 --- a/fedora_repository.module +++ b/fedora_repository.module @@ -646,27 +646,27 @@ function fedora_repository_replace_stream_form(&$form_state, $pid, $dsId, $dsLab * @return type */ function fedora_repository_replace_stream_form_validate($form, &$form_state) { -// If a file was uploaded, process it. + // If a file was uploaded, process it. if (isset($_FILES['files']) && is_uploaded_file($_FILES['files']['tmp_name']['file'])) { -// attempt to save the uploaded file + // attempt to save the uploaded file $file = file_save_upload('file', array(), file_directory_path()); -// set error is file was not uploaded + // set error is file was not uploaded if (!$file) { form_set_error('file', 'Error uploading file.'); return; } - - $doc = new DOMDocument(); - module_load_include('inc', 'Fedora_Repository', 'MimeClass'); + + module_load_include('inc', 'fedora_repository', 'MimeClass'); $mime = new MimeClass(); - if ($mime->getType($file->filepath) == 'text/xml' && !$doc->load($file->filepath)) { + + if ($mime->getType($file->filepath) == 'text/xml' && !DOMDocument::load($file->filepath)) { form_set_error('file', 'Invalid XML format.'); return; } -// set files to form_state, to process when form is submitted + // set files to form_state, to process when form is submitted $form_state['values']['file'] = $file; } } @@ -683,39 +683,32 @@ function fedora_repository_replace_stream_form_submit($form, &$form_state) { $pid = $form_state['values']['pid']; $dsid = $form_state['values']['dsId']; $dsLabel = $form_state['values']['dsLabel']; -// Remove the original file extension from the label and add the new one + + // Remove the original file extension from the label and add the new one $indexOfDot = strrpos($dsLabel, '.'); //use strrpos to get the last dot if ($indexOfDot !== FALSE) { $dsLabel = substr($dsLabel, 0, $indexOfDot); $dsLabel .= substr($file->filename, strrpos($file->filename, '.')); // Add the file extention to the end of the label.; } - module_load_include('inc', 'Fedora_Repository', 'MimeClass'); - module_load_include('inc', 'fedora_repository', 'api/fedora_item'); - $file_basename = basename($file->filepath); - $file_directory = dirname($file->filepath); - $streamUrl = $base_url . '/' . $file_directory . '/' . urlencode($file_basename); + $streamUrl = url($file->filepath, array( + 'absolute' => TRUE, + )); /* ----------------------------------------------------------------- * TODO: need a better way to get mimetypes */ + module_load_include('inc', 'fedora_repository', 'MimeClass'); $mimetype = new MimeClass(); $dformat = $mimetype->getType($file->filepath); + module_load_include('inc', 'fedora_repository', 'api/fedora_item'); $item = new Fedora_Item($pid); - $info = $item->get_datastream_info($dsid); - - if($info->datastream->controlGroup == 'M') { - $item->modify_datastream_by_reference($streamUrl, $dsid, $dsLabel, $dformat); - } elseif ($info->datastream->controlGroup == 'X') { - if($dformat == 'text/xml') { - $item->modify_datastream_by_value(file_get_contents($file->filepath), $dsid, $dsLabel, $dformat); - } - else { - drupal_set_message('File must be of mimetype text/xml in order to replace inline XML datastream.', 'error'); - } + + if(in_array($info->datastream->controlGroup, array('M', 'X'))) { + $item->modify_datastream($streamUrl, $dsid, $dsLabel, $dformat); } else { - drupal_set_message('Cannot replace Redirect or Managed Datastream.', 'error'); + drupal_set_message(t('Cannot replace Redirect or Managed Datastream.'), 'error'); } $form_state['redirect'] = 'fedora/repository/' . $pid; From fa77552e57052ace01abef279e0a8cf3946083e2 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 25 Apr 2012 09:22:14 -0300 Subject: [PATCH 03/27] Get the extension without exploding. --- MimeClass.inc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/MimeClass.inc b/MimeClass.inc index 42c11e37..b2950f6e 100644 --- a/MimeClass.inc +++ b/MimeClass.inc @@ -231,9 +231,7 @@ class MimeClass { * @return type */ public function get_mimetype($filename, $debug = FALSE) { - - $file_name_and_extension = explode('.', $filename); - $ext = strtolower(array_pop($file_name_and_extension)); + $ext = strtolower(substr($filename, strrpos($filename, '.') + 1)); if (!empty($this->private_mime_types[$ext])) { if (TRUE === $debug) From 01ac63a3d98c996614f925e6f810098fe7e36117 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 25 Apr 2012 10:05:45 -0300 Subject: [PATCH 04/27] Allow the addition of Redirect and External datastreams. --- fedora_repository.module | 80 ++++++++++++++++++++------------------ formClass.inc | 83 +++++++++++++++++++++++++++++----------- 2 files changed, 104 insertions(+), 59 deletions(-) diff --git a/fedora_repository.module b/fedora_repository.module index 208e028e..940d1585 100644 --- a/fedora_repository.module +++ b/fedora_repository.module @@ -377,37 +377,25 @@ function add_stream_form_submit($form, &$form_state) { $form_state['rebuild'] = TRUE; return; } - module_load_include('inc', 'fedora_repository', 'MimeClass'); + module_load_include('inc', 'fedora_repository', 'ObjectHelper'); module_load_include('inc', 'fedora_repository', 'api/fedora_item'); $pathToModule = drupal_get_path('module', 'fedora_repository'); - $file = $form_state['values']['add-stream-file-location']; - $pid = $form_state['values']['pid']; $dsid = $form_state['values']['stream_id']; $dsLabel = $form_state['values']['stream_label'] . substr($file, strrpos($file, '.')); // Add the file extention to the end of the label.; - $file_basename = basename($file); - $file_directory = dirname($file); - $streamUrl = $base_url . '/' . $file_directory . '/' . drupal_urlencode($file_basename); - /* ----------------------------------------------------------------- - * need a better way to get mimetypes - */ - $mimetype = new MimeClass(); - $dformat = $mimetype->getType($file); - $controlGroup = "M"; - if ($dformat == 'text/xml') { - $controlGroup = 'X'; - } try { $item = new Fedora_Item($pid); - $item->add_datastream_from_url($streamUrl, $dsid, $dsLabel, $dformat, $controlGroup); + $item->add_datastream_from_url($form_state['storage']['stream_url'], $dsid, $dsLabel, $form_state['storage']['ds_mimetype'], $form_state['values']['control_group']); - $object_helper = new ObjectHelper(); - $object_helper->get_and_do_datastream_rules($pid, $dsid, $file); + if ($file = $form_state['values']['add-stream-file-location']) { + $object_helper = new ObjectHelper(); + $object_helper->get_and_do_datastream_rules($pid, $dsid, $file); - file_delete($file); + file_delete($file); + } } catch (exception $e) { drupal_set_message(t('@message', array('@message' => check_plain($e->getMessage()))), 'error'); return; @@ -434,6 +422,7 @@ function add_stream_form(&$form_state, $pid) { * @return type */ function add_stream_form_validate($form, &$form_state) { + module_load_include('inc', 'fedora_repository', 'MimeClass'); if ($form_state['clicked_button']['#value'] == 'OK') { $form_state['rebuild'] = TRUE; return; @@ -444,15 +433,15 @@ function add_stream_form_validate($form, &$form_state) { form_set_error('', t('Data stream ID cannot be more than 64 characters.')); return FALSE; } - if (!(preg_match("/^[a-zA-Z]/", $dsid))) { - form_set_error('', t("Data stream ID (@dsid) has to start with a letter.", array('@dsid' => check_plain($dsid)))); + elseif (!(preg_match("/^[a-zA-Z]/", $dsid))) { + form_set_error('', t("Data stream ID (@dsid) has to start with a letter.", array('@dsid' => $dsid))); return FALSE; } - if (strlen($dsLabel) > 64) { + elseif (strlen($dsLabel) > 64) { form_set_error('', t('Data stream Label cannot be more than 64 characters.')); return FALSE; } - if (strpos($dsLabel, '/')) { + elseif (strpos($dsLabel, '/') !== FALSE) { form_set_error('', t('Data stream Label cannot contain a "/".')); return FALSE; } @@ -462,12 +451,30 @@ function add_stream_form_validate($form, &$form_state) { // 'file_validate_size' => array(30 * 1024), ); - $fileObject = file_save_upload('add-stream-file-location', $validators); - -// Move the uploaded file to Drupal's files directory. - file_move($fileObject->filepath, 0, 'FILE_EXISTS_RENAME'); - $form_state['values']['add-stream-file-location'] = $fileObject->filepath; -// TODO: Add error checking here. + $mimetype = new MimeClass(); + $controlGroup = $form_state['values']['control_group']; + if (in_array($controlGroup, array('X', 'M')) && ($fileObject = file_save_upload('add-stream-file-location', $validators)) !== 0) { + // Move the uploaded file to Drupal's files directory. + file_move($fileObject->filepath, 0, 'FILE_EXISTS_RENAME'); + $form_state['values']['add-stream-file-location'] = $fileObject->filepath; + $form_state['storage']['ds_mimetype'] = $mimetype->getType($fileObject->filepath); + + $file_basename = basename($fileObject->filepath); + $file_directory = dirname($fileObject->filepath); + + $form_state['storage']['stream_url'] = url($file_directory . '/' . drupal_urlencode($file_basename), array( + 'absolute' => TRUE, + )); + } + elseif (in_array($controlGroup, array('M', 'R', 'E')) && ($ref = $form_state['values']['ds_reference'])) { + $form_state['storage']['ds_mimetype'] = $mimetype->getType($ref); + $form_state['storage']['stream_url'] = $form_state['values']['ds_reference']; + } + else { + form_set_error('', t('No file given when "X" or "M", or no reference given when "M", "R" or "E".')); + } + + // TODO: Add error checking here. $form_state['rebuild'] = FALSE; } @@ -680,6 +687,11 @@ function fedora_repository_replace_stream_form_validate($form, &$form_state) { function fedora_repository_replace_stream_form_submit($form, &$form_state) { global $base_url; $file = $form_state['values']['file']; + + if ($file !== NULL) { + $file = $form_state['values']['reference']; + } + $pid = $form_state['values']['pid']; $dsid = $form_state['values']['dsId']; $dsLabel = $form_state['values']['dsLabel']; @@ -702,14 +714,9 @@ function fedora_repository_replace_stream_form_submit($form, &$form_state) { $mimetype = new MimeClass(); $dformat = $mimetype->getType($file->filepath); - module_load_include('inc', 'fedora_repository', 'api/fedora_item'); $item = new Fedora_Item($pid); - if(in_array($info->datastream->controlGroup, array('M', 'X'))) { - $item->modify_datastream($streamUrl, $dsid, $dsLabel, $dformat); - } else { - drupal_set_message(t('Cannot replace Redirect or Managed Datastream.'), 'error'); - } + $item->modify_datastream($streamUrl, $dsid, $dsLabel, $dformat); $form_state['redirect'] = 'fedora/repository/' . $pid; } @@ -1052,7 +1059,6 @@ function fedora_repository_urlencode_string($str) { * @return type */ function fedora_object_as_attachment($pid, $dsId, $label=NULL, $version=NULL) { - global $user; module_load_include('inc', 'fedora_repository', 'ObjectHelper'); if ($pid == NULL || $dsId == NULL) { @@ -1061,7 +1067,7 @@ function fedora_object_as_attachment($pid, $dsId, $label=NULL, $version=NULL) { } $objectHelper = new ObjectHelper(); - $objectHelper->makeObject($pid, $dsId, 1, $label, FALSE, $version); + $objectHelper->makeObject($pid, $dsId, TRUE, $label, FALSE, $version); } /** diff --git a/formClass.inc b/formClass.inc index 713f1fcb..db90798c 100644 --- a/formClass.inc +++ b/formClass.inc @@ -656,17 +656,21 @@ class formClass { } } - $form['add_datastream_label'] = array( - '#value' => t('

Add Datastream:

'), - '#weight' => -10, + $form['fieldset'] = array( + '#type' => 'fieldset', + '#title' => t('Add datastream'), ); + //$form['add_datastream_label'] = array( + // '#value' => t('

Add Datastream:

'), + // '#weight' => -10, + //); - $form['pid'] = array( + $form['fieldset']['pid'] = array( '#type' => 'hidden', '#value' => "$pid" ); - $form['stream_label'] = array( + $form['fieldset']['stream_label'] = array( '#title' => 'Datastream Label', '#required' => 'TRUE', '#description' => t('A Human readable label'), @@ -674,35 +678,37 @@ class formClass { ); $form['#attributes']['enctype'] = 'multipart/form-data'; - $form['add-stream-file-location'] = array( + $form['fieldset']['add-stream-file-location'] = array( '#type' => 'file', '#title' => t('Upload Document'), '#size' => 48, // '#required'=>'TRUE', - '#description' => t('The file to upload.') + '#description' => t('The file to upload. (Only for Managed and Inline)') + ); + $form['fieldset']['ds_reference'] = array( + '#type' => 'textfield', + '#title' => t('Datastream reference'), + '#size' => 48, + '#description' => t('A URL reference to resolve for the contents of the datastream. (Required for External and Redirect, but will still work for Managed and Inline.)'), ); $form['#redirect'] = "fedora/repository/$pid/"; - $form['submit'] = array( + $form['fieldset']['submit'] = array( '#type' => 'submit', '#value' => t('Add Datastream') ); if (!empty($unused_dsids)) { - $dsidsForForm = array(); - foreach ($unused_dsids as $dsid) { - $dsidsForForm[$dsid] = $dsid; - } - $form['stream_id'] = array( + $form['fieldset']['stream_id'] = array( '#type' => 'select', '#title' => t('Datastream ID'), '#default_value' => variable_get('feed_item_length', 'teaser'), - '#weight' => '-1', + '#weight' => -1, '#description' => t('Datastream IDs defined by the content model.'), + '#options' => array_combine($unused_dsids, $unused_dsids), ); - $form['stream_id']['#options'] = array_combine($unused_dsids, $unused_dsids); } else { - $form['stream_id'] = array( + $form['fieldset']['stream_id'] = array( '#title' => 'Datastream ID', '#required' => 'TRUE', '#description' => t('An ID for this stream that is unique to this object. Must start with a letter and contain only alphanumeric characters and dashes and underscores.'), @@ -710,6 +716,18 @@ class formClass { '#weight' => -1, ); } + $form['fieldset']['control_group'] = array( + '#type' => 'select', + '#title' => t('Control group'), + '#options' => array( + 'X' => t('Inline XML'), + 'M' => t('Managed datastream'), + 'E' => t('Externally Referenced/managed datastream'), + 'R' => t('Redirect datastream'), + ), + '#description' => t('The manner in which the datastream will be stored. "Inline XML" must be XML and will be placed directly into the FOXML for the object. "Managed" datastreams are made to live on the filesystem as discrete files in the Fedora data directory. Both "Redirect" and "External" streams are URL references; the difference being the redirect stream instruct clients to perform an HTTP redirect, such that the data does not pass though Fedora (useful for streaming). External streams are mediated (by which I mean loaded and streamed from) the Fedora server.'), + '#weight' => 0, + ); return $form; } @@ -836,12 +854,33 @@ class formClass { $form = array(); $form['#attributes']['enctype'] = 'multipart/form-data'; - $form['file'] = array( - '#type' => 'file', - '#title' => t('Upload Document'), - '#description' => t('The file to upload.') - ); - + + module_load_include('inc', 'fedora_repository', 'api/fedora_item'); + $item = new Fedora_Item($pid); + $info = $item->get_datastream_info($dsId); + $control_group = $info->datastream->controlGroup; + if (in_array($control_group, array('M', 'X'))) { + $form['file'] = array( + '#type' => 'file', + '#title' => t('Upload Document'), + '#description' => t('A file with which to replace the contents of this datastream.'), + ); + } + if ($control_group != 'X') { + $form['reference'] = array( + '#type' => 'textfield', + '#title' => t('Reference to object'), + '#description' => t('A URL the datastream will be updated to reference.'), + ); + } + if ($control_group == 'M') { + $form['note'] = array( + '#type' => 'item', + '#title' => t('NOTE'), + '#value' => t('If both a file and a reference are given, the file will be given preference.'), + ); + } + $form['pid'] = array( '#type' => 'value', '#value' => $pid, From 8cfdc902ab4aed96ce89377b9947af994c241e9c Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 25 Apr 2012 10:32:26 -0300 Subject: [PATCH 05/27] Fix issue with downloading versioned datastreams. Had to do with migration to use of newer REST API; it takes the version parameter differently, as a query parameter instead of a position in the URL. --- ObjectHelper.inc | 14 +++++++++----- fedora_repository.module | 3 --- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/ObjectHelper.inc b/ObjectHelper.inc index e866f62f..c83c5eb8 100644 --- a/ObjectHelper.inc +++ b/ObjectHelper.inc @@ -72,7 +72,6 @@ class ObjectHelper { return ' '; } - if (variable_get('fedora_object_restrict_datastreams', FALSE) == TRUE) { if (($cm = ContentModel::loadFromObject($pid)) == FALSE) { drupal_set_message(t("You do not have access to objects without an Islandora Content Model."), 'error'); @@ -91,7 +90,6 @@ class ObjectHelper { module_load_include('inc', 'fedora_repository', 'api/fedora_item'); $item = new Fedora_Item($pid); - if (isset($item->datastreams[$dsID])) { $mimeType = $item->datastreams[$dsID]['MIMEType']; if ($label == NULL) { @@ -123,8 +121,14 @@ class ObjectHelper { $mimeType = 'image/jpeg'; } $url = variable_get('fedora_base_url', 'http://localhost:8080/fedora') . '/objects/' . $pid . '/datastreams/' . $dsID . '/content'; + $query_options = array(); if ($version) { - $url .= '/' . $version; //drupal_urlencode($version); + $query_options['asOfDateTime'] = $version; //drupal_urlencode($version); + } + if ($query_options) { + $url = url($url, array( + 'query' => $query_options, + )); } $ch = curl_init(); $user_agent = "Mozilla/4.0 pp(compatible; MSIE 5.01; Windows NT 5.0)"; @@ -184,7 +188,6 @@ class ObjectHelper { $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' @@ -195,7 +198,7 @@ class ObjectHelper { } header('HTTP/1.1 307 Moved Temporarily'); - header('Location: ' . $info . '?' . http_build_query($query)); //Fedora seems to discard the query portion. + header('Location: ' . url($info, array('query' => $query))); } 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) @@ -211,6 +214,7 @@ class ObjectHelper { } else { //Curl error... + watchdog('fedora_repository', 'Curl error. Info: @info', array('@info' => print_r(curl_getinfo($ch), TRUE)), WATCHDOG_WARNING); } } curl_close($ch); diff --git a/fedora_repository.module b/fedora_repository.module index 940d1585..28dc4e8e 100644 --- a/fedora_repository.module +++ b/fedora_repository.module @@ -2272,9 +2272,6 @@ function theme_fedora_repository_solution_packs_list($solution_packs) { $header = array(); $rows = array(); - - - drupal_add_css(drupal_get_path('module', 'update') . '/update.css'); return $output; } From 7bc755f231380e0b99f472c6877b32a52dd630fa Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 25 Apr 2012 11:04:13 -0300 Subject: [PATCH 06/27] Make control group selection optional. --- fedora_repository.module | 25 +++++++++++++------- formClass.inc | 50 +++++++++++++++++++++++++--------------- 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/fedora_repository.module b/fedora_repository.module index 28dc4e8e..f14dde6b 100644 --- a/fedora_repository.module +++ b/fedora_repository.module @@ -388,7 +388,7 @@ function add_stream_form_submit($form, &$form_state) { try { $item = new Fedora_Item($pid); - $item->add_datastream_from_url($form_state['storage']['stream_url'], $dsid, $dsLabel, $form_state['storage']['ds_mimetype'], $form_state['values']['control_group']); + $item->add_datastream_from_url($form_state['storage']['stream_url'], $dsid, $dsLabel, $form_state['storage']['ds_mimetype'], $form_state['storage']['control_group']); if ($file = $form_state['values']['add-stream-file-location']) { $object_helper = new ObjectHelper(); @@ -450,14 +450,12 @@ function add_stream_form_validate($form, &$form_state) { // 'file_validate_image_resolution' => array('85x85'), // 'file_validate_size' => array(30 * 1024), ); - - $mimetype = new MimeClass(); - $controlGroup = $form_state['values']['control_group']; - if (in_array($controlGroup, array('X', 'M')) && ($fileObject = file_save_upload('add-stream-file-location', $validators)) !== 0) { + + $controlGroup = $form_state['storage']['control_group'] = $form_state['values']['control_group']; + if ((($controlGroup && in_array($controlGroup, array('X', 'M'))) || !$controlGroup) && (($fileObject = file_save_upload('add-stream-file-location', $validators)) !== 0)) { // Move the uploaded file to Drupal's files directory. file_move($fileObject->filepath, 0, 'FILE_EXISTS_RENAME'); $form_state['values']['add-stream-file-location'] = $fileObject->filepath; - $form_state['storage']['ds_mimetype'] = $mimetype->getType($fileObject->filepath); $file_basename = basename($fileObject->filepath); $file_directory = dirname($fileObject->filepath); @@ -466,14 +464,25 @@ function add_stream_form_validate($form, &$form_state) { 'absolute' => TRUE, )); } - elseif (in_array($controlGroup, array('M', 'R', 'E')) && ($ref = $form_state['values']['ds_reference'])) { - $form_state['storage']['ds_mimetype'] = $mimetype->getType($ref); + elseif ($controlGroup && in_array($controlGroup, array('M', 'R', 'E')) && ($ref = $form_state['values']['ds_reference'])) { $form_state['storage']['stream_url'] = $form_state['values']['ds_reference']; } else { form_set_error('', t('No file given when "X" or "M", or no reference given when "M", "R" or "E".')); } + $mimeClass = new MimeClass(); + $mimetype = $form_state['storage']['ds_mimetype'] = $mimeClass->getType($form_state['storage']['stream_url']); + + if (!$controlGroup) { + if ($mimetype == 'text/xml') { + $form_state['storage']['control_group'] = 'X'; + } + else { + $form_state['storage']['control_group'] = 'M'; + } + } + // TODO: Add error checking here. $form_state['rebuild'] = FALSE; } diff --git a/formClass.inc b/formClass.inc index db90798c..a5f9bef6 100644 --- a/formClass.inc +++ b/formClass.inc @@ -331,6 +331,13 @@ class formClass { '#options' => array(ObjectHelper::$DISPLAY_ALWAYS => t('Always'), ObjectHelper::$DISPLAY_NEVER => t('Never'), ObjectHelper::$DISPLAY_NO_MODEL_OUTPUT => t('Only if no Content Model display output.')), '#description' => t('Determines when to display the list of objects when viewing a collection page.'), ); + + $form['advanced']['fedora_control_group_control_during_ingest'] = array( + '#type' => 'checkbox', + '#title' => t('Allow control groups select in datastream ingest'), + '#description' => t('Whether or not we should allow the user to select which control group to ingest a stream as, or to follow the old paradigm--to add stream IDed as XML as inline, and everything else as managed.'), + '#default_value' => variable_get('fedora_control_group_control_during_ingest', FALSE), + ); //Export functionality $form['advanced']['module']['export_area'] = array( @@ -685,12 +692,16 @@ class formClass { // '#required'=>'TRUE', '#description' => t('The file to upload. (Only for Managed and Inline)') ); - $form['fieldset']['ds_reference'] = array( - '#type' => 'textfield', - '#title' => t('Datastream reference'), - '#size' => 48, - '#description' => t('A URL reference to resolve for the contents of the datastream. (Required for External and Redirect, but will still work for Managed and Inline.)'), - ); + + if (variable_get('fedora_control_group_control_during_ingest', FALSE)) { + $form['fieldset']['ds_reference'] = array( + '#type' => 'textfield', + '#title' => t('Datastream reference'), + '#size' => 48, + '#description' => t('A URL reference to resolve for the contents of the datastream. (Required for External and Redirect, but will still work for Managed and Inline.)'), + ); + } + $form['#redirect'] = "fedora/repository/$pid/"; $form['fieldset']['submit'] = array( '#type' => 'submit', @@ -716,18 +727,21 @@ class formClass { '#weight' => -1, ); } - $form['fieldset']['control_group'] = array( - '#type' => 'select', - '#title' => t('Control group'), - '#options' => array( - 'X' => t('Inline XML'), - 'M' => t('Managed datastream'), - 'E' => t('Externally Referenced/managed datastream'), - 'R' => t('Redirect datastream'), - ), - '#description' => t('The manner in which the datastream will be stored. "Inline XML" must be XML and will be placed directly into the FOXML for the object. "Managed" datastreams are made to live on the filesystem as discrete files in the Fedora data directory. Both "Redirect" and "External" streams are URL references; the difference being the redirect stream instruct clients to perform an HTTP redirect, such that the data does not pass though Fedora (useful for streaming). External streams are mediated (by which I mean loaded and streamed from) the Fedora server.'), - '#weight' => 0, - ); + + if (variable_get('fedora_control_group_control_during_ingest', FALSE)) { + $form['fieldset']['control_group'] = array( + '#type' => 'select', + '#title' => t('Control group'), + '#options' => array( + 'X' => t('Inline XML'), + 'M' => t('Managed datastream'), + 'E' => t('Externally Referenced/managed datastream'), + 'R' => t('Redirect datastream'), + ), + '#description' => t('The manner in which the datastream will be stored. "Inline XML" must be XML and will be placed directly into the FOXML for the object. "Managed" datastreams are made to live on the filesystem as discrete files in the Fedora data directory. Both "Redirect" and "External" streams are URL references; the difference being the redirect stream instruct clients to perform an HTTP redirect, such that the data does not pass though Fedora (useful for streaming). External streams are mediated (by which I mean loaded and streamed from) the Fedora server.'), + '#weight' => 0, + ); + } return $form; } From 132248951db9ea383ce3d3c2a2d36a408da83e7a Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 25 Apr 2012 12:33:04 -0300 Subject: [PATCH 07/27] Fix error when label contains an extension. Error intro'd during datastream replace 'improvements'. --- fedora_repository.module | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/fedora_repository.module b/fedora_repository.module index f14dde6b..f5e8602e 100644 --- a/fedora_repository.module +++ b/fedora_repository.module @@ -674,10 +674,14 @@ function fedora_repository_replace_stream_form_validate($form, &$form_state) { return; } + /* ----------------------------------------------------------------- + * TODO: need a better way to get mimetypes + */ module_load_include('inc', 'fedora_repository', 'MimeClass'); $mime = new MimeClass(); + $mimetype = $form_state['storage']['mime_type'] = $mime->getType($file->filepath); - if ($mime->getType($file->filepath) == 'text/xml' && !DOMDocument::load($file->filepath)) { + if ($mimetype == 'text/xml' && !DOMDocument::load($file->filepath)) { form_set_error('file', 'Invalid XML format.'); return; } @@ -694,37 +698,28 @@ function fedora_repository_replace_stream_form_validate($form, &$form_state) { * @param array $form_state */ function fedora_repository_replace_stream_form_submit($form, &$form_state) { - global $base_url; $file = $form_state['values']['file']; - - if ($file !== NULL) { - $file = $form_state['values']['reference']; - } - + $pid = $form_state['values']['pid']; $dsid = $form_state['values']['dsId']; $dsLabel = $form_state['values']['dsLabel']; + $streamUrl = ($file !== NULL) ? + url($file->filepath, array('absolute' => TRUE)): + url($form_state['values']['reference'], array('absolute' => TRUE)); + // Remove the original file extension from the label and add the new one - $indexOfDot = strrpos($dsLabel, '.'); //use strrpos to get the last dot - if ($indexOfDot !== FALSE) { - $dsLabel = substr($dsLabel, 0, $indexOfDot); - $dsLabel .= substr($file->filename, strrpos($file->filename, '.')); // Add the file extention to the end of the label.; + // use strrpos to get the last dot + if (($indexOfDot = strrpos($dsLabel, '.')) !== FALSE) { + $dsLabel = substr($dsLabel, 0, $indexOfDot) . + substr($streamUrl, strrpos($streamUrl, '.')); // Add the file extention to the end of the label. } - $streamUrl = url($file->filepath, array( - 'absolute' => TRUE, - )); + - /* ----------------------------------------------------------------- - * TODO: need a better way to get mimetypes - */ - module_load_include('inc', 'fedora_repository', 'MimeClass'); - $mimetype = new MimeClass(); - $dformat = $mimetype->getType($file->filepath); + $dformat = $form_state['storage']['mime_type']; $item = new Fedora_Item($pid); - $item->modify_datastream($streamUrl, $dsid, $dsLabel, $dformat); $form_state['redirect'] = 'fedora/repository/' . $pid; From 5b3fe1ef7627d9b6cf5b326dfdaa70b6b3a0aff5 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Thu, 26 Apr 2012 09:48:03 -0300 Subject: [PATCH 08/27] Use Sparql query for breadcrumbs. --- ObjectHelper.inc | 52 +++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/ObjectHelper.inc b/ObjectHelper.inc index c83c5eb8..1a60784b 100644 --- a/ObjectHelper.inc +++ b/ObjectHelper.inc @@ -969,21 +969,33 @@ class ObjectHelper { $breadcrumbs[] = l(t('Home'), ''); } 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'; - - if (count($results = self::performItqlQuery($query_string)) > 0 && $level > 0) { + $sparql_query_string = << +PREFIX rels-ext: +SELECT ?parentObject ?title ?content +FROM <#ri> +WHERE { + ?this fedora-model:label ?title ; + ?relationship ?parentObject . + ?parentObject fedora-model:state fedora-model:Active ; + fedora-model:hasModel ?content . + FILTER( + sameTerm(?this, ) && + ( + sameTerm(?relationship, rels-ext:isMemberOfCollection) || + sameTerm(?relationship, rels-ext:isMemberOf) || + sameTerm(?relationship, rels-ext:isPartOf) + ) && + !sameTerm(?content, ) + ) . +} +ORDER BY DESC(?title) +EOQ; + + $results = self::performSparqlQuery($sparql_query_string); + $next_pid = NULL; + + if (count($results) > 0 && $level > 0) { $parent = $results[0]['parentObject']; $this_title = $results[0]['title']; @@ -993,13 +1005,17 @@ class ObjectHelper { $breadcrumbs[] = l($this_title, "fedora/repository/$pid"); - $level--; - $this->getBreadcrumbs($parent, $breadcrumbs); + $next_pid = $parent; } else { watchdog('fedora_repository', 'Error generating breadcrumbs for %pid. Verify there exists relationships back up to %root. (May also be due to a hierarchy deeper than %max_depth).', array('%pid' => $pid, '%root' => $root, '%max_depth' => $max_depth), WATCHDOG_WARNING); $breadcrumbs[] = '...'; //Add an non-link, as we don't know how to get back to the root. - $this->getBreadcrumbs($root, $breadcrumbs); //And render the last two links and break (on the next pass). + $next_pid = $root; //And cue the last two links to render and break recursion (on the next pass). + } + + if ($next_pid !== NULL) { + $level--; + $this->getBreadcrumbs($next_pid, $breadcrumbs); } } } From 3696cab9eac8832e4a9ba09ffc6bfd4ca9338333 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Thu, 26 Apr 2012 10:03:45 -0300 Subject: [PATCH 09/27] Generate the download form. ... As opposed to spitting out markup for it directly. --- ObjectHelper.inc | 18 +++--------------- fedora_repository.module | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/ObjectHelper.inc b/ObjectHelper.inc index 1a60784b..aa093839 100644 --- a/ObjectHelper.inc +++ b/ObjectHelper.inc @@ -359,7 +359,7 @@ class ObjectHelper { $content = ''; $id = $dataStreamValue->ID; $label = $dataStreamValue->label; - $label = str_replace("_", " ", $label); + //$label = str_replace("_", " ", $label); $label_deslashed = preg_replace('/\//i', '${1}_', $label); // Necessary to handle the case of Datastream labels that contain slashes. Ugh. $mimeType = $dataStreamValue->MIMEType; @@ -368,20 +368,8 @@ class ObjectHelper { 'target' => '_blank', ), )); - $action = url("fedora/repository/object_download/$pid/$id/$label_deslashed"); - $downloadVersion = '
'; - if (user_access(ObjectHelper::$EDIT_FEDORA_METADATA)) { - $versions = $item->get_datastream_history($id); - if (is_array($versions)) { - $downloadVersion = '
'; - $downloadVersion .= ''; - $downloadVersion .= '
'; - } - } + + $downloadVersion = drupal_get_form('fedora_repository_download_datastream_form', $pid, $id, $label_deslashed); return array( array( diff --git a/fedora_repository.module b/fedora_repository.module index f5e8602e..5b6052b1 100644 --- a/fedora_repository.module +++ b/fedora_repository.module @@ -623,6 +623,42 @@ function fedora_repository_purge_stream_form_submit($form, &$form_state) { $form_state['redirect'] = $base_url . "/fedora/repository/$pid"; } +function fedora_repository_download_datastream_form(&$form_state, $pid, $dsid, $label) { + $form = array( + '#action' => url("fedora/repository/object_download/$pid/$dsid/$label"), + 'submit' => array( + '#type' => 'submit', + '#value' => t('Download'), + ), + ); + + if (user_access(ObjectHelper::$EDIT_FEDORA_METADATA)) { + $item = new Fedora_Item($pid); + $versions = $item->get_datastream_history($dsid); + $version_array = array(); + if (is_array($versions)) { + foreach ($versions as $version) { + $version_array[] = $version->createDate; + } + } + else { + $version_array[] = $versions->createDate; + } + + if (count($version_array) > 1) { + $form['#attributes'] = array( + 'onsubmit' => 'this.action="' . $form['#action'] . '/" + this.version.value;' + ); + $form['version'] = array( + '#type' => 'select', + '#options' => array_combine($version_array, $version_array), + ); + } + } + + return $form; +} + /** * fedora repository replace stream * @param type $pid From 6006effbb359b441785d5b621dc200083f0c045c Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Thu, 26 Apr 2012 16:05:48 -0300 Subject: [PATCH 10/27] Make a little closed to convertQDC.xsl --- ObjectHelper.inc | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/ObjectHelper.inc b/ObjectHelper.inc index 3979aaba..2534540b 100644 --- a/ObjectHelper.inc +++ b/ObjectHelper.inc @@ -448,16 +448,35 @@ class ObjectHelper { $rows = array(); foreach ($simplexml->getNamespaces(TRUE) as $ns) { foreach ($simplexml->children($ns) as $child) { - $rows[] = array( - array( - 'data' => $child->getName(), - 'class' => 'dc-tag-name', - ), - array( - 'data' => (string)$child, - 'class' => 'dc-content', - ), - ); + $data = array(); + $rendered_data = ''; + if ($grand_children = $child->children()) { + foreach($grand_children as $grand_child) { + $data[] = $grand_child->tagName() . ' = ' . (string)$grand_child; + } + } + else { + $rendered_data = (string)$child; + } + + if ($data) { + $rendered_data = theme('item_list', $data); + } + + if ($rendered_data) { + $rows[] = array( + array( + 'data' => $child->getName(), + 'class' => 'dc-tag-name', + ), + array( + 'data' => $rendered_data, + 'class' => 'dc-content', + ), + ); + } + + } } From 278afdf4d80eca6239a73f449bbb8759c7553097 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Thu, 26 Apr 2012 16:06:27 -0300 Subject: [PATCH 11/27] Fix syntax error involving reference. --- plugins/tagging_form.inc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/tagging_form.inc b/plugins/tagging_form.inc index f00274d4..ae3bba92 100644 --- a/plugins/tagging_form.inc +++ b/plugins/tagging_form.inc @@ -61,10 +61,11 @@ function fedora_repository_image_tagging_form($form_state, $pid) { $tagset = new TagSet($obj); $tags = array(); foreach ($tagset->tags as $tag) { - $form_tag =& $form['tags-wrapper']['tags'][$tag['name']] = array( + $form['tags-wrapper']['tags'][$tag['name']] = array( '#prefix' => '
  • ', '#suffix' => '
  • ', ); + $form_tag =& $form['tags-wrapper']['tags'][$tag['name']]; $tag_title_text = t('Added by @creator.', array( '@creator' => $tag['creator'], From 08545aa19498bd7bd76e0bca7bcd543f7b1aff59 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Thu, 26 Apr 2012 16:07:41 -0300 Subject: [PATCH 12/27] Fix error message. Was using wrong variable name. --- ObjectHelper.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ObjectHelper.inc b/ObjectHelper.inc index aa093839..f8195a11 100644 --- a/ObjectHelper.inc +++ b/ObjectHelper.inc @@ -996,7 +996,7 @@ EOQ; $next_pid = $parent; } else { - watchdog('fedora_repository', 'Error generating breadcrumbs for %pid. Verify there exists relationships back up to %root. (May also be due to a hierarchy deeper than %max_depth).', array('%pid' => $pid, '%root' => $root, '%max_depth' => $max_depth), WATCHDOG_WARNING); + watchdog('fedora_repository', 'Error generating breadcrumbs for %pid. Verify there exists relationships back up to %root. (May also be due to a hierarchy deeper than %max_depth).', array('%pid' => $pid, '%root' => $root, '%max_depth' => $max_level), WATCHDOG_WARNING); $breadcrumbs[] = '...'; //Add an non-link, as we don't know how to get back to the root. $next_pid = $root; //And cue the last two links to render and break recursion (on the next pass). } From 27d6c763ff52d53ceb104a4e7adaac30adca03d5 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Fri, 27 Apr 2012 10:12:02 -0300 Subject: [PATCH 13/27] Fix syntax error. --- plugins/tagging_form.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/tagging_form.inc b/plugins/tagging_form.inc index ae3bba92..9b7c4658 100644 --- a/plugins/tagging_form.inc +++ b/plugins/tagging_form.inc @@ -70,7 +70,7 @@ function fedora_repository_image_tagging_form($form_state, $pid) { $tag_title_text = t('Added by @creator.', array( '@creator' => $tag['creator'], )); - $tag_mnpl_search_path = "fedora/repository/mnpl_advanced_search/tag:{$tag['name']}" + $tag_mnpl_search_path = "fedora/repository/mnpl_advanced_search/tag:{$tag['name']}"; $form_tag['tag'] = array( '#value' => l($tag['name'], $tag_mnpl_search_path, array('attributes' => array( 'title' => $tag_title_text From 2ac5ad45c7707d19ead5675053ced284f0c0742c Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Fri, 27 Apr 2012 10:12:21 -0300 Subject: [PATCH 14/27] Try to use covertQDC.xsl before using the Drupal's table generating business. --- ObjectHelper.inc | 87 ++++++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 39 deletions(-) diff --git a/ObjectHelper.inc b/ObjectHelper.inc index 603c2189..ce8abbcb 100644 --- a/ObjectHelper.inc +++ b/ObjectHelper.inc @@ -429,50 +429,59 @@ class ObjectHelper { return ''; } - $simplexml = new SimpleXMLElement($xmlstr); + if (($xsl_path = "$path/xsl/convertQDC.xsl") && + ($xsl = DOMDocument::load($xsl_path)) && + ($ds = DOMDocument::loadXML($xmlstr))) { + $transform = new XSLTProcessor(); + $transform->importStylesheet($domdoc); + return $transform->transformToHTML($ds); + } + else { + $simplexml = new SimpleXMLElement($xmlstr); - $headers = array( - array( - 'data' => t('Metadata'), - 'colspan' => 2, - ), - ); - $rows = array(); - foreach ($simplexml->getNamespaces(TRUE) as $ns) { - foreach ($simplexml->children($ns) as $child) { - $data = array(); - $rendered_data = ''; - if ($grand_children = $child->children()) { - foreach($grand_children as $grand_child) { - $data[] = $grand_child->tagName() . ' = ' . (string)$grand_child; + $headers = array( + array( + 'data' => t('Metadata'), + 'colspan' => 2, + ), + ); + $rows = array(); + foreach ($simplexml->getNamespaces(TRUE) as $ns) { + foreach ($simplexml->children($ns) as $child) { + $data = array(); + $rendered_data = ''; + if ($grand_children = $child->children()) { + foreach($grand_children as $grand_child) { + $data[] = $grand_child->getName() . ' = ' . (string)$grand_child; + } } + else { + $rendered_data = (string)$child; + } + + if ($data) { + $rendered_data = theme('item_list', $data); + } + + if ($rendered_data) { + $rows[] = array( + array( + 'data' => $child->getName(), + 'class' => 'dc-tag-name', + ), + array( + 'data' => $rendered_data, + 'class' => 'dc-content', + ), + ); + } + + } - else { - $rendered_data = (string)$child; - } - - if ($data) { - $rendered_data = theme('item_list', $data); - } - - if ($rendered_data) { - $rows[] = array( - array( - 'data' => $child->getName(), - 'class' => 'dc-tag-name', - ), - array( - 'data' => $rendered_data, - 'class' => 'dc-content', - ), - ); - } - - } - } - return theme('table', $headers, $rows, array('class' => 'dc-table')); + return theme('table', $headers, $rows, array('class' => 'dc-table')); + } } /** From 1460b8e5cea623ccbcacd9e32ca0e9ae92e3e3b6 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Fri, 27 Apr 2012 10:16:54 -0300 Subject: [PATCH 15/27] Fix error. --- ObjectHelper.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ObjectHelper.inc b/ObjectHelper.inc index ce8abbcb..0aa5f590 100644 --- a/ObjectHelper.inc +++ b/ObjectHelper.inc @@ -433,8 +433,8 @@ class ObjectHelper { ($xsl = DOMDocument::load($xsl_path)) && ($ds = DOMDocument::loadXML($xmlstr))) { $transform = new XSLTProcessor(); - $transform->importStylesheet($domdoc); - return $transform->transformToHTML($ds); + $transform->importStylesheet($xsl); + return $transform->transformToXML($ds); } else { $simplexml = new SimpleXMLElement($xmlstr); From 7645a7b438e71d8d500f1d8863ebf7baf391173d Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Fri, 27 Apr 2012 10:38:21 -0300 Subject: [PATCH 16/27] Format XSLT and pass parameters. --- ObjectHelper.inc | 10 +++++++- xsl/convertQDC.xsl | 62 +++++++++++++++++++++++----------------------- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/ObjectHelper.inc b/ObjectHelper.inc index 0aa5f590..ac5f9048 100644 --- a/ObjectHelper.inc +++ b/ObjectHelper.inc @@ -432,9 +432,17 @@ class ObjectHelper { if (($xsl_path = "$path/xsl/convertQDC.xsl") && ($xsl = DOMDocument::load($xsl_path)) && ($ds = DOMDocument::loadXML($xmlstr))) { + $xslt_opts = array( + 'BASEURL' => $base_url, + 'PATH' => url($path, array('absolute' => TRUE)), + 'baseUrl' => $base_url, //XXX: Deprecated; just here for legacy cases. + 'path' => url($path, array('absolute' => TRUE)), //XXX: Deprecated; just here for legacy cases. + ); $transform = new XSLTProcessor(); $transform->importStylesheet($xsl); - return $transform->transformToXML($ds); + $transform->setParameter('', $xslt_opts); + $transformed = $transform->transformToDoc($ds); + return $transformed->saveHTML(); } else { $simplexml = new SimpleXMLElement($xmlstr); diff --git a/xsl/convertQDC.xsl b/xsl/convertQDC.xsl index 5d881e35..62edd12e 100644 --- a/xsl/convertQDC.xsl +++ b/xsl/convertQDC.xsl @@ -1,33 +1,33 @@ - - - - - - - - -
    - - - - - - - - - - -

    MetaData

    - -
    - = -
    -
    -
    - -
    - - -
    \ No newline at end of file + + + + + +
    + + + + + + + + + + + + + + + + + +

    MetaData

    + +
    +
    +
    +
    +
    + From 47d85f6a6fbf421dde4c43bfff00a6697518d9f2 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Fri, 27 Apr 2012 10:45:56 -0300 Subject: [PATCH 17/27] Add comments and rename XSLT so it is not used by default... The XSLT will still be used if it is present, though. --- ObjectHelper.inc | 3 +-- xsl/{convertQDC.xsl => convertQDC.xsl.deprecated} | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) rename xsl/{convertQDC.xsl => convertQDC.xsl.deprecated} (85%) diff --git a/ObjectHelper.inc b/ObjectHelper.inc index ac5f9048..f2d47e0e 100644 --- a/ObjectHelper.inc +++ b/ObjectHelper.inc @@ -420,7 +420,6 @@ class ObjectHelper { function getFormattedDC($item) { global $base_url; $path = drupal_get_path('module', 'fedora_repository'); - module_load_include('inc', 'fedora_repository', 'ConnectionHelper'); $dsid = array_key_exists('QDC', $item->get_datastreams_list_as_array()) ? 'QDC' : 'DC'; $xmlstr = $item->get_datastream_dissemination($dsid); @@ -430,7 +429,7 @@ class ObjectHelper { } if (($xsl_path = "$path/xsl/convertQDC.xsl") && - ($xsl = DOMDocument::load($xsl_path)) && + ($xsl = DOMDocument::load($xsl_path)) && //Fails loading XSLT -> FALSE ($ds = DOMDocument::loadXML($xmlstr))) { $xslt_opts = array( 'BASEURL' => $base_url, diff --git a/xsl/convertQDC.xsl b/xsl/convertQDC.xsl.deprecated similarity index 85% rename from xsl/convertQDC.xsl rename to xsl/convertQDC.xsl.deprecated index 62edd12e..724f7c70 100644 --- a/xsl/convertQDC.xsl +++ b/xsl/convertQDC.xsl.deprecated @@ -1,4 +1,5 @@ + From 01c5a4736f1d12795512b92956f4d4de77bcf36c Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Fri, 27 Apr 2012 14:51:12 -0300 Subject: [PATCH 18/27] Fix error in CollectionClass. Was able to instantiate without a PID, which would mean that the 'collectionObject' object helper would not get created... Blargh. --- CollectionClass.inc | 8 +++----- ObjectHelper.inc | 2 -- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/CollectionClass.inc b/CollectionClass.inc index 5882a460..2ac6facc 100644 --- a/CollectionClass.inc +++ b/CollectionClass.inc @@ -28,11 +28,9 @@ class CollectionClass { * @return CollectionClass */ function __construct($pid = NULL) { - if (!empty($pid)) { - module_load_include('inc', 'fedora_repository', 'ObjectHelper'); - $this->collectionObject = new ObjectHelper($pid); - $this->pid = $pid; - } + module_load_include('inc', 'fedora_repository', 'ObjectHelper'); + $this->collectionObject = new ObjectHelper(); + $this->pid = $pid; } public static function getCollectionQuery($pid) { diff --git a/ObjectHelper.inc b/ObjectHelper.inc index f2d47e0e..01a2b0a5 100644 --- a/ObjectHelper.inc +++ b/ObjectHelper.inc @@ -32,8 +32,6 @@ class ObjectHelper { drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); module_load_include('inc', 'fedora_repository', 'ConnectionHelper'); $connectionHelper = new ConnectionHelper(); - //$this->fedoraUser = $connectionHelper->getUser(); - //$this->fedoraPass = $connectionHelper->getPassword(); } private static function getBinaryLength($bin) { From 6d57165be044c0f871cf0b879a3a3a6c224ad1dd Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Mon, 30 Apr 2012 18:08:46 -0300 Subject: [PATCH 19/27] Avoid warning/error when file does not exist. --- ObjectHelper.inc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ObjectHelper.inc b/ObjectHelper.inc index f2d47e0e..9e06facf 100644 --- a/ObjectHelper.inc +++ b/ObjectHelper.inc @@ -2,7 +2,7 @@ /** - * @file + * @file * Object Helper Class */ @@ -429,6 +429,7 @@ class ObjectHelper { } if (($xsl_path = "$path/xsl/convertQDC.xsl") && + (is_readable($xsl_path)) && ($xsl = DOMDocument::load($xsl_path)) && //Fails loading XSLT -> FALSE ($ds = DOMDocument::loadXML($xmlstr))) { $xslt_opts = array( From 5655a5170beea922607d98258cda2942bc3eedbc Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Mon, 30 Apr 2012 18:19:57 -0300 Subject: [PATCH 20/27] Extract Drupal collection view assembly into separate function. Hurray for enabling code reuse! --- CollectionClass.inc | 118 ++++++++++++++++++++++++++++---------------- 1 file changed, 76 insertions(+), 42 deletions(-) diff --git a/CollectionClass.inc b/CollectionClass.inc index 5882a460..93733259 100644 --- a/CollectionClass.inc +++ b/CollectionClass.inc @@ -672,6 +672,75 @@ class CollectionClass { return $page; } + /** + * Assemble results in a somewhat more logical manner... + * + * ... Compared to generating a table in XSLT to contain a list (as + * renderCollection() used to do/does by default). + * + * @param $sparql_results array + * The array of results as yielded by ObjectHelper::parseSparqlResults() + * (and those associated functions which make use of it) + * @return + * An array to be passed to drupal_render, containing a pager, an unordered + * list of items, and another pager. + */ + public static function assembleCollectionView($sparql_results) { + $per_page = 20; //XXX: Make this configurable. + $pager_name = 0; + $total = count($sparql_results); + $pager_page = self::hackPager($pager_name, $per_page, $total); + + $results = array(); + foreach (array_slice($sparql_results, $per_page * $pager_page, $per_page) as $result) { + $title = $result['title']; + $obj_path = "fedora/repository/{$result['object']}"; + $tn_path = ($result['thumbnail'] ? + "fedora/repository/{$result['thumbnail']}": + "$obj_path/TN"); + $thumbnail = theme('image', $tn_path, $title, $title, array(), FALSE); + $results[] = array( + 'data' => l($thumbnail, $obj_path, array( + 'html' => TRUE, + 'attributes' => array( + 'class' => 'results-image', + ), + )) . l($title, $obj_path, array('attributes' => array('class' => 'results-text'))), + ); + } + if (!$results) { + drupal_set_message(t("No objects in this collection (or bad query).")); + } + else { + $first = $per_page * $pager_page; + $last = (($total - $first) > $per_page)? + ($first + $per_page): + $total; + $results_range_text = t('Results @first to @last of @total', array( + '@first' => $first + 1, + '@last' => $last, + '@total' => $total, + )); + + return array( + array( + '#type' => 'markup', + '#value' => theme('pager', array(), $per_page, $pager_name), + ), + array( + '#type' => 'markup', + '#value' => theme('item_list', $results, $result_range_text, 'ul', array( + 'class' => 'islandora-collection-results-list', + )) + ), + array( + '#type' => 'markup', + '#value' => theme('pager', array(), $per_page, $pager_name) + ), + ); + } + } + /** * render collection * @global type $base_url @@ -703,48 +772,13 @@ class CollectionClass { $objectList = ''; if (isset($content) && $content != FALSE) { if (!$xslContent) { //Didn't find an XSLT. - $intermediate_results = ObjectHelper::parse_sparql_results($content); - unset($content); - - $per_page = 20; //XXX: Make this configurable. - $pager_name = 0; - $total = count($intermediate_results); - $pager_page = self::hackPager($pager_name, $per_page, $total); - - $results = array(); - foreach (array_slice($intermediate_results, $per_page * $pager_page, $per_page) as $result) { - $title = $result['title']; - $obj_path = "fedora/repository/{$result['object']}"; - $thumbnail = theme('image', "$obj_path/TN", $title, $title, array(), FALSE); - $results[] = array( - 'data' => l($thumbnail, $obj_path, array( - 'html' => TRUE, - 'attributes' => array( - 'class' => 'results-image', - ), - )) . l($title, $obj_path, array('attributes' => array('class' => 'results-text'))), - ); - } - if (!$results) { - drupal_set_message(t("No objects in this collection (or bad query).")); - } - else { - $first = $per_page * $pager_page; - $last = (($total - $first) > $per_page)? - ($first + $per_page): - $total; - $results_range_text = t('Results @first to @last of @total', array( - '@first' => $first + 1, - '@last' => $last, - '@total' => $total, - )); - //$objectList = '

    ' . $results_range_text . '

    '; - $objectList .= theme('pager', array(), $per_page, $pager_name); - $objectList .= theme('item_list', $results, $result_range_text, 'ul', array( - 'class' => 'islandora-collection-results-list', - )); - $objectList .= theme('pager', array(), $per_page, $pager_name); - } + return drupal_render( + self::assembleCollectionView( + $this->collectionObject->parseSparqlResults( + $content + ) + ) + ); } else { if (!$pageNumber) { From ee2477df91ef79fa1ae6714decda506fe9bea3f0 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Mon, 30 Apr 2012 18:20:50 -0300 Subject: [PATCH 21/27] Add the page parameter to the islandora_tabs hook call. ... Facilitates implementation of equivalent functionality, where the object was instantiated with the PID, and then the page was passed to the method declared in your ISLANDORACM stream. --- fedora_repository.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fedora_repository.module b/fedora_repository.module index 5b6052b1..a9209294 100644 --- a/fedora_repository.module +++ b/fedora_repository.module @@ -1071,7 +1071,7 @@ function fedora_repository_get_items($pid = NULL, $dsId = NULL, $collection = NU $object_details = array(); } - $hook_tabs = module_invoke_all('islandora_tabs', $content_models, $pid); + $hook_tabs = module_invoke_all('islandora_tabs', $content_models, $pid, $page_number); $cmodels_tabs = array_merge($cmodels_tabs, $object_details, $hook_tabs); return tabs_render($cmodels_tabs); From d2b0a11a7a065ad641743d0d44bd1e6d4eb6e9b7 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Tue, 1 May 2012 14:20:46 -0300 Subject: [PATCH 22/27] Truncate titles for regular display to 60 character +/- a word. Should make the length an actual configurable value... Shouldn't be hard, though. --- CollectionClass.inc | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/CollectionClass.inc b/CollectionClass.inc index 18d5a107..b027ac4c 100644 --- a/CollectionClass.inc +++ b/CollectionClass.inc @@ -687,23 +687,27 @@ class CollectionClass { $per_page = 20; //XXX: Make this configurable. $pager_name = 0; $total = count($sparql_results); - $pager_page = self::hackPager($pager_name, $per_page, $total); + $pager_page = self::hackPager($pager_name, $per_page, $total); + $max_title_length = 60; $results = array(); foreach (array_slice($sparql_results, $per_page * $pager_page, $per_page) as $result) { - $title = $result['title']; + $title = $result['title']; + $truncated_title = truncate_utf8($title, $max_title_length, TRUE, TRUE, 5); $obj_path = "fedora/repository/{$result['object']}"; $tn_path = ($result['thumbnail'] ? "fedora/repository/{$result['thumbnail']}": - "$obj_path/TN"); - $thumbnail = theme('image', $tn_path, $title, $title, array(), FALSE); + "$obj_path/TN"); + + $thumbnail = theme('image', $tn_path, $truncated_title, $title, array(), FALSE); + $results[] = array( 'data' => l($thumbnail, $obj_path, array( 'html' => TRUE, 'attributes' => array( 'class' => 'results-image', ), - )) . l($title, $obj_path, array('attributes' => array('class' => 'results-text'))), + )) . l($truncated_title, $obj_path, array('attributes' => array('class' => 'results-text'))), ); } if (!$results) { From ee2b6a95882bb3269c5668679e79667df516fb9b Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Tue, 1 May 2012 14:22:19 -0300 Subject: [PATCH 23/27] Use hook_islandora_tabs() to add ALL the tabs. ... Including those provided by islandora proper. --- fedora_repository.module | 109 +++++++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 45 deletions(-) diff --git a/fedora_repository.module b/fedora_repository.module index a9209294..fec7256e 100644 --- a/fedora_repository.module +++ b/fedora_repository.module @@ -951,6 +951,63 @@ function makeObject($pid, $dsID) { $objectHelper->makeObject($pid, $dsID); } +/** + * Implementation of hook_islandora_tabs(). + * + * @param $content_models array + * An array of ContentModel objects to which the current Fedora Object + * subscribes. + * @param $pid string + * A string containing the Fedora PID of the current Fedora Object. + * @param $page_number integer + * An integer for which page we should start on in the loaded object. + * @return array + * An array containing a tabset (an array of tabpages), renderable with + * drupal_render(). + */ +function fedora_repository_islandora_tabs($content_models, $pid, $page_number) { + $cmodels_tabs = array( + '#type' => 'tabset', + ); + + foreach ($content_models as $content_model) { + $content_model_fieldset = $content_model->displayExtraFieldset($pid, $page_number); + + // Each content model may return either a tabpage array or plain HTML. If + // it is HTML, stick it in a tabpage. + if (is_array($content_model_fieldset)) { + $cmodels_tabs = array_merge($cmodels_tabs, $content_model_fieldset); + } + else { + $cmodels_tabs[$content_model->pid] = array( + '#type' => 'tabpage', + '#title' => $content_model->name, + '#content' => $content_model_fieldset, + ); + } + } + + // Add a 'manage object' tab for all objects, where detailed list of content is shown. + // XXX: Perhaps this should be extracted into its own object? + module_load_include('inc', 'fedora_repository', 'plugins/FedoraObjectDetailedContent'); + $obj = new FedoraObjectDetailedContent($pid); + + //can disable showing the object details tab in admin UI + if (variable_get('fedora_repository_show_object_details_tab', TRUE)) { + $object_details = $obj->showFieldSets(); + if ($object_details['fedora_object_details']['#selected'] == TRUE) { + foreach (element_children($cmodels_tabs) as $key) { + $cmodels_tabs[$key]['#selected'] = FALSE; + } + } + } + else { + $object_details = array(); + } + + return array_merge($cmodels_tabs, $object_details); +} + /** * Sends an ITQL query to the Fedora Resource index (can only communicate with Kowari or mulgara) * Reads the pid and datastream id as url parameters. Queries the collection object for the query @@ -984,7 +1041,7 @@ function fedora_repository_get_items($pid = NULL, $dsId = NULL, $collection = NU $pid = variable_get('fedora_repository_pid', 'islandora:root'); } - $item = new fedora_item($pid); + $item = new Fedora_Item($pid); if (!$item->exists()) { drupal_not_found(); exit(); @@ -1023,57 +1080,19 @@ function fedora_repository_get_items($pid = NULL, $dsId = NULL, $collection = NU return makeObject($pid, $dsId); } - $content = '
    '; - - module_load_include('inc', 'fedora_repository', 'CollectionClass'); - $collectionClass = new CollectionClass(); - module_load_include('inc', 'fedora_repository', 'ContentModel'); - module_load_include('inc', 'fedora_repository', 'plugins/FedoraObjectDetailedContent'); $breadcrumbs = array(); $objectHelper->getBreadcrumbs($pid, $breadcrumbs); drupal_set_breadcrumb(array_reverse($breadcrumbs)); - $offset = $limit * $page_number; $content_models = $objectHelper->get_content_models_list($pid); -// Each content model may return either a tabset array or plain HTML. If it's HTML, stick it in a tab. - $cmodels_tabs = array( - '#type' => 'tabset', - ); - foreach ($content_models as $content_model) { - $content_model_fieldset = $content_model->displayExtraFieldset($pid, $page_number); - if (is_array($content_model_fieldset)) { - $cmodels_tabs = array_merge($cmodels_tabs, $content_model_fieldset); - } - else { - $cmodels_tabs[$content_model->pid] = array( - '#type' => 'tabpage', - '#title' => $content_model->name, - '#content' => $content_model_fieldset, - ); - } - } -// Add a 'manage object' tab for all objects, where detailed list of content is shown. - $obj = new FedoraObjectDetailedContent($pid); - - //can disable showing the object details tab in admin UI - if (variable_get('fedora_repository_show_object_details_tab', TRUE)) { - $object_details = $obj->showFieldSets(); - if ($object_details['fedora_object_details']['#selected'] == TRUE) { - foreach ($cmodels_tabs as &$cmodel_tab) { - if (is_array($cmodel_tab)) { - $cmodel_tab['#selected'] = FALSE; - } - } - } - } - else { - $object_details = array(); - } - $hook_tabs = module_invoke_all('islandora_tabs', $content_models, $pid, $page_number); - $cmodels_tabs = array_merge($cmodels_tabs, $object_details, $hook_tabs); - + + $cmodels_tabs = array( + '#type' => 'tabset', + ); + + $cmodels_tabs = array_merge($cmodels_tabs, $hook_tabs); return tabs_render($cmodels_tabs); } From 83cd4b871a063992589d0ff3245747036b310744 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Tue, 1 May 2012 14:46:45 -0300 Subject: [PATCH 24/27] Introduce hook_islandora_tabs_alter(). Called just before return of drupal_render()'d markup. Passed the tabset and associative array of the parameters with which hook_islandora_tabs() was called; that is: array( 'content_models' => {an array of ContentModel objects}, 'pid' => {the PID of the object being rendered}, 'page' => {the page of the object to be displayed}, ) --- fedora_repository.module | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/fedora_repository.module b/fedora_repository.module index fec7256e..7a1c7946 100644 --- a/fedora_repository.module +++ b/fedora_repository.module @@ -1086,13 +1086,24 @@ function fedora_repository_get_items($pid = NULL, $dsId = NULL, $collection = NU $content_models = $objectHelper->get_content_models_list($pid); + //Get the tabs from all modules... $hook_tabs = module_invoke_all('islandora_tabs', $content_models, $pid, $page_number); $cmodels_tabs = array( '#type' => 'tabset', ); - $cmodels_tabs = array_merge($cmodels_tabs, $hook_tabs); + + //Assemble parameters, to pass during alter + $params = array( + 'content_models' => $content_models, + 'pid' => $pid, + 'page' => $page_number, + ); + + //Allow returned tabs to be altered, before return. + drupal_alter('islandora_tabs', $cmodels_tabs, $params); + return tabs_render($cmodels_tabs); } From 73c55ca3caffa0f8e8c5c4ad295d955af9f25b98 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Tue, 1 May 2012 15:10:09 -0300 Subject: [PATCH 25/27] Use hook_islandora_tabs_alter() to ensure that fedora_object_details tab remains selected. --- fedora_repository.module | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/fedora_repository.module b/fedora_repository.module index 7a1c7946..a1151afd 100644 --- a/fedora_repository.module +++ b/fedora_repository.module @@ -994,20 +994,36 @@ function fedora_repository_islandora_tabs($content_models, $pid, $page_number) { //can disable showing the object details tab in admin UI if (variable_get('fedora_repository_show_object_details_tab', TRUE)) { - $object_details = $obj->showFieldSets(); - if ($object_details['fedora_object_details']['#selected'] == TRUE) { - foreach (element_children($cmodels_tabs) as $key) { - $cmodels_tabs[$key]['#selected'] = FALSE; - } - } - } - else { - $object_details = array(); + $object_details = $obj->showFieldSets(); + $cmodel_tabs = array_merge($cmodels_tabs, $object_details); } return array_merge($cmodels_tabs, $object_details); } +/** + * Implementation of hook_islandora_tabs_alter(). + * + * @param &$tabs array + * The array of tabs/tabset to alter. + * @param $params array + * An associative array containing the parameters with which the original + * hook was called. + * @see fedora_repository_get_items() + */ +function fedora_repository_islandora_tabs_alter(&$tabs, $params) { + //Deselect all other tabs if the fedora_object_details tab is supposed + // to be selected. + $object_details_key = 'fedora_object_details'; + if ($tabs[$object_details_key]['#selected']) { + foreach (element_children($tabs) as $key) { + if ($key != $object_details_key) { + $tabs[$key]['#selected'] = FALSE; + } + } + } +} + /** * Sends an ITQL query to the Fedora Resource index (can only communicate with Kowari or mulgara) * Reads the pid and datastream id as url parameters. Queries the collection object for the query From c7e05f4c3004ac7a58ebab0b558cc39314e68639 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Tue, 1 May 2012 15:52:04 -0300 Subject: [PATCH 26/27] Improve code documentation. --- fedora_repository.module | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/fedora_repository.module b/fedora_repository.module index a1151afd..886ab4d6 100644 --- a/fedora_repository.module +++ b/fedora_repository.module @@ -966,9 +966,7 @@ function makeObject($pid, $dsID) { * drupal_render(). */ function fedora_repository_islandora_tabs($content_models, $pid, $page_number) { - $cmodels_tabs = array( - '#type' => 'tabset', - ); + $cmodels_tabs = array(); foreach ($content_models as $content_model) { $content_model_fieldset = $content_model->displayExtraFieldset($pid, $page_number); @@ -1025,17 +1023,26 @@ function fedora_repository_islandora_tabs_alter(&$tabs, $params) { } /** - * Sends an ITQL query to the Fedora Resource index (can only communicate with Kowari or mulgara) - * Reads the pid and datastream id as url parameters. Queries the collection object for the query - * if there is no query datastream falls back to the query shipped with the module. + * Menu callback for "fedora/repository". + * + * If user is allow, and we are given a PID and a sensical DSID, return the + * datastream via the makeObject() function; otherwise, call out to the PIDs' + * ContentModels and all Drupal modules for Islandora tabs. * - * @global type $user - * @param type $pid - * @param type $dsId - * @param type $collection - * @param type $page_number - * @param type $limit - * @return type + * @global $user stdObject + * @param $pid string + * An optional string containing the PID of an object. (defaults to islandora:root) + * @param $dsId string + * An optional string containing the dsid of an object. ("-" will be ignored + * to allow later parameters without including one). + * @param $collection string + * The collection name... Deprecated. + * @param $page_number string/integer(?) + * A page number to start on... Seems to be going towards deprecation? + * @param $limit string/integer(?) + * Used to limit the number of results returned? Deprecated? + * @return string + * A string containing markup for the rendered tabs. */ function fedora_repository_get_items($pid = NULL, $dsId = NULL, $collection = NULL, $page_number = NULL, $limit = NULL) { module_load_include('inc', 'fedora_repository', 'ObjectHelper'); @@ -1108,7 +1115,7 @@ function fedora_repository_get_items($pid = NULL, $dsId = NULL, $collection = NU $cmodels_tabs = array( '#type' => 'tabset', ); - $cmodels_tabs = array_merge($cmodels_tabs, $hook_tabs); + $cmodels_tabs += $hook_tabs; //Assemble parameters, to pass during alter $params = array( From 61204b9168d3a4bf1e1451078436f5b12debe9ed Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 2 May 2012 16:06:54 -0400 Subject: [PATCH 27/27] Fix datastream replacement errors. --- fedora_repository.module | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fedora_repository.module b/fedora_repository.module index 886ab4d6..7235aa36 100644 --- a/fedora_repository.module +++ b/fedora_repository.module @@ -741,7 +741,7 @@ function fedora_repository_replace_stream_form_submit($form, &$form_state) { $dsLabel = $form_state['values']['dsLabel']; $streamUrl = ($file !== NULL) ? - url($file->filepath, array('absolute' => TRUE)): + $file->filepath: url($form_state['values']['reference'], array('absolute' => TRUE)); // Remove the original file extension from the label and add the new one @@ -751,10 +751,9 @@ function fedora_repository_replace_stream_form_submit($form, &$form_state) { substr($streamUrl, strrpos($streamUrl, '.')); // Add the file extention to the end of the label. } - - $dformat = $form_state['storage']['mime_type']; + module_load_include('inc', 'fedora_repository', 'api/fedora_item'); $item = new Fedora_Item($pid); $item->modify_datastream($streamUrl, $dsid, $dsLabel, $dformat);