<?php
/**
 * @file
 *   This file is the Drupal module file for fedora_repository.
 */

/**
 * Drupal hook for admin form
 *
 * Stores this info in the drupal variables table.
 * the name and pid can also be passed as url parameters
 */
function fedora_repository_admin() {
  module_load_include('inc', 'fedora_repository', 'formClass');
  $admin_form = new formClass();
  return $admin_form->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 = NULL, $name = NULL) {
  if (!user_access('purge objects and datastreams')) {
    drupal_set_message(t('You do not have access to add a datastream to this object.'), 'error');
    return '';
  }
  if ($pid == NULL) {
    drupal_set_message(t('You must specify an object pid to purge an object.'), 'error');
    return '';
  }
  $output = t('Are you sure you wish to purge object %name %pid!<br /><b>This cannot be undone</b><br />', array(
        '%name' => $name,
        '%pid' => $pid)
  );

  $output .= drupal_get_form('fedora_repository_purge_object_form', $pid);
  return $output;
}

/**
 * fedora repository ingest object
 *
 * @param type $collection_pid
 * @param type $collection_label
 * @param type $content_model
 *
 * @return type
 */
function fedora_repository_ingest_object($collection_pid=NULL, $collection_label = NULL, $content_model = NULL) {
  module_load_include('inc', 'fedora_repository', 'api/fedora_utils');
  module_load_include('inc', 'fedora_repository', 'ObjectHelper');
  if (!user_access('ingest new fedora objects')) {
    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 the form if the submit button was pressed (other buttons may be used for AHAH.
  if ($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 the form if the submit button was pressed (other buttons may be used for AHAH.
  if ($form_state['ahah_submission']) {
    $form_state['submitted'] = FALSE;
    return;
  }
  if (strpos($form_state['clicked_button']['#id'], 'edit-submit') === 0 && $form_state['ahah_submission'] != 1) {
    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';
        $fileObject = 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], '')) {
          $fileObject = $form_state['values'][$ifl];
        }
        elseif (!empty($_FILES['files']['name'][$ifl])) {
          $fileObject = file_save_upload($ifl, $validators);
        }

        if ($fileObject !== NULL && property_exists($fileObject, 'filepath')) {
          file_move($fileObject->filepath, 0, 'FILE_EXISTS_RENAME');
          $form_state['values'][$ifl] = $fileObject->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 (!user_access('purge objects and datastreams')) {
    return NULL;
  }
  if ($pid == NULL) {
    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 $collection_pid
 * @param type $collectionName
 *
 * @return type
 */
function add_stream($collection_pid=NULL, $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 (!user_access('ingest new fedora objects')) {
    drupal_set_message(t('You do not have permission to ingest.'), 'error');
    return '';
  }
  if ($collection_pid == NULL) {
    drupal_set_message(t('You must specify an collection object pid to ingest an object.'), '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'];
  $dsLabel = $form_state['values']['stream_label'] . substr($form_state['storage']['stream_url'], strrpos($form_state['storage']['stream_url'], '.')); // Add the file extention to the end of the label.;

  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;
  }
  unset($form_state['storage']); //Using storage; need to unset it for forms to work properly...
  $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_access(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<br />', 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');
      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 (user_access(ObjectHelper::$EDIT_FEDORA_METADATA)) {
    $item = new Fedora_Item($pid);
    $versions = $item->get_datastream_history($dsid);
    $version_array = array();
    if (is_array($versions)) {
      foreach ($versions as $version) {
        $version_array[] = $version->createDate;
      }
    }
    else {
      $version_array[] = $versions->createDate;
    }

    if (count($version_array) > 1) {
      $form['#attributes'] = array(
        'onsubmit' => 'this.action="' . $form['#action'] . '/" + this.version.value;',
      );
      $form['version'] = array(
        '#type' => 'select',
        '#options' => array_combine($version_array, $version_array),
      );
    }
  }

  return $form;
}

/**
 * fedora repository replace stream
 *
 * @param type $pid
 * @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_access(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_access(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 is a custom edit metadata function defined 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 will
 * need 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,
  );
}

/**
 * drupal hook
 * determines if a user has access to what they are asking for
 *
 * @param type $op
 * @param type $node
 * @param type $account
 * @return type
 */
function fedora_repository_access($op, $node = NULL, $account = NULL) {
  module_load_include('inc', 'fedora_repository', 'ObjectHelper');
  $objectHelper = new ObjectHelper();
  return $objectHelper->fedora_repository_access($op, $node, $account);
}

/**
 * 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_access(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);
}

/**
 * Implementation of hook_islandora_tabs().
 *
 * @param $content_models array
 *   An array of ContentModel objects to which the current Fedora Object
 *   subscribes.
 * @param $pid string
 *   A string containing the Fedora PID of the current Fedora Object.
 * @param $page_number integer
 *   An integer for which page we should start on in the loaded object.
 * @return array
 *   An array containing a tabset (an array of tabpages), renderable with
 *   drupal_render().
 */
function fedora_repository_islandora_tabs($content_models, $pid, $page_number) {
  $cmodels_tabs = array();

  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;
}

/**
 * Implementation of hook_islandora_tabs_alter().
 *
 * @param &$tabs array
 *   The array of tabs/tabset to alter.
 * @param $params array
 *   An associative array containing the parameters with which the original
 *   hook was called.
 * @see fedora_repository_get_items()
 */
function fedora_repository_islandora_tabs_alter(&$tabs, $params) {
  //Deselect all other tabs if the fedora_object_details tab is supposed
  //  to be selected.
  $object_details_key = 'fedora_object_details';
  if ($tabs[$object_details_key]['#selected']) {
    foreach (element_children($tabs) as $key) {
      if ($key != $object_details_key) {
        $tabs[$key]['#selected'] = FALSE;
      }
    }
  }
}

/**
 * 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 $user stdObject
 * @param $pid string
 *   An optional string containing the PID of an object.  (defaults to islandora:root)
 * @param $dsId string
 *   An optional string containing the dsid of an object. ("-" will be ignored
 *   to allow later parameters without including one).
 * @param $collection string
 *   The collection name...  Deprecated.
 * @param $page_number string/integer(?)
 *   A page number to start on...  Seems to be going towards deprecation?
 * @param $limit string/integer(?)
 *   Used to limit the number of results returned?  Deprecated?
 * @return string
 *   A string containing markup for the rendered tabs.
 */
function fedora_repository_get_items($pid = NULL, $dsId = NULL, $collection = NULL, $page_number = NULL, $limit = NULL) {
  module_load_include('inc', 'fedora_repository', 'ObjectHelper');
  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_access(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 ($dsId != NULL && $dsId != '-') { //if we have a dsID return the stream otherwise query for a collection of objects
//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 $user
 * @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
 * @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_access(OBJECTHELPER::$OBJECT_HELPER_VIEW_FEDORA, $pid, $user)) {
//drupal_set_message(t("You do not have access to Fedora objects within the attempted namespace or access to Fedora denied"), 'error');
    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();
}

//Search Stuff ********************************************************************

/**
 * Implements hook_search().
 * sends a search query to fedora fgsearch which is backed by Lucene
 * In our implementation of Fedora we have api-a and api-m locked down
 * to authorized users but at the object level.  We can query Lucene and the
 * RI index to get a list of results without authorization but to view any
 * datastreams users must be authorized.
 *
 * @param type $op
 * @param type $keys
 * @return array
 */
function fedora_repository_search($op = 'search', $keys = NULL) {
  module_load_include('inc', 'fedora_repository', 'ObjectHelper');
  module_load_include('inc', 'fedora_repository', 'api/fedora_utils');

  switch ($op) {
    case 'name':
      if (user_access('view fedora collection')) {
        return t('Digital Repository', array('-9'));
      }
    case 'search':
      if (user_access('view fedora collection')) {
//demo search string ?operation=gfindObjects&indexName=DemoOnLucene&query=fgs.DS.first.text%3Achristmas&hitPageStart=11&hitPageSize=10
        $resultData = NULL;
        $numberOfHitsPerPage = NULL;
        $index = strpos($keys, '.');
        $test = substr($keys, 0, $index + 1);
        $type = NULL;
        if ($index > 0) {
          $index = strpos($keys, ':');
          $type = substr($keys, 0, $index);
          $keys = substr($keys, $index + 1);
        }

        $index = strpos($keys, ':');
        $startPage = substr($keys, 0, $index);
        if ($index > 1) {
          $keys = substr($keys, $index + 1);
        }

        if (!$startPage) {
          $startPage = 1;
        }

        $xmlDoc = NULL;

        $path = drupal_get_path('module', 'fedora_repository');
        $xmlDoc = new DomDocument();
        $xmlDoc->load($path . '/searchTerms.xml');
        $nodeList = $xmlDoc->getElementsByTagName('default');
        if (!$type) {
          $type = $nodeList->item(0)->nodeValue;
        }
        $nodeList = $xmlDoc->getElementsByTagName('number_of_results');
        $numberOfHitsPerPage = $nodeList->item(0)->nodeValue;

        $indexName = variable_get('fedora_index_name', 'DemoOnLucene');
        $keys = htmlentities(urlencode($keys));
        $searchQuery = NULL;
        if (isset($type) && strcmp($type, ':')) {
          $searchQuery = $type . ':' . $keys;
        }
        else {
          $searchQuery = $keys;
        }

        $searchUrl = variable_get('fedora_fgsearch_url', 'http://localhost:8080/fedoragsearch/rest');
        $searchString = '?operation=gfindObjects&indexName=' . $indexName . '&restXslt=copyXml&query=' . $searchQuery;
        $searchString .= '&hitPageSize=' . $numberOfHitsPerPage . '&hitPageStart=' . $startPage;

        $searchUrl .= $searchString;
        $objectHelper = new ObjectHelper();
        $resultData = do_curl($searchUrl);

        $results[] = array(
          array(
            'data' => $resultData,
            'colspan' => 2
          )
        );
        return $results;
      }
  }
}

/**
 * Implements hook_search_page().
 * Display the search results
 *
 * @param type $resultData
 *
 * @return array
 */
function fedora_repository_search_page($resultData) {
  $path = drupal_get_path('module', 'fedora_repository');
  $isRestricted = variable_get('fedora_namespace_restriction_enforced', TRUE);
  $proc = NULL;
  // No results.
  if (!$resultData[0][0]['data']) {
    return '';
  }
  $text = utf8_encode($resultData[0][0]['data']);

  try {
    $proc = new XsltProcessor();
  } catch (Exception $e) {
    $out[] = array(
      array(
        'data' => $e->getMessage(),
        'colspan' => 2,
      ),
    );
    return $out;
  }

  // Inject into xsl stylesheet.
  $proc->setParameter('', 'searchToken', drupal_get_token('search_form')); //token generated by Drupal, keeps tack of what tab etc we are on
  $proc->setParameter('', 'searchUrl', url('search') . '/fedora_repository'); //needed in our xsl
  $proc->setParameter('', 'objectsPage', base_path());
  $proc->setParameter('', 'allowedPidNameSpaces', variable_get('fedora_pids_allowed', 'default: demo: changeme: islandora: ilives: islandora-book: books: newspapers: '));
  $proc->registerPHPFunctions();
  $xsl = new DomDocument();
  if ($isRestricted) {
    $xsl->load($path . '/xsl/results.xsl');
  }
  else {
    $xsl->load($path . '/xsl/unfilteredresults.xsl');
  }

  $input = new DomDocument();
  $didLoadOk = $input->loadXML(utf8_encode($resultData[0][0]['data']));

  if (!$didLoadOk) {
    $results[] = array(
      array(
        'data' => 'Error parsing results',
        'colspan' => 2
      )
    );
  }
  else {
    $xsl = $proc->importStylesheet($xsl);
    $newdom = $proc->transformToDoc($input);

    $results[] = array(
      array(
        'data' => $newdom->saveHTML(),
        'colspan' => 2
      )
    );
  }

  $header = array(
    array(
      'data' => t('Collection results'),
      NULL,
    ),
    (NULL)
  );

  $output .= theme('table', $header, $results);
  return $output;
}

/**
 * Implementation of hook_form_alter().
 * allows the advanced search form in drupal
 *
 * @param type $form
 * @param type $form_state
 * @param type $form_id
 */
function fedora_repository_form_alter(&$form, &$form_state, $form_id) {
// Advanced node search form
  module_load_include('inc', 'fedora_repository', 'SearchClass');
  $path = drupal_get_path('module', 'fedora_repository');
  if ($form_id == 'search_form' && arg(1) == 'fedora_repository' && user_access('use advanced search')) {
    $default_value = $form['basic']['inline']['keys']['#default_value'];
    $index = strpos($default_value, '.');
    $test = substr($default_value, 0, $index + 1);
    $type = NULL;
    if ($index > 0) {
      $index = strpos($default_value, ':');
      $type = substr($default_value, 0, $index);
      $default_value = substr($default_value, $index + 1);
    }
    $form['basic']['inline']['keys']['#default_value'] = $default_value;
// Keyword boxes:
    $form['advanced'] = array(
      '#type' => 'fieldset',
      '#title' => t('Advanced search'),
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
      '#attributes' => array(
        'class' => 'search-advanced'
      ),
    );
    $form['advanced']['keywords'] = array(
      '#prefix' => '<div class="criterion">',
      '#suffix' => '</div>',
    );
    $xmlDoc = new DomDocument();
    $xmlDoc->load($path . '/searchTerms.xml');
    $nodeList = $xmlDoc->getElementsByTagName('term');
    $searchClass = new SearchClass();
    $types = $searchClass->get_search_terms_array();

    $form['advanced']['type'] = array(
      '#type' => 'select',
      '#title' => t('Choose a field to search'),
      '#prefix' => '<div class="criterion">', '#suffix' => '</div>', '#options' => $types,
      '#default_value' => $type,
    );
    $form['advanced']['submit'] = array(
      '#type' => 'submit',
      '#value' => t('Advanced search'),
      '#prefix' => '<div class="action clear-block">', '#suffix' => '</div>',
    );
    $form['#validate'][] = 'fedora_repository_search_validate';
  }
}

/**
 * Implementation of hook_search_validate()
 *
 * @param type $form
 * @param type $form_state
 */
function fedora_repository_search_validate($form, &$form_state) {
// Initialise using any existing basic search keywords.
  $keys = $form_state['values']['processed_keys'];

  if (isset($form_state['values']['type'])) {
    $type = $form_state['values']['type'];
    if ($type) {
      $keys = $type . ':' . $keys;
    }
  }

  if (!empty($keys)) {
    form_set_value($form['basic']['inline']['processed_keys'], trim($keys), $form_state); //set the form string
  }
}

/**
 * fedora repository theme
 * @return type
 */
function fedora_repository_theme() {
  return array(
    'fedora_repository_mnpl_advanced_search_form' => array(
      'arguments' => array(
        'form' => NULL,
      ),
    ),
    'fedora_repository_time' => array(
      'arguments' => array(
        'element' => NULL
      ),
      'fedora_repository_solution_packs_list' => array(
        'arguments' => array(
          'solution_packs' => NULL,
        ),
      ),
    ),
  );
}

/**
 * Get a list of terms from a lucene index
 *
 * @param type $field
 * @param type $startTerm
 * @param type $displayName
 * @return type
 */
function fedora_repository_list_terms($field, $startTerm = NULL, $displayName = NULL) {
  module_load_include('inc', 'fedora_repository', 'SearchClass');
  $searchClass = new SearchClass();
  return $searchClass->getTerms($field, $startTerm, $displayName);
}

/**
 * fedora repository mnpl advanced search form
 * @return type
 */
function fedora_repository_mnpl_advanced_search_form() {
  module_load_include('inc', 'fedora_repository', 'SearchClass');
  $searchClass = new SearchClass();
  return $searchClass->build_advanced_search_form();
}

/**
 * theme fedora repository mnpl advanced search form
 * @param type $form
 * @return type
 */
function theme_fedora_repository_mnpl_advanced_search_form($form) {
  module_load_include('inc', 'fedora_repository', 'SearchClass');
  $advanced_search_form = new SearchClass();
  return $advanced_search_form->theme_advanced_search_form($form);
}

/**
 * fedora repository mnpl advanced search
 * @param type $query
 * @param type $startPage
 * @return type
 */
function fedora_repository_mnpl_advanced_search($query, $startPage = 1) {
  module_load_include('inc', 'fedora_repository', 'SearchClass');
  $searchClass = new SearchClass();
  $retVal = $searchClass->custom_search($query, $startPage);
  return $searchClass->custom_search($query, $startPage);
}

/**
 * fedora repository mnpl_advanced search form submit
 * @param type $form
 * @param type $form_state
 */
function fedora_repository_mnpl_advanced_search_form_submit($form, &$form_state) {
  $type_id = $form_state['values']['type'];
  $repeat = variable_get('fedora_repository_advanced_block_repeat', t('3'));
  $searchString = $form_state['values']['type1'] . ':' . $form_state['values']['fedora_terms1'];
  if ($form_state['values']['fedora_terms2'] != '') {
    $searchString .=' +' . $form_state['values']['andor1'] . '+' . $form_state['values']['type2'] . ':' . $form_state['values']['fedora_terms2'];
  }
  if ($repeat > 2 && $repeat < 9) {
    for ($i = 3; $i < $repeat + 1; $i++) {
      $t = $i - 1;
      if ($form_state['values']["fedora_terms$i"] != '') {
        $searchString .= '+' . $form_state['values']["andor$t"] . '+' . $form_state['values']["type$i"] . ':' . $form_state['values']["fedora_terms$i"];
      }
    }
  }
  drupal_goto("fedora/repository/mnpl_advanced_search/$searchString");
}

/**
 * fedora repository install demo page
 * @return type
 */
function fedora_repository_install_demos_page() {
  $output = drupal_get_form('fedora_repository_demo_objects_form');
  return $output;
}

/**
 * fedora repository demo objects form
 * @return string
 */
function fedora_repository_demo_objects_form() {
  module_load_include('inc', 'fedora_repository', 'ObjectHelper');
  module_load_include('inc', 'fedora_repository', 'api/fedora_item');
  $form = array();
  $existing_demos = array();

  $form['install_demos'] = array(
    '#title' => t('Islandora Demo Collections'),
    '#type' => 'fieldset',
    '#description' => t('Install demo image and document collections and content models.'),
  );
  $demo_objects = array();
// Check if the top-level islandora collection exists. If not, display a button to ingest.

  $form['install_demos']['demo_collections'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Collections to ingest'),
    '#options' => array(),
    '#description' => t('Choose which demo collections you would like ingested into the repository.'),
  );

  foreach (array(
'islandora:collectionCModel' => 'Islandora default content models',
 'islandora:root' => 'Islandora top-level collection',
 'islandora:demos' => 'Islandora demos collection',
 'islandora:largeimages' => 'Sample large image content model (requires <a href="http://sourceforge.net/projects/djatoka/">Djatoka</a> and <a href="http://www.kakadusoftware.com/index.php?option=com_content&task=view&id=26&Itemid=22">Kakadu</a>.)',
  )
  as $available_demo => $available_demo_desc) {
    try {
      $demo_objects[$available_demo] = new Fedora_Item($available_demo);
    } catch (exception $e) {

    }

    if (empty($demo_objects[$available_demo]->objectProfile)) {
//The demo objects collection does not exist in the repository, display a button to ingest them.
      $form['install_demos']['demo_collections']['#options'][$available_demo] = $available_demo_desc;
    }
    else {
      array_push($existing_demos, $demo_objects[$available_demo]);
    }
  }

// Check if the SmileyStuff collectoin exists, and if it has a COLLECTION_VIEW datastream. If it doesn't then we can add it.

  $smiley_stuff = new Fedora_Item('demo:SmileyStuff');
  if (!empty($smiley_stuff->objectProfile)) {
    $datastreams_list = $smiley_stuff->get_datastreams_list_as_array();
    if (empty($datastreams_list['COLLECTION_VIEW'])) {
      $form['install_demos']['demo_collections']['#options']['demo:SmileyStuff'] = 'Add Islandora Collection View to Fedora Smiley Stuff Collection';
    }
    else {
      $demo_objects['demo:SmileyStuff'] = $smiley_stuff;
    }
  }
  else {
    $form['install_demos']['smileynote'] = array(
      '#value' => '<p>If you install the ' . l('fedora demo objects', 'https://wiki.duraspace.org/display/FCR30/Demonstration+Objects') . ' Islandora can display them as a collection.</p>'
    );
  }

  $form['install_demos']['ingest'] = array(
    '#type' => 'submit',
    '#name' => 'install_demos',
    '#value' => 'Install Selected Demos',
    '#disabled' => (empty($form['install_demos']['demo_collections']['#options'])) ? TRUE : FALSE,
  );

  $form['existing_demos'] = array(
    '#prefix' => '<p>Demo collections already installed in this repository:</p><ul>',
    '#suffix' => '</ul>',
  );

  if (!empty($existing_demos)) {
    foreach ($existing_demos as $pid => $demo_object) {

      $form['existing_demos'][$demo_object->pid] = array(
        '#prefix' => '<li>',
        '#value' => l($demo_object->pid, $demo_object->url()),
        '#suffix' => '</li>',
      );
    }
  }

  return $form;
}

/**
 * fedora repository demo objects form submit
 * @global type $base_url
 * @param type $form
 * @param type $form_state
 */
function fedora_repository_demo_objects_form_submit($form, &$form_state) {
  module_load_include('inc', 'fedora_repository', 'api/fedora_item');
  module_load_include('inc', 'fedora_repository', 'api/dublin_core');
  module_load_include('inc', 'fedora_repository', 'api/fedora_utils');
  global $base_url;
  if ($form_state['clicked_button']['#name'] == 'install_demos') {
    if (!empty($form_state['values']['demo_collections']['islandora:collectionCModel'])) {
      try {
        $collectioncm = Fedora_Item::ingest_new_item('islandora:collectionCModel', 'A', 'Islandora Collection Content Model');
        $collectioncm->add_relationship('hasModel', 'fedora-system:ContentModel-3.0', FEDORA_MODEL_URI);
        $collectioncm->add_datastream_from_file(drupal_get_path('module', 'fedora_repository') . '/content_models/COLLECTIONCM.xml', 'ISLANDORACM', 'Islandora Content Model.xml', 'application/xml', 'X');
      } catch (exception $e) {

      }
      try {
        $strictpdfcm = Fedora_Item::ingest_new_item('islandora:strict_pdf', 'A', 'Strict PDF Content Model');
        $strictpdfcm->add_relationship('hasModel', 'fedora-system:ContentModel-3.0', FEDORA_MODEL_URI);
        $strictpdfcm->add_datastream_from_file(drupal_get_path('module', 'fedora_repository') . '/content_models/STRICT_PDFCM.xml', 'ISLANDORACM', 'Islandora Content Model.xml', 'application/xml', 'X');
      } catch (exception $e) {

      }

// Install a collection object that points to all content model objects
      try {
        $cmodel_collection_xml = Fedora_Item::create_object_FOXML('islandora:ContentModelCollection');
        $cmodel_collection = Fedora_Item::ingest_from_FOXML($cmodel_collection_xml);

//$dc = new Dublin_Core(new Fedora_Item('islandora:ContentModelCollection'));
        $dc = new Dublin_Core($cmodel_collection);
        $dc->set_element('dc:title', array('Installed Content Model'));
        $dc->save();
        $cmodel_collection->add_datastream_from_string('select $object $title from <#ri>
          where ($object <fedora-model:label> $title
          and ($object <fedora-model:hasModel> <info:fedora/fedora-system:ContentModel-3.0>
          or $object <fedora-rels-ext:isMemberOfCollection> <info:fedora/islandora:ContentModelsCollection>)
          and $object <fedora-model:state> <info:fedora/fedora-system:def/model#Active>)
          order by $title', 'QUERY', 'Content Model Collection Query', 'text/plain');
        $cmodel_collection->add_relationship('isMemberOfCollection', 'islandora:root');
        $cmodel_collection->add_relationship('hasModel', 'islandora:collectionCModel', FEDORA_MODEL_URI);
        $cmodel_collection->add_datastream_from_file(drupal_get_path('module', 'fedora_repository') . '/collection_views/simple_list_view.xml', 'COLLECTION_VIEW', 'Collection View', 'text/xml', 'X');
        $cmodel_collection->add_datastream_from_file(drupal_get_path('module', 'fedora_repository') . '/images/contentModel.jpg', 'TN', 'Thumbnail', 'image/jpg', 'M');
        drupal_set_message(t("Successfully installed <a href=\"@base_url/fedora/repository/islandora:ContentModelCollection\">islandora:ContentModelCollection</a>.", array('@base_url' => check_plain($base_url))), 'message');
      } catch (exception $e) {

      }
    }

    if (!empty($form_state['values']['demo_collections']['islandora:root'])) {
      $new_item = Fedora_Item::ingest_new_item('islandora:root', 'A', 'Islandora Top-level Collection');
      $new_item->add_relationship('hasModel', 'islandora:collectionCModel', FEDORA_MODEL_URI);
      $cp = $new_item->add_datastream_from_file(drupal_get_path('module', 'fedora_repository') . '/collection_policies/COLLECTION-COLLECTION POLICY.xml', 'COLLECTION_POLICY', 'Collection Policy', 'text/xml', 'X');
      try {
        $tn = $new_item->add_datastream_from_file(drupal_get_path('module', 'fedora_repository') . '/images/Gnome-emblem-photos.png', 'TN', 'Thumbnail.png', 'image/png', 'M');
        drupal_set_message(t("Successfully installed <a href=\"@base_url/fedora/repository/islandora:root\">islandora:root</a>.", array('@base_url' => check_plain($base_url))), 'message');
      } catch (exception $e) {

      }
    }

    if (!empty($form_state['values']['demo_collections']['islandora:demos'])) {
      $new_item = fedora_item::ingest_new_item('islandora:demos', 'A', 'Islandora Demo Collection');
      $new_item->add_relationship('isMemberOfCollection', 'islandora:root');
      $new_item->add_relationship('hasModel', 'islandora:collectionCModel', FEDORA_MODEL_URI);
      $cp = $new_item->add_datastream_from_file(drupal_get_path('module', 'fedora_repository') . '/collection_policies/COLLECTION-COLLECTION POLICY.xml', 'COLLECTION_POLICY', 'Collection Policy', 'text/xml', 'X');

// $cv = $new_item->add_datastream_from_file( drupal_get_path('module', 'fedora_repository') . '/collection_views/COLLECTION_VIEW.xml', 'COLLECTION_VIEW', 'Collection View.xml', 'text/xml', 'X');
      $tn = $new_item->add_datastream_from_file(drupal_get_path('module', 'fedora_repository') . '/images/Gnome-emblem-photos.png', 'TN', 'Thumbnail.png', 'image/png', 'M');
      try {
        $new_item = Fedora_Item::ingest_new_item('islandora:pdf_collection', 'A', 'PDF Collection');
        $new_item->add_relationship('isMemberOfCollection', 'islandora:demos');
        $new_item->add_relationship('hasModel', 'islandora:collectionCModel', FEDORA_MODEL_URI);
        $cp = $new_item->add_datastream_from_file(drupal_get_path('module', 'fedora_repository') . '/collection_policies/PDF-COLLECTION POLICY.xml', 'COLLECTION_POLICY', 'Collection Policy', 'text/xml', 'X');
        $tn = $new_item->add_datastream_from_file(drupal_get_path('module', 'fedora_repository') . '/images/Crystal_Clear_mimetype_pdf.png', 'TN', 'Thumbnail.png', 'image/png', 'M');
        drupal_set_message(t("Successfully installed <a href=\"@base_url/fedora/repository/islandora:demos\">islandora:demos</a>.", array('@base_url' => check_plain($base_url))), 'message');
      } catch (exception $e) {

      }
    }

    if (!empty($form_state['values']['demo_collections']['demo:SmileyStuff'])) {
      $smiley_stuff = new Fedora_Item('demo:SmileyStuff');
      $new_item = $smiley_stuff->add_datastream_from_file(drupal_get_path('module', 'fedora_repository') . '/collection_views/SmileyStuff-COLLECTION_VIEW.xml', 'COLLECTION_VIEW', 'Collection View', 'text/xml', 'X');
      $smiley_stuff->add_relationship('isMemberOfCollection', 'info:fedora/islandora:demos');
      $tn = $smiley_stuff->add_datastream_from_file(drupal_get_path('module', 'fedora_repository') . '/images/smileytn.png', 'TN', 'Thumbnail.png', 'image/png', 'M');
      $cp = $smiley_stuff->add_datastream_from_file(drupal_get_path('module', 'fedora_repository') . '/collection_policies/JPG-COLLECTION POLICY.xml', 'COLLECTION_POLICY', 'Collection Policy.xml', 'application/xml', 'X');

      $cm = new Fedora_Item('demo:DualResImage');
      try {
        $cmstream = $cm->add_datastream_from_file(drupal_get_path('module', 'fedora_repository') . '/content_models/STANDARD JPG.xml', 'ISLANDORACM', 'Content Model.xml', 'application/xml', 'X');
      } catch (exception $e) {

      }
      $dual_res_image_collection_cmodel = new Fedora_Item('demo:DualResImageCollection');
      try {
        $cmstream = $dual_res_image_collection_cmodel->add_datastream_from_file(drupal_get_path('module', 'fedora_repository') . '/content_models/COLLECTIONCM.xml', 'ISLANDORACM', 'Islandora Content Model.xml', 'application/xml', 'X');
        drupal_set_message(t("Successfully installed <a href=\"@base_url/fedora/repository/demo:SmileyStuff\">demo:SmileyStuff</a> collection view.", array('@base_url' => check_plain($base_url))), 'message');
      } catch (exception $e) {

      }
    }

    if (!empty($form_state['values']['demo_collections']['islandora:largeimages'])) {
      $error = '';
      foreach (array('islandora_jp2Sdep-slideCModel.xml', 'islandora_mods2htmlSdef.xml', 'islandora_mods2htmlSdep.xml',
    'islandora_slideCModel.xml', 'islandora_viewerSdep-slideCModel.xml', 'ilives_jp2Sdef.xml', 'ilives_viewerSdef.xml') as $foxml_file) {
        try {
          $item = Fedora_Item::ingest_from_FOXML_file(drupal_get_path('module', 'fedora_repository') . '/content_models/' . $foxml_file);
        } catch (exception $e) {
          $error .= " - Problem ingesting $foxml_file";
        }
      }
      try {
        $item = Fedora_Item::ingest_from_FOXML_file(drupal_get_path('module', 'fedora_repository') . '/content_models/islandora_largeimages.xml');
        $tn = $item->add_datastream_from_file(drupal_get_path('module', 'fedora_repository') . '/images/Gnome-emblem-photos.png', 'TN', 'Thumbnail.png', 'image/png', 'M');
        drupal_set_message(t("Successfully installed <a href=\"@base_url/fedora/repository/islandora:largeimages\">islandora:largeimages</a>.", array('@base_url' => check_plain($base_url))), 'message');
      } catch (exception $e) {
        $error .= " - Problem ingesting islandora:largeimages collection";
      }
    }

    if (!empty($error)) {
      drupal_set_message(t('Some problems occurred: @error', array('@error' => $error)));
    }
  }
}

/**
 * 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 = '<div class="container-inline">' . $element['#children'] . '</div>';
  return theme('form_element', $element, $output);
}

/**
 * theme fedora repository time
 * @param type $element
 * @return type
 */
function theme_fedora_repository_time($element) {
  $output = '<div class="container-inline">' . $element['#children'] . '</div>';
  return theme('form_element', $element, $output);
}

/* Export (basket) functionality */

/**
 * fedora repository remove item from basket
 * @param type $pid
 */
function fedora_repository_remove_item_from_basket($pid) {

  module_load_include('inc', 'fedora_repository', 'ObjectHelper');
  $pids = empty($_SESSION['basket']['processed']) ? array() : $_SESSION['basket']['processed'];

  $objectHelper = new ObjectHelper();
// getting child PIDs if any
  $cpids = $objectHelper->get_child_pids(array($pid));

  if (array_key_exists($pid, $pids)) {
// remove item from basket
    unset($_SESSION['basket']['processed'][$pid]);
  }
  if (!empty($cpids)) { // there are children
    foreach ($cpids as $child_pid => $value) {
// remove child item from basket recursively
      fedora_repository_remove_item_from_basket($child_pid);
    }
  }
}

/**
 * fedora repository basket
 * @return type
 */
function fedora_repository_basket() {
  $pids = _fedora_repository_get_basket_pids();
  $output = drupal_get_form('fedora_repository_basket_form', $pids);

  return $output;
}

function fedora_repository_basket_form($form_state, $pids) {
  $form = array();

  if (!empty($pids)) {
    $form['pid'] = array();
    $form['title'] = array();
    $form['desc'] = array();
  }
  else {
    return;
  }

  ksort($pids);
  foreach ($pids as $pid => $arr) {
    $cbs[$pid] = '';

    $form['pid'][$pid] = array('#value' => l($pid, "fedora/repository/$pid"));
    $form['title'][$pid] = array('#value' => $arr['title']);
    $form['desc'][$pid] = array('#value' => $arr['desc']);
  }

  $form['remove'] = array(
    '#type' => 'checkboxes',
    '#options' => $cbs,
  );

  $form['remove_submit'] = array(
    '#type' => 'submit',
    '#value' => t('Remove selected'),
  );

  $form['remove_all'] = array(
    '#type' => 'submit',
    '#value' => t('Empty basket'),
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Export selected'),
  );

  $form['submit_all'] = array(
    '#type' => 'submit',
    '#value' => t('Export all'),
  );

  return $form;
}

/**
 * theme fedora repository basket form
 * @param type $form
 * @return string
 */
function theme_fedora_repository_basket_form($form) {
  $header = array(
    theme('table_select_header_cell'),
    t('PID'),
    t('Title'),
    t('Description'),
  );

  if (isset($form['pid']) && is_array($form['pid'])) {
    foreach (element_children($form['pid']) as $key) {
      $rows[] = array(
        drupal_render($form['remove'][$key]),
        drupal_render($form['pid'][$key]),
        drupal_render($form['title'][$key]),
        drupal_render($form['desc'][$key]),
      );
    }
  }
  else {
    $rows[] = array(array('data' => t('Your basket is empty.'), 'colspan' => '4'));
  }

  $output = theme('table', $header, $rows);

  $frm = drupal_render($form);
  $output = $frm . $output . $frm;

  return $output;
}

/**
 * fedora repository basket form validate
 * @param type $form
 * @param type $form_state
 */
function fedora_repository_basket_form_validate($form, &$form_state) {

}

/**
 * fedora repository basket form submit
 * @global type $user
 * @param type $form
 * @param type $form_state
 * @return type
 */
function fedora_repository_basket_form_submit($form, &$form_state) {
  if ($form_state['values']['op'] == $form_state['values']['remove_submit']) {
    $pids = $form_state['clicked_button']['#post']['remove'];

    if (isset($pids)) {
      foreach ($pids as $pid) {
        fedora_repository_remove_from_basket($pid);
      }
      drupal_set_message(t("Selected objects removed"));
      return;
    }
  }

  if ($form_state['values']['op'] == $form_state['values']['remove_all']) {
    _fedora_repository_empty_basket();
    drupal_set_message(t("Basket emptied"));
    return;
  }

  if ($form_state['values']['op'] == $form_state['values']['submit_all']) {
    $msg = t("All objects exported to staging area");
    $pids = _fedora_repository_get_basket_pids();
  }
  elseif ($form_state['values']['op'] == $form_state['values']['submit']) {
    $msg = t("Selected objects exported to staging area");
    $pids = array_filter($form_state['values']['remove']);
  }

  if (!empty($pids)) {
    global $user;
    $log = array();
    $success = TRUE;
    $export_dir = variable_get('export_area', file_directory_path() . '/fedora_export_area') . '/' . $user->name . '/' . date("Ymd-His");
    $foxml_dir = $export_dir . '/foxml';

    if (!file_exists($foxml_dir) && !@mkdir($foxml_dir, 0775, TRUE)) {
      drupal_set_message(t("Failed to create foxml dir @dir. Check that export dir exsits and has correct permissions", array('@dir' => $foxml_dir)), 'error');
      return FALSE;
    }

    module_load_include('inc', 'fedora_repository', 'api/fedora_export');
    foreach ($pids as $pid => $arr) {

      $objects_dir = $export_dir . '/objects/' . $pid;
      if (!file_exists($objects_dir) && !@mkdir($objects_dir, 0775, TRUE)) {
        drupal_set_message(t("Failed to create objects dir @dir. Check that export dir exsits and has correct permissions", array('@dir' => $objects_dir)), 'error');
        return FALSE;
      }

      if (!export_to_export_area($pid, $foxml_dir, $objects_dir, $log)) {
        $success = FALSE;
      }
    }
    $msg = $success ? $msg : t("Failed to export objects to staging area");
    $msg .= ":<br/>" . implode("<br/>", $log);

    drupal_set_message($msg, $success ? 'info' : 'error');
//_fedora_repository_empty_basket();
  }
  else {
    drupal_set_message(t("No objects selected or basket empty"), 'error');
  }

  return;
}

/**
 * Get all pids saved to the basket.
 *
 * @return type
 */
function _fedora_repository_get_basket_pids() {

// Set empty defaults if basket elements are missing
  $_SESSION['basket'] = isset($_SESSION['basket']) ? $_SESSION['basket'] : array('processed' => array(), 'unprocessed' => array());
  $_SESSION['basket']['processed'] = isset($_SESSION['basket']['processed']) ? $_SESSION['basket']['processed'] : array();
  $_SESSION['basket']['unprocessed'] = isset($_SESSION['basket']['unprocessed']) ? $_SESSION['basket']['unprocessed'] : array();

  $pids = empty($_SESSION['basket']['processed']) ? array() : $_SESSION['basket']['processed'];

  module_load_include('inc', 'fedora_repository', 'ObjectHelper');
  $ob = new ObjectHelper();
  foreach ($_SESSION['basket']['unprocessed'] as $pid) {
// Check if the pid already exists in the tree
    if (array_key_exists($pid, $pids)) {
      continue;
    }

    $pids += $ob->get_all_related_pids($pid);
//    $pids += array($pid);
  }

  $_SESSION['basket']['processed'] = $pids;
  $_SESSION['basket']['unprocessed'] = array();

  return $pids;
}

/**
 * fedora repository empty basket
 */
function _fedora_repository_empty_basket() {
  unset($_SESSION['basket']);
}

/**
 * fedora repository add to basket
 * @param type $pid
 * @param type $warn
 * @param type $searchResultsFlag
 */
function fedora_repository_add_to_basket($pid, $warn = TRUE, $searchResultsFlag = FALSE) {
  if ($warn && _is_added_to_basket($pid)) {
    drupal_set_message(t("Object already in basket"));
  }

  if (!isset($_SESSION['basket'])) {
    $_SESSION['basket'] = array();
    $_SESSION['basket']['unprocessed'] = array($pid => $pid);
  }
  else {
    $_SESSION['basket']['unprocessed'][$pid] = $pid;
  }

  if (!$searchResultsFlag) {
    drupal_goto('fedora/basket');
  }
}

/**
 * fedora repository remove from basket
 * @param type $pid
 * @return type
 */
function fedora_repository_remove_from_basket($pid) {
  if (isset($_SESSION['basket']['unprocessed'][$pid])) {
    unset($_SESSION['basket']['unprocessed'][$pid]);
  }

  if (isset($_SESSION['basket']['processed'][$pid])) {
    unset($_SESSION['basket']['processed'][$pid]);
  }
  return;
}

/**
 * theme add to basket link
 * @param type $pid
 * @param type $type
 * @return type
 */
function theme_add_to_basket_link($pid, $type = 'object') {
  $object = t($type);
  $path = drupal_urlencode($pid);

  $save = "export_big.png";
  $saved = "exported_big.png";
//  $path = drupal_get_path('module', 'fedora_repository').'/images/'.$save ;
  /*
    var_dump($path);
    var_dump(theme('image',drupal_get_path('module', 'fedora_repository').'/images/'.$save));
    die();
   */
  if (!_is_added_to_basket($pid)) {
    return l(
        theme('image', drupal_get_path('module', 'fedora_repository') . '/images/' . $save, t("Add to basket"), t("Add this @object to my basket", array('@object' => $object))), "fedora/repository/addToBasket/" . $path, array('html' => TRUE)
    );
  }

  return theme('image', drupal_get_path('module', 'fedora_repository') . '/images/' . $saved, t("In basket"), t("This @object is already in your basket", array('@object' => $object)));
}

/**
 * is added to basket
 * @param type $pid
 * @param type $account
 * @return type
 */
function _is_added_to_basket($pid, $account = NULL) {
  return isset($_SESSION['basket']['unprocessed'][$pid]) || isset($_SESSION['basket']['processed'][$pid]);
//  return db_result(db_query("SELECT uid FROM {repository_basket} WHERE uid = %d AND pid = '%s'", $account->uid, $pid));
}

/**
 * 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:
 *   <content_model name="Collection" version="2" ...
 *
 * @param Fedora_Item $item
 * @param string $dsid
 * @param string $datastream_file
 *
 * @return mixed
 *   int, or NULL if no version attribute was found.
 */
function fedora_repository_get_islandora_datastream_version($item = NULL, $dsid = NULL, $datastream_file = NULL) {
  $return = NULL;
  if (!empty($item) && !empty($dsid)) {
    $doc = simplexml_load_string($item->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);
}