Browse Source

Added management and batch capabilites to Collections

pull/38/head
Alan Stanley 13 years ago
parent
commit
351d44ed4d
  1. 241
      BatchIngest.inc
  2. 203
      CollectionClass.inc
  3. 53
      CollectionManagement.inc
  4. 18
      ContentModel.inc
  5. 1
      ObjectHelper.inc
  6. 35
      api/fedora_item.inc
  7. 11
      fedora_repository.module
  8. 436
      xsl/mods_to_dc.xsl

241
BatchIngest.inc

@ -0,0 +1,241 @@
<?php
function batch_creation_form(&$form_state, $collection_pid, $content_models) {
module_load_include('inc', 'fedora_repository', 'api/fedora_utils');
module_load_include('inc', 'fedora_repository', 'CollectionPolicy');
$cm_options = array();
$name_mappings = array();
foreach ($content_models as $content_model) {
if ($content_model->pid != "islandora:collectionCModel") {
$cm_options[$content_model->pid] = $content_model->name;
$name_mappings[] = $content_model->pid . '^' . $content_model->pid_namespace;
}
}
$mappings = implode('~~~', $name_mappings);
$form['#attributes']['enctype'] = 'multipart/form-data';
$form['titlebox'] = array(
'#type' => 'item',
'#value' => t("Batch ingest into $collection_pid"),
);
$form['collection_pid'] = array(
'#type' => 'hidden',
'#value' => $collection_pid,
);
$form['namespace_mappings'] = array(
'#type' => 'hidden',
'#value' => $mappings,
);
$form['metadata_type'] = array(
'#title' => "Choose Metadata Type",
'#type' => 'radios',
'#options' => array('MODS' => 'MODS', "DC" => "DUBLIN CORE"),
'#required' => true,
'#description' => t("Select primary metadata schema"),
);
$form['content_model'] = array(
'#title' => "Choose content model to be associated with objects ingested",
'#type' => 'select',
'#options' => $cm_options,
'#required' => true,
'#description' => t("Content models describe the behaviours of objects with which they are associated."),
);
$form['indicator']['file-location'] = array(
'#type' => 'file',
'#title' => t('Upload zipped folder'),
'#size' => 48,
'#description' => t('The zipped folder should contain all files necessary to build objects.<br .>
Related files must have the same filename, but with differing extensions to indicate mimetypes.<br />
ie. <em>myFile.xml</em> and <em>myFile.jpg</em>'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Create Objects ')
);
return($form);
}
function batch_creation_form_validate($form, &$form_state) {
$fieldName = 'file-location';
if (isset($_FILES['files']) && is_uploaded_file($_FILES['files']['tmp_name'][$fieldName])) {
$file = file_save_upload($fieldName);
if ($file->filemime != 'application/zip') {
form_set_error($fieldName, 'Input file must be a .zip file');
return;
}
if (!$file) {
form_set_error($fieldName, 'Error uploading file.');
return;
}
$form_state['values']['file'] = $file;
}
else {
// set error
form_set_error($fieldName, 'Error uploading file.');
return;
}
}
function batch_creation_form_submit($form, &$form_state) {
module_load_include('inc', 'fedora_repository', 'ContentModel');
module_load_include('inc', 'fedora_repository', 'api/fedora_item');
global $user;
$namespace_mappings = array();
$content_model = $form_state['values']['content_model'];
$metadata = $form_state['values']['metadata_type'];
$collection_pid = $form_state['values']['collection_pid'];
$namespace_process = explode('~~~', $form_state['values']['namespace_mappings']);
foreach ($namespace_process as $line) {
$line_parts = explode('^', $line);
$namespace_mappings[$line_parts[0]] = $line_parts[1];
}
$namespace = $namespace_mappings[$content_model];
$namespace = preg_replace('/:.*/', '', $namespace);
$dirName = "temp" . $user->uid;
$tmpDir = file_directory_path() . '/' . $dirName . '/';
mkdir($tmpDir);
$file = $form_state['values']['file'];
$fileName = $file->filepath;
$file_list = array();
$cmdString = "unzip -q -o -d $tmpDir \"$fileName\"";
system($cmdString, $retVal);
$dirs = array();
$doNotAdd = array('.', '..', '__MACOSX');
array_push($dirs, $tmpDir);
$files = scandir($tmpDir);
foreach ($files as $file) {
if (is_dir("$tmpDir/$file") & !in_array($file, $doNotAdd)) {
array_push($dirs, $tmpDir . $file);
}
}
foreach ($dirs as $directory) {
if ($inputs = opendir($directory)) {
while (FALSE !== ($file_name = readdir($inputs))) {
if (!in_array($file_name, $doNotAdd) && is_dir($file_name) == FALSE) {
$ext = strrchr($file_name, '.');
$base = preg_replace("/$ext$/", '', $file_name);
$ext = substr($ext, 1);
if ($ext) {
$file_list[$base][$ext] = "$directory/" . $file_name;
}
}
}
closedir($inputs);
}
}
/**
* use the content model class to construct a class representing the selected content model
* call execIngestmethods on each mimetype passed in
*/
if (($cm = ContentModel::loadFromModel($content_model, 'ISLANDORACM')) === FALSE) {
drupal_set_message("$content_model not found", "error");
return;
}
$batch = array(
'title' => 'Ingesting Objects',
'operations' => array(),
'file' => drupal_get_path('module', 'fedora_repository') . '/BatchIngest.inc',
);
foreach ($file_list as $label => $object_files) {
if ($object_files['xml']) {
$batch['operations'][] = array('create_batch_objects', array($label, $content_model, $object_files, $collection_pid, $namespace, $metadata));
}
}
$batch['operations'][] = array('recursive_directory_delete', array($tmpDir));
batch_set($batch);
batch_process();
}
function create_batch_objects($label, $content_model, $object_files, $collection_pid, $namespace, $metadata) {
module_load_include('inc', 'fedora_repository', 'ContentModel');
module_load_include('inc', 'fedora_repository', 'MimeClass');
$cm = ContentModel::loadFromModel($content_model, 'ISLANDORACM');
$allowedMimeTypes = $cm->getMimetypes();
$mime_helper = new MimeClass();
$pid = fedora_item::get_next_PID_in_namespace($namespace);
module_load_include('inc', 'fedora_reppository', 'api/fedora_item');
$item = Fedora_item::ingest_new_item($pid, 'A', $label, $owner);
$item->add_relationship('hasModel', $content_model, FEDORA_MODEL_URI);
$item->add_relationship('isMemberOfCollection', $collection_pid);
if ($metadata == 'DC') {
$dc_xml = file_get_contents($object_files['xml']);
$item->modify_datastream_by_value($dc_xml, 'DC', "Dublin Core", 'text/xml');
}
if ($metadata == 'MODS') {
$mods_xml = file_get_contents($object_files['xml']);
$item->add_datastream_from_string($mods_xml, 'MODS');
$dc_xml = batch_create_dc_from_mods($mods_xml);
}
unset($object_files['xml']);
$use_primary = TRUE;
foreach ($object_files as $ext => $filename) {
$file_mimetype = $mime_helper->get_mimetype($filename);
if (in_array($file_mimetype, $allowedMimeTypes)) {
$added = $cm->execIngestRules($filename, $file_mimetype);
}
else {
$item->purge("$pid $label not ingested. $file_mimetype not permitted in objects associated with $content_model");
continue;
}
$ds_label = $use_primary ? $cm->getDatastreamNameDSID():$ext;
$item->add_datastream_from_file($filename, $ds_label);
$use_primary = FALSE;
if (!empty($_SESSION['fedora_ingest_files'])) {
foreach ($_SESSION['fedora_ingest_files'] as $dsid => $datastream_file) {
$item->add_datastream_from_file($datastream_file, $dsid);
}
}
}
}
function batch_create_dc_from_mods($mods_xml) {
$path = drupal_get_path('module', 'fedora_repository');
module_load_include('inc', 'fedora_repository', 'ObjectHelper');
module_load_include('inc', 'fedora_repository', 'CollectionClass');
if ($xmlstr == NULL || strlen($xmlstr) < 5) {
return " ";
}
try {
$proc = new XsltProcessor();
} catch (Exception $e) {
drupal_set_message(t("!e", array('!e' => $e->getMessage())), 'error');
return " ";
}
$xsl = new DomDocument();
$xsl->load($path . '/xsl/mods_to_dc.xsl');
$input = new DomDocument();
$input->loadXML(trim($xmlstr));
$xsl = $proc->importStylesheet($xsl);
$newdom = $proc->transformToDoc($input);
$dc_xml = $newdom->saveXML();
return $dc_xml;
}
function recursive_directory_delete($dir) {
if (!file_exists($dir))
return true;
if (!is_dir($dir))
return unlink($dir);
foreach (scandir($dir) as $item) {
if ($item == '.' || $item == '..')
continue;
if (!recursive_directory_delete($dir . DIRECTORY_SEPARATOR . $item))
return false;
}
return rmdir($dir);
}

