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) diff --git a/ObjectHelper.inc b/ObjectHelper.inc index 2534540b..603c2189 100644 --- a/ObjectHelper.inc +++ b/ObjectHelper.inc @@ -83,7 +83,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'); @@ -102,7 +101,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) { @@ -128,8 +126,14 @@ class ObjectHelper { if (function_exists("curl_init")) { $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)"; @@ -205,7 +209,7 @@ class ObjectHelper { } header('HTTP/1.1 307 Moved Temporarily'); - header('Location: ' . $effective_url . '?' . http_build_query($query)); //Fedora seems to discard the query portion. + header('Location: ' . url($effective_url, 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) @@ -376,7 +380,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; @@ -385,20 +389,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( @@ -1005,21 +997,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']; @@ -1029,13 +1033,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); + 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. - $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); } } } diff --git a/fedora_repository.module b/fedora_repository.module index e83d91f5..5b6052b1 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['storage']['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; } @@ -461,13 +450,40 @@ function add_stream_form_validate($form, &$form_state) { // 'file_validate_image_resolution' => array('85x85'), // '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. + + $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; + + $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 ($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; } @@ -607,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 @@ -646,27 +698,31 @@ 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'); + + /* ----------------------------------------------------------------- + * TODO: need a better way to get mimetypes + */ + module_load_include('inc', 'fedora_repository', 'MimeClass'); $mime = new MimeClass(); - if ($mime->getType($file->filepath) == 'text/xml' && !$doc->load($file->filepath)) { + $mimetype = $form_state['storage']['mime_type'] = $mime->getType($file->filepath); + + if ($mimetype == '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; } } @@ -678,45 +734,29 @@ 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']; + $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 - $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.; + + $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 + // 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. } - 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); + - /* ----------------------------------------------------------------- - * TODO: need a better way to get mimetypes - */ - $mimetype = new MimeClass(); - $dformat = $mimetype->getType($file->filepath); + $dformat = $form_state['storage']['mime_type']; $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'); - } - } else { - drupal_set_message('Cannot replace Redirect or Managed Datastream.', 'error'); - } + $item->modify_datastream($streamUrl, $dsid, $dsLabel, $dformat); $form_state['redirect'] = 'fedora/repository/' . $pid; } @@ -1059,7 +1099,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) { @@ -1068,7 +1107,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); } /** @@ -2273,9 +2312,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; } diff --git a/formClass.inc b/formClass.inc index 713f1fcb..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( @@ -656,17 +663,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 +685,41 @@ 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)') ); + + 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['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 +727,21 @@ class formClass { '#weight' => -1, ); } + + 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; } @@ -836,12 +868,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,