diff --git a/admin/islandora.admin.inc b/admin/islandora.admin.inc index 49de312c..e3aeb60c 100644 --- a/admin/islandora.admin.inc +++ b/admin/islandora.admin.inc @@ -7,6 +7,7 @@ /** * Create admin form + * * @return array */ function islandora_repository_admin($form, &$form_state) { diff --git a/css/islandora.admin.css b/css/islandora.admin.css index ab1e4e86..1cd1976d 100644 --- a/css/islandora.admin.css +++ b/css/islandora.admin.css @@ -1,9 +1,17 @@ -/* - Document : islandora_basic_collection.admin.css - Created on : May 23, 2012, 11:23:06 AM - Description: - Purpose of the stylesheet follows. -*/ +/** + * @file + * Css file for Islandora admin pages + */ +/* Solution pack admin page */ +.islandora-solution-pack-fieldset +{ + padding-top: 0.5em; +} +.islandora-solution-pack-fieldset table th, +.islandora-solution-pack-fieldset table td +{ + width: 33%; +} \ No newline at end of file diff --git a/images/folder.png b/images/folder.png new file mode 100644 index 00000000..f4c80d83 Binary files /dev/null and b/images/folder.png differ diff --git a/includes/breadcrumb.inc b/includes/breadcrumb.inc index d1cacdbe..5e553277 100644 --- a/includes/breadcrumb.inc +++ b/includes/breadcrumb.inc @@ -5,6 +5,9 @@ * This file contains functions to create breadcrumbs on Islandora object pages. */ +/** + * Callback function to get the breadcrumbs for an object page + */ function islandora_get_breadcrumbs($object) { $breadcrumbs = array(); diff --git a/includes/datastream.inc b/includes/datastream.inc index fea8747c..3fde916f 100644 --- a/includes/datastream.inc +++ b/includes/datastream.inc @@ -6,6 +6,7 @@ */ define('DS_COMP_STREAM', 'DS-COMPOSITE-MODEL'); + /** * Callback function to view or download a datastream. * @@ -33,6 +34,9 @@ function islandora_view_datastream($object, $dsid, $method = 'view') { exit(); } +/** + * For a given object, return all parent collections. + */ function islandora_datastream_get_parents($islandora_object) { $parent_collections = array(); @@ -295,7 +299,7 @@ function islandora_add_datastream_form_validate($form, &$form_state) { } } else { - // todo: this is unsafe, should probably be fixed see: + // @TODO: this is unsafe, should probably be fixed see: // http://api.drupal.org/api/drupal/includes!file.inc/function/file_save_upload/7 $arr = array(); } @@ -462,7 +466,7 @@ function islandora_edit_datastream($object, $ds_id) { } } -//@TODO: theme / preprocess +// @TODO: theme / preprocess function islandora_edit_datastream_registry_render($edit_registry) { $output = array( '#type' => 'markup', diff --git a/includes/ingest-menu.inc b/includes/ingest-menu.inc index 56ae500e..5e7d9436 100644 --- a/includes/ingest-menu.inc +++ b/includes/ingest-menu.inc @@ -7,6 +7,7 @@ /** * Callback function for islandora/ingest/%collection_pid + * * @TODO: validate?: pid, registry return * @param string $pid */ diff --git a/includes/islandora.ingest.inc b/includes/islandora.ingest.inc index bf33466a..a9869ed1 100644 --- a/includes/islandora.ingest.inc +++ b/includes/islandora.ingest.inc @@ -5,6 +5,9 @@ * This file contains ingest callback functions */ +/** + * @TODO: needs documentation + */ function islandora_ingest_get_information(AbstractFedoraObject $collection_object) { $models = $collection_object->models; $collection_info = module_invoke_all('islandora_ingest_get_information', $models, $collection_object); @@ -12,6 +15,9 @@ function islandora_ingest_get_information(AbstractFedoraObject $collection_objec return $collection_info; } +/** + * @TODO: needs documentation + */ function islandora_ingest_get_object($content_models, $collection_pid, $relationship, $namespace) { module_load_include('inc', 'islandora', 'includes/tuque'); global $user; @@ -25,8 +31,123 @@ function islandora_ingest_get_object($content_models, $collection_pid, $relation return $object; } +/** + * @TODO: needs documentation + */ +function islandora_ingest_new_object_prepare($namespace = NULL, $label = NULL, $datastreams = array(), $content_models = array(), $relationships = array(), $collection_pid = NULL) { + // include Tuque library + module_load_include('inc', 'islandora', 'includes/tuque'); + global $user; + // new connection + try { + $connection = new IslandoraTuque($user); + } catch (Exception $e) { + drupal_set_message(t('Unable to connect to the repository %e', array('%e' => $e)), 'error'); + return; + } + // construct new object + $object = $connection->repository->constructObject($namespace); + + // add label + if (!empty($label)) { + $object->label = $label; + } + // add content model relationship(s) + foreach ($content_models as $content_model) { + $object->relationships->add(FEDORA_MODEL_URI, 'hasModel', $content_model); + } + // add collection relationship(s) + if (!empty($relationships)) { + foreach ($relationships as $relationship) { + $object->relationships->add(FEDORA_RELS_EXT_URI, $relationship['relationship'], $relationship['pid']); + } + } + // add datastreams + foreach ((array) $datastreams as $ds) { + // variables + $ds_id = $ds['dsid']; + $ds_label = isset($ds['label']) ? $ds['label'] : ''; + $ds_mimetype = isset($ds['mimetype']) ? $ds['mimetype'] : 'text/xml'; + $ds_control_group = (isset($ds['control_group']) AND in_array($ds['control_group'], array('X', 'M', 'R', 'E'))) ? $ds['control_group'] : 'M'; + $ds_datastream_file = url($ds['datastream_file'], array('absolute' => TRUE)); + + // datastream object + $datastream = $object->constructDatastream($ds_id, $ds_control_group); + $datastream->label = $ds_label; + $datastream->mimetype = $ds_mimetype; + switch ($ds_control_group) { + case 'M': + $datastream->setContentFromUrl($ds_datastream_file); + break; + case 'X': + $datastream->setContentFromString(file_get_contents($ds_datastream_file)); + break; + } + $object->ingestDatastream($datastream); + } + + module_invoke_all('islandora_ingest_pre_ingest', $object, $content_models, $collection_pid); + return $object; +} + +/** + * @TODO: needs documentation + */ function islandora_ingest_add_object(&$object) { $object->repository->ingestObject($object); module_invoke_all('islandora_ingest_post_ingest', $object); return $object; -} \ No newline at end of file +} + + +function islandora_ingest_new_object($object_model) { + // prepare variables + // namespace + $namespace = $object_model['pid']; + // label + $label = !empty($object_model['label']) ? $object_model['label'] : NULL; + // datastreams + $datastreams = array(); + if (!empty($object_model['datastreams']) AND is_array($object_model['datastreams'])) { + $datastreams = $object_model['datastreams']; + } + // content models + $content_models = array(); + if (!empty($object_model['cmodel'])) { + if (is_array($object_model['cmodel'])) { + $content_models = $object_model['cmodel']; + } + else { + $content_models[] = $object_model['cmodel']; + } + } + // relationships + $relationships = array(); + // single parent + if (!empty($object_model['parent']) AND !is_array($object_model['parent'])) { + $relationships[] = array('relationship' => 'isMemberOfCollection', 'pid' => $object_model['parent']); + } + // parents array + if (!empty($object_model['parents']) AND is_array($object_model['parents'])) { + foreach ($object_model['parents'] as $parent) { + $relationships[] = array('relationship' => 'isMemberOfCollection', 'pid' => $parent); + } + } + // other relationships + if (!empty($object_model['relationships']) AND is_array($object_model['relationships'])) { + foreach ($object_model['relationships'] as $relationship) { + $relationships[] = array('relationship' => $relationship['relationship'], 'pid' => $relationship['pid']); + } + } + + // build new object + $object = islandora_ingest_new_object_prepare($namespace, $label, $datastreams, $content_models, $relationships); + + // ingest (and return) new object + return islandora_ingest_add_object($object); +} + + + + + diff --git a/includes/purge.form.inc b/includes/purge.form.inc index 62c18ba9..32517933 100644 --- a/includes/purge.form.inc +++ b/includes/purge.form.inc @@ -26,36 +26,9 @@ function islandora_purge_object_submit($form, &$form_state) { $object_id = $form_state['values']['pid']; $collection = $form_state['values']['col']; - if (!$object_id) { - drupal_set_message(t('Cannot remove object, object id not set')); - return; - } + // purge object + islandora_object_purge($object_id); - $object = islandora_object_load($object_id); - - if (!$object) { - drupal_set_message(t('Could not remove object, object not found')); - return; - } - $content_models = $object->models; - $arr = module_invoke_all('islandora_pre_purge_object', $object); //notify modules of pending deletion - if (isset($arr['delete']) && $arr['delete']) { - try { - $object->delete(); - } catch (Exception $e) { - drupal_set_message(t('Error deleting Islandora object %s %e', array('%s' => $object_id, '%e' => $e)), 'error'); - return ""; - } - } - else { - try { - $object->repository->purgeObject($object_id); - } catch (Exception $e) { - drupal_set_message(t('Error purging Islandora object %s %e', array('%s' => $object_id, '%e' => $e)), 'error'); - return ""; - } - } - module_invoke_all('islandora_post_purge_object', $object_id, $content_models); //notify modules post deletion drupal_goto($collection); } diff --git a/includes/solution_packs.inc b/includes/solution_packs.inc new file mode 100644 index 00000000..4d124a71 --- /dev/null +++ b/includes/solution_packs.inc @@ -0,0 +1,487 @@ +Islandora configuration page.', array('@config_url' => $config_url)), 'error'); + } + + // set variables + $enabled_solution_packs = module_invoke_all('islandora_required_objects'); + + $output = ''; + + foreach ($enabled_solution_packs as $solution_pack_module => $solution_pack_info) { + $objects = array(); + foreach ($solution_pack_info as $field => $value) { + switch ($field) { + case 'title': + $solution_pack_name = $value; + break; + case 'objects': + $objects = $value; + break; + } + } + // get form + $form_array = drupal_get_form('islandora_solution_pack_form_' . $solution_pack_module, $solution_pack_module, $solution_pack_name, $objects); + // render form + $output .= drupal_render($form_array); + } + + return $output; +} + +/** + * Solution pack admin page + */ +function islandora_solution_pack_form($form, &$form_state, $solution_pack_module, $solution_pack_name, $objects = array()) { + + // set variables + global $base_url; + global $base_path; + $needs_update = FALSE; + $needs_install = FALSE; + $could_not_connect = FALSE; + $form = array(); + + $form['solution_pack'] = array( + '#type' => 'fieldset', + '#collapsible' => FALSE, + '#collapsed' => FALSE, + '#attributes' => array('class' => array('islandora-solution-pack-fieldset')), + ); + + // adding values + $form['solution_pack']['solution_pack_module'] = array( + '#type' => 'value', + '#value' => $solution_pack_module, + ); + $form['solution_pack']['solution_pack_name'] = array( + '#type' => 'value', + '#value' => $solution_pack_name, + ); + $form['solution_pack']['objects'] = array( + '#type' => 'value', + '#value' => $objects, + ); + + // table + // header + $table_header = array(t('Label'), t('PID'), t('Status')); + $table_rows = array(); + + // loop over defined objects + foreach ($objects as $object) { + $datastreams = NULL; + if (isset($object['pid'])) { + // set variables + $pid = $object['pid']; + + // table row + $table_row = array(); + + // check object status + $object_status = islandora_check_object_status($object); + + // set status labels + switch ($object_status) { + case 'up_to_date': + $object_status = t('Up-to-date'); + break; + case 'missing': + $object_status = t('Missing'); + $needs_install = TRUE; + break; + case 'missing_datastream': + $object_status = t('Missing datastream'); + $needs_update = TRUE; + break; + case 'out_of_date': + $object_status = t('Out-of-date'); + $needs_update = TRUE; + break; + case 'could_not_connect': + $object_status = t('Could not connect'); + $could_not_connect = TRUE; + break; + } + + // label + if ($needs_install OR $could_not_connect) { + $label = $object['label'] ? $object['label'] : ''; + } + else { + $label = $object['label'] ? l($object['label'], $base_url . '/islandora/object/' . $pid) : ''; + } + $table_row[] = $label; + // pid + $table_row[] = $pid; + // object status + $table_row[] = $object_status; + // add row + $table_rows[] = $table_row; + } + } + + // title + if (!$form_state['submitted']) { + $form['solution_pack']['solution_pack_label'] = array( + '#markup' => filter_xss($solution_pack_name), + '#prefix' => '

', + '#suffix' => '

', + ); + + // install status + $form['solution_pack']['install_status'] = array( + '#markup' => '' . t('Object status:') . ' ', + '#prefix' => '
', + '#suffix' => '
', + ); + if (!$needs_install AND !$needs_update AND !$could_not_connect) { + $form['solution_pack']['install_status']['#markup'] .= ' ' . theme('image', array('path' => 'misc/watchdog-ok.png')) . ' ' . t('All required objects are installed and up-to-date.'); + $submit_button_text = t("Force reinstall objects"); + } + elseif ($needs_install) { + $form['solution_pack']['install_status']['#markup'] .= ' ' . theme('image', array('path' => 'misc/watchdog-warning.png')) . ' ' . t('Some objects are missing and must be installed. See objects list for details.'); + $submit_button_text = t("Install objects"); + } + elseif ($needs_update) { + $form['solution_pack']['install_status']['#markup'] .= ' ' . theme('image', array('path' => 'misc/watchdog-warning.png')) . ' ' . t('Some objects must be reinstalled. See objects list for details.'); + $submit_button_text = t("Reinstall objects"); + } + elseif ($could_not_connect) { + $form['solution_pack']['install_status']['#markup'] .= ' ' . theme('image', array('path' => 'misc/watchdog-error.png')) . ' ' . t('Could not connect to the repository.'); + $submit_button_text = ''; + } + + // table + $form['solution_pack']['table'] = array( + '#type' => 'item', + '#markup' => theme('table', array('header' => $table_header, 'rows' => $table_rows)), + ); + } + + // submit + if (!$could_not_connect) { + $form['solution_pack']['submit'] = array( + '#value' => $submit_button_text, + '#type' => 'submit', + '#name' => $solution_pack_module, + '#attributes' => array('class' => array('islandora-solution-pack-submit')), + '#weight' => 40, + ); + // submit callback + $form['solution_pack']['#submit'] = array( + 'islandora_solution_pack_form_submit', + ); + } + + return $form; +} + +/** + * Submit handler for solution pack form. + * + * @param array $form + * The form submitted. + * @param array_reference $form_state + * The state of the form submited. + */ +function islandora_solution_pack_form_submit($form, &$form_state) { + + // get variables + $solution_pack_module = $form_state['values']['solution_pack_module']; + $solution_pack_name = $form_state['values']['solution_pack_name']; + $objects = $form_state['values']['objects']; + + $batch = array( + 'title' => t('Installing / updating solution pack objects'), + 'file' => drupal_get_path('module', 'islandora') . '/includes/solution_packs.inc', + 'operations' => array(), + ); + + foreach ($objects as $object) { + // Add this object to the batch job queue. + $batch['operations'][] = array('islandora_batch_reingest_object', array($object)); + } + + batch_set($batch); + + // Hook to let solution pack objects be modified. + // Not using module_invoke so solution packs can be expanded by other modules. + module_invoke_all('islandora_postprocess_solution_pack', $solution_pack_module); + +} + + + + +/** + * Batch reingest object(s) + * + * @param type $object + * @param type $context + * @return type + */ +function islandora_batch_reingest_object($object_model, &$context) { + + module_load_include('inc', 'islandora', 'includes/utilities'); + module_load_include('inc', 'islandora', 'includes/islandora.ingest'); + // include Tuque library + module_load_include('inc', 'islandora', 'includes/tuque'); + global $user; + global $base_url; + // new connection + try { + $connection = new IslandoraTuque($user); + } + catch (Exception $e) { + drupal_set_message(t('Unable to connect to the repository %e', array('%e' => $e)), 'error'); + return; + } + + if (!empty($object_model) && is_array($object_model)) { + // set and validate PID + $pid = $object_model['pid']; + if (!islandora_validate_pid($pid)) { + return NULL; + } + + // purge object + // check if object already exits + $object_query = $connection->api->a->findObjects('query', 'pid=' . $pid); + $reinstall = FALSE; + if (!empty($object_query['results'])) { + islandora_object_purge($pid); + $reinstall = TRUE; + } + + // build and ingest new object + try { + $object = islandora_ingest_new_object($object_model); + $object_name = $object->label; + if ($reinstall) { + drupal_set_message(t('Successfully reinstalled @object_name.', array('@object_name' => $object_name, '@pid' => $pid))); + } + else { + drupal_set_message(t('Successfully installed @object_name.', array('@object_name' => $object_name, '@pid' => $pid))); + } + } + catch (Exception $e) { + drupal_set_message(t('Installation of object @pid failed', array('@pid' => $pid)), 'error'); + } + } +} + + +/** + * Callback function that can be called from the solution pack's hook_install() and hook_uninstall() functions. + * + * @TODO: add documentation + */ +function islandora_install_solution_pack($module_name = NULL, $op = 'install') { + // check if a module name is given. // @TODO: check module name for existance + if (!empty($module_name)) { + + // include files + module_load_include('inc', 'islandora', 'includes/tuque'); + module_load_include('module', 'islandora', 'islandora'); + module_load_include('inc', 'islandora', 'includes/islandora.ingest'); + module_load_include('inc', 'islandora', 'includes/utilities'); + module_load_include('module', $module_name, $module_name); + + // set globals + global $base_url; + global $user; + + // set variables + $sp_admin = url($base_url . '/admin/islandora/solution_packs'); + $config_url = url('admin/islandora/configure'); + + // get module info + $info_file = drupal_get_path('module', $module_name) . '/' . $module_name . '.info'; + $info_array = drupal_parse_info_file($info_file); + $module_label = $info_array['name']; + + // check connection + $url = variable_get('islandora_base_url', 'http://localhost:8080/fedora'); + $info = islandora_describe_repository($url); + if (!$info) { + // operation + switch ($op) { + case 'install': + drupal_set_message(st('@module_label: Did not install any objects. Could not connect to the repository. Please check the settings on the Islandora configuration page and install the required objects manually on the solution pack admin page.', array('@module_label' => $module_label, '@config_url' => $config_url, '@sp_url' => $sp_admin)), 'error'); + break; + + case 'uninstall': + drupal_set_message(st('@module_label: Did not uninstall any objects. Could not connect to the repository. Please check the settings on the Islandora configuration page and uninstall the required objects manually if necessary.', array('@module_label' => $module_label, '@config_url' => $config_url)), 'error'); + break; + } + return; + } + + // create new connection + try { + $connection = new IslandoraTuque($user); + } + catch (Exception $e) { + drupal_set_message(st('Unable to connect to the repository %e', array('%e' => $e)), 'error'); + return; + } + + // get object models + $enabled_solution_packs = module_invoke_all('islandora_required_objects'); + $islandora_required_objects = $module_name . '_islandora_required_objects'; + $required_objects = $islandora_required_objects(); + $objects = $required_objects[$module_name]['objects']; + + // loop over object models + foreach ($objects as $object) { + // set variables + $pid = $object['pid']; + $label = isset($object['label']) ? $object['label'] : st('Object'); + // check if object already exists + $query = $connection->api->a->findObjects('query', 'pid=' . $pid); + // object url + $object_url = url($base_url . '/islandora/object/' . $pid); + + // operation: install or uninstall + switch ($op) { + case 'install': + // if object exists, don't re-ingest + if (!empty($query['results'])) { + // check object status + $object_status = islandora_check_object_status($object); + // set messages + switch ($object_status) { + case 'up_to_date': + drupal_set_message(st('@module_label: did not install @label. The object already exists and is up-to-date.', array('@module_label' => $module_label, '@label' => $label, '@pid' => $pid, '@object_url' => $object_url))); + break; + case 'missing_datastream': + drupal_set_message(st('@module_label: did not install @label. The object already exists but is missing a datastream. Please reinstall the object on the solution pack admin page.', array('@module_label' => $module_label, '@label' => $label, '@pid' => $pid, '@objecturl' => $object_url, '@sp_admin' => $sp_admin)), 'warning'); + break; + case 'out_of_date': + drupal_set_message(st('@module_label: did not install @label. The object already exists but is out-of-date. Please update the object on the solution pack admin page.', array('@module_label' => $module_label, '@label' => $label, '@pid' => $pid, '@object_url' => $object_url, '@sp_admin' => $sp_admin)), 'warning'); + break; + } + } + else { + // build and ingest new object + islandora_ingest_new_object($object); + // set message + drupal_set_message(st('@module_label: installed @label object.', array('@module_label' => $module_label, '@label' => $label, '@pid' => $pid, '@object_url' => $object_url))); + } + break; + + case 'uninstall': + // if object exists, set message + if (!empty($query['results'])) { + $object_url = url($base_url . '/islandora/object/' . $pid); + drupal_set_message(st('@module_label: did not remove @label. It may be used by other sites.', array('@pid' => $pid, '@object_url' => $object_url, '@label' => $label, '@module_label' => $module_label)), 'warning'); + } + break; + } + } + } +} + + +/** + * Function to check the status of an object against an object model array. + * + * @param array $object_model + * an array describing an object + * @return string + * Returns one of the following values: + * up_to_date, missing, missing_datastream or out_of_date + * You can perform an appropriate action based on this value. + * Returns FALSE if the array is empty + * + * @see islandora_solution_pack_form() + * @see islandora_install_solution_pack() + * @TODO: should this function live in islandora.module so it can be called easier without having to include the solution_packs.inc file? + */ +function islandora_check_object_status($object_model = array()) { + if (!empty($object_model)) { + // set variables + $pid = $object_model['pid']; + $object_status = 'up_to_date'; + + // table row + $table_row = array(); + + // check connection + module_load_include('inc', 'islandora', 'includes/utilities'); + $url = variable_get('islandora_base_url', 'http://localhost:8080/fedora'); + $info = islandora_describe_repository($url); + if (!$info) { + $object_status = 'could_not_connect'; + } + else { + + // load object + $object = islandora_object_load($pid); + // check if object exists + if (!$object) { + $object_status = 'missing'; + } + else { + // object defined with single datastream file // @TODO: should dsversion be mandatory for the check to valid? + if (isset($object_model['dsid']) && isset($object_model['datastream_file']) && isset($object_model['dsversion'])) { + $datastreams = array( + array( + 'dsid' => $object_model['dsid'], + 'datastream_file' => $object_model['datastream_file'], + 'dsversion' => $object_model['dsversion'], + ), + ); + } + // object defined with multiple datastreams (using an array) + elseif (!empty($object_model['datastreams'])) { + $datastreams = $object_model['datastreams']; + } + if (!empty($datastreams) && is_array($datastreams)) { + // loop over defined datastreams + foreach ($datastreams as $ds) { + $ds_id = $ds['dsid']; + // check if defined datastream exists in the object + if (!$object[$ds_id]) { + $object_status = 'missing_datastream'; + break; + } + elseif (isset($ds['dsversion'])) { + // Check if the datastream is versioned and needs updating. + $installed_version = islandora_get_islandora_datastream_version($object, $ds['dsid']); + $available_version = islandora_get_islandora_datastream_version(NULL, NULL, $ds['datastream_file']); + + if ($available_version > $installed_version) { + $object_status = 'out_of_date'; + break; + } + } + } + } + } + } + return $object_status; + } + else { + return FALSE; + } +} + + + diff --git a/includes/utilities.inc b/includes/utilities.inc index d4cb0b40..a8dd68b3 100644 --- a/includes/utilities.inc +++ b/includes/utilities.inc @@ -37,6 +37,9 @@ function islandora_convert_bytes_to_human_readable($bytes, $precision = 2) { } } +/** + * Creates a label for control group symbols. + */ function islandora_control_group_to_human_readable($control_group) { switch ($control_group) { case 'M': @@ -91,7 +94,7 @@ function islandora_validate_dsid($dsid) { * or if the url is incorrect. */ function islandora_describe_repository($url) { - + module_load_include('inc', 'islandora', 'includes/tuque'); $connection = new IslandoraTuque(NULL, $url); try { $info = $connection->api->a->describeRepository(); diff --git a/islandora.info b/islandora.info index 1179f00b..188380f9 100644 --- a/islandora.info +++ b/islandora.info @@ -1,4 +1,4 @@ -name = Islandora Repository +name = Islandora description = "View and manage Fedora objects" package = Islandora version = 7.x-dev diff --git a/islandora.install b/islandora.install index 3fdd0fd7..c44c6418 100644 --- a/islandora.install +++ b/islandora.install @@ -3,4 +3,26 @@ /** * @file * This file contains all install functions. - */ \ No newline at end of file + */ + +/** + * Implements hook_install(). + * + * @see islandora_islandora_required_objects(). + */ +function islandora_install() { + module_load_include('inc', 'islandora', 'includes/solution_packs'); + // install object(s) + islandora_install_solution_pack('islandora'); +} + +/** + * Implements hook_uninstall(). + * + * @see islandora_islandora_required_objects(). + */ +function islandora_uninstall() { + module_load_include('inc', 'islandora', 'includes/solution_packs'); + // uninstall callback + islandora_install_solution_pack('islandora', 'uninstall'); +} \ No newline at end of file diff --git a/islandora.module b/islandora.module index 17171ff8..1845eeb4 100644 --- a/islandora.module +++ b/islandora.module @@ -59,6 +59,15 @@ function islandora_menu() { 'weight' => -1, ); + $items['admin/islandora/solution_packs'] = array( + 'title' => 'Solution packs', + 'description' => 'Install content models and collections required by installed solution packs.', + 'page callback' => 'islandora_solution_packs_admin', + 'access arguments' => array(FEDORA_ADD_DS), + 'file' => 'includes/solution_packs.inc', + 'type' => MENU_NORMAL_ITEM, + ); + $items['islandora/object/%islandora_object/manage/ingest'] = array( 'title' => 'Add an object', 'page callback' => 'islandora_ingest_callback', @@ -201,10 +210,14 @@ function islandora_menu() { return $items; } +/** + * Implements hook_admin_paths(). + */ function islandora_admin_paths() { $paths = array(); $paths['islandora/object/*/manage*'] = TRUE; $paths['islandora/object/*/delete'] = TRUE; + $paths['islandora/object/*/datastream/*/edit'] = TRUE; return $paths; } @@ -250,6 +263,19 @@ function islandora_init() { } } +/** + * Implements hook_forms(). + */ +function islandora_forms($form_id) { + $forms = array(); + if (strpos($form_id, 'islandora_solution_pack_form_') !== FALSE) { + $forms[$form_id] = array( + 'callback' => 'islandora_solution_pack_form', + ); + } + return $forms; +} + /** * a function to call other modules edit page. If there are not any modules * that handle this function this module will build a default page. @@ -348,8 +374,9 @@ function islandora_view_object($fedora_object = NULL) { } /** - * the default view hook. If there are no modules registered to handle this objects cmodels or there are + * The default view hook. If there are no modules registered to handle this objects cmodels or there are * not any cmodels specified this will create a default display. + * * @param string $object_id * @return string */ @@ -366,7 +393,8 @@ function islandora_islandora_view_object($object) { } /** - * Theme registry function + * Implements hook_theme(). + * * @return array */ function islandora_theme() { @@ -385,7 +413,8 @@ function islandora_theme() { } /** - * drupal hook_permissions function + * Implements hook_permission(). + * * @return array */ function islandora_permission() { @@ -422,7 +451,8 @@ function islandora_permission() { } /** - * a helper function to get a connection and return an object + * A helper function to get a connection and return an object + * * @global object $user * @param string $object_id * @return FedoraObject @@ -449,6 +479,51 @@ function islandora_object_load($object_id) { } } +/** + * A helper function to get a connection and purge an object + * + * @global object $user + * @param string $object_id + * @return FedoraObject + */ +function islandora_object_purge($object_id) { + if (!$object_id) { + drupal_set_message(t('Cannot remove object, object id not set')); + return; + } + + // load object + $object = islandora_object_load($object_id); + + if (!$object) { + drupal_set_message(t('Could not remove object, object not found')); + return; + } + $content_models = $object->models; + $arr = module_invoke_all('islandora_pre_purge_object', $object); // notify modules of pending deletion + if (isset($arr['delete']) && $arr['delete']) { + try { + $object->delete(); + } catch (Exception $e) { + drupal_set_message(t('Error deleting Islandora object %s %e', array('%s' => $object_id, '%e' => $e)), 'error'); + return ""; + } + } + else { + try { + $object->repository->purgeObject($object_id); + } catch (Exception $e) { + drupal_set_message(t('Error purging Islandora object %s %e', array('%s' => $object_id, '%e' => $e)), 'error'); + return ""; + } + } + module_invoke_all('islandora_post_purge_object', $object_id, $content_models); // notify modules post deletion +} + + +/** + * Ingest access callback + */ function islandora_ingest_access_callback($object, $perm) { if (islandora_access_callback($object, $perm) === FALSE) { return FALSE; @@ -462,4 +537,70 @@ function islandora_ingest_access_callback($object, $perm) { else { return FALSE; } -} \ No newline at end of file +} + +/** + * 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: + * content); + } + elseif (!empty($datastream_file)) { + $doc = simplexml_load_file($datastream_file); + } + + if (!empty($doc) && $version = (int)$doc->attributes()->version) { + $return = $version; + } + + return $return; +} + +/** + * Implements hook_islandora_required_objects(). + */ +function islandora_islandora_required_objects() { + + // module path + $module_path = drupal_get_path('module', 'islandora'); + + return array( + 'islandora' => array( + 'title' => 'Islandora', + 'objects' => array( + array( + 'pid' => 'islandora:root', + 'label' => 'Top-level collection', + 'cmodel' => 'islandora:collectionCModel', + 'datastreams' => array( + array( + 'dsid' => 'COLLECTION_POLICY', + 'label' => 'Collection policy', + 'mimetype' => 'text/xml', + 'control_group' => 'X', + 'datastream_file' => "$module_path/xml/islandora_collection_policy.xml", + ), + array( + 'dsid' => 'TN', + 'label' => 'Thumbnail', + 'mimetype' => 'image/png', + 'control_group' => 'M', + 'datastream_file' => "$module_path/images/folder.png", + ), + ), + ), + ), + ), + ); +} diff --git a/theme/islandora-object.tpl.php b/theme/islandora-object.tpl.php index d6efaac3..e876f679 100644 --- a/theme/islandora-object.tpl.php +++ b/theme/islandora-object.tpl.php @@ -53,22 +53,22 @@ * */ ?> - +
-

Details

+

- - '); ?>
+ +