203
CollectionClass.inc

@ -499,6 +499,7 @@ class CollectionClass {
function showFieldSets($page_number) { function showFieldSets($page_number) {
module_load_include('inc', 'fedora_repository', 'api/fedora_item'); module_load_include('inc', 'fedora_repository', 'api/fedora_item');
module_load_include('inc', 'fedora_repository', 'CollectionManagement'); module_load_include('inc', 'fedora_repository', 'CollectionManagement');
module_load_include('inc', 'fedora_repository', 'BatchIngest');
global $base_url; global $base_url;
$tabset = array(); $tabset = array();
global $user; global $user;
@ -525,23 +526,24 @@ class CollectionClass {
if (!$show_ingest_tab) { if (!$show_ingest_tab) {
$view_selected = true; $view_selected = true;
} }
if(!$collection_items){
$view_selected = false;
$add_selected = true;
}
$view_selected = !$show_ingest_tab; $view_selected = !$show_ingest_tab;
drupal_set_message();
$tabset['view_tab'] = array( $tabset['view_tab'] = array(
'#type' => 'tabpage', '#type' => 'tabpage',
'#title' => 'View', '#title' => 'View',
'#selected' => $view_selected, '#selected' => $view_selected,
'#content' => $collection_items '#content' => $collection_items,
); );
$tabset['add_tab'] = array( $tabset['add_tab'] = array(
// #type and #title are the minimum requirements.
'#type' => 'tabpage', '#type' => 'tabpage',
'#title' => t('Add'), '#title' => t('Add'),
'#selected' => $show_ingest_tab, '#selected' => $add_selected,
// This will be the content of the tab. // This will be the content of the tab.
'#content' => $add_to_collection, '#content' => $add_to_collection,
); );
@ -552,9 +554,10 @@ class CollectionClass {
'#title' => t('Manage This Collection'), '#title' => t('Manage This Collection'),
// This will be the content of the tab. // This will be the content of the tab.
'#content' => drupal_get_form('collection_management_form', $this->pid, $content_models), '#content' => drupal_get_form('collection_management_form', $this->pid, $content_models),
'#selected' => false,
); );
} }
if ($show_batch_tab) { if ($show_batch_tab && user_access('create batch process')) {
$tabset['batch_ingest_tab'] = array( $tabset['batch_ingest_tab'] = array(
// #type and #title are the minimum requirements. // #type and #title are the minimum requirements.
'#type' => 'tabpage', '#type' => 'tabpage',
@ -672,189 +675,3 @@ class CollectionClass {
} }
function batch_creation_form(&$form_state, $collection_pid, $content_models) {
module_load_include('inc', 'fedora_repository', 'api/fedora_utils');
module_load_include('inc', 'fedora_repository', 'CollectionPolicy');
$cm_options = array();
$name_mappings = array();
foreach ($content_models as $content_model) {
if ($content_model->pid != "islandora:collectionCModel") {
$cm_options[$content_model->pid] = $content_model->name;
$name_mappings[] = $content_model->pid . '^' . $content_model->pid_namespace;
}
}
$mappings = implode('~~~', $name_mappings);
$form['#attributes']['enctype'] = 'multipart/form-data';
$form['titlebox'] = array(
'#type' => 'item',
'#value' => t("Batch ingest into $collection_pid"),
);
$form['parent_collection'] = array(
'#type' => 'hidden',
'#value' => $collection_pid,
);
$form['namespace_mappings'] = array(
'#type' => 'hidden',
'#value' => $mappings,
);
$form['metadata_type'] = array(
'#title' => "Choose Metadata Type",
'#type' => 'radios',
'#options' => array('MODS' => 'MODS', "DC" => "DUBLIN CORE"),
'#required' => true,
'#description' => t("Select primary metadata schema"),
);
$form['content_model'] = array(
'#title' => "Choose content model to be associated with objects ingested",
'#type' => 'select',
'#options' => $cm_options,
'#required' => true,
'#description' => t("Content models describe the behaviours of objects with which they are associated."),
);
$form['indicator']['file-location'] = array(
'#type' => 'file',
'#title' => t('Upload zipped folder'),
'#size' => 48,
'#description' => t('The zipped folder should contain all files necessary to build objects.<br .>
Related files must have the same filename, but with diffening extensions to indicate mimetypes.<br />
ie. <em>myFile.xml</em> and <em>myFile.jpg</em>'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit')
);
return($form);
}
function batch_creation_form_validate($form, &$form_state) {
$fieldName = 'file-location';
if (isset($_FILES['files']) && is_uploaded_file($_FILES['files']['tmp_name'][$fieldName])) {
$file = file_save_upload($fieldName);
if ($file->filemime != 'application/zip') {
form_set_error($fieldName, 'Input file must be a .zip file');
return;
}
if (!$file) {
form_set_error($fieldName, 'Error uploading file.');
return;
}
$form_state['values']['file'] = $file;
}
else {
// set error
form_set_error($fieldName, 'Error uploading file.');
return;
}
}
function batch_creation_form_submit($form, &$form_state) {
module_load_include('inc', 'fedora_repository', 'ContentModel');
global $user;
$namespace_mappings = array();
$content_model = $form_state['values']['content_model'];
$metadata = $form_state['values']['meta_data_type'];
$namespace_process = explode('~~~', $form_state['values']['namespace_mappings']);
foreach ($namespace_process as $line) {
$line_parts = explode('^', $line);
$namespace_mappings[$line_parts[0]] = $line_parts[1];
}
$namespace = $namespace_mappings[$content_model];
$dirName = "temp" . $user->uid;
$tmpDir = file_directory_path() . '/' . $dirName . '/';
mkdir($tmpDir);
$file = $form_state['values']['file'];
$fileName = $file->filepath;
$file_list = array();
$cmdString = "unzip -q -o -d $tmpDir \"$fileName\"";
system($cmdString, $retVal);
$dirs = array();
$doNotAdd = array('.', '..', '__MACOSX');
array_push($dirs, $tmpDir);
$files = scandir($tmpDir);
foreach ($files as $file) {
if (is_dir("$tmpDir/$file") & !in_array($file, $doNotAdd)) {
array_push($dirs, $tmpDir . $file);
}
}
foreach ($dirs as $directory) {
if ($inputs = opendir($directory)) {
while (FALSE !== ($file_name = readdir($inputs))) {
if (!in_array($file_name, $doNotAdd)) {
$ext = strrchr($file_name, '.');
$base = preg_replace("/$ext$/", '', $file_name);
$ext = substr($ext, 1);
$file_list[$base][$ext] = "$directory" . $file_name;
}
}
closedir($inputs);
}
}
/**
* use the content model class to construct a class representing the selected content model
* call execIngestmethods on each mimetype passed in
*/
create_fedora_batch($file_list, $content_model, $metadata, $namespace);
}
function create_fedora_batch($file_list, $content_model, $metadata, $namespace) {
module_load_include('inc', 'fedora_repository', 'api/fedora_item');
if (($cm = ContentModel::loadFromModel($content_model, 'ISLANDORACM')) !== FALSE) {
$allowedMimeTypes = $cm->getMimetypes();
if (!in_array($dformat, $allowedMimeTypes)) {
form_set_error('ingest-file-location', t('The uploaded file\'s mimetype (' . $dformat . ') is not associated with this Content Model. The allowed types are ' .
implode(' ', $allowedMimeTypes)));
return;
}
elseif (!$cm->execIngestRules($file, $dformat)) {
drupal_set_message(t('Error following Content Model Rules'), 'error');
foreach (ContentModel::$errors as $err) {
drupal_set_message($err, 'error');
}
}
}
$batch = array(
'title' => 'Ingesting Objects',
'operations' => array(),
'file' => drupal_get_path('module', 'fedora_repository') . '/CollectionClass.inc',
);
foreach ($file_list as $label => $object_files) {
$batch['operations'][] = array('create_fedora_objects', array($label, $content_model, $object_files, $collection_pid, $metadata));
}
batch_set($batch);
}
function create_fedora_objects($lable, $content_model, $object_files, $collection_pid, $namespace, $metadata, $content_model) {
$namespace = preg_replace('/:.*/', '', $namespace);
$pid = fedora_item::get_next_PID_in_namespace($namespace);
module_load_include('inc', 'fedora_reppository', 'api/fedora_item');
$item = Fedora_item::ingest_new_item($pid, 'A', $label, $owner);
$item->add_relationship('hasModel', $content_model, FEDORA_MODEL_URI);
if ($metadata == 'DC') {
$dc_xml = file_get_contents($object_files['xml']);
$object_files['xml'] = null;
$item->modify_datastream_by_value($dc_xml, 'DC', "Dublin Core", 'tex/xml');
}
if ($metadata == 'MODS') {
$item->add_datastream_from_file($object_files['xml'], 'MODS');
//add crosswalk to dc logic
}
foreach ($object_files as $file) {
}
}

53
CollectionManagement.inc

@ -7,7 +7,7 @@
* @param string $content_models * @param string $content_models
* @return array * @return array
*/ */
function collection_management_form(&$form_state, $parent_collection_pid, $content_models) { function collection_management_form(&$form_state, $this_collection_pid, $content_models) {
module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); module_load_include('inc', 'fedora_repository', 'api/fedora_utils');
$restricted = FALSE; $restricted = FALSE;
if (variable_get('fedora_namespace_restriction_enforced', true)) { if (variable_get('fedora_namespace_restriction_enforced', true)) {
@ -22,7 +22,7 @@ function collection_management_form(&$form_state, $parent_collection_pid, $conte
} }
module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); module_load_include('inc', 'fedora_repository', 'api/fedora_utils');
module_load_include('inc', 'fedora_repository', 'CollectionPolicy'); module_load_include('inc', 'fedora_repository', 'CollectionPolicy');
$item = new Fedora_Item($parent_collection_pid); $item = new Fedora_Item($this_collection_pid);
$collection_name = $item->objectProfile->objLabel; $collection_name = $item->objectProfile->objLabel;
$new_content_models = get_content_models_as_option_array(); $new_content_models = get_content_models_as_option_array();
$cm_options = array(); $cm_options = array();
@ -43,7 +43,7 @@ function collection_management_form(&$form_state, $parent_collection_pid, $conte
$form['child_creation']['titlebox'] = array( $form['child_creation']['titlebox'] = array(
'#type' => 'item', '#type' => 'item',
'#value' => t("Create New Child Collection within $parent_collection_pid"), '#value' => t("Create New Child Collection within $this_collection_pid"),
); );
$form['child_creation']['collection_name'] = array( $form['child_creation']['collection_name'] = array(
@ -75,11 +75,14 @@ function collection_management_form(&$form_state, $parent_collection_pid, $conte
'#description' => t("Namespace for objects in this collection."), '#description' => t("Namespace for objects in this collection."),
); );
} }
$form['child_creation']['parent_collection'] = array( $form['parent_collection'] = array(
'#type' => 'hidden', '#type' => 'hidden',
'#value' => $parent_collection_pid, '#value' => $this_collection_pid,
);
$form['collection_pid'] = array(
'#type' => 'hidden',
'#value' => $this_collection_pid,
); );
$form['child_creation']['content_models'] = array( $form['child_creation']['content_models'] = array(
'#title' => "Choose allowable content models for this collection", '#title' => "Choose allowable content models for this collection",
'#type' => 'checkboxes', '#type' => 'checkboxes',
@ -101,7 +104,7 @@ function collection_management_form(&$form_state, $parent_collection_pid, $conte
); );
$form['change_cmodel']['titlebox'] = array( $form['change_cmodel']['titlebox'] = array(
'#type' => 'item', '#type' => 'item',
'#value' => t("Change Content Models within $parent_collection_pid"), '#value' => t("Change Content Models within $this_collection_pid"),
); );
$form['change_cmodel']['current_content_model'] = array( $form['change_cmodel']['current_content_model'] = array(
@ -118,7 +121,7 @@ function collection_management_form(&$form_state, $parent_collection_pid, $conte
); );
$form['change_cmodel']['collection_pid'] = array( $form['change_cmodel']['collection_pid'] = array(
'#type' => 'hidden', '#type' => 'hidden',
'#value' => $parent_collection_pid, '#value' => $this_collection_pid,
); );
$form['change_cmodel']['submit'] = array( $form['change_cmodel']['submit'] = array(
'#type' => 'submit', '#type' => 'submit',
@ -129,7 +132,7 @@ function collection_management_form(&$form_state, $parent_collection_pid, $conte
$form['delete_collection'] = array( $form['delete_collection'] = array(
'#title' => "Permanently Delete $collection_name", '#title' => "Permanently Delete $collection_name",
'#type' => 'fieldset', '#type' => 'fieldset',
'#description' => t("Clicking this button will delete $collection_name and all objects within. <br /> <strong>This action cannot be undone.</strong>"), '#description' => t("Clicking this button will delete all objects within $collection_name. <br /> <strong>This action cannot be undone.</strong>"),
'#collapsible' => TRUE, '#collapsible' => TRUE,
'#collapsed' => TRUE, '#collapsed' => TRUE,
); );
@ -263,14 +266,34 @@ function collection_management_form_submit($form, &$form_state) {
} }
if ($form_state['clicked_button']['#id'] == 'delete_collection') { if ($form_state['clicked_button']['#id'] == 'delete_collection') {
$collection_name = $form_state['values']['collection_name'];
$pids = get_related_items_as_array($collection_pid, 'isMemberOfCollection');
$batch = array(
'title' => "Deleting Objects from $name",
'operations' => array(),
'file' => drupal_get_path('module', 'fedora_repository') . '/CollectionManagement.inc',
);
foreach ($pids as $pid) {
$batch['operations'][] = array('delete_objects_as_batch', array($pid));
}
batch_set($batch);
batch_process('/fedora/repository');
}
}
function delete_objects_as_batch($pid) {
module_load_include('inc', 'fedora_repository', 'api/fedora_item');
$name = $user->name; $name = $user->name;
$objects = get_related_items_as_array($collection_pid, $relationship); $item_to_delete = new Fedora_Item($pid);
$objects[] = $collection_pid; $models = $item_to_delete->get_models();
foreach ($objects as $object) { foreach ($models as $model) {
$item_to_delete = new Fedora_Item($object); if ($model['object'] != 'islandora:collectionCModel') {
$item_to_delete->purge("$object purged by $name"); $item_to_delete->purge("$object purged by $name");
} }
drupal_goto('fedora/repository');
} }
} }

18
ContentModel.inc

@ -4,7 +4,6 @@
* @file * @file
* *
*/ */
/** /**
* @file * @file
* Content Model Class * Content Model Class
@ -491,6 +490,23 @@ class ContentModel extends XMLDatastream {
return $ret; return $ret;
} }
/**
* Gets the DSID of the default datastream
* from the <datastreams> element of the schema.
* Returns FALSE on failure.
*
* @return String
*/
public function getDatastreamNameDSID() {
$datastreams = $this->xml->getElementsByTagName('datastreams');
$datastream = $datastreams->item(0);
if ($datastreams->length > 0) {
$datastream = $datastreams->item(0)->getElementsByTagName('datastream');
return $datastream->item(0)->getAttribute('dsid');
}
}
/** /**
* Gets an array of form elements to use in the ingest form. The results of this array are passed * Gets an array of form elements to use in the ingest form. The results of this array are passed
* to the specified ingest form builder. The form builder can optionally not use the elements as defined * to the specified ingest form builder. The form builder can optionally not use the elements as defined

1
ObjectHelper.inc

@ -21,6 +21,7 @@ class ObjectHelper {
public static $VIEW_DETAILED_CONTENT_LIST = 'view detailed list of content'; public static $VIEW_DETAILED_CONTENT_LIST = 'view detailed list of content';
public static $MANAGE_COLLECTIONS = 'manage collections'; public static $MANAGE_COLLECTIONS = 'manage collections';
public static $DELETE_ENTIRE_COLLECTIONS = 'delete entire collections'; public static $DELETE_ENTIRE_COLLECTIONS = 'delete entire collections';
public static $CREATE_BATCH_PROCESS = 'create batch process';
public static $DISPLAY_ALWAYS = 0; public static $DISPLAY_ALWAYS = 0;
public static $DISPLAY_NEVER = 1; public static $DISPLAY_NEVER = 1;
public static $DISPLAY_NO_MODEL_OUTPUT = 2; public static $DISPLAY_NO_MODEL_OUTPUT = 2;

35
api/fedora_item.inc

@ -562,7 +562,6 @@ class Fedora_Item {
$relsextxml->loadXML($relsext); $relsextxml->loadXML($relsext);
$relsextxml->normalizeDocument(); $relsextxml->normalizeDocument();
$rels = $relsextxml->getElementsByTagNameNS('info:fedora/fedora-system:def/relations-external#', '*'); $rels = $relsextxml->getElementsByTagNameNS('info:fedora/fedora-system:def/relations-external#', '*');
foreach ($rels as $child) { foreach ($rels as $child) {
if (empty($relationship) || preg_match("/$relationship/", $child->tagName)) { if (empty($relationship) || preg_match("/$relationship/", $child->tagName)) {
$relationships[] = array( $relationships[] = array(
@ -572,12 +571,36 @@ class Fedora_Item {
); );
} }
} }
return $relationships;
}
function get_models() {
$relationships = array();
try {
$relsext = $this->get_datastream_dissemination('RELS-EXT');
} catch (exception $e) {
drupal_set_message(t("Error retrieving RELS-EXT of object $pid"), 'error');
return $relationships;
}
// Parse the RELS-EXT into an associative array.
$relsextxml = new DOMDocument();
$relsextxml->loadXML($relsext);
$relsextxml->normalizeDocument();
$mods = $relsextxml->getElementsByTagNameNS(FEDORA_MODEL_URI, '*');
foreach ($mods as $child) {
if (empty($relationship) || preg_match("/$relationship/", $child->tagName)) {
$relationships[] = array(
'subject' => $this->pid,
'predicate' => $child->tagName,
'object' => substr($child->getAttributeNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'resource'), 12),
);
}
}
return $relationships; return $relationships;
//$children = $relsextxml->RDF->description;
//$children = $relsextxml->RDF->description;
//$params = array( 'pid' => $this->pid,
// 'relationship' => 'NULL' );
//return $this->soap_call( 'getRelationships', $params );
} }
/** /**

11
fedora_repository.module

@ -832,6 +832,7 @@ function fedora_repository_perm() {
OBJECTHELPER::$VIEW_DETAILED_CONTENT_LIST, OBJECTHELPER::$VIEW_DETAILED_CONTENT_LIST,
OBJECTHELPER::$MANAGE_COLLECTIONS, OBJECTHELPER::$MANAGE_COLLECTIONS,
OBJECTHELPER::$DELETE_ENTIRE_COLLECTIONS, OBJECTHELPER::$DELETE_ENTIRE_COLLECTIONS,
OBJECTHELPER::$CREATE_BATCH_PROCESS,
); );
} }
@ -989,7 +990,17 @@ function fedora_repository_get_items($pid = NULL, $dsId = NULL, $collection = NU
// Add a 'manage object' tab for all objects, where detailed list of content is shown. // Add a 'manage object' tab for all objects, where detailed list of content is shown.
$obj = new FedoraObjectDetailedContent($pid); $obj = new FedoraObjectDetailedContent($pid);
$object_details = $obj->showFieldSets(); $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;
}
}
}
$cmodels_tabs = array_merge($cmodels_tabs, $object_details); $cmodels_tabs = array_merge($cmodels_tabs, $object_details);
return tabs_render($cmodels_tabs); return tabs_render($cmodels_tabs);
} }

436
xsl/mods_to_dc.xsl

@ -0,0 +1,436 @@
<xsl:stylesheet version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mods="http://www.loc.gov/mods/v3" exclude-result-prefixes="mods" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:srw_dc="info:srw/schema/1/dc-schema" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--
This stylesheet transforms MODS version 3.2 records and collections of records to simple Dublin Core (DC) records,
based on the Library of Congress' MODS to simple DC mapping <http://www.loc.gov/standards/mods/mods-dcsimple.html>
The stylesheet will transform a collection of MODS 3.2 records into simple Dublin Core (DC)
as expressed by the SRU DC schema <http://www.loc.gov/standards/sru/dc-schema.xsd>
The stylesheet will transform a single MODS 3.2 record into simple Dublin Core (DC)
as expressed by the OAI DC schema <http://www.openarchives.org/OAI/2.0/oai_dc.xsd>
Because MODS is more granular than DC, transforming a given MODS element or subelement to a DC element frequently results in less precise tagging,
and local customizations of the stylesheet may be necessary to achieve desired results.
This stylesheet makes the following decisions in its interpretation of the MODS to simple DC mapping:
When the roleTerm value associated with a name is creator, then name maps to dc:creator
When there is no roleTerm value associated with name, or the roleTerm value associated with name is a value other than creator, then name maps to dc:contributor
Start and end dates are presented as span dates in dc:date and in dc:coverage
When the first subelement in a subject wrapper is topic, subject subelements are strung together in dc:subject with hyphens separating them
Some subject subelements, i.e., geographic, temporal, hierarchicalGeographic, and cartographics, are also parsed into dc:coverage
The subject subelement geographicCode is dropped in the transform
Revision 1.1 2007-05-18 <tmee@loc.gov>
Added modsCollection conversion to DC SRU
Updated introductory documentation
Version 1.0 2007-05-04 Tracy Meehleib <tmee@loc.gov>
-->
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:choose>
<xsl:when test="//mods:modsCollection">
<srw_dc:dcCollection xsi:schemaLocation="info:srw/schema/1/dc-schema http://www.loc.gov/standards/sru/dc-schema.xsd">
<xsl:apply-templates/>
<xsl:for-each select="mods:modsCollection/mods:mods">
<srw_dc:dc xsi:schemaLocation="info:srw/schema/1/dc-schema http://www.loc.gov/standards/sru/dc-schema.xsd">
<xsl:apply-templates/>
</srw_dc:dc>
</xsl:for-each>
</srw_dc:dcCollection>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="mods:mods">
<oai_dc:dc xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
<xsl:apply-templates/>
</oai_dc:dc>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="mods:titleInfo">
<dc:title>
<xsl:value-of select="mods:nonSort"/>
<xsl:if test="mods:nonSort">
<xsl:text> </xsl:text>
</xsl:if>
<xsl:value-of select="mods:title"/>
<xsl:if test="mods:subTitle">
<xsl:text>: </xsl:text>
<xsl:value-of select="mods:subTitle"/>
</xsl:if>
<xsl:if test="mods:partNumber">
<xsl:text>. </xsl:text>
<xsl:value-of select="mods:partNumber"/>
</xsl:if>
<xsl:if test="mods:partName">
<xsl:text>. </xsl:text>
<xsl:value-of select="mods:partName"/>
</xsl:if>
</dc:title>
</xsl:template>
<xsl:template match="mods:name">
<xsl:choose>
<xsl:when test="mods:role/mods:roleTerm[@type='text']='creator' or mods:role/mods:roleTerm[@type='code']='cre' ">
<dc:creator>
<xsl:call-template name="name"/>
</dc:creator>
</xsl:when>
<xsl:otherwise>
<dc:contributor>
<xsl:call-template name="name"/>
</dc:contributor>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="mods:classification">
<dc:subject>
<xsl:value-of select="."/>
</dc:subject>
</xsl:template>
<xsl:template match="mods:subject[mods:topic | mods:name | mods:occupation | mods:geographic | mods:hierarchicalGeographic | mods:cartographics | mods:temporal] ">
<dc:subject>
<xsl:for-each select="mods:topic">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">--</xsl:if>
</xsl:for-each>
<xsl:for-each select="mods:occupation">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">--</xsl:if>
</xsl:for-each>
<xsl:for-each select="mods:name">
<xsl:call-template name="name"/>
</xsl:for-each>
</dc:subject>
<xsl:for-each select="mods:titleInfo/mods:title">
<dc:subject>
<xsl:value-of select="mods:titleInfo/mods:title"/>
</dc:subject>
</xsl:for-each>
<xsl:for-each select="mods:geographic">
<dc:coverage>
<xsl:value-of select="."/>
</dc:coverage>
</xsl:for-each>
<xsl:for-each select="mods:hierarchicalGeographic">
<dc:coverage>
<xsl:for-each select="mods:continent|mods:country|mods:provence|mods:region|mods:state|mods:territory|mods:county|mods:city|mods:island|mods:area">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">--</xsl:if>
</xsl:for-each>
</dc:coverage>
</xsl:for-each>
<xsl:for-each select="mods:cartographics/*">
<dc:coverage>
<xsl:value-of select="."/>
</dc:coverage>
</xsl:for-each>
<xsl:if test="mods:temporal">
<dc:coverage>
<xsl:for-each select="mods:temporal">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">-</xsl:if>
</xsl:for-each>
</dc:coverage>
</xsl:if>
<xsl:if test="*[1][local-name()='topic'] and *[local-name()!='topic']">
<dc:subject>
<xsl:for-each select="*[local-name()!='cartographics' and local-name()!='geographicCode' and local-name()!='hierarchicalGeographic'] ">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">--</xsl:if>
</xsl:for-each>
</dc:subject>
</xsl:if>
</xsl:template>
<xsl:template match="mods:abstract | mods:tableOfContents | mods:note">
<dc:description>
<xsl:value-of select="."/>
</dc:description>
</xsl:template>
<xsl:template match="mods:originInfo">
<xsl:apply-templates select="*[@point='start']"/>
<xsl:for-each select="mods:dateIssued[@point!='start' and @point!='end'] |mods:dateCreated[@point!='start' and @point!='end'] | mods:dateCaptured[@point!='start' and @point!='end'] | mods:dateOther[@point!='start' and @point!='end']">
<dc:date>
<xsl:value-of select="."/>
</dc:date>
</xsl:for-each>
<xsl:for-each select="mods:publisher">
<dc:publisher>
<xsl:value-of select="."/>
</dc:publisher>
</xsl:for-each>
</xsl:template>
<xsl:template match="mods:dateIssued | mods:dateCreated | mods:dateCaptured">
<dc:date>
<xsl:choose>
<xsl:when test="@point='start'">
<xsl:value-of select="."/>
<xsl:text> - </xsl:text>
</xsl:when>
<xsl:when test="@point='end'">
<xsl:value-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</dc:date>
</xsl:template>
<xsl:template match="mods:genre">
<xsl:choose>
<xsl:when test="@authority='dct'">
<dc:type>
<xsl:value-of select="."/>
</dc:type>
<xsl:for-each select="mods:typeOfResource">
<dc:type>
<xsl:value-of select="."/>
</dc:type>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<dc:type>
<xsl:value-of select="."/>
</dc:type>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="mods:typeOfResource">
<xsl:if test="@collection='yes'">
<dc:type>Collection</dc:type>
</xsl:if>
<xsl:if test=". ='software' and ../mods:genre='database'">
<dc:type>DataSet</dc:type>
</xsl:if>
<xsl:if test=".='software' and ../mods:genre='online system or service'">
<dc:type>Service</dc:type>
</xsl:if>
<xsl:if test=".='software'">
<dc:type>Software</dc:type>
</xsl:if>
<xsl:if test=".='cartographic material'">
<dc:type>Image</dc:type>
</xsl:if>
<xsl:if test=".='multimedia'">
<dc:type>InteractiveResource</dc:type>
</xsl:if>
<xsl:if test=".='moving image'">
<dc:type>MovingImage</dc:type>
</xsl:if>
<xsl:if test=".='three-dimensional object'">
<dc:type>PhysicalObject</dc:type>
</xsl:if>
<xsl:if test="starts-with(.,'sound recording')">
<dc:type>Sound</dc:type>
</xsl:if>
<xsl:if test=".='still image'">
<dc:type>StillImage</dc:type>
</xsl:if>
<xsl:if test=". ='text'">
<dc:type>Text</dc:type>
</xsl:if>
<xsl:if test=".='notated music'">
<dc:type>Text</dc:type>
</xsl:if>
</xsl:template>
<xsl:template match="mods:physicalDescription">
<xsl:if test="mods:extent">
<dc:format>
<xsl:value-of select="mods:extent"/>
</dc:format>
</xsl:if>
<xsl:if test="mods:form">
<dc:format>
<xsl:value-of select="mods:form"/>
</dc:format>
</xsl:if>
<xsl:if test="mods:internetMediaType">
<dc:format>
<xsl:value-of select="mods:internetMediaType"/>
</dc:format>
</xsl:if>
</xsl:template>
<xsl:template match="mods:mimeType">
<dc:format>
<xsl:value-of select="."/>
</dc:format>
</xsl:template>
<xsl:template match="mods:identifier">
<xsl:variable name="type" select="translate(@type,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')"/>
<xsl:choose>
<xsl:when test="contains ('isbn issn uri doi lccn uri', $type)">
<dc:identifier>
<xsl:value-of select="$type"/>: <xsl:value-of select="."/>
</dc:identifier>
</xsl:when>
<xsl:otherwise>
<dc:identifier>
<xsl:value-of select="."/>
</dc:identifier>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="mods:location">
<dc:identifier>
<xsl:for-each select="mods:url">
<xsl:value-of select="."/>
</xsl:for-each>
</dc:identifier>
</xsl:template>
<xsl:template match="mods:language">
<dc:language>
<xsl:value-of select="normalize-space(.)"/>
</dc:language>
</xsl:template>
<xsl:template match="mods:relatedItem[mods:titleInfo | mods:name | mods:identifier | mods:location]">
<xsl:choose>
<xsl:when test="@type='original'">
<dc:source>
<xsl:for-each select="mods:titleInfo/mods:title | mods:identifier | mods:location/mods:url">
<xsl:if test="normalize-space(.)!= ''">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">--</xsl:if>
</xsl:if>
</xsl:for-each>
</dc:source>
</xsl:when>
<xsl:when test="@type='series'"/>
<xsl:otherwise>
<dc:relation>
<xsl:for-each select="mods:titleInfo/mods:title | mods:identifier | mods:location/mods:url">
<xsl:if test="normalize-space(.)!= ''">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">--</xsl:if>
</xsl:if>
</xsl:for-each>
</dc:relation>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="mods:accessCondition">
<dc:rights>
<xsl:value-of select="."/>
</dc:rights>
</xsl:template>
<xsl:template name="name">
<xsl:variable name="name">
<xsl:for-each select="mods:namePart[not(@type)]">
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:for-each>
<xsl:value-of select="mods:namePart[@type='family']"/>
<xsl:if test="mods:namePart[@type='given']">
<xsl:text>, </xsl:text>
<xsl:value-of select="mods:namePart[@type='given']"/>
</xsl:if>
<xsl:if test="mods:namePart[@type='date']">
<xsl:text>, </xsl:text>
<xsl:value-of select="mods:namePart[@type='date']"/>
<xsl:text/>
</xsl:if>
<xsl:if test="mods:displayForm">
<xsl:text> (</xsl:text>
<xsl:value-of select="mods:displayForm"/>
<xsl:text>) </xsl:text>
</xsl:if>
<xsl:for-each select="mods:role[mods:roleTerm[@type='text']!='creator']">
<xsl:text> (</xsl:text>
<xsl:value-of select="normalize-space(.)"/>
<xsl:text>) </xsl:text>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="normalize-space($name)"/>
</xsl:template>
<xsl:template match="mods:dateIssued[@point='start'] | mods:dateCreated[@point='start'] | mods:dateCaptured[@point='start'] | mods:dateOther[@point='start'] ">
<xsl:variable name="dateName" select="local-name()"/>
<dc:date>
<xsl:value-of select="."/>-<xsl:value-of select="../*[local-name()=$dateName][@point='end']"/>
</dc:date>
</xsl:template>
<xsl:template match="mods:temporal[@point='start'] ">
<xsl:value-of select="."/>-<xsl:value-of select="../mods:temporal[@point='end']"/>
</xsl:template>
<xsl:template match="mods:temporal[@point!='start' and @point!='end'] ">
<xsl:value-of select="."/>
</xsl:template>
<!-- suppress all else:-->
<xsl:template match="*"/>
</xsl:stylesheet>
Loading…
Cancel
Save