createAdminForm(); } /** * drupal hook * calls the fedora_repositorys_admin form */ function fedora_repository_menu() { module_load_include('inc', 'fedora_repository', 'formClass'); $admin_menu = new formClass(); return $admin_menu->createMenu(); } /** * Implements hook_help(). * drupal hook to show help * * @param string $path * The path to supply the help for. * @param type $arg * * @return string * The help string apropriate to the given path. */ function fedora_repository_help($path, $arg) { switch ($path) { case 'admin/modules#description' : return t('Grabs a list of items from a collection in Drupal that are presented on the home page.'); case 'node/add#fedora_repository' : return t('Use this page to grab a list of items from a Fedora collection.'); } } /** * fedora repository purge object * * @param type $pid * @param type $name * * @return type */ function fedora_repository_purge_object($pid, $name = NULL) { if (!fedora_repository_check_perm('purge objects and datastreams', $pid)) { drupal_set_message(t('You do not have access to add a datastream to this object.'), 'error'); return ''; } $output = t('Are you sure you wish to purge object %name %pid!
This cannot be undone
', array( '%name' => $name, '%pid' => $pid) ); $output .= drupal_get_form('fedora_repository_purge_object_form', $pid); return $output; } /** * fedora repository ingest object * * XXX: Is this even used? * * @param type $collection_pid * @param type $collection_label * @param type $content_model * * @return type */ function fedora_repository_ingest_object($collection_pid, $collection_label = NULL, $content_model = NULL) { module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); module_load_include('inc', 'fedora_repository', 'ObjectHelper'); if (!fedora_repository_check_perm('ingest new fedora objects', $collection_pid)) { drupal_set_message(t('You do not have permission to ingest.'), 'error'); return ''; } if (!valid_pid($collection_pid)) { if (valid_pid(urldecode($collection_pid))) { $collection_pid = urldecode($collection_pid); } else { drupal_set_message(t("This collection PID @collection_pid is not valid", check_plain($collection_pid)), 'error'); return ' '; } } if ($collection_pid == NULL) { drupal_set_message(t('You must specify a collection object pid to ingest an object.'), 'error'); return ''; } $output = drupal_get_form('fedora_repository_ingest_form', $collection_pid, $collection_label, $content_model); $breadcrumbs = array(); $object_helper = new ObjectHelper(); $object_helper->getBreadcrumbs($collection_pid, $breadcrumbs); drupal_set_breadcrumb(array_reverse($breadcrumbs)); return $output; } /** * fedora repository ingest form submit * @global type $base_url * @global type $user * * @param array $form * @param array $form_state */ function fedora_repository_ingest_form_submit(array $form, array &$form_state) { // Only validate if the submit button was pressed, AHAH may use other buttons. if (array_key_exists('ahah_submission', $form_state) && $form_state['ahah_submission']) { $form_state['submitted'] = FALSE; return; } if ($form_state['storage']['xml'] && module_exists('islandora_content_model_forms')) { module_load_include('inc', 'islandora_content_model_forms', 'IngestObjectMetadataForm'); $xml_form = new IngestObjectMetadataForm(); $xml_form->submit($form, $form_state); } elseif (strpos($form_state['clicked_button']['#id'], 'edit-submit') === 0) { global $base_url; module_load_include('inc', 'fedora_repository', 'CollectionClass'); module_load_include('inc', 'fedora_repository', 'CollectionPolicy'); module_load_include('inc', 'fedora_repository', 'ContentModel'); $contentModelPid = ContentModel::getPidFromIdentifier($form_state['values']['models']); $contentModelDsid = ContentModel::getDSIDFromIdentifier($form_state['values']['models']); $err = TRUE; $redirect = TRUE; if (($cp = CollectionPolicy::loadFromCollection($form_state['values']['collection_pid'])) !== FALSE) { $relationship = $cp->getRelationship(); if (($cm = ContentModel::loadFromModel($contentModelPid, $contentModelDsid)) !== FALSE) { $pid = $cp->getNextPid($contentModelDsid); global $user; $form_state['values']['user_id'] = $user->name; $form_state['values']['pid'] = $pid; $form_state['values']['content_model_pid'] = $contentModelPid; $form_state['values']['relationship'] = $relationship; $err = (!$cm->execFormHandler($form_state['values'], $form_state)); // Empty this variable. $_SESSION['fedora_ingest_files'] = ''; $attr = $cm->getIngestFormAttributes(); $redirect = $attr['redirect']; if ($redirect) { $form_state['storage'] = NULL; } } } if ($redirect) { $form_state['redirect'] = ($err) ? ' ' : url("fedora/repository/{$form_state['values']['collection_pid']}"); } } } /** * fedora repository ingest form validate * * @param type $form * @param type $form_state * * @return type */ function fedora_repository_ingest_form_validate($form, &$form_state) { // Only validate if the submit button was pressed, AHAH may use other buttons. $is_ahah_submission = (array_key_exists('ahah_submission', $form_state) && $form_state['ahah_submission']); if ($is_ahah_submission) { $form_state['submitted'] = FALSE; return; } if (strpos($form_state['clicked_button']['#id'], 'edit-submit') === 0 && !$is_ahah_submission) { switch ($form_state['storage']['step']) { case 1: $form_state['storage']['step']++; $form_state['rebuild'] = TRUE; break; case 2: // XML based form. if ($form_state['storage']['xml']) { module_load_include('inc', 'xml_form_api', 'XMLForm'); $xml_form = new XMLForm($form_state); $xml_form->validate($form, $form_state); } // Get the uploaded file. $validators = array(); $ifl = 'ingest-file-location'; $file_object = NULL; // Check if it's already there; this is what upload_element provides. if (is_a($form_state['values'][$ifl], 'stdClass') && property_exists($form_state['values'][$ifl], '')) { $file_object = $form_state['values'][$ifl]; } elseif (!empty($_FILES['files']['name'][$ifl])) { $file_object = file_save_upload($ifl, $validators); } if ($file_object !== NULL && property_exists($file_object, 'filepath')) { file_move($file_object->filepath, 0, 'FILE_EXISTS_RENAME'); $form_state['values'][$ifl] = $file_object->filepath; } if (isset($form_state['values'][$ifl]) && file_exists($form_state['values'][$ifl])) { module_load_include('inc', 'fedora_repository', 'ContentModel'); module_load_include('inc', 'fedora_repository', 'MimeClass'); $file = $form_state['values'][$ifl]; $contentModelPid = ContentModel::getPidFromIdentifier($form_state['values']['models']); $contentModelDsid = ContentModel::getDSIDFromIdentifier($form_state['values']['models']); if (($cm = ContentModel::loadFromModel($contentModelPid, $contentModelDsid)) !== FALSE) { $allowedMimeTypes = $cm->getMimetypes(); $mimetype = new MimeClass(); $dformat = $mimetype->getType($file); if (!empty($file)) { if (!in_array($dformat, $allowedMimeTypes)) { form_set_error($ifl, t("The uploaded file's mimetype (@mime) is not associated with this Content Model. The allowed types are: @allowed", array( '@mime' => $dformat, '@allowed' => implode(', ', $allowedMimeTypes), ))); file_delete($file); return; } elseif (!$cm->execIngestRules($file, $dformat)) { drupal_set_message(t('Error following Content Model Rules'), 'error'); foreach (ContentModel::$errors as $err) { drupal_set_message(check_plain($err), 'error'); } } } } } $form_state['rebuild'] = FALSE; break; } } } /** * fedora repository ingest form * * @param type $form_state * @param type $collection_pid * @param type $collection_label * @param type $content_model * * @return type */ function fedora_repository_ingest_form(&$form_state, $collection_pid, $collection_label = NULL, $content_model = NULL) { module_load_include('inc', 'fedora_repository', 'formClass'); // For the sake of easily maintaining the module in different core versions // create our own form_values variable. if (empty($form_state['storage']['step'])) { $form_state['storage']['step'] = 1; } $ingest_form = new formClass(); $form_state['storage']['content_model'] = $content_model; $form_state['storage']['collection_pid'] = $collection_pid; $form = $ingest_form->createIngestForm($collection_pid, $collection_label, $form_state); return $form; } /** * fedora repository purge object form * * @global type $base_url * * @param type $form_state * @param type $pid * @param type $referrer * * @return mixed * NULL or the form array. */ function fedora_repository_purge_object_form(&$form_state, $pid, $referrer = NULL) { global $base_url; if (!fedora_repository_check_perm('purge objects and datastreams', $pid)) { return NULL; } $form['pid'] = array( '#type' => 'hidden', '#value' => "$pid", ); if (!strstr(drupal_get_destination(), urlencode('fedora/repository'))) { $form['referrer'] = array( '#type' => 'hidden', '#value' => $referrer, ); } if (!isset($form_state['storage']['confirm'])) { // Do your normal $form definition here. $form['submit'] = array( '#type' => 'image_button', '#src' => drupal_get_path('module', 'fedora_repository') . '/images/purge_big.png', '#value' => t('Purge'), '#suffix' => 'Purge this object', ); return $form; } else { /* ALSO do $form definition here. Your final submit handler * (after user clicks Yes, I Confirm) * will only see $form_state info defined here. * Form you create here passed as param1 to confirm_form*/ // Had better luck leaving off last param 'name'. return confirm_form($form, 'Confirm Purge Object', $referrer, 'Are you sure you want to delete this object? This action cannot be undone.', 'Delete', 'Cancel'); } return $form; } /** * add stream * * @param type $pid * @param type $collectionName * * @return type */ function add_stream($pid, $collectionName=NULL) { module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); if (!valid_pid($collection_pid)) { drupal_set_message(t("This PID is not valid!"), 'error'); return ' '; } if (!fedora_repository_check_perm('add fedora datastreams', $pid)) { drupal_set_message(t('You do not have permission to ingest.'), 'error'); return ''; } $output .= drupal_get_form('fedora_repository_add_stream_form', $pid); return $output; } /** * add stream form submit * @global type $base_url * * @param type $form * @param type $form_state * * @return type */ function add_stream_form_submit($form, &$form_state) { global $base_url; if (!empty($form_state['submit']) && $form_state['submit'] == 'OK') { $form_state['rebuild'] = TRUE; return; } module_load_include('inc', 'fedora_repository', 'ObjectHelper'); module_load_include('inc', 'fedora_repository', 'api/fedora_item'); $pathToModule = drupal_get_path('module', 'fedora_repository'); $pid = $form_state['values']['pid']; $dsid = $form_state['values']['stream_id']; // Add the file extention to the end of the label. $dsLabel = $form_state['values']['stream_label'] . substr($form_state['storage']['stream_url'], strrpos($form_state['storage']['stream_url'], '.')); 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['storage']['control_group']); 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); } } catch (exception $e) { drupal_set_message(t('@message', array('@message' => check_plain($e->getMessage()))), 'error'); return; } // Using storage; need to unset it for forms to work properly... unset($form_state['storage']); $form_state['rebuild'] = TRUE; } /** * add stream form * * @param type $form_state * @param type $pid * * @return type */ function add_stream_form(&$form_state, $pid) { module_load_include('inc', 'fedora_repository', 'formClass'); $addDataStreamForm = new formClass(); return $addDataStreamForm->createAddDataStreamForm($pid, $form_state); } /** * add stream form validate * * @param type $form * @param type $form_state * * @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; } $dsid = $form_state['values']['stream_id']; $dsLabel = $form_state['values']['stream_label']; if (strlen($dsid) > 64) { form_set_error('', t('Data stream ID cannot be more than 64 characters.')); return FALSE; } 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; } elseif (strlen($dsLabel) > 64) { form_set_error('', t('Data stream Label cannot be more than 64 characters.')); return FALSE; } elseif (strpos($dsLabel, '/') !== FALSE) { form_set_error('', t('Data stream Label cannot contain a "/".')); return FALSE; } $validators = array( // 'file_validate_is_image' => array(), // 'file_validate_image_resolution' => array('85x85'), // 'file_validate_size' => array(30 * 1024), ); $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)))) { // Move the uploaded file to Drupal's files directory. $file_path = $fileObject->filepath; file_move($file_path, 0, FILE_EXISTS_RENAME); $form_state['values']['add-stream-file-location'] = $file_path; $form_state['storage']['stream_url'] = file_create_url($file_path); } 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; } /** * fedora repository purge stream * @global type $user * * @param type $pid * @param type $dsId * @param type $name * * @return type */ function fedora_repository_purge_stream($pid = NULL, $dsId = NULL, $name = NULL) { module_load_include('inc', 'fedora_repository', 'ObjectHelper'); global $user; if ($pid == NULL || $dsId == NULL) { drupal_set_message(t('You must specify an object pid and DataStream ID to purge a datastream'), 'error'); return ' '; } if (!fedora_repository_check_perm(OBJECTHELPER :: $PURGE_FEDORA_OBJECTSANDSTREAMS, $pid, $user)) { drupal_set_message(t("You do not have access to Fedora objects within the attempted namespace or you do not have permission to purge objects."), 'error'); return ' '; } $output = t('Are you sure you wish to purge this datastream %name
', array( '%name' => $name) ); $output .= drupal_get_form('fedora_repository_purge_stream_form', $pid, $dsId); return $output; } /** * Validates the purge object form. * * @param array $form * The form to validate. * @param array $form_state * The state of the form to validate */ function fedora_repository_purge_object_form_validate($form, &$form_state) { module_load_include('inc', 'fedora_repository', 'api/fedora_collection'); $pid = $form_state['values']['pid']; $object_helper = new ObjectHelper(); $content_models = $object_helper->get_content_models_list($pid); foreach ($content_models as $content_model) { if ($content_model->pid == 'islandora:collectionCModel') { $member_pids = get_related_items_as_array($pid, 'isMemberOfCollection', 10000, 0, FALSE); if (is_array($member_pids) && ! empty($member_pids)) { form_set_error('new_collection_pid', t("Please purge all members of this collection before deleting the collection itself.")); return; } } } } /** * fedora repository purge object form submit * * @param type $form * The submited form. * @param type $form_state * The state of the submitted form. */ function fedora_repository_purge_object_form_submit($form, &$form_state) { module_load_include('inc', 'fedora_repository', 'ConnectionHelper'); module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); $pid = $form_state['values']['pid']; $parents = get_parent_collections_from_pid($pid); if (!isset($form_state['storage']['confirm'])) { /* This will cause the form to be rebuilt, * entering the confirm part of the form.*/ $form_state['storage']['confirm'] = TRUE; // Along with this. $form_state['rebuild'] = TRUE; } else { /* This is where you do your processing after * they have pressed the confirm button.*/ $params = array( "pid" => $pid, "logMessage" => "Purged", "force" => "", ); try { $soap_helper = new ConnectionHelper(); $client = $soap_helper->getSoapClient(variable_get('fedora_soap_manage_url', 'http://localhost:8080/fedora/wsdl?api=API-M')); $object = $client->__soapCall('purgeObject', array($params)); unset($form_state['storage']['confirm']); } catch (exception $e) { if (preg_match('/org\.fcrepo\.server\.security\.xacml\.pep\.AuthzDeniedException/', $e->getMessage())) { drupal_set_message(t('Error: Insufficient permissions to purge object.'), 'error'); } else { drupal_set_message(t('@message', array('@message' => check_plain($e->getMessage()))), 'error'); } return; } // Set the form's redirect to its first identifiable parent collection. $form_state['redirect'] = "fedora/repository/$parents[0]/"; } } /** * fedora repository purge stream form * * @param type $form_state * @param type $pid * @param type $dsId * * @return type */ function fedora_repository_purge_stream_form(&$form_state, $pid, $dsId) { $form['pid'] = array( '#type' => 'hidden', '#value' => "$pid", ); $form['dsid'] = array( '#type' => 'hidden', '#value' => "$dsId", ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Purge'), ); return $form; } /** * fedora repository purge stream form submit * * @global type $base_url * * @param type $form * @param array $form_state */ function fedora_repository_purge_stream_form_submit($form, &$form_state) { global $base_url; module_load_include('inc', 'fedora_repository', 'api/fedora_item'); $pid = $form_state['values']['pid']; $item = new Fedora_Item($pid); $dsid = $form_state['values']['dsid']; try { $item->purge_datastream($dsid); } catch (exception $e) { drupal_set_message(t('@message', array('@message' => check_plain($e->getMessage()))), 'error'); } $form_state['redirect'] = "fedora/repository/$pid"; } /** * * @param unknown_type $form_state * @param unknown_type $pid * @param unknown_type $dsid * @param unknown_type $label */ function fedora_repository_download_datastream_form(&$form_state, $pid, $dsid, $label) { module_load_include('inc', 'fedora_repository', 'ObjectHelper'); $form = array( '#action' => url("fedora/repository/object_download/$pid/$dsid/$label"), 'submit' => array( '#type' => 'submit', '#value' => t('Download'), ), ); if (fedora_repository_check_perm(ObjectHelper::$EDIT_FEDORA_METADATA, $pid)) { $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 * @param type $dsId * @param type $dsLabel * @param type $collectionName * * @return string */ function fedora_repository_replace_stream($pid, $dsId, $dsLabel = '', $collectionName = NULL) { if ($pid == NULL || $dsId == NULL) { drupal_set_message(t('You must specify an pid and dsId to replace.'), 'error'); return ''; } $output = drupal_get_form('fedora_repository_replace_stream_form', $pid, $dsId, $dsLabel); return $output; } /** * fedora repository replace stream form * * @param type $form_state * @param type $pid * @param type $dsId * @param type $dsLabel * * @return type */ function fedora_repository_replace_stream_form(&$form_state, $pid, $dsId, $dsLabel) { module_load_include('inc', 'fedora_repository', 'formClass'); $replaceDataStreamForm = new formClass(); return $replaceDataStreamForm->createReplaceDataStreamForm($pid, $dsId, $dsLabel, $form_state); } /** * fedora repository replace stream form validate * @param type $form * @param type $form_state * @return type */ function fedora_repository_replace_stream_form_validate($form, &$form_state) { // 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. $file = file_save_upload('file', array(), file_directory_path()); // set error is file was not uploaded if (!$file) { form_set_error('file', 'Error uploading file.'); return; } /* ----------------------------------------------------------------- * TODO: need a better way to get mimetypes */ $doc = new DOMDocument(); module_load_include('inc', 'fedora_repository', 'MimeClass'); $mime = new MimeClass(); $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. (XML could not be parsed)'); return; } // set files to form_state, to process when form is submitted $form_state['values']['file'] = $file; } elseif (!$form_state['values']['ds_reference']) { form_set_error('', 'Need either a file or a reference!'); } } /** * fedora repository replace stream form submit * @global type $base_url * @param type $form * @param array $form_state */ function fedora_repository_replace_stream_form_submit($form, &$form_state) { $file = $form_state['values']['file']; $pid = $form_state['values']['pid']; $dsid = $form_state['values']['dsId']; $dsLabel = $form_state['values']['dsLabel']; $streamUrl = ($file !== NULL) ? file_create_url($file->filepath): 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. } $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); unset($form_state['storage']); $form_state['redirect'] = 'fedora/repository/' . $pid; } /** * fedora repository edit qdc page * @global type $user * @param type $pid * @param type $dsId * @return type */ function fedora_repository_edit_qdc_page($pid = NULL, $dsId = NULL) { module_load_include('inc', 'fedora_repository', 'ObjectHelper'); global $user; if ($pid == NULL || $dsId == NULL) { drupal_set_message(t('You must specify an object pid and a Dublin Core DataStream ID to edit metadata'), 'error'); return ' '; } if (!fedora_repository_check_perm(OBJECTHELPER :: $EDIT_FEDORA_METADATA, $pid, $user)) { drupal_set_message(t("You do not have access to Fedora objects within the attempted namespace or you do not have permission to edit meta data for this object."), 'error'); return ' '; } $output = drupal_get_form('fedora_repository_edit_qdc_form', $pid, $dsId); return $output; } /** * fedora repository edit qdc form * @global type $user * * @param type $form_state * @param type $pid * @param type $dsId * * @return type */ function fedora_repository_edit_qdc_form(&$form_state, $pid, $dsId = NULL) { module_load_include('inc', 'fedora_repository', 'ContentModel'); module_load_include('inc', 'fedora_repository', 'ObjectHelper'); if ($pid == NULL) { drupal_set_message(t('You must specify an object pid!'), 'error'); } global $user; if (!fedora_repository_check_perm(OBJECTHELPER :: $EDIT_FEDORA_METADATA, $pid, $user)) { drupal_set_message(t("You do not have access to Fedora objects within the attempted namespace or you do not have permission to edit meta data for this object."), 'error'); return ' '; } module_load_include('inc', 'fedora_repository', 'formClass'); module_load_include('inc', 'fedora_repository', 'ConnectionHelper'); $soapHelper = new ConnectionHelper(); $client = $soapHelper->getSoapClient(variable_get('fedora_soap_url', 'http://localhost:8080/fedora/services/access?wsdl')); // Check if there's a custom edit metadata function in the content model. $output = ''; if (($cm = ContentModel::loadFromObject($pid)) !== FALSE) { $output = $cm->buildEditMetadataForm($pid, $dsId); } if (empty($output)) { // There is no custom function, so just load the standard QDC form. $metaDataForm = new formClass(); // Currently we only edit the dc metadata. // If you defined a custom form with a custom handler you are sol for now. $output = $metaDataForm->createMetaDataForm($pid, $dsId, $client, $form_state); } return $output; } /** * fedora repository edit qdc form validate * * @param type $form * @param boolean $form_state */ function fedora_repository_edit_qdc_form_validate($form, &$form_state) { if ($form_state['storage']['xml']) { if ($form_state['storage']['step'] == 1) { $form_state['storage']['step']++; $form_state['rebuild'] = TRUE; } module_load_include('inc', 'xml_form_api', 'XMLForm'); $xml_form = new XMLForm($form_state); $xml_form->validate($form, $form_state); } } /** * Check if there is a custom edit metadata function defined in the * content model. If so, call it, if not do the submit action for the * standard QDC metadata. Custom forms willneed to implement their own * equivalent to the FormClass->updateMetaData function * * @param array $form * @param array $form_state * * @return */ function fedora_repository_edit_qdc_form_submit($form, &$form_state) { if ($form_state['storage']['xml']) { module_load_include('inc', 'islandora_content_model_forms', 'EditObjectMetadataForm'); $xml_form = new EditObjectMetadataForm(); $xml_form->submit($form, $form_state); } else { module_load_include('inc', 'fedora_repository', 'ConnectionHelper'); global $base_url; if (strstr($form_state['clicked_button']['#id'], 'edit-submit')) { $soap_helper = new ConnectionHelper(); $client = $soap_helper->getSoapClient(variable_get('fedora_soap_manage_url', 'http://localhost:8080/fedora/wsdl?api=API-M')); /* Check the content model for a custom * edit metadata form submit function.*/ if (isset($form_state['values']['pid'])) { module_load_include('inc', 'fedora_repository', 'ContentModel'); if (($cm = ContentModel::loadFromObject($form_state['values']['pid'])) !== FALSE) { return $cm->handleEditMetadataForm($form_state['values']['form_id'], $form_state, $client); } } module_load_include('inc', 'fedora_repository', 'formClass'); $metaDataForm = new formClass(); $return_value = $metaDataForm->updateMetaData($form_state['values']['form_id'], $form_state['values'], $client); $form_state['storage'] = NULL; $form_state['redirect'] = $base_url . '/fedora/repository/' . $form_state['values']['pid']; return $return_value; } } } /** * drupal hook * creates a new permission than can be assigned to roles */ function fedora_repository_perm() { module_load_include('inc', 'fedora_repository', 'ObjectHelper'); return array( OBJECTHELPER::$OBJECT_HELPER_VIEW_FEDORA, OBJECTHELPER::$EDIT_FEDORA_METADATA, OBJECTHELPER::$PURGE_FEDORA_OBJECTSANDSTREAMS, OBJECTHELPER::$ADD_FEDORA_STREAMS, OBJECTHELPER::$INGEST_FEDORA_OBJECTS, OBJECTHELPER::$EDIT_TAGS_DATASTREAM, OBJECTHELPER::$VIEW_DETAILED_CONTENT_LIST, ); } /** * Grabs a stream from fedora sets the mimetype and returns it. $dsID is the * datastream id. * @param $pid String * @param $dsID String */ function makeObject($pid, $dsID) { module_load_include('inc', 'fedora_repository', 'ObjectHelper'); module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); if (!valid_pid($pid)) { drupal_set_message(t("Invalid PID!"), 'error'); return ' '; } if (!valid_dsid($dsID)) { drupal_set_message(t("Invalid dsID!"), 'error'); return ' '; } if ($pid == NULL || $dsID == NULL) { drupal_set_message(t("No pid or dsid given to create an object with.")); return ' '; } global $user, $conf; if (!fedora_repository_check_perm(OBJECTHELPER :: $OBJECT_HELPER_VIEW_FEDORA, $pid, $user)) { drupal_access_denied(); return; drupal_set_message(t("You do not have access to Fedora objects within the attempted namespace."), 'error'); return ' '; } //Disable the page cache, so entire datastreams do not get thrown into the page cache. $conf['cache'] = CACHE_DISABLED; module_load_include('inc', 'fedora_repository', 'ObjectHelper'); $objectHelper = new ObjectHelper(); $objectHelper->makeObject($pid, $dsID); } /** * Implements 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(); 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, ); } } // Can disable showing the object details tab in admin UI. if (variable_get('fedora_repository_show_object_details_tab', TRUE)) { // 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); $object_details = $obj->showFieldSets(); $cmodels_tabs = array_merge($cmodels_tabs, $object_details); } return $cmodels_tabs; } /** * Implements 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; } } } } /** * 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 stdObject $user * * @param string $pid * An optional string containing the PID of an object. * (defaults to islandora:root) * @param string $dsId * An optional string containing the dsid of an object. ("-" will be ignored * to allow later parameters without including one). * @param string $collection * The collection name... Deprecated. * @param string/integer(?) $page_number * A page number to start on... Seems to be going towards deprecation? * @param string/integer(?) $limit * 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'); module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); module_load_include('inc', 'fedora_repository', 'api/fedora_item'); global $user; if (!fedora_available()) { drupal_set_message(t('The Fedora repository server is currently unavailable. Please contact the site administrator.'), 'warning', FALSE); return ''; } if (!risearch_available()) { drupal_set_message(t('The Fedora resource index search is currently unavailable. Please contact the site administrator.'), 'warning', FALSE); return ''; } if ($pid == NULL) { $pid = variable_get('fedora_repository_pid', 'islandora:root'); } $item = new Fedora_Item($pid); if (!$item->exists()) { drupal_not_found(); exit(); } if ($pid & !valid_pid($pid)) { drupal_set_message(t("Invalid PID!"), 'error'); return ' '; } if ($dsId & !valid_dsid($dsId)) { drupal_set_message(t("Invalid dsID!"), 'error'); return ' '; } if (!fedora_repository_check_perm(OBJECTHELPER::$OBJECT_HELPER_VIEW_FEDORA, $pid, $user)) { if (user_access('access administration pages')) { drupal_set_message(t("PIDs may be added to allowed namespaces, or all namespace restrictions removed !here", array('!here' => l('here', 'admin/settings/fedora_repository'))), 'warning'); } drupal_access_denied(); exit; return ' '; } $objectHelper = new ObjectHelper(); if ($pid == NULL) { $pid = variable_get('fedora_repository_pid', 'islandora:root'); } $headers = module_invoke_all('file_download', "/fedora/repository/$pid"); if (in_array(-1, $headers)) { drupal_access_denied(); exit; return ' '; } // If we have a dsID return the stream // otherwise query for a collection of objects. if ($dsId != NULL && $dsId != '-') { // Probably should check pid as well here. return makeObject($pid, $dsId); } $breadcrumbs = array(); $objectHelper->getBreadcrumbs($pid, $breadcrumbs); drupal_set_breadcrumb(array_reverse($breadcrumbs)); drupal_set_title(truncate_utf8($item->objectProfile->objLabel, 56, TRUE, TRUE)); $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 += $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); } /** * fedora repository urlencode string * FIXME: URL-encoding is not the same as HTML/XML encoding... * @param type $str * @return type */ function fedora_repository_urlencode_string($str) { return htmlentities($str); } /** * Uses makeobject to get a stream. Sets the Content Disposition in the header so it suggests a filename * and sends it as an attachment. This should prompt for a download of the object. * * @global type $conf * @param type $pid * @param type $dsId * @param type $label * @param type $version * @return type */ function fedora_object_as_attachment($pid, $dsId, $label=NULL, $version=NULL) { module_load_include('inc', 'fedora_repository', 'ObjectHelper'); if ($pid == NULL || $dsId == NULL) { drupal_set_message(t("no pid or dsid given to create an object with!")); return ' '; } //Disable the page cache, so entire datastreams do not get thrown into the page cache. $GLOBALS['conf']['cache'] = CACHE_DISABLED; $objectHelper = new ObjectHelper(); $objectHelper->makeObject($pid, $dsId, TRUE, $label, FALSE, $version); } /** * repository page * * @param type $pid * @param type $dsId * @param type $collection * @param type $pageNumber * @return type */ function repository_page($pid = NULL, $dsId = NULL, $collection = NULL, $pageNumber = NULL) { // Do security check at fedora_repository_get_items function as // it has to be called there in case someone trys to come in a back door. return fedora_repository_get_items($pid, $dsId, $collection, $pageNumber); } /** * repository service * * XXX: Is this even used? * * @global type $user * @param type $pid * @param type $servicePid * @param type $serviceMethod * @return type */ function repository_service($pid = NULL, $servicePid = NULL, $serviceMethod = NULL) { module_load_include('inc', 'fedora_repository', 'api/fedora_item'); module_load_include('inc', 'fedora_repository', 'ObjectHelper'); global $user; if (!fedora_repository_check_perm(OBJECTHELPER::$OBJECT_HELPER_VIEW_FEDORA, $pid, $user)) { drupal_access_denied(); if (user_access('access administration pages')) { drupal_set_message(t("PIDs may be added to allowed namespaces, or all namespace restrictions removed @here", array('@here' => l('here', 'admin/settings/fedora_repository'))), 'error'); } return ' '; } if ($pid == NULL) { $pid = variable_get('fedora_repository_pid', 'islandora:root'); } $headers = module_invoke_all('file_download', "/fedora/repository/$pid"); if (in_array(-1, $headers)) { drupal_access_denied(); exit; return ' '; } $item = new Fedora_Item($pid); if ($item !== FALSE) { echo $item->get_dissemination($servicePid, $serviceMethod); } exit(); } /** * Implements hook_theme(). * * @return array * The themes for the fedora_repository module. */ function fedora_repository_theme() { return array( 'fedora_repository_time' => array( 'arguments' => array( 'element' => NULL, ), 'fedora_repository_solution_packs_list' => array( 'arguments' => array( 'solution_packs' => NULL, ), ), ), ); } /** * fedora repository required fedora objects * * @return array * array( 'path-to-foxml-file', * 'pid', * 'dsid', * 'path-to-datastream-file', * int dsversion, * boolean required) */ function fedora_repository_required_fedora_objects() { $module_path = drupal_get_path('module', 'fedora_repository'); return array( 'fedora_repository' => array( 'module' => 'fedora_repository', 'title' => 'Islandora Core', 'objects' => array( array( 'pid' => 'islandora:collectionCModel', 'label' => 'Islandora Collection Content Model', 'dsid' => 'ISLANDORACM', 'datastream_file' => "./$module_path/content_models/COLLECTIONCM.xml", 'dsversion' => 2, 'cmodel' => 'fedora-system:ContentModel-3.0', ), array( 'pid' => 'islandora:root', 'label' => 'Islandora Top-level Collection', 'cmodel' => 'islandora:collectionCModel', 'datastreams' => array( array( 'dsid' => 'COLLECTION_POLICY', 'datastream_file' => "./$module_path/collection_policies/COLLECTION-COLLECTION POLICY.xml", ), array( 'dsid' => 'TN', 'datastream_file' => "./$module_path/images/Gnome-emblem-photos.png", 'mimetype' => 'image/png', ), ), ), ), ), ); } /** * Functions to create a time selector form element type. */ function fedora_repository_elements() { $type['fedora_repository_time'] = array( "#input" => TRUE, "#process" => array("fedora_repository_expand_time"), ); return $type; } /** * fedora repository expand time * * @param type $element * * @return string */ function fedora_repository_expand_time($element) { // Default to current time, check default_value but set value so that if // default value is present it will override value. if (empty($element['#default_value'])) { $element['#value'] = array( 'hour' => intval(format_date(time(), 'custom', 'h')), 'minute' => intval(format_date(time(), 'custom', 'i')), ); } $element['#tree'] = TRUE; foreach ($element['#value'] as $type => $value) { switch ($type) { case 'hour': $options = drupal_map_assoc(range(1, 24)); break; case 'minute': $options = range(0, 59); break; } if ($type != 'meridiem') { foreach ($options as $option) { strlen($option) <= 1 ? $options[$option] = 0 . $option : ''; } } $element[$type] = array( '#type' => 'select', '#default_value' => $element['#value'][$type], '#options' => $options, ); } return $element; } /** * fedora repository time * * @param type $element * * @return type */ function fedora_repository_time($element) { $output = '
' . $element['#children'] . '
'; return theme('form_element', $element, $output); } /** * theme fedora repository time * * @param type $element * * @return type */ function theme_fedora_repository_time($element) { $output = '
' . $element['#children'] . '
'; return theme('form_element', $element, $output); } /** * fedora repository display schema * * @param type $file * * @return type */ function fedora_repository_display_schema($file) { $path = drupal_get_path('module', 'fedora_repository'); if (strtolower(substr($file, -3)) == 'xsd' && file_exists($path . '/' . $file)) { drupal_goto($path . '/' . $file); } else { drupal_goto(); } return; } /** * fedora repository batch reingest object * * @param array $object * An array defining an object to ingest. * @param string $module_name * The string needed in the finished callback to be * sent out in the postprocess hook. * @param array $context * Variables shared between batch iterations * and finished callback */ function fedora_repository_batch_reingest_object($object, $module_name, &$context) { module_load_include('inc', 'fedora_repository', 'api/fedora_item'); module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); $context['results']['module_name'] = $module_name; if (!empty($object) && is_array($object)) { $pid = $object['pid']; if (!valid_pid($pid)) { return NULL; } // Does the object exist? If so, purge it. $item = new Fedora_Item($pid); if ($item->exists()) { $item->purge(t('Remove during re-install batch job')); } // Need to have this a couple places... // (After trying from FOXML and later for individual DSs) $new_item = NULL; // Seems like this might be getting messed up due to scope?. $datastreams = array(); // Ingest the object from the source file. if (!empty($object['foxml_file'])) { $foxml_file = $object['foxml_file']; $new_item = Fedora_Item::ingest_from_FOXML_file($foxml_file); if ($new_item->exists()) { // Batch operation was successful; can still add additional DSs, though. $context['message'][] = t('%pid installed.', array('%pid' => $new_item->pid)); } } if (!empty($object['dsid']) && !empty($object['datastream_file'])) { $datastreams[] = array( 'dsid' => $object['dsid'], 'datastream_file' => $object['datastream_file'], ); } elseif (!empty($object['datastreams'])) { $datastreams = $object['datastreams']; } $label = !empty($object['label']) ? $object['label'] : ''; if (!isset($new_item)) { $new_item = Fedora_Item::ingest_new_item($pid, 'A', $label); } elseif (!empty($label)) { $new_item->modify_object($label); } if (isset($new_item)) { if (!empty($object['cmodel'])) { $new_item->add_relationship('hasModel', $object['cmodel'], FEDORA_MODEL_URI); } if (!empty($object['parent'])) { $new_item->add_relationship('isMemberOfCollection', $object['parent']); } foreach ((array) $datastreams as $ds) { if ($ds['dsid'] == 'DC') { $new_item->modify_datastream_by_value(file_get_contents($ds['datastream_file']), $ds['dsid'], $ds['label'], 'text/xml'); } else { $new_item->add_datastream_from_file($ds['datastream_file'], $ds['dsid'], !empty($ds['label']) ? $ds['label'] : '', !empty($ds['mimetype']) ? $ds['mimetype'] : 'text/xml'); } } } } } /** * This function will send the postprocess solution pack hook. * It is referenced by the solution pack form's batch finished entry. * */ function fedora_repository_solutionpack_send_postprocess($success, $results, $operations) { // Hook to let solution pack objects be modified. // Not using module_invoke so solution packs can be expanded by other modules. if ($success) { module_invoke_all('fedora_repository_postprocess_solution_pack', $results['module_name']); } } /** * Content model, collection view and collection policy datastreams may * now optionally define a version * number in their top-level XML element as an attribute, as in: * get_datastream_dissemination($dsid)); } elseif (!empty($datastream_file)) { $doc = simplexml_load_file($datastream_file); } if (!empty($doc) && $version = (int) $doc->attributes()->version) { $return = $version; } return $return; } /** * theme fedora repository solution pack list * * @param type $solution_packs * * @return string */ function theme_fedora_repository_solution_packs_list($solution_packs) { module_load_include('inc', 'fedora_repository', 'api/fedora_item'); module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); $output = ''; $header = array(); $rows = array(); drupal_add_css(drupal_get_path('module', 'update') . '/update.css'); return $output; } /** * Implements hook_forms(). * * @param string $form_id * * @return array */ function fedora_repository_forms($form_id) { $forms = array(); if (strpos($form_id, 'fedora_repository_solution_pack_form_') === 0) { $forms[$form_id] = array( 'callback' => 'fedora_repository_solution_pack_form', ); } return $forms; } /** * Implements hook_imagecache_default_presets(). */ function fedora_repository_imagecache_default_presets() { return array( 'fedora_repository_collection_thumbnail' => array( 'presetname' => 'fedora_repository_collection_thumbnail', 'actions' => array( 0 => array( 'weight' => 0, 'module' => 'imagecache', 'action' => 'imagecache_scale', 'data' => array( 'width' => 200, 'height' => 200, 'upscale' => TRUE, ), ), ), ), ); } /** * Actually render an image, given an arbitrary path and preset. * * Note: If imagecache_external is not available, the full-sized image will be * produced... Might want to look into restricting the display size by adding * the width and height attributes to the theme('image') call, based on the * selected preset? (get the presets and figure out the size from its actions?) * * @param $tn_path string * @param $imagecache_preset string * @return * Markup for the image, making use of imagecache_external if it is available. */ function _fedora_repository_render_image($tn_path, $imagecache_preset = 'fedora_repository_collection_thumbnail', $truncated_title = '', $title = '') { $thumbnail = NULL; if ($thumbnail === NULL && module_exists('imagecache_external') && is_callable('theme_imagecache_external_image') && variable_get('fedora_repository_use_imagecache_external_in_collection_view', FALSE) && imagecache_external_can_fetch($tn_path, TRUE)) { $thumbnail = theme('imagecache_external_image', $imagecache_preset, $tn_path, $truncated_title, $title); } if ($thumbnail === NULL) { $thumbnail = theme('image', $tn_path, $truncated_title, $title, array(), FALSE); } return $thumbnail; } /** * Render an image, given a PID, DSID and preset. * * Produces a Drupal path for the image, passes to * _fedora_repository_render_image(), and returns the result. * * @see _fedora_repository_render_image() * @todo * Set the title/alt text(truncated title) for passing into _fedora_repository_render_image() * * @param $pid string * A string containing a Fedora PID. * @param $dsid * A string indicating a DSID on the object indicated by $pid. * @param $imagecache_preset * An imagecache preset with which to render the image; defaults to * fedora_repository_collection_thumbnail, which is added in this module's * implementation of hook_imagecache_default_presets(). */ function fedora_repository_render_image($pid, $dsid, $imagecache_preset = 'fedora_repository_collection_thumbnail') { $tn_path = "fedora/repository/$pid/$dsid"; return _fedora_repository_render_image($tn_path, $imagecache_preset); } /** * Convenience function used in XSLT callback... * * @param string $string * A string containing some markup to convert to a domnode. */ function fedora_repository_string_to_domnode($string) { return DOMDocument::loadXML($string); } /** * Permission check function at old name. * * Defers the call to fedora_repository_check_perm() and displays a message * to encourage any people using the old function to change their code. * * @deprecated */ function fedora_repository_access() { drupal_set_message(t('Contact your code maintainer to change all occurences of fedora_repository_access() to fedora_repository_check_perm().')); return call_user_func_array('fedora_repository_check_perm', func_get_args()); } /** * Hookable access check for module-specific permissions. * * @global $user * @see hook_fedora_repository_check_perm() * * @param string $op * The operation to be performed. * @param string|null $pid * A PID to check, or NULL to use the root collection PID. * @param object|null $as_user * An account to check the permission on, or NULL to use the current user. * @param boolean $reset_cache * A boolean to reset the static cache, if required in long-running processes. * * @return boolean * A boolean indicating if the operation should be permitted (TRUE) or denied * (FALSE). */ function fedora_repository_check_perm($op, $pid = NULL, $as_user = NULL, $reset_cache = FALSE) { static $cache = array(); if ($reset_cache) { $cache = array(); } // The PID can be empty for the root object. if (empty($pid)) { $pid = variable_get('fedora_repository_pid', 'islandora:root'); } if ($as_user === NULL) { global $user; $as_user = $user; } // Populate the cache on a miss. if (!isset($cache[$op][$pid][$as_user->uid])) { $results = module_invoke_all('fedora_repository_check_perm', $op, $pid, $as_user); // Nothing returned FALSE, and something returned TRUE. $cache[$op][$pid][$as_user->uid] = (!in_array(FALSE, $results, TRUE) && in_array(TRUE, $results, TRUE)); } return $cache[$op][$pid][$as_user->uid]; } /** * Implements hook_fedora_repository_check_perm(). * * Checks the PID namespace if restrictions are enabled, in addition to * permitting according to Drupal permissions. */ function fedora_repository_fedora_repository_check_perm($op, $pid, $user) { $to_return = TRUE; if (variable_get('fedora_namespace_restriction_enforced', TRUE)) { // Get the namespace (with colon) $pid_namespace = substr($pid, 0, strpos($pid, ':') + 1); $allowed_namespaces = explode(" ", variable_get('fedora_pids_allowed', 'default: demo: changeme: islandora: ilives: islandora-book: books: newspapers: ')); $to_return = in_array($pid_namespace, $allowed_namespaces); } if ($to_return && user_access($op, $user)) { // Straight Drupal permissions, let's allow it. return TRUE; } elseif ($to_return === FALSE) { // PID namespace is outside of those allowed. Forbid! return FALSE; } else { // Neither allowing of forbidding, to allow other modules to override. return NULL; } }