diff --git a/CollectionClass.inc b/CollectionClass.inc index a46b1b5f..e1ec846e 100644 --- a/CollectionClass.inc +++ b/CollectionClass.inc @@ -6,11 +6,6 @@ * Collection Class Class */ -if (!defined('PHP_VERSION_ID')) { //XXX: This should go elsewhere - $version = explode('.', PHP_VERSION); - define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2])); -} - /** * This CLASS caches the streams so once you call a getstream once it will always return * the same stream as long as you are using the instance of this class. Cached to @@ -33,85 +28,114 @@ class CollectionClass { * @return CollectionClass */ function __construct($pid = NULL) { - if (!empty($pid)) { - module_load_include('inc', 'fedora_repository', 'ObjectHelper'); - $this->collectionObject = new ObjectHelper($pid); - $this->pid = $pid; + module_load_include('inc', 'fedora_repository', 'ObjectHelper'); + $this->collectionObject = new ObjectHelper(); + $this->pid = $pid; + } + + public static function getCollectionQuery($pid) { + if ($query = self::getCollectionQueryFromStream($pid)) { + return $query; + } + else { + return self::getDefaultCollectionQuery($pid); } } + + protected static function getCollectionQueryFromStream($pid) { + module_load_include('inc', 'fedora_repository', 'api/fedora_item'); + $item = new Fedora_Item($pid); + if ($item->exists() && array_key_exists('QUERY', $item->datastreams)) { + return $item->get_datastream_dissemination('QUERY'); + } + else { + return FALSE; + } + } + + protected static function getDefaultCollectionQuery($pid) { + return 'select $object $title $content from <#ri> + where ($object $title + and $object $content + and ($object + or $object ) + and $object ) + minus $content + order by $title'; + } /** - * gets objects related to this object. must include offset and limit - * calls getRelatedItems but enforces limit and offset - * @param type $pid - * @param type $limit + * Gets objects related to this object. Must include offset and limit! + * + * Calls self::getRelatedItems() but requires limit and offset. + * + * @param $pid string + * A string containing a Fedora PID. + * @param $limit + * An integer * @param type $offset * @param type $itqlquery * @return type */ function getRelatedObjects($pid, $limit, $offset, $itqlquery=NULL) { - if (!isset($itqlquery)) { - module_load_include('inc', 'fedora_repository', 'api/fedora_item'); - $item = new Fedora_Item($pid); - if ($item->exists() && array_key_exists('QUERY', $item->datastreams)) { - $itqlquery = $item->get_datastream_dissemination('QUERY'); - } - } return $this->getRelatedItems($pid, $itqlquery, $limit, $offset); } /** - * Gets objects related to this item. It will query the object for a Query stream and use that as a itql query - * or if there is no query stream it will use the default. If you pass a query to this method it will use the passed in query no matter what - * @global type $user - * @param type $pid - * @param type $itqlquery - * @param int $limit + * Gets objects related to this item. + * + * Query the resource index using the provided iTQL query. If no query is + * provided, one should be obtained via self::getCollectionQuery() which + * grabs the child objects. + * + * @param $pid string + * A string containing a PID which may be substituted into the query, + * in place of the %parent_collection% placeholder. + * @param $query_string string + * An optional iTQL query. + * @param $limit int + * An optional integer to limit the number of results returned. * @param int $offset - * @return type + * An optional integer used to offset the results returned. (Query should + * involve a sort to maintain consistency. + * @return string + * Sparql XML results from the resource index. */ - function getRelatedItems($pid, $itqlquery = NULL, $limit = NULL, $offset = NULL) { - module_load_include('inc', 'fedora_repository', 'ObjectHelper'); + function getRelatedItems($pid, $query_string = NULL, $limit = NULL, $offset = NULL) { module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); - if (!isset($offset)) { - $offset = 0; - } - global $user; - if (!fedora_repository_access(OBJECTHELPER :: $OBJECT_HELPER_VIEW_FEDORA, $pid, $user)) { + module_load_include('inc', 'fedora_repository', 'ObjectHelper'); + if (!fedora_repository_access(OBJECTHELPER :: $OBJECT_HELPER_VIEW_FEDORA, $pid)) { drupal_set_message(t("You do not have access to Fedora objects within the attempted namespace or access to Fedora denied."), 'error'); return ' '; } - $objectHelper = new ObjectHelper(); - $query_string = $itqlquery; - if (!isset($query_string)) { - $query_string = NULL; - $item = new Fedora_Item($pid); - if ($item->exists() && array_key_exists('QUERY', $item->datastreams)) { - $query_string = $item->get_datastream_dissemination('QUERY'); - } - if ($query_string == NULL) { - $query_string = 'select $object $title $content from <#ri> - where ($object $title - and $object $content - and ($object - or $object ) - and $object ) - minus $content - order by $title'; - } - } - else { - // Replace %parent_collection% with the actual collection PID - $query_string = preg_replace("/\%parent_collection\%/", "", $query_string); + + if ($query_string === NULL) { + $query_string = self::getCollectionQuery($pid); } - $query_string = htmlentities(urlencode($query_string)); + // Replace %parent_collection% with the actual collection PID + $query_string = preg_replace("/\%parent_collection\%/", "", $query_string); - $content = ''; $url = variable_get('fedora_repository_url', 'http://localhost:8080/fedora/risearch'); - $url .= "?type=tuples&flush=TRUE&format=Sparql&limit=$limit&offset=$offset&lang=itql&stream=on&query=" . $query_string; - $content .= do_curl($url); + + $settings = array( + 'type' => 'tuples', + 'flush' => TRUE, + 'format' => 'Sparql', + 'lang' => 'itql', + 'stream' => 'on', + 'query' => $query_string + ); + if ($limit > 0) { + $settings['limit'] = $limit; + } + if ($offset > 0) { + $settings['offset'] = $offset; + } + + $url .= '?' . http_build_query($settings, NULL, '&'); + $content = do_curl($url); return $content; } @@ -200,7 +224,7 @@ class CollectionClass { * @return ContentModel */ function getContentModels($collection_pid, $showError = TRUE) { - module_load_include('inc', 'Fedora_Repository', 'ContentModel'); + module_load_include('inc', 'fedora_repository', 'ContentModel'); $collection_stream = $this->getCollectionPolicyStream($collection_pid); try { $xml = new SimpleXMLElement($collection_stream); @@ -227,7 +251,7 @@ class CollectionClass { * $dsid is the datastream id of the content model. */ function getNextPid($pid, $dsid) { - module_load_include('inc', 'Fedora_Repository', 'ConnectionHelper'); + module_load_include('inc', 'fedora_repository', 'ConnectionHelper'); $pidNameSpace = $this->getPidNameSpace($pid, $dsid); $pname = substr($pidNameSpace, 0, strpos($pidNameSpace, ":")); module_load_include('inc', 'fedora_repository', 'api/fedora_item'); @@ -345,7 +369,7 @@ class CollectionClass { $parametersArray["$name"] = $value; } } - // module_load_include( $phpFile, 'Fedora_Repository', ' '); + // module_load_include( $phpFile, 'fedora_repository', ' '); require_once(drupal_get_path('module', 'fedora_repository') . '/' . $phpFile); $thisClass = new $phpClass (); $returnValue = $thisClass->$phpMethod($parametersArray, $dsid, $file, $file_ext); @@ -422,7 +446,7 @@ class CollectionClass { $phpClass = strip_tags($ingest_form->form_builder_method->class_name->asXML()); $phpMethod = strip_tags($ingest_form->form_builder_method->method_name->asXML()); $dsid = strip_tags($ingest_form['dsid']); - // module_load_include('php', 'Fedora_Repository', $phpFile); + // module_load_include('php', 'fedora_repository', $phpFile); require_once(drupal_get_path('module', $drupal_module) . '/' . $phpFile); $thisClass = new $phpClass (); @@ -490,9 +514,12 @@ class CollectionClass { module_load_include('inc', 'fedora_repository', 'CollectionClass'); $collectionClass = new CollectionClass(); $xslContent = $collectionClass->getCollectionViewStream($pid); - if (!$xslContent && $canUseDefault) { //no xslt so we will use the default sent with the module + + //If there's no XSLT from the object, then check if the one which used to exist, does... + if (!$xslContent && $canUseDefault && file_exists($path . '/xsl/sparql_to_html.xsl')) { $xslContent = file_get_contents($path . '/xsl/sparql_to_html.xsl'); } + return $xslContent; } @@ -519,7 +546,6 @@ class CollectionClass { $results = $this->getRelatedItems($this->pid, $query); $collection_items = $this->renderCollection($results, $this->pid, NULL, NULL, $page_number); - //$collection_item = new Fedora_Item($this->pid); //XXX: This didn't seem to be used... $show_batch_tab = FALSE; $policy = CollectionPolicy::loadFromCollection($this->pid, TRUE); @@ -554,17 +580,6 @@ class CollectionClass { '#tab_name' => 'add-tab', ); } - - if ($show_batch_tab && user_access('create batch process')) { //XXX: Is this not put in by the batch module? - $tabset['batch_ingest_tab'] = array( - // #type and #title are the minimum requirements. - '#type' => 'tabpage', - '#title' => t('Batch Ingest'), - // This will be the content of the tab. - '#content' => drupal_get_form('batch_creation_form', $this->pid, $content_models), - '#tab_name' => 'batch-ingest-tab', - ); - } return $tabset; } @@ -575,10 +590,8 @@ class CollectionClass { * @return string */ function getIngestInterface() { - global $base_url; - $objectHelper = new ObjectHelper(); - module_load_include('inc', 'Fedora_Repository', 'CollectionPolicy'); - $collectionPolicyExists = $objectHelper->getMimeType($this->pid, CollectionPolicy::getDefaultDSID()); + module_load_include('inc', 'fedora_repository', 'CollectionPolicy'); + $collectionPolicyExists = $this->collectionObject->getMimeType($this->pid, CollectionPolicy::getDefaultDSID()); if (user_access(ObjectHelper :: $INGEST_FEDORA_OBJECTS) && $collectionPolicyExists) { if (!empty($collectionPolicyExists)) { $allow = TRUE; @@ -597,6 +610,146 @@ class CollectionClass { return $ingestObject; } + /** + * Unfortunate function, I know... + * + * Does just what it says: Hacks the default Drupal pager such that it might + * be rendered, likely with: theme('pager', array(), $per_page, $pager_name) + * (I reccomend seeing the real documentation for more detail, but the first + * array can be a list of the tags to use for first, previous, next and last + * (text in the pager), I don't believe per_page is actually used in the theme + * function, and $pager_name is an integer used to identify the pager (such + * that there can be more than one--that is, tracking different lists of + * content on a single page. You can render the exact same pager multiple + * times, say if you want one at the top and bottom of a list, using the same + * ID/pager_name. + * + * @global $pager_total array + * Numerically indexed array, where keys are the $pager_names and values + * are the number of pages in the given set, based on: ceil($total_items/$per_page); + * @global $pager_page_array array + * Numerically indexed array, where keys are the $pager_names and values + * are the page selected in the relevant set. + * @param $pager_name int + * An integer to identify the pager to affect. Do note that paging in using + * this function will add the 'page' HTTP GET parameter to the URL, with + * the value containing a comma-separated list with max($pager_name + 1) + * values--that is, if you create a single pager named '10', the 'next' + * link will look something like: 0,0,0,0,0,0,0,0,0,0,1 + * @param $per_page int + * An integer representing the number of items per page. + * @param $total_items int + * An integer representing the total number of items in the set. + * @return int + * An integer representing what the current page should be. + */ + protected static function hackPager($pager_name, $per_page = NULL, $total_items = NULL) { + global $pager_total, $pager_page_array; + + if ($per_page !== NULL && $total_items !== NULL) { + $pager_total[$pager_name] = ceil($total_items / $per_page); + } + + //XXX: Don't know that this is neccessary, to try to load all the time, or + // whether Drupal will load it automatically somewhere... Docs seems a + // a little sparse. + $page_info = explode(',', isset($_GET['page']) ? $_GET['page'] : ''); + $page = $page_info[$pager_name]; + if ($page < 0) { + $page = 0; + } + + if (!isset($pager_page_array)) { + $pager_page_array = pager_load_array($page, $pager_name, $page_info); + } + else { + $pager_page_array = pager_load_array($page, $pager_name, $pager_page_array); + } + + $page = $pager_page_array[$pager_name]; + return $page; + } + + /** + * Assemble results in a somewhat more logical manner... + * + * ... Compared to generating a table in XSLT to contain a list (as + * renderCollection() used to do/does by default). + * + * @param $sparql_results array + * The array of results as yielded by ObjectHelper::parseSparqlResults() + * (and those associated functions which make use of it). + * Each result must contain: + * - 'object': The PID/URI of the child object. + * - 'title': A title for the child object. + * and may contain: + * - 'thumbnail': URI to a datastream. (will default to the 'TN' stream on the child) + * @return + * An array to be passed to drupal_render, containing a pager, an unordered + * list of items, and another pager. + */ + public static function assembleCollectionView($sparql_results) { + $per_page = 20; //XXX: Make this configurable. + $pager_name = 0; + $total = count($sparql_results); + $pager_page = self::hackPager($pager_name, $per_page, $total); + $max_title_length = 60; + + $results = array(); + foreach (array_slice($sparql_results, $per_page * $pager_page, $per_page) as $result) { + $title = $result['title']; + $truncated_title = truncate_utf8($title, $max_title_length, TRUE, TRUE, 5); + $obj_path = "fedora/repository/{$result['object']}"; + + //Get a thumbnail + $tn_path = ($result['thumbnail'] ? + "fedora/repository/{$result['thumbnail']}": + "$obj_path/TN"); + + $thumbnail = _fedora_repository_render_image($tn_path); + + $results[] = array( + 'data' => l($thumbnail, $obj_path, array( + 'html' => TRUE, + 'attributes' => array( + 'class' => 'results-image', + ), + )) . l($truncated_title, $obj_path, array('attributes' => array('class' => 'results-text'))), + ); + } + if (!$results) { + drupal_set_message(t("No objects in this collection (or bad query).")); + } + else { + $first = $per_page * $pager_page; + $last = (($total - $first) > $per_page)? + ($first + $per_page): + $total; + $results_range_text = t('Results @first to @last of @total', array( + '@first' => $first + 1, + '@last' => $last, + '@total' => $total, + )); + + return array( + array( + '#type' => 'markup', + '#value' => theme('pager', array(), $per_page, $pager_name), + ), + array( + '#type' => 'markup', + '#value' => theme('item_list', $results, $result_range_text, 'ul', array( + 'class' => 'islandora-collection-results-list', + )) + ), + array( + '#type' => 'markup', + '#value' => theme('pager', array(), $per_page, $pager_name) + ), + ); + } + } + /** * render collection * @global type $base_url @@ -607,76 +760,67 @@ class CollectionClass { * @param int $pageNumber * @return type */ - function renderCollection($content, $pid, $dsId, $collection, $pageNumber = NULL) { + function renderCollection($content, $pid, $dsId, $collectionName, $pageNumber = NULL) { $path = drupal_get_path('module', 'fedora_repository'); global $base_url; - $collection_pid = $pid; //we will be changing the pid later maybe - $objectHelper = new ObjectHelper(); - $parsedContent = NULL; - $contentModels = $objectHelper->get_content_models_list($pid); - $isCollection = FALSE; - //if this is a collection object store the $pid in the session as it will come in handy - //after a purge or ingest to return to the correct collection. - - $fedoraItem = NULL; - - - - $collectionName = $collection; - - if (!$pageNumber) { - $pageNumber = 1; - } + + $contentModels = $this->collectionObject->get_content_models_list($pid); if (empty($collectionName)) { - $collectionName = variable_get('fedora_repository_name', 'Collection'); + $collectionName = menu_get_active_title(); } + $xslContent = $this->getXslContent($pid, $path); - //get collection list and display using xslt------------------------------------------- $objectList = ''; if (isset($content) && $content != FALSE) { - $input = new DomDocument(); - $input->loadXML(trim($content)); - $results = $input->getElementsByTagName('result'); - if ($results->length > 0) { - try { - $proc = new XsltProcessor(); - $options = array( //Could make this the return of a hook? - 'collectionPid' => $collection_pid, - 'collectionTitle' => $collectionName, - 'baseUrl' => $base_url, - 'path' => "$base_url/$path", - 'hitPage' => $pageNumber, - ); - - if (defined('PHP_VERSION_ID') && PHP_VERSION_ID >= 50100) { + if (!$xslContent) { //Didn't find an XSLT. + return drupal_render( + self::assembleCollectionView( + $this->collectionObject->parseSparqlResults( + $content + ) + ) + ); + } + else { + if (!$pageNumber) { + $pageNumber = 1; + } + + //get collection list and display using xslt------------------------------------------- + $input = new DomDocument(); + $input->loadXML(trim($content)); + $results = $input->getElementsByTagName('result'); + if ($results->length > 0) { + try { + $proc = new XsltProcessor(); + $options = array( //Could make this the return of a hook? + 'collectionPid' => $pid, + 'collectionTitle' => $collectionName, + 'baseUrl' => $base_url, + 'path' => "$base_url/$path", + 'hitPage' => $pageNumber, + ); + $proc->setParameter('', $options); - } - else { - foreach ($options as $name => $value) { - $proc->setParameter('', $name, $value); - } - } - $proc->registerPHPFunctions(); - $xsl = new DomDocument(); - $xsl->loadXML($xslContent); - // php xsl does not seem to work with namespaces so removing it below - // I may have just been being stupid here - // $content = str_ireplace('xmlns="http://www.w3.org/2001/sw/DataAccess/rf1/result"', '', $content); + $proc->registerPHPFunctions(); + $xsl = new DomDocument(); + $xsl->loadXML($xslContent); + + $xsl = $proc->importStylesheet($xsl); + $newdom = $proc->transformToDoc($input); - $xsl = $proc->importStylesheet($xsl); - $newdom = $proc->transformToDoc($input); + $objectList = $newdom->saveHTML(); //is the xml transformed to html as defined in the xslt associated with the collection object - $objectList = $newdom->saveXML(); //is the xml transformed to html as defined in the xslt associated with the collection object - - if (!$objectList) { - throw new Exception("Invalid XML."); + if (!$objectList) { + throw new Exception("Invalid XML."); + } + } catch (Exception $e) { + drupal_set_message(check_plain($e->getMessage()), 'error'); + return ''; } - } catch (Exception $e) { - drupal_set_message(check_plain($e->getMessage()), 'error'); - return ''; } } } diff --git a/CollectionPolicy.inc b/CollectionPolicy.inc index 71d95a6c..a6957974 100644 --- a/CollectionPolicy.inc +++ b/CollectionPolicy.inc @@ -392,7 +392,7 @@ class CollectionPolicy extends XMLDatastream { function getContentModels() { $ret = FALSE; if ($this->validate()) { - module_load_include('inc', 'Fedora_Repository', 'ContentModel'); + module_load_include('inc', 'fedora_repository', 'ContentModel'); $ret = array(); $content_models = $this->xml->getElementsByTagName('content_models')->item(0)->getElementsByTagName('content_model'); for ($i = 0; $i < $content_models->length; $i++) { diff --git a/MimeClass.inc b/MimeClass.inc index 42c11e37..b2950f6e 100644 --- a/MimeClass.inc +++ b/MimeClass.inc @@ -231,9 +231,7 @@ class MimeClass { * @return type */ public function get_mimetype($filename, $debug = FALSE) { - - $file_name_and_extension = explode('.', $filename); - $ext = strtolower(array_pop($file_name_and_extension)); + $ext = strtolower(substr($filename, strrpos($filename, '.') + 1)); if (!empty($this->private_mime_types[$ext])) { if (TRUE === $debug) diff --git a/ObjectDetails.inc b/ObjectDetails.inc new file mode 100644 index 00000000..9ee2d88b --- /dev/null +++ b/ObjectDetails.inc @@ -0,0 +1,272 @@ + array( + "name" => "Hidden", + "module" => "fedora_repository", + "file" => "ObjectDetails.inc", + "function" => "fedora_repository_object_details_hidden", + "description" => t("No object details page"), + ), + 'xslt' => array( + "name" => "XSLT", + "module" => "fedora_repository", + "file" => "ObjectDetails.inc", + "function" => "fedora_repository_object_details_xslt", + "description" => t("Show a datastream with an XSLT"), + "config" => "admin/settings/fedora_repository/object_details_xslt", + ), + 'table' => array( + "name" => "Table", + "module" => "fedora_repository", + "file" => "ObjectDetails.inc", + "function" => "fedora_repository_object_details_table", + "description" => t("Show a datastream with a table"), + "config" => "admin/settings/fedora_repository/object_details_table", + ) + ); + return $profiles; +} + +/** + * The renderer for the "hidden" display mode. In this mode, no data is + * displayed. This is supplied so you can disable the object details metadata + * display without disabling the tab entirely. + * @param item The item with the metadata to display. + * @return The fully composed object details metadata display. + */ +function fedora_repository_object_details_hidden($item) { + // do nothing + return ""; +} + +/** + * The renderer for the "xslt" display mode. In this mode, an xslt is applied + * to the selected datastream to produce a user defined look and feel to the + * output data. + * @param item The item with the metadata to display. + * @return The fully composed object details metadata display. + */ +function fedora_repository_object_details_XSLT($item) { + global $base_url; + $path = drupal_get_path('module', 'fedora_repository'); + module_load_include('inc', 'fedora_repository', 'ConnectionHelper'); + + $dsid = variable_get('islandora_object_details_xslt_datastream', 'DC'); + // special case for DC+QDC for backward compatibility + if ($dsid == 'DC' || $dsid == 'QDC') { + $dsid = array_key_exists('QDC', $item->get_datastreams_list_as_array()) ? 'QDC' : 'DC'; + } + $xmlstr = $item->get_datastream_dissemination($dsid); + + if (empty($xmlstr)) { + return t('Error - could not find datastream @dsid on object @pid
Please contact the site administrator.', + array('@dsid' => $dsid, '@pid' => $item->pid)); + } + + try { + $proc = new XsltProcessor(); + } catch (Exception $e) { + watchdog('fedora_repository', "Error while creating XSLT processor: @e", array('@e' => $e->getMessage()), WATCHDOG_ERROR); + return; + } + + $proc->setParameter('', 'baseUrl', $base_url); + $proc->setParameter('', 'path', $path); + $input = NULL; + + $xsl_file = variable_get('islandora_object_details_xslt_sheet', 'sites/all/modules/islandora/object_details_xslts/convertQDC.xsl'); + // set an error message in case xslt parsing fails + $output = t("Failed to parse xslt file at @xsltFile", array('@xsltFile' => $xsl_file)); + if (is_readable($xsl_file)) { + $xsl = new DomDocument(); + $input = new DomDocument(); + try { + $xsl->load($xsl_file); + + $input->loadXML(trim($xmlstr)); + } catch (Exception $e) { + watchdog('fedora_repository', "Problem loading XSL file: @e", array('@e' => $e->getMessage()), NULL, WATCHDOG_ERROR); + } + $xsl = $proc->importStylesheet($xsl); + $newdom = $proc->transformToDoc($input); + $output = $newdom->saveHTML(); + } + return $output; +} + +/** + * The renderer for the "table" display mode. In this mode, the requested + * datastream is rendered using a simple table with keys(tags) on the left and + * values on the right. + * @param item The item with the metadata to display. + * @return The fully composed object details metadata display. + */ +function fedora_repository_object_details_table($item) { + global $base_url; + $path = drupal_get_path('module', 'fedora_repository'); + module_load_include('inc', 'fedora_repository', 'ConnectionHelper'); + + $dsid = variable_get('islandora_object_details_table_datastream', 'DC'); + // special case for DC+QDC for backward compatibility + if ($dsid == 'DC' || $dsid == 'QDC') { + $dsid = array_key_exists('QDC', $item->get_datastreams_list_as_array()) ? 'QDC' : 'DC'; + } + $xmlstr = $item->get_datastream_dissemination($dsid); + + if (empty($xmlstr)) { + return t('Error - could not find datastream @dsid on object @pid
Please contact the site administrator.', + array('@dsid' => $dsid, '@pid' => $item->pid)); + } + + $simplexml = new SimpleXMLElement($xmlstr); + + $headers = array( + array( + 'data' => t('Metadata'), + 'colspan' => 2, + ), + ); + $rows = array(); + foreach ($simplexml->getNamespaces(TRUE) as $ns) { + foreach ($simplexml->children($ns) as $child) { + $rows[] = array( + array( + 'data' => $child->getName(), + 'class' => 'dc-tag-name', + ), + array( + 'data' => (string)$child, + 'class' => 'dc-content', + ), + ); + } + } + + return theme('table', $headers, $rows, array('class' => 'dc-table')); +} + +/** + * Configuration page for the xslt display mode. + * + * This mode requires two parameters: the datastream to render, and the xslt to + * apply to it. + * + * @return + * The configuration page. + */ +function fedora_repository_object_details_XSLT_config() { + $form = array(); + $form['config'] = array( + '#type' => 'fieldset', + '#title' => t("XSLT display options"), + ); + + $options = module_invoke_all("object_details_get_available_xslts"); + + $form['config']['xslt'] = array( + '#type' => 'select', + '#title' => t("XSL transform to use"), + '#default_value' => variable_get('islandora_object_details_xslt_sheet', 'sites/all/modules/islandora/object_details_xslts/convertQDC.xsl'), + '#options' => $options, + '#key_type' => 'associative', + '#required' => TRUE, + ); + $form['config']['dsid'] = array( + '#type' => 'textfield', + '#title' => t("Datastream to transform"), + '#default_value' => variable_get('islandora_object_details_xslt_datastream', 'DC'), + '#required' => TRUE, + ); + $form['submit'] = array( + '#type' => 'submit', + '#value' => t("Submit"), + '#weight' => 1, + ); + + return $form; +} +/** + * Custom submit handler for the xslt configuration page. + * + * @param $form + * @param &$form_state + * The user supplied values for the form. + */ +function fedora_repository_object_details_XSLT_config_submit($form, &$form_state) { + variable_set('islandora_object_details_xslt_sheet', $form_state['values']['xslt']); + variable_set('islandora_object_details_xslt_datastream', $form_state['values']['dsid']); +} + +/** + * Base function to supply the available xslt files. + * + * Modules implementing this hook need to return an array describing where the + * XSLT is. The array key is the path to the XSLT (paths start with sites/) and + * the value in the array is the display name. In the simplest form you can use + * file_scan_directory like we do here - this puts the filename as the display + * name and will automatically detect new files as they are added. + */ +function fedora_repository_object_details_get_available_xslts() { + $folder = drupal_get_path("module", "fedora_repository") ."/object_details_xslts/"; + // retrieve the filenames from the system + $xslts = file_scan_directory($folder, ".xsl"); + $options = array(); + foreach ($xslts as $xsl) { + $options[$xsl->filename] = $xsl->basename; + } + return $options; +} + +/** + * Configuration page for the table display mode. This mode requires only one + * parameter: the datastream to render. + * + * @return + * The configuration page. + */ +function fedora_repository_object_details_table_config() { + $form = array(); + $form['config'] = array( + '#type' => 'fieldset', + '#title' => t("Table display options"), + ); + + $form['config']['dsid'] = array( + '#type' => 'textfield', + '#title' => t("Datastream to transform"), + '#default_value' => variable_get('islandora_object_details_table_datastream', 'DC'), + '#required' => TRUE, + ); + $form['submit'] = array( + '#type' => 'submit', + '#value' => t("Submit"), + '#weight' => 1, + ); + + return $form; +} + +/** + * Custom submit handler for the table configuration page. + * + * @param $form + * @param &$form_state + * The user supplied values for the form. + */ +function fedora_repository_object_details_table_config_submit($form, &$form_state) { + variable_set('islandora_object_details_table_datastream', $form_state['values']['dsid']); +} diff --git a/ObjectHelper.inc b/ObjectHelper.inc index aeaf09d0..12f8dd9b 100644 --- a/ObjectHelper.inc +++ b/ObjectHelper.inc @@ -2,7 +2,7 @@ /** - * @file + * @file * Object Helper Class */ @@ -32,8 +32,37 @@ class ObjectHelper { drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); module_load_include('inc', 'fedora_repository', 'ConnectionHelper'); $connectionHelper = new ConnectionHelper(); - //$this->fedoraUser = $connectionHelper->getUser(); - //$this->fedoraPass = $connectionHelper->getPassword(); + } + + /** + * Get the size of the indicated datastream. + * + * Note that this only works for Inline XML and Managed datastream, as Fedora + * does not know anything about external or redirect streams, other than a URI. + * If run on an external or redirect stream, Fedora (and therefore this + * function) will return the integer value '0'. + * This function requires the use of the API-M method getDatastream, and defaults + * to returning '0' if it is not accessible. + * + * @param $pid string + * A string containing the PID of a Fedora object. + * @param $dsid string + * A string containing the datastream ID of datastream on the Fedora object + * indicated by the PID. + * @param $quiet boolean + * A boolean indicating whether SOAP errors should be displayed. + * @return integer + * An integer representing the size of the datastream, or zero if it could not be determined. + */ + static function getDatastreamSize($pid, $dsid, $quiet = FALSE) { + module_load_include('inc', 'fedora_repository', 'api/fedora_item'); + $item = new Fedora_Item($pid); + if ($ds_info = $item->get_datastream($dsid, '', $quiet)) { + return $ds_info->size; + } + else { + return 0; + } } /** @@ -72,7 +101,6 @@ class ObjectHelper { return ' '; } - if (variable_get('fedora_object_restrict_datastreams', FALSE) == TRUE) { if (($cm = ContentModel::loadFromObject($pid)) == FALSE) { drupal_set_message(t("You do not have access to objects without an Islandora Content Model."), 'error'); @@ -91,7 +119,6 @@ class ObjectHelper { module_load_include('inc', 'fedora_repository', 'api/fedora_item'); $item = new Fedora_Item($pid); - if (isset($item->datastreams[$dsID])) { $mimeType = $item->datastreams[$dsID]['MIMEType']; if ($label == NULL) { @@ -107,40 +134,41 @@ class ObjectHelper { if ((!isset($user)) || $user->uid == 0) { $fedoraUser = 'anonymous'; $fedoraPass = 'anonymous'; - $contentSize = 0; - } - else { + } else { $fedoraUser = $user->name; $fedoraPass = $user->pass; - $dataStreamInfo = $item->get_datastream_info($dsID); - $contentSize = $dataStreamInfo->datastream->size; } + + $dataStreamInfo = $item->get_datastream_info($dsID); + $contentSize = $dataStreamInfo->datastream->size; if (function_exists("curl_init")) { - if (!isset($mimeType)) { - $pid = variable_get('fedora_default_display_pid', 'demo:10'); - $dsID = variable_get('fedora_default_display_dsid', 'TN'); - $mimeType = 'image/jpeg'; - } $url = variable_get('fedora_base_url', 'http://localhost:8080/fedora') . '/objects/' . $pid . '/datastreams/' . $dsID . '/content'; + $query_options = array(); if ($version) { - $url .= '/' . $version; //drupal_urlencode($version); - } - $ch = curl_init(); - $user_agent = "Mozilla/4.0 pp(compatible; MSIE 5.01; Windows NT 5.0)"; - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); - curl_setopt($ch, CURLOPT_FAILONERROR, 1); // Fail on errors - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // allow redirects - //curl_setopt($ch, CURLOPT_TIMEOUT, 15); // times out after 15s - curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_USERPWD, "$fedoraUser:$fedoraPass"); - // There seems to be a bug in Fedora 3.1's REST authentication, removing this line fixes the authorization denied error. - // curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); // return into a variable - - curl_setopt($ch, CURLOPT_URL, $url); + $query_options['asOfDateTime'] = $version; //drupal_urlencode($version); + } + if ($query_options) { + $url = url($url, array( + 'query' => $query_options, + )); + } + $ch = curl_init($url); + + $user_agent = "Mozilla/4.0 pp(compatible; MSIE 5.01; Windows NT 5.0)"; + $curl_opts = array( + CURLOPT_SSL_VERIFYPEER => FALSE, + CURLOPT_SSL_VERIFYHOST => FALSE, + CURLOPT_FAILONERROR => TRUE, // Fail on errors + CURLOPT_FOLLOWLOCATION => TRUE, // allow redirects + //CURLOPT_TIMEOUT => 15, // times out after 15s + CURLOPT_USERAGENT => $user_agent, + CURLOPT_USERPWD => "$fedoraUser:$fedoraPass", + // There seems to be a bug in Fedora 3.1's REST authentication, removing this line fixes the authorization denied error. + //CURLOPT_HTTPAUTH => CURLAUTH_ANY, + CURLOPT_RETURNTRANSFER => TRUE, // return into a variable; need to at first, so additional headers can be set later. + ); + curl_setopt_array($ch, $curl_opts); if ($filePath !== FALSE) { $fp = fopen($filePath, 'w'); @@ -150,42 +178,47 @@ class ObjectHelper { fclose($fp); } else { - header("Content-type: $mimeType"); - if ($contentSize > 0) { - header("Content-length: $contentSize"); - } - - if ($asAttachment) { - $suggestedFileName = "$label"; - $pos = strpos($suggestedFileName, '.'); - - /* - * Here we used to take an object of, say, type application/pdf with label, say, "My Document" - * and we assemble the output filename extension based on the post-slash portion of the mimetype. - * (If the label has a period anywhere in it, we leave it alone.) - * - * This is great for simple mimetypes like application/pdf, text/html, image/jpeg, etc. - * but it's terrible for, say, application/vnd.oasis.opendocument.text (.odt). - * - * Instead we'll use the get_extension function in MimeClass.inc to discover a valid extension - * for the mimetype in question. - */ - if ($pos === FALSE) { - module_load_include('inc', 'fedora_repository', 'MimeClass'); - $mimeclass = new MimeClass(); - $ext = $mimeclass->get_extension($mimeType); - $suggestedFileName = "$label.$ext"; - } - - header('Content-Disposition: attachment; filename="' . $suggestedFileName . '"'); - } - curl_setopt($ch, CURLOPT_NOBODY, TRUE); - $curl_out = curl_exec($ch); - if ($curl_out !== FALSE) { - $info = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); - //dd($info, 'effective URL'); - if ($url !== $info) { //Handle redirect streams (the final URL is not the same as the Fedora URL) + $curl_stat = curl_exec($ch); + + if ($curl_stat !== FALSE) { + $info = curl_getinfo($ch); + + //Set what headers we can... + if ($mimeType = $info['content_type']) { + header("Content-Type: $mimeType"); + + if ($asAttachment) { + $suggestedFileName = "$label"; + $pos = strpos($suggestedFileName, '.'); + + /* + * Here we used to take an object of, say, type application/pdf with + * label, say, "My Document" and we assemble the output filename + * extension based on the post-slash portion of the mimetype. (If the + * label has a period anywhere in it, we leave it alone.) + * + * This is great for simple mimetypes like application/pdf, text/html, + * image/jpeg, etc., but it's terrible for, say + * application/vnd.oasis.opendocument.text (.odt). + * + * Instead we'll use the get_extension function in MimeClass.inc to + * discover a valid extension for the mimetype in question. + */ + if ($pos === FALSE) { + module_load_include('inc', 'fedora_repository', 'MimeClass'); + $mimeclass = new MimeClass(); + $ext = $mimeclass->get_extension($mimeType); + $suggestedFileName = "$label.$ext"; + } + + header('Content-Disposition: attachment; filename="' . $suggestedFileName . '"'); + } + } + + $effective_url = $info['url']; + //dd($info, 'header/nobody info'); + if ($url !== $effective_url) { //Handle redirect streams (the final URL is not the same as the Fedora URL) //Add the parameters passed to Drupal, leaving out the 'q' $query = array(); @@ -195,22 +228,41 @@ class ObjectHelper { } header('HTTP/1.1 307 Moved Temporarily'); - header('Location: ' . $info . '?' . http_build_query($query)); //Fedora seems to discard the query portion. + header('Location: ' . url($effective_url, array('query' => $query))); } elseif ((isset($user) && $user->uid != 0) || $forceSoap || isset($_SERVER['HTTPS'])) { //If not anonymous, soap is force or we're using HTTPS //Have the webserver mediate the transfer (download and restream) - curl_setopt($ch, CURLOPT_NOBODY, FALSE); - curl_setopt($ch, CURLOPT_HTTPGET, TRUE); //CURLOPT_NOBODY sets it to 'HEAD' - $toReturn = curl_exec($ch); - echo $toReturn; + if (($contentSize = self::getDatastreamSize($pid, $dsID, TRUE)) > 0) { + header("Content-Length: $contentSize"); + } + + $opts = array( + CURLOPT_NOBODY => FALSE, + CURLOPT_HTTPGET => TRUE, //CURLOPT_NOBODY sets it to 'HEAD' + CURLOPT_RETURNTRANSFER => FALSE, //Want to output as efficiently as possible now... + ); + curl_setopt_array($ch, $opts); + $curl_stat = curl_exec($ch); + + if (!$curl_stat) { + watchdog('fedora_repository', 'Error in ObjectHelper->makeObject() for @pid/@dsid. See link for attempted URL.', array( + '@pid' => $pid, + '@dsid' => $dsID, + ), WATCHDOG_WARNING, $url); + } } - else { + else { //Try to redirect directly to Fedora. + header('HTTP/1.1 307 Moved Temporarily'); header('Location: ' . $url); } } else { - //Curl error... + watchdog('fedora_repository', 'Curl error while trying to get datastream %dsid from Fedora object %pid. Curl info: !info', array( + '%pid' => $pid, + '%dsid' => $dsID, + '!info' => print_r(curl_getinfo($ch), TRUE), + ), WATCHDOG_WARNING); } } curl_close($ch); @@ -313,64 +365,77 @@ class ObjectHelper { function create_link_for_ds($pid, $dataStreamValue) { global $base_url; $path = drupal_get_path('module', 'fedora_repository'); + module_load_include('inc', 'fedora_repository', 'api/fedora_item'); - require_once($path . '/api/fedora_item.inc'); $item = new Fedora_Item($pid); + $purge_image = ' '; if (user_access(ObjectHelper :: $PURGE_FEDORA_OBJECTSANDSTREAMS)) { $allow = TRUE; if (module_exists('fedora_fesl')) { $allow = fedora_fesl_check_roles($pid, 'write'); } if ($allow) { - $purgeImage = 'purge datastream'; + $purge_text = t('Purge datastream "@label"', array('@label' => $dataStreamValue->label)); + $purge_path = "fedora/repository/purgeStream/$pid/{$dataStreamValue->ID}/{$dataStreamValue->label}"; + $purge_image = l(theme('image', "$path/images/purge.gif", $purge_text, $purge_text, NULL, FALSE), $purge_path, array( + 'html' => TRUE, + )); } } else { - $purgeImage = ' '; + $purge_image = ' '; } - $fullPath = base_path() . $path; // Add an icon to replace a datastream // @TODO Note: using l(theme_image(..), ...); for these image links (and other links) may remove the need to have clean urls enabled. - $replaceImage = ' '; + $replace_image = ' '; if (user_access(ObjectHelper :: $ADD_FEDORA_STREAMS)) { $allow = TRUE; if (module_exists('fedora_fesl')) { $allow = fedora_fesl_check_roles($pid, 'write'); } if ($allow) { - $replaceImage = 'label . '" href="' . $base_url . '/fedora/repository/replaceStream/' . $pid . '/' . $dataStreamValue->ID . '/' . $dataStreamValue->label . '">replace datastream'; + $replace_text = t('Replace datastream "@label"', array('@label' => $dataStreamValue->label)); + $replace_path = "fedora/repository/replaceStream/$pid/{$dataStreamValue->ID}/{$dataStreamValue->label}"; + $replace_image = l(theme('image', "$path/images/replace.png", $replace_text, $replace_text, NULL, FALSE), $replace_path, array( + 'html' => TRUE, + )); } } $content = ''; $id = $dataStreamValue->ID; $label = $dataStreamValue->label; - $label = str_replace("_", " ", $label); + //$label = str_replace("_", " ", $label); + $label_deslashed = preg_replace('/\//i', '${1}_', $label); // Necessary to handle the case of Datastream labels that contain slashes. Ugh. $mimeType = $dataStreamValue->MIMEType; - $view = '' . t('View') . ''; - $action = "$base_url/fedora/repository/object_download/" . drupal_urlencode($pid) . '/' . $id . '/' . drupal_urlencode(preg_replace('/\//i', '${1}_', $label)); // Necessary to handle the case of Datastream labels that contain slashes. Ugh. - $downloadVersion = '
'; - if (user_access(ObjectHelper :: $EDIT_FEDORA_METADATA)) { - $versions = $item->get_datastream_history($id); - if (is_array($versions)) { - $downloadVersion = '
'; - $downloadVersion .= ''; - $downloadVersion .= '
'; - } - } - - $content .= "$label $view $downloadVersion $mimeType $replaceImage $purgeImage\n"; - return $content; + $view = l(t('View'), "fedora/repository/$pid/$id/$label_deslashed", array( + 'attributes' => array( + 'target' => '_blank', + ), + )); + + $downloadVersion = drupal_get_form('fedora_repository_download_datastream_form', $pid, $id, $label_deslashed); + + return array( + array( + 'data' => $label, + ), + array( + 'data' => $view, + ), + array( + 'data' => $downloadVersion, + ), + array( + 'data' => $mimeType + ), + array( + 'data' => $replace_image . $purge_image, + ), + ); } /** @@ -382,38 +447,76 @@ class ObjectHelper { function getFormattedDC($item) { global $base_url; $path = drupal_get_path('module', 'fedora_repository'); - module_load_include('inc', 'fedora_repository', 'ConnectionHelper'); $dsid = array_key_exists('QDC', $item->get_datastreams_list_as_array()) ? 'QDC' : 'DC'; $xmlstr = $item->get_datastream_dissemination($dsid); - - + if (empty($xmlstr)) { return ''; } - - try { - $proc = new XsltProcessor(); - } catch (Exception $e) { - drupal_set_message($e->getMessage(), 'error'); - return; + + if (($xsl_path = "$path/xsl/convertQDC.xsl") && + (is_readable($xsl_path)) && + ($xsl = DOMDocument::load($xsl_path)) && //Fails loading XSLT -> FALSE + ($ds = DOMDocument::loadXML($xmlstr))) { + $xslt_opts = array( + 'BASEURL' => $base_url, + 'PATH' => url($path, array('absolute' => TRUE)), + 'baseUrl' => $base_url, //XXX: Deprecated; just here for legacy cases. + 'path' => url($path, array('absolute' => TRUE)), //XXX: Deprecated; just here for legacy cases. + ); + $transform = new XSLTProcessor(); + $transform->importStylesheet($xsl); + $transform->setParameter('', $xslt_opts); + $transformed = $transform->transformToDoc($ds); + return $transformed->saveHTML(); } + else { + $simplexml = new SimpleXMLElement($xmlstr); - $proc->setParameter('', 'baseUrl', $base_url); - $proc->setParameter('', 'path', $base_url . '/' . $path); - $input = NULL; - $xsl = new DomDocument(); - try { - $xsl->load($path . '/xsl/convertQDC.xsl'); - $input = new DomDocument(); - $input->loadXML(trim($xmlstr)); - } catch (Exception $e) { - watchdog('fedora_repository', "Problem loading XSL file: @e", array('@e' => $e->getMessage()), NULL, WATCHDOG_ERROR); - } - $xsl = $proc->importStylesheet($xsl); - $newdom = $proc->transformToDoc($input); - $output = $newdom->saveHTML(); - return $output; + $headers = array( + array( + 'data' => t('Metadata'), + 'colspan' => 2, + ), + ); + $rows = array(); + foreach ($simplexml->getNamespaces(TRUE) as $ns) { + foreach ($simplexml->children($ns) as $child) { + $data = array(); + $rendered_data = ''; + if ($grand_children = $child->children()) { + foreach($grand_children as $grand_child) { + $data[] = $grand_child->getName() . ' = ' . (string)$grand_child; + } + } + else { + $rendered_data = (string)$child; + } + + if ($data) { + $rendered_data = theme('item_list', $data); + } + + if ($rendered_data) { + $rows[] = array( + array( + 'data' => $child->getName(), + 'class' => 'dc-tag-name', + ), + array( + 'data' => $rendered_data, + 'class' => 'dc-content', + ), + ); + } + + + } + } + + return theme('table', $headers, $rows, array('class' => 'dc-table')); + } } /** @@ -432,16 +535,17 @@ class ObjectHelper { $dsid = array_key_exists('QDC', $ds_list) ? 'QDC' : 'DC'; $path = drupal_get_path('module', 'fedora_repository'); - //$baseUrl=substr($baseUrl, 0, (strpos($baseUrl, "/")-1)); if (user_access(ObjectHelper :: $EDIT_FEDORA_METADATA)) { $allow = TRUE; if (module_exists('fedora_fesl')) { $allow = fedora_fesl_check_roles($pid, 'write'); } if ($allow) { - - $output .= '
' . t('Edit Meta Data') . ''; + $link_image = theme('image', "$path/images/edit.gif", t('Edit Metadata')); + $link = l($link_image, "fedora/repository/editmetadata/$pid", array( + 'html' => TRUE, + )); + $output .= '
' . $link; } } return $output; @@ -461,7 +565,7 @@ class ObjectHelper { * */ function get_formatted_datastream_list($object_pid, $contentModels, &$fedoraItem) { - global $fedoraUser, $fedoraPass, $base_url, $user; + global $base_url, $user; module_load_include('inc', 'fedora_repository', 'ConnectionHelper'); module_load_include('inc', 'fedora_repository', 'ObjectHelper'); module_load_include('inc', 'fedora_repository', 'api/fedora_item'); @@ -473,58 +577,42 @@ class ObjectHelper { if (user_access(ObjectHelper :: $VIEW_DETAILED_CONTENT_LIST)) { $availableDataStreamsText = 'Detailed List of Content'; - //$metaDataText='Description'; + $mainStreamLabel = NULL; $object = $fedoraItem->get_datastreams_list_as_SimpleXML(); if (!isset($object)) { drupal_set_message(t("No datastreams available")); return ' '; } - $hasOBJStream = NULL; - $hasTNStream = FALSE; - $dataStreamBody = "
\n"; $cmDatastreams = array(); if (variable_get('fedora_object_restrict_datastreams', FALSE) == TRUE && ($cm = ContentModel::loadFromObject($object_pid)) !== FALSE) { $cmDatastreams = $cm->listDatastreams(); } - $dataStreamBody .= $this->get_parent_objects_asHTML($object_pid); - $dataStreamBody .= ''; + $headers = array( + array( + 'data' => $availableDataStreamsText, + 'colspan' => 4, + ), + ); + $DSs = array(); foreach ($object as $datastream) { foreach ($datastream as $datastreamValue) { - if (variable_get('fedora_object_restrict_datastreams', FALSE) == FALSE || ((isset($user) && in_array('administrator', $user->roles)) || in_array($datastreamValue->ID, $cmDatastreams))) { - if ($datastreamValue->ID == 'OBJ') { - $hasOBJStream = '1'; - $mainStreamLabel = $datastreamValue->label; - $mainStreamLabel = str_replace("_", " ", $mainStreamLabel); - } - if ($datastreamValue->ID == 'TN') { - $hasTNStream = TRUE; - } + if (variable_get('fedora_object_restrict_datastreams', FALSE) == FALSE || ((isset($user) && in_array('administrator', $user->roles)) || in_array($datastreamValue->ID, $cmDatastreams))) { //create the links to each datastream - $dataStreamBody .= $this->create_link_for_ds($object_pid, $datastreamValue); //"\n"; + $DSs []= $this->create_link_for_ds($object_pid, $datastreamValue); } } } - $dataStreamBody .= "

' . t("!text", array('!text' => $availableDataStreamsText)) . '

$key :$value
\n"; + + $dataStreamBody = theme('table', $headers, $DSs); //if they have access let them add a datastream - if (user_access(ObjectHelper :: $ADD_FEDORA_STREAMS)) { - $allow = TRUE; - if (module_exists('fedora_fesl')) { - $allow = fedora_fesl_check_roles($object_pid, 'write'); - } - if ($allow) { - $dataStreamBody .= drupal_get_form('add_stream_form', $object_pid); - } + if (user_access(ObjectHelper::$ADD_FEDORA_STREAMS) && //If allowed throw Drupal + ((module_exists('fedora_fesl') && fedora_fesl_check_roles($object_pid, 'write')) || //And allowed throw FESL + !module_exists('fedora_fesl'))) { //Or not using FESL, draw the add datastream form. + $dataStreamBody .= drupal_get_form('add_stream_form', $object_pid); } - $fieldset = array( - '#title' => t("!text", array('!text' => $availableDataStreamsText)), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - '#value' => $dataStreamBody - ); - $dataStreamBody = '
' . theme('fieldset', $fieldset) . '
'; return $dataStreamBody; } @@ -536,30 +624,9 @@ class ObjectHelper { * */ function getStream($pid, $dsid, $showError = FALSE) { - module_load_include('inc', 'fedora_repository', 'ConnectionHelper'); - $soapHelper = new ConnectionHelper(); - try { - $client = $soapHelper->getSoapClient(variable_get('fedora_soap_url', 'http://localhost:8080/fedora/services/access?wsdl')); - $params = array( - 'pid' => "$pid", - 'dsID' => "$dsid", - 'asOfDateTime' => "" - ); - - if (!isset($client)) { - drupal_set_message(t('Error connection to Fedora using soap client.')); - return NULL; - } - $object = $client->__soapCall('getDatastreamDissemination', array('parameters' => $params)); - } catch (Exception $e) { - if ($showError) { - drupal_set_message(t('Error getting Datastream for %pid and %datastream
', array('%pid' => $pid, '%datastream' => $dsid)), 'error'); - } - return NULL; - } - $content = $object->dissemination->stream; - $content = trim($content); - return $content; + module_load_include('inc', 'fedora_repository', 'api/fedora_item'); + $item = new fedora_item($pid); + return $item->get_datastream_dissemination($dsid); } /** @@ -586,7 +653,7 @@ class ObjectHelper { try { $sxml = new SimpleXMLElement($content_models); } catch (exception $e) { - watchdog(t("Fedora_Repository"), "Could not find a parent object for %s", $pid, NULL, WATCHDOG_ERROR); + watchdog(t("fedora_repository"), "Could not find a parent object for %s", $pid, NULL, WATCHDOG_ERROR); return $pids; } @@ -616,55 +683,44 @@ class ObjectHelper { * @param type $pid * @return type */ - function fedora_repository_access($op, $pid) { - global $user; - + function fedora_repository_access($op, $pid = NULL, $as_user = NULL) { $returnValue = FALSE; - $isRestricted = variable_get('fedora_namespace_restriction_enforced', TRUE); - if (!$isRestricted) { - $namespaceAccess = TRUE; - } + if ($pid == NULL) { $pid = variable_get('fedora_repository_pid', 'islandora:root'); } - $nameSpaceAllowed = explode(" ", variable_get('fedora_pids_allowed', 'default: demo: changeme: islandora: ilives: islandora-book: books: newspapers: ')); - $pos = NULL; - foreach ($nameSpaceAllowed as $nameSpace) { - $pos = stripos($pid, $nameSpace); - if ($pos === 0) { - $namespaceAccess = TRUE; - } - } - if ($namespaceAccess) { - $user_access = user_access($op); - if ($user_access == NULL) { - return FALSE; - } - return $user_access; + + $isRestricted = variable_get('fedora_namespace_restriction_enforced', TRUE); + $namespace_access = NULL; + if (!$isRestricted) { + $namespace_access = TRUE; } - else { - return FALSE; + else { + $pid_namespace = substr($pid, 0, strpos($pid, ':') + 1); //Get the namespace (with colon) + $allowed_namespaces = explode(" ", variable_get('fedora_pids_allowed', 'default: demo: changeme: islandora: ilives: islandora-book: books: newspapers: ')); + + $namespace_access = in_array($pid_namespace, $allowed_namespaces); } + + return ($namespace_access && user_access($op, $as_user)); } /** * internal function * uses an xsl to parse the sparql xml returned from the ITQL query - * - * + * @deprecated + * This is only used in the fedora/repository/collection path, + * which should probably be nuked. * @param $content String */ function parseContent($content, $pid, $dsId, $collection, $pageNumber = NULL) { $path = drupal_get_path('module', 'fedora_repository'); global $base_url; $collection_pid = $pid; //we will be changing the pid later maybe - //module_load_include('php', ''Fedora_Repository'', 'ObjectHelper'); $objectHelper = $this; $parsedContent = NULL; - $contentModels = $objectHelper->get_content_models_list($pid); + $contentModels = $this->get_content_models_list($pid); $isCollection = FALSE; - //if this is a collection object store the $pid in the session as it will come in handy - //after a purge or ingest to return to the correct collection. $fedoraItem = NULL; $datastreams = $this->get_formatted_datastream_list($pid, $contentModels, $fedoraItem); @@ -672,6 +728,9 @@ class ObjectHelper { if (!empty($contentModels)) { foreach ($contentModels as $contentModel) { if ($contentModel == variable_get('fedora_collection_model_pid', 'islandora:collectionCModel')) { + //if this is a collection object store the $pid in the session as it will come in handy + //after a purge or ingest to return to the correct collection. + $_SESSION['fedora_collection'] = $pid; $isCollection = TRUE; } @@ -688,9 +747,9 @@ class ObjectHelper { //show the collections datastreams if ($results->length > 0 || $isCollection == TRUE) { // if(strlen($objectList)>22||$contentModel=='Collection'||$contentModel=='Community')//length of empty dom still equals 22 because of etc - module_load_include('inc', 'Fedora_Repository', 'CollectionPolicy'); - $collectionPolicyExists = $objectHelper->getMimeType($pid, CollectionPolicy::getDefaultDSID()); - if (user_access(ObjectHelper :: $INGEST_FEDORA_OBJECTS) && $collectionPolicyExists) { + module_load_include('inc', 'fedora_repository', 'CollectionPolicy'); + $collectionPolicyExists = $this->getMimeType($pid, CollectionPolicy::getDefaultDSID()); + if (user_access(ObjectHelper::$INGEST_FEDORA_OBJECTS) && $collectionPolicyExists) { if (!empty($collectionPolicyExists)) { $allow = TRUE; if (module_exists('fedora_fesl')) { @@ -698,9 +757,11 @@ class ObjectHelper { } if ($allow) { // $ingestObject = ' $collectionName, '!collection_pid' => $collection_pid)) . '" href="' . base_path() . - 'fedora/ingestObject/' . $collection_pid . '/' . $collectionName . '">' . t('Add a New Object') . ' ' . t('Add to this Collection'); + $ingest_text = t('Ingest a new object into @collection_name PID @collection_pid', array('@collection_name' => $collectionName, '@collection_pid' => $collection_pid)); + $ingestObject = l(theme('image', "$path/images/ingest.png", $ingest_text), "fedora/ingestObject/$collection_pid/$collectionName", array('attributes' => array( + 'class' => 'icon', + 'title' => $ingest_text, + ))) . t('Add to this Collection'); } } } @@ -745,19 +806,35 @@ class ObjectHelper { return $output; } + /** + * Get the query to find parent objects. + * + * @param $pid string + * A string containing a Fedora PID to find the parents for. + * @return string + * A string containing an iTQL query, selecting something into $object and $title + */ + static function parentQuery($pid) { + return 'select $object $title from <#ri> + where ($object $title + and $object + and $object ) + order by $title'; + } + /** * Gets the parent objects that this object is related to * - * @param unknown_type $pid - * @return unknown + * @param $pid string + * A string containing a Fedora PID to find the parents for. + * @return string + * A string containing Sparql XML (the results of the self::parentQuery()) */ function get_parent_objects($pid) { - $query_string = 'select $object $title from <#ri> - where ($object $title - and $object - and $object ) - order by $title'; - $objects = $this->getCollectionInfo($pid, $query_string); + $query_string = self::parentQuery(); + module_load_include('inc', 'fedora_repository', 'CollectionClass'); + $collection_class = new CollectionClass($pid); + $objects = CollectionClass::getRelatedItems($pid, $query_string); return $objects; } @@ -768,31 +845,24 @@ class ObjectHelper { * @return string */ function get_parent_objects_asHTML($pid) { - global $base_url; - $parent_collections = $this->get_parent_objects($pid); - try { - $parent_collections = new SimpleXMLElement($parent_collections); - } catch (exception $e) { - drupal_set_message(t('Error getting parent objects @e', array('@e' => check_plain($e->getMessage())))); - return; - } - - $parent_collections_HTML = ''; - foreach ($parent_collections->results->result as $result) { - $collection_label = $result->title; - foreach ($result->object->attributes() as $a => $b) { - if ($a == 'uri') { - $uri = (string) $b; - $uri = $base_url . '/fedora/repository' . substr($uri, strpos($uri, '/')) . '/-/' . $collection_label; - } - } - $parent_collections_HTML .= '' . $collection_label . '
'; + module_load_include('inc', 'fedora_repository', 'CollectionClass'); + $results = self::performItqlQuery(self::parentQuery($pid)); + + $parent_collections = array(); + foreach ($results as $result) { + $collection_title = $result['title']; + $collection_pid = $result['object']; + $path = "fedora/repository/$collection_pid/-/$collection_title"; + $parent = array( + 'data' => l($collection_title, $path), + ); + + $parent_collections[] = $parent; } - if (!empty($parent_collections_HTML)) { - $parent_collections_HTML = '
'; + + if (!empty($parent_collections)) { + return theme('item_list', $parent_collections, t('Belongs to these collections'), 'ul'); } - - return $parent_collections_HTML; } /** @@ -842,6 +912,8 @@ class ObjectHelper { /** * Get a tree of related pids - for the basket functionality * + * FIXME: This doesn't actually get a tree... + * * @param type $pid * @return type */ @@ -852,19 +924,18 @@ class ObjectHelper { module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); // Get title and descriptions for $pid - $query_string = 'select $title $desc from <#ri> + $query_string = 'select $title $description from <#ri> where $o $title and $o $desc and $o '; - - $url = variable_get('fedora_repository_url', 'http://localhost:8080/fedora/risearch'); - $url .= "?type=tuples&flush=TRUE&format=csv&limit=1000&lang=itql&stream=on&query="; - $content = do_curl($url . htmlentities(urlencode($query_string))); - - $rows = explode("\n", $content); - $fields = explode(',', $rows[1]); - - $pids[$pid] = array('title' => $fields[0], 'description' => $fields[1]); + + $results = self::performItqlQuery($query_string); + + $pids = array(); + //There should only be one... Anyway. + foreach($results as $result) { + $pids[$pid] = $result; + } // $pids += $this->get_child_pids(array($pid)); @@ -878,38 +949,24 @@ class ObjectHelper { * @return type */ function get_child_pids($pids) { + //Build the parts which are used to filter to the list of input. + $query_chunks = array(); + foreach ($pids as $pid) { + $query_chunks[] = '$s '; + } // Get pid, title and description for children of object $pid $query_string = 'select $o $title from <#ri> ' . -// $query_string = 'select $o $title $desc from <#ri> '. 'where $s $o ' . 'and $o $title ' . -// 'and $o $desc '. - 'and ( '; - - foreach ($pids as $pid) { - $query_string .= '$s or '; - } - $query_string = substr($query_string, 0, -3) . ' )'; - - $url = variable_get('fedora_repository_url', 'http://localhost:8080/fedora/risearch'); - $url .= "?type=tuples&flush=TRUE&format=csv&limit=1000&lang=itql&stream=on&query="; - $url .= htmlentities(urlencode($query_string)); - $content = $this->doCurl($url); - - $rows = explode("\n", $content); - // Knock of the first heading row - array_shift($rows); + 'and ( ' . implode(' or ', $query_chunks) . ' )'; + + $results = self::performItqlQuery($query_string); $child_pids = array(); - if (count($rows)) { + if ($results) { // iterate through each row - foreach ($rows as $row) { - if ($row == "") { - continue; - } - $fields = explode(',', $row); - $child_pid = substr($fields[0], 12); - $child_pids[$child_pid] = array('title' => $fields[1], 'description' => $fields[2]); + foreach ($results as $result) { + $child_pids[$result['o']] = array('title' => $result['title']); } if (!empty($child_pids)) { $child_pids += $this->get_child_pids(array_keys($child_pids)); @@ -938,58 +995,80 @@ class ObjectHelper { /** * Builds an array of drupal links for use in breadcrumbs. * + * @todo Make fully recursive... + * * @global type $base_url * @param type $pid * @param type $breadcrumbs * @param type $level */ - function getBreadcrumbs($pid, &$breadcrumbs, $level=10) { + function getBreadcrumbs($pid, &$breadcrumbs) { module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); // Before executing the query, we hve a base case of accessing the top-level collection global $base_url; - if ($pid == variable_get('fedora_repository_pid', 'islandora:root')) { - //$breadcrumbs[] = l(t('Digital repository'), 'fedora/repository'); - $breadcrumbs[] = l(variable_get('fedora_repository_title', 'Digital repository'), 'fedora/repository'); - $breadcrumbs[] = l(t('Home'), $base_url); + static $max_level = 10; + static $level = -1; + + if (count($breadcrumbs) === 0) { + $level = $max_level; + } + + $root = variable_get('fedora_repository_pid', 'islandora:root'); + + if ($pid == $root) { + $breadcrumbs[] = l(menu_get_active_title(), 'fedora/repository'); + $breadcrumbs[] = l(t('Home'), ''); } else { - $query_string = 'select $parentObject $title $content from <#ri> - where ( $title - and $parentObject $content - and ( $parentObject - or $parentObject - or $parentObject) - and $parentObject ) - minus $content - order by $title desc'; - $query_string = htmlentities(urlencode($query_string)); - - $url = variable_get('fedora_repository_url', 'http://localhost:8080/fedora/risearch'); - $url .= "?type=tuples&flush=TRUE&format=CSV&limit=1&offset=0&lang=itql&stream=on&query=" . $query_string; + $sparql_query_string = << +PREFIX rels-ext: +SELECT ?parentObject ?title ?content +FROM <#ri> +WHERE { + ?this ?relationship ?parentObject . + ?parentObject fedora-model:label ?title ; + fedora-model:state fedora-model:Active ; + fedora-model:hasModel ?content . + FILTER( + sameTerm(?this, ) && + ( + sameTerm(?relationship, rels-ext:isMemberOfCollection) || + sameTerm(?relationship, rels-ext:isMemberOf) || + sameTerm(?relationship, rels-ext:isPartOf) + ) && + !sameTerm(?content, ) + ) . +} +ORDER BY DESC(?title) +EOQ; + + $results = self::performSparqlQuery($sparql_query_string); + $next_pid = NULL; - $result = preg_split('/[\r\n]+/', do_curl($url)); - array_shift($result); // throw away first line - $matches = str_getcsv(join("\n", $result)); - if (count($matches) >= 2) { - $parent = preg_replace('/^info:fedora\//', '', $matches[0]); - - if (0 == strlen($matches[1])) { - $matches[1] = "Unlabeled Object"; + if (count($results) > 0 && $level > 0) { + $parent_pid = $results[0]['parentObject']; + $parent_title = $results[0]['title']; + + if (empty($this_title)) { + $this_title = t('Unlabeled Object'); } - $breadcrumbs[] = l($matches[1], 'fedora/repository/' . $pid); - if ($parent == variable_get('fedora_repository_pid', 'islandora:root')) { - //$breadcrumbs[] = l(t('Digital repository'), 'fedora/repository'); - $breadcrumbs[] = l(variable_get('fedora_repository_name', 'Digital repository'), 'fedora/repository'); - $breadcrumbs[] = l(t('Home'), $base_url); - } - elseif ($level > 0) { - $this->getBreadcrumbs($parent, $breadcrumbs, $level - 1); + if ($parent_pid != $root) { + $breadcrumbs[] = l($parent_title, "fedora/repository/$parent_pid"); } + + $next_pid = $parent_pid; } - else { - $breadcrumbs[] = l(t("Path Calculation Error"), 'fedora/repository/' . $pid); + watchdog('fedora_repository', 'Error generating breadcrumbs for %pid. Verify there exists relationships back up to %root. (May also be due to a hierarchy deeper than %max_depth).', array('%pid' => $pid, '%root' => $root, '%max_depth' => $max_level), WATCHDOG_WARNING); + $breadcrumbs[] = '...'; //Add an non-link, as we don't know how to get back to the root. + $next_pid = $root; //And cue the last two links to render and break recursion (on the next pass). + } + + if ($next_pid !== NULL) { + $level--; + $this->getBreadcrumbs($next_pid, $breadcrumbs); } } } @@ -1012,5 +1091,150 @@ class ObjectHelper { drupal_set_message(t($configMess . "
" . $messMap[$app] . "
", array('%app' => $app)), 'warning', FALSE); } + /** + * Parse the passed in Sparql XML string into a more easily usable format. + * + * @param $sparql string + * A string containing Sparql result XML. + * @return array + * Indexed (numerical) array, containing a number of associative arrays, + * with keys being the same as the variable names in the query. + * URIs beginning with 'info:fedora/' will have this beginning stripped + * off, to facilitate their use as PIDs. + */ + public static function parseSparqlResults($sparql) { + //Load the results into a SimpleXMLElement + $doc = new SimpleXMLElement($sparql, 0, FALSE, 'http://www.w3.org/2001/sw/DataAccess/rf1/result'); + + $results = array(); //Storage. + + //Build the results. + foreach ($doc->results->children() as $result) { + //Built a single result. + $r = array(); + foreach ($result->children() as $element) { + $val = NULL; + + $attrs = $element->attributes(); + if (!empty($attrs['uri'])) { + $val = self::pidUriToBarePid((string)$attrs['uri']); + } + elseif(!empty($attrs['datatype'])) { + $dt = (string)$attrs['datatype']; + $val = (string)$element; //Default to a string... + if ($dt == 'http://www.w3.org/2001/XMLSchema#int') { + $val = intval($val); + } + else { + watchdog('fedora_repository', 'Datatype @dt_uri handled as string.', array( + '@dt_uri' => $dt, + ), WATCHDOG_DEBUG); + } + } + else { + $val = (string)$element; + } + + //Map the name to the value in the array. + $r[$element->getName()] = $val; + } + + //Add the single result to the set to return. + $results[] = $r; + } + return $results; + } + + /** + * Performs the given Resource Index query and return the results. + * + * @param $query string + * A string containing the RI query to perform. + * @param $type string + * The type of query to perform, as used by the risearch interface. + * @param $limit int + * An integer, used to limit the number of results to return. + * @param $offset int + * An integer, used to offset the results (results should be ordered, to + * maintain consistency. + * + * @return array + * Indexed (numerical) array, containing a number of associative arrays, + * with keys being the same as the variable names in the query. + * URIs beginning with 'info:fedora/' will have this beginning stripped + * off, to facilitate their use as PIDs. + */ + static function performRiQuery($query, $type = 'itql', $limit = -1, $offset = 0) { + //Setup the query options... + $options = array( + 'type' => 'tuples', + 'flush' => TRUE, + 'format' => 'Sparql', //Sparql XML is processed into the array below. + 'lang' => $type, + 'query' => $query + ); + //Add limit if provided. + if ($limit > 0) { + $options['limit'] = $limit; + } + //Add offset if provided. + if ($offset > 0) { + $options['offset'] = $offset; + } + + //Construct the query URL. + $queryUrl = url(variable_get('fedora_repository_url', 'http://localhost:8080/fedora/risearch'), array('query' => $options)); + + //Perform the query. + module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); + $curl_result = do_curl_ext($queryUrl); + + //If the query failed, write message to the logs and return. + if (!$curl_result[0]) { + watchdog('fedora_repository', 'Failed to perform %type resource index query: %query', array('%type' => $type, '%query' => $query), WATCHDOG_ERROR); + return FALSE; + } + + //Pass the query's results off to a decent parser. + return self::parseSparqlResults($curl_result[0]); + } + /** + * Thin wrapper for self::_performRiQuery(). + * + * @see self::performRiQuery() + */ + public static function performItqlQuery($query, $limit = -1, $offset = 0) { + return self::performRiQuery($query, 'itql', $limit, $offset); + } + /** + * Thin wrapper for self::performRiQuery(). + * + * @see self::_performRiQuery() + */ + public static function performSparqlQuery($query, $limit = -1, $offset = 0) { + return self::performRiQuery($query, 'sparql', $limit, $offset); + } + /** + * Utility function used in self::performRiQuery(). + * + * Strips off the 'info:fedora/' prefix from the passed in string. + * + * @param $uri string + * A string containing a URI. + * + * @return string + * The input string less the 'info:fedora/' prefix (if it has it). + * The original string otherwise. + */ + protected static function pidUriToBarePid($uri) { + $chunk = 'info:fedora/'; + $pos = strpos($uri, $chunk); + if ($pos === 0) { //Remove info:fedora/ chunk + return substr($uri, strlen($chunk)); + } + else { //Doesn't start with info:fedora/ chunk... + return $uri; + } + } } diff --git a/SearchClass.inc b/SearchClass.inc index 751dbbfa..473076a1 100644 --- a/SearchClass.inc +++ b/SearchClass.inc @@ -36,7 +36,7 @@ class SearchClass { try { $implementation = new $solrClass(); } catch (Exception $e) { - watchdog(t("Fedora_Repository"), "Error getting solr search results class: !message", array('!message' => $e->getMessage()), NULL, WATCHDOG_ERROR); + watchdog(t("fedora_repository"), "Error getting solr search results class: !message", array('!message' => $e->getMessage()), NULL, WATCHDOG_ERROR); return 'Error getting solr search results class. Check watchdog for more info.'; } return $implementation->$solrFunction($query, $startPage, $fq, $dismax); @@ -253,7 +253,7 @@ class SearchClass { $objectHelper = new ObjectHelper(); $resultData = do_curl($searchString, 1); - $path = drupal_get_path('module', 'Fedora_Repository'); + $path = drupal_get_path('module', 'fedora_repository'); $output .= $this->applySpecifiedXSLT($resultData, $path . '/xsl/browseIndexToResultPage.xslt', $displayName); //$output .= '
'.$alpha_out; @@ -367,7 +367,7 @@ class SearchClass { * @param $query the query that was executed. May want to pass this on. */ function applyLuceneXSLT($resultData, $startPage = 1, $xslt_file = '/xsl/results.xsl', $query=NULL) { - $path = drupal_get_path('module', 'Fedora_Repository'); + $path = drupal_get_path('module', 'fedora_repository'); $test = $xslt_file; $isRestricted = variable_get('fedora_namespace_restriction_enforced', TRUE); if (!isRestricted && $xslt_file == NULL) { @@ -425,7 +425,7 @@ class SearchClass { * @return type */ function applyXSLT($resultData, $orderBy = 0) { - $path = drupal_get_path('module', 'Fedora_Repository'); + $path = drupal_get_path('module', 'fedora_repository'); $proc = NULL; if (!$resultData) { //drupal_set_message(t('No Results!')); @@ -590,7 +590,7 @@ class SearchClass { */ function get_search_terms_array($path = NULL, $file = NULL) { if (!isset($path)) { - $path = drupal_get_path('module', 'Fedora_Repository'); + $path = drupal_get_path('module', 'fedora_repository'); } $xmlDoc = new DomDocument(); if (!isset($file)) { diff --git a/SecurityClass.inc b/SecurityClass.inc index 970b108b..e2bf71ba 100644 --- a/SecurityClass.inc +++ b/SecurityClass.inc @@ -71,7 +71,7 @@ class SecurityClass { try { $xml = new SimpleXMLElement($policyStream); } catch (Exception $e) { - watchdog(t("Fedora_Repository"), "No roles found in security policy, could not parse policy stream.", NULL, WATCHDOG_ERROR); + watchdog(t("fedora_repository"), "No roles found in security policy, could not parse policy stream.", NULL, WATCHDOG_ERROR); //we may not want to send this to the screen. drupal_set_message(t('No roles found in security policy, could not parse policy stream: !message', array('!message' => check_plain($e->getMessage()))), 'error'); return NULL; @@ -108,9 +108,9 @@ class SecurityClass { function createPersonalPolicy($user) { $doc = new DOMDocument(); try { - $doc->load(drupal_get_path('module', 'Fedora_Repository') . '/policies/noObjectEditPolicy.xml'); + $doc->load(drupal_get_path('module', 'fedora_repository') . '/policies/noObjectEditPolicy.xml'); } catch (exception $e) { - watchdog(t("Fedora_Repository"), "Problem loading policy file.", NULL, WATCHDOG_ERROR); + watchdog(t("fedora_repository"), "Problem loading policy file.", NULL, WATCHDOG_ERROR); } $conditions = $doc->getElementsByTagName('Condition'); foreach ($conditions as $condition) { diff --git a/XMLDatastream.inc b/XMLDatastream.inc index ab8044f4..460affc8 100644 --- a/XMLDatastream.inc +++ b/XMLDatastream.inc @@ -227,7 +227,7 @@ abstract class XMLDatastream { * @return boolean $success */ public function saveToFedora() { - module_load_include('inc', 'Fedora_Repository', 'api/fedora_item'); + module_load_include('inc', 'fedora_repository', 'api/fedora_item'); if ($this->validate()) { $item = new Fedora_Item($this->pid); $item->modify_datastream_by_value($this->dumpXml(), $this->dsid, $this->name, 'application/xml'); diff --git a/api/fedora_export.inc b/api/fedora_export.inc index f3c82160..32d7b49d 100644 --- a/api/fedora_export.inc +++ b/api/fedora_export.inc @@ -57,7 +57,6 @@ function export_objects_for_pid($pid, $dir, &$log) { $file = $dir . '/' . $ds->label . '.' . get_file_extension($ds->MIMEType); $paths[$ds->ID] = $file; - //$content = $ob_helper->getDatastreamDissemination($pid, $ds->ID); if ($content = $ob_helper->getStream($pid, $ds->ID, FALSE)) { if (!$fp = @fopen($file, 'w')) { $log[] = log_line(t("Failed to open file %file to write datastream %dsid for pid %pid", array('%file' => $file, '%dsid' => $ds->ID, '%pid' => $pid)), 'error'); diff --git a/api/fedora_item.inc b/api/fedora_item.inc index 279a3e51..93e2b65e 100644 --- a/api/fedora_item.inc +++ b/api/fedora_item.inc @@ -7,6 +7,14 @@ define('RELS_EXT_URI', 'info:fedora/fedora-system:def/relations-external#'); define("FEDORA_MODEL_URI", 'info:fedora/fedora-system:def/model#'); define("ISLANDORA_PAGE_URI", 'info:islandora/islandora-system:def/pageinfo#'); +define("ISLANDORA_RELS_EXT_URI", 'http://islandora.ca/ontology/relsext#'); +define("ISLANDORA_RELS_INT_URI", "http://islandora.ca/ontology/relsint#"); + +define("RELS_TYPE_URI", 0); +define("RELS_TYPE_PLAIN_LITERAL", 1); +define("RELS_TYPE_STRING", 2); +define("RELS_TYPE_INT", 3); +define("RELS_TYPE_DATETIME", 4); /** * Fedora Item Class @@ -122,6 +130,7 @@ class Fedora_Item { $datastream_url = drupal_urlencode($datastream_file); $url = file_create_url($datastream_url); + // add_datastream_from_url forces a re-sync of the datastream list $return_value = $this->add_datastream_from_url($url, $datastream_id, $datastream_label, $datastream_mimetype, $controlGroup, $logMessage); if ($original_path != $datastream_file) { @@ -157,7 +166,7 @@ class Fedora_Item { 'pid' => $this->pid, 'dsID' => $datastream_id, 'altIDs' => NULL, - 'dsLabel' => $datastream_label, + 'dsLabel' => truncate_utf8($datastream_label, 255, TRUE, TRUE), 'versionable' => TRUE, 'MIMEType' => $datastream_mimetype, 'formatURI' => NULL, @@ -169,8 +178,10 @@ class Fedora_Item { 'logMessage' => ($logMessage != NULL) ? $logMessage : 'Ingested object ' . $datastream_id ); - - return $this->soap_call('addDataStream', $params); + $soap_result = $this->soap_call('addDataStream', $params); + // make sure to refresh the datastream list after adding so this item stays in sync with the repository + $this->datastreams = $this->get_datastreams_list_as_array(); + return $soap_result; } /** @@ -189,6 +200,7 @@ class Fedora_Item { $tmpfile = fopen($tmpfilename, 'w'); fwrite($tmpfile, $str, strlen($str)); fclose($tmpfile); + // add_datastream_from_file forces a re-sync of the datastream list $returnvalue = $this->add_datastream_from_file($tmpfilename, $datastream_id, $datastream_label, $datastream_mimetype, $controlGroup, $logMessage); unlink($tmpfilename); return $returnvalue; @@ -228,11 +240,22 @@ class Fedora_Item { * The object to be related to. * @param string $namespaceURI * The predicate namespace. - * @param boolean $literal_value - * Whether or not the object should be added as a URI (FALSE) or a literal (TRUE). + * @param int $literal_value + * Used to type the value. + * - 0: URI + * - 1: plain literal + * - 2: string (explicitly typed) + * - 3: integer + * - 4: dateTime + * @return ??? + * Value returned from SOAP call for modify_datastream. */ - function add_relationship($relationship, $object, $namespaceURI = RELS_EXT_URI, $literal_value = FALSE) { - //dd($this, 'The Fedora_Item'); + function add_relationship($relationship, $object, $namespaceURI = RELS_EXT_URI, $literal_value = RELS_TYPE_URI) { + static $relsextxml = NULL; + if ($relsextxml === NULL) { + $relsextxml = new DOMDocument(); //Avoid new instantiations in long-running processes + } + $ds_list = $this->get_datastreams_list_as_array(); $f_prefix = 'info:fedora/'; if (!array_key_exists('RELS-EXT', $ds_list)) { @@ -247,12 +270,10 @@ RDF; $relsext = $this->get_datastream_dissemination('RELS-EXT'); - if (!$literal_value && strpos($object, $f_prefix) !== 0) { + if ($literal_value == REL_TYPE_URI && strpos($object, $f_prefix) !== 0) { $object = $f_prefix . $object; } - $relsextxml = new DOMDocument(); - $relsextxml->loadXML($relsext); $description = $relsextxml->getElementsByTagNameNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'Description'); if ($description->length == 0) { @@ -267,8 +288,20 @@ RDF; // Create the new relationship node. $newrel = $relsextxml->createElementNS($namespaceURI, $relationship); - if ($literal_value) { + if ($literal_value > 0) { $newrel->appendChild($relsextxml->createTextNode($object)); + if ($literal_value == RELS_TYPE_STRING) { + $newrel->setAttribute('rdf:datatype', 'http://www.w3.org/2001/XMLSchema#string'); + } + elseif ($literal_value == RELS_TYPE_INT) { + $newrel->setAttribute('rdf:datatype', 'http://www.w3.org/2001/XMLSchema#int'); + } + elseif ($literal_value == RELS_TYPE_DATETIME) { + $newrel->setAttribute('rdf:datatype', 'http://www.w3.org/2001/XMLSchema#dateTime'); + } + else { + //plain literal. + } } else { $newrel->setAttribute('rdf:resource', $object); @@ -276,7 +309,7 @@ RDF; $description->appendChild($newrel); - $this->modify_datastream($relsextxml->saveXML(), 'RELS-EXT', "Fedora Object-to-Object Relationship Metadata", 'application/rdf+xml'); + return $this->modify_datastream($relsextxml->saveXML(), 'RELS-EXT', "Fedora Object-to-Object Relationship Metadata", 'application/rdf+xml'); //print ($description->dump_node()); /* $params = array( 'pid' => $this->pid, @@ -301,8 +334,8 @@ RDF; * The object to be related to. (NULL/value for which empty() evaluates to true will remove all relations of the given type, ignoring $literal_value) * @param string $namespaceURI * The predicate namespace. - * @param boolean $literal_value - * Whether or not the object should be looked for as a URI (FALSE) or a literal (TRUE). + * @param int $literal_value + * Same as add_relationship. NOTE: dateTime implemented. * @return boolean * Whether or not this operation has produced any changes in the RELS-EXT */ @@ -317,8 +350,10 @@ RDF; foreach ($rels as $rel) { if ( //If either no object is specified, or the object matches (in either the literal or URI case), remove this node from it's parent, and mark as changed. empty($object) || - (!$literal_value && $rel->getAttributeNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'resource') == $object) || - ($literal_value && $rel->textContent == $object)) { + (($literal_value == RELS_TYPE_URI) && $rel->getAttributeNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'resource') == $object) || + (($literal_value == RELS_TYPE_PLAIN_LITERAL) && $rel->textContent == $object) || + (($literal_value == RELS_TYPE_STRING) && $rel->getAttribute('rdf:datatype') == 'http://www.w3.org/2001/XMLSchema#string' && $rel->textContent == $object) || + (($literal_value == RELS_TYPE_INT) && $rel->getAttribute('rdf:datatype') == 'http://www.w3.org/2001/XMLSchema#int' && intval($rel->textContent) == $object)) { $rel->parentNode->removeChild($rel); $modified = TRUE; } @@ -482,6 +517,12 @@ RDF; * @return null */ function get_datastream_dissemination($dsid, $as_of_date_time = "", $quiet=TRUE) { + if (!array_key_exists($dsid, $this->datastreams)) { + watchdog('fedora_repository', 'Requested invalid datastream dissemination @dsid on object @pid', + array('@dsid' => $dsid, '@pid' => $pid)); + return NULL; + } + $params = array( 'pid' => $this->pid, 'dsID' => $dsid, @@ -506,13 +547,18 @@ RDF; * @param type $as_of_date_time * @return type */ - function get_datastream($dsid, $as_of_date_time = '') { + function get_datastream($dsid, $as_of_date_time = '', $quiet = TRUE) { + if (!array_key_exists($dsid, $this->datastreams)) { + watchdog('fedora_repository', 'Requested invalid datastream dissemination @dsid on object @pid', + array('@dsid' => $dsid, '@pid' => $pid)); + return NULL; + } $params = array( 'pid' => $this->pid, 'dsID' => $dsid, 'asOfDateTime' => $as_of_date_time, ); - $object = self::soap_call('getDatastream', $params); + $object = self::soap_call('getDatastream', $params, $quiet); return $object->datastream; } @@ -635,18 +681,15 @@ RDF; // datastream, instead of returning it as an array, only // the single item will be returned directly. We have to // check for this. - if (count($this->datastreams_list->datastreamDef) > 1) { - foreach ($this->datastreams_list->datastreamDef as $ds) { - if (!is_object($ds)) { - print_r($ds); - } - $ds_list[$ds->ID]['label'] = $ds->label; - $ds_list[$ds->ID]['MIMEType'] = $ds->MIMEType; - $ds_list[$ds->ID]['URL'] = $this->url() . '/' . $ds->ID . '/' . drupal_urlencode($ds->label); - } + $xml_list = $this->datastreams_list->datastreamDef; + if (!is_array($this->datastreams_list->datastreamDef)) { + $xml_list = array($xml_list); } - else { - $ds = $this->datastreams_list->datastreamDef; + + foreach ($xml_list as $ds) { + if (!is_object($ds)) { + print_r($ds); + } $ds_list[$ds->ID]['label'] = $ds->label; $ds_list[$ds->ID]['MIMEType'] = $ds->MIMEType; $ds_list[$ds->ID]['URL'] = $this->url() . '/' . $ds->ID . '/' . drupal_urlencode($ds->label); @@ -772,9 +815,9 @@ RDF; /** * Set the object to a deleted state */ - function move_to_trash($log_message = 'Flagged deleted using Islandora API.') { + function move_to_trash($log_message = 'Flagged deleted using Islandora API.', $quiet = TRUE) { // Loop through the datastreams and mark them deleted - foreach ($this->get_datastreams_list_as_array() as $dsid) { + foreach ($this->get_datastreams_list_as_array() as $dsid => $info) { $this->set_datastream_state($dsid, 'D'); } @@ -782,7 +825,7 @@ RDF; $params = array( 'pid' => $this->pid, 'state' => 'D', - 'logMessage' => $logMessage, + 'logMessage' => $log_message, 'label' => $this->objectProfile->objLabel, 'ownerId' => null, ); @@ -831,7 +874,10 @@ RDF; 'logMessage' => $log_message, 'force' => $force, ); - return $this->soap_call('purgeDatastream', $params); + $soap_result = $this->soap_call('purgeDatastream', $params); + // make sure to refresh the datastream list after adding so this item stays in sync with the repository + $this->datastreams = $this->get_datastreams_list_as_array(); + return $soap_result; } /** @@ -847,11 +893,10 @@ RDF; /** * Get Next PID in Namespace - * @param type $pid_namespace - * @return type + * @param $pid_namespace string + * @return string */ - static function get_next_PID_in_namespace($pid_namespace = '') { - + static function get_next_PID_in_namespace($pid_namespace = '', $number_of_pids = 1) { if (empty($pid_namespace)) { // Just get the first one in the config settings. $allowed_namespaces = explode(" ", variable_get('fedora_pids_allowed', 'default: demo: changeme: islandora: ilives: islandora-book: books: newspapers: ')); @@ -865,11 +910,12 @@ RDF; } $params = array( - 'numPIDs' => '', + 'numPIDs' => $number_of_pids, 'pidNamespace' => $pid_namespace, ); $result = self::soap_call('getNextPID', $params); + return $result->pid; } @@ -885,7 +931,6 @@ RDF; 'logMessage' => 'Fedora Object Ingested' ); $object = self::soap_call('ingest', $params); - //dd($object, 'Soap return'); return new Fedora_Item($object->objectPID); } @@ -925,11 +970,11 @@ RDF; /** * Modify Object - * @param type $label - * @param type $state - * @param type $ownerId - * @param type $logMessage - * @param type $quiet + * @param $label string + * @param $state string + * @param $ownerId string + * @param $logMessage string + * @param $quiet boolean * @return type */ function modify_object($label = '', $state = NULL, $ownerId = NULL, $logMessage = 'Modified by Islandora API', $quiet=TRUE) { @@ -969,6 +1014,8 @@ RDF; * Error suppression? Refer to soap_call for usage (just passed along here). */ function modify_datastream($filename_or_content, $dsid, $label, $mime_type, $force = FALSE, $logMessage='Modified by Islandora API', $quiet=FALSE) { + $toReturn = NULL; + //Determine if it's inline xml; if it is, modify by value if ($this->get_datastream($dsid)->controlGroup === 'X') { $content = ''; @@ -979,7 +1026,7 @@ RDF; $content = $filename_or_content; } - $this->modify_datastream_by_value($content, $dsid, $label, $mime_type, $force, $logMessage); + $toReturn = $this->modify_datastream_by_value($content, $dsid, $label, $mime_type, $force, $logMessage); } //Otherwise, write to web-accessible temp file and modify by reference. else { @@ -1000,12 +1047,14 @@ RDF; $file_url = file_create_url($file); - $this->modify_datastream_by_reference($file_url, $dsid, $label, $mime_type, $force, $logMessage); + $toReturn = $this->modify_datastream_by_reference($file_url, $dsid, $label, $mime_type, $force, $logMessage); if ($created_temp && is_file($file) && is_writable($file)) { file_delete($file); } } + + return $toReturn; } /** @@ -1142,6 +1191,7 @@ RDF; $pid = self::get_next_PID_in_namespace(); } if (empty($owner)) { + global $user; if (!empty($user->uid)) { // Default to current Drupal user. $owner = $user->uid; } @@ -1164,7 +1214,7 @@ RDF; $label_property = $foxml->createElementNS("info:fedora/fedora-system:def/foxml#", "foxml:property"); $label_property->setAttribute("NAME", "info:fedora/fedora-system:def/model#label"); - $label_property->setAttribute("VALUE", $label); + $label_property->setAttribute("VALUE", truncate_utf8($label, 255, TRUE, TRUE)); $owner_property = $foxml->createElementNS("info:fedora/fedora-system:def/foxml#", "foxml:property"); $owner_property->setAttribute("NAME", "info:fedora/fedora-system:def/model#ownerId"); diff --git a/api/fedora_utils.inc b/api/fedora_utils.inc index eb56bdcc..a730d7a4 100644 --- a/api/fedora_utils.inc +++ b/api/fedora_utils.inc @@ -85,7 +85,7 @@ function do_curl($url, $return_to_variable = 1, $number_of_post_vars = 0, $post * an array that consists of three value or NULL if curl is not suported: * - element 0: * The value returned from the curl_exec function call. - * This is either a TRUE or FALSE value or the actual data returned from + * This is either a boolean value or the actual data returned from * accessing the URL. * - element 1: * The error code reslting from attempting to access the URL with curl_exec @@ -93,7 +93,7 @@ function do_curl($url, $return_to_variable = 1, $number_of_post_vars = 0, $post * A string representing a textual representation of the error code that * resulted from attempting to access the URL with curl_exec */ -function do_curl_ext($url, $return_to_variable = 1, $number_of_post_vars = 0, $post = NULL) { +function do_curl_ext($url, $return_to_variable = TRUE, $number_of_post_vars = 0, $post = NULL) { global $user; // Check if we are inside Drupal and there is a valid user. @@ -113,7 +113,7 @@ function do_curl_ext($url, $return_to_variable = 1, $number_of_post_vars = 0, $p curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_FAILONERROR, TRUE); // Fail on errors - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // allow redirects + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); // allow redirects curl_setopt($ch, CURLOPT_TIMEOUT, 90); // times out after 90s curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); curl_setopt($ch, CURLOPT_RETURNTRANSFER, $return_to_variable); // return into a variable @@ -239,13 +239,24 @@ function get_collections_as_option_array() { $allowed_string = variable_get('fedora_pids_allowed', 'default: demo: changeme: islandora:'); $namespaces = explode(':', $allowed_string); $query = 'select $object $title from <#ri> - where ($object $title - and $object - and $object ) - order by $title'; + where ($object $title + and $object + and $object ) + order by $title'; $url = variable_get('fedora_repository_url', 'http://localhost:8080/fedora/risearch'); - $url .= "?type=tuples&flush=TRUE&format=csv&limit=1000&lang=itql&stream=on&query="; - $content = do_curl($url . htmlentities(urlencode($query))); + + $options = array( + 'type' => 'tuples', + 'flush' => 'TRUE', + 'format' => 'csv', + 'limit' => '1000', + 'lang' => 'itql', + 'stream' => 'on', + 'query' => $query, + ); + //The url function will take care of URL encoding... + $content = do_curl(url($url, array('query' => $options))); + $list = explode("\n", $content); array_shift($list); $list = preg_replace('/info:fedora\//', '', $list); diff --git a/fedora_repository.install b/fedora_repository.install index 164ce02e..0840e2e4 100644 --- a/fedora_repository.install +++ b/fedora_repository.install @@ -34,71 +34,70 @@ function fedora_collections_enable() { * @see _update_cron_notify() */ function fedora_repository_requirements($phase) { - global $base_url; - $requirements = array(); + $t = get_t(); //May not have access to the regular t() function; and so Drupal provides... if ($phase == 'install') { // Test for SOAP - $requirements['fedora-soap']['title'] = t("PHP SOAP extension library"); + $requirements['fedora-soap']['title'] = $t("PHP SOAP extension library"); if (!class_exists('SoapClient')) { - $requirements['fedora-soap']['value'] = t("Not installed"); + $requirements['fedora-soap']['value'] = $t("Not installed"); $requirements['fedora-soap']['severity'] = REQUIREMENT_ERROR; - $requirements['fedora-soap']['description'] = t('Ensure that the PHP SOAP extension is installed.'); + $requirements['fedora-soap']['description'] = $t('Ensure that the PHP SOAP extension is installed.'); } else { - $requirements['fedora-soap']['value'] = t("Installed"); + $requirements['fedora-soap']['value'] = $t("Installed"); $requirements['fedora-soap']['severity'] = REQUIREMENT_OK; } // Test for Curl - $requirements['curl']['title'] = "PHP Curl extension library"; + $requirements['curl']['title'] = $t('PHP Curl extension library'); if (!function_exists('curl_init')) { - $requirements['curl']['value'] = t("Not installed"); + $requirements['curl']['value'] = $t("Not installed"); $requirements['curl']['severity'] = REQUIREMENT_ERROR; - $requirements['curl']['description'] = t("Ensure that the PHP Curl extension is installed."); + $requirements['curl']['description'] = $t("Ensure that the PHP Curl extension is installed."); } else { - $requirements['curl']['value'] = t("Installed"); + $requirements['curl']['value'] = $t("Installed"); $requirements['curl']['severity'] = REQUIREMENT_OK; } - // Test for DOM - $requirements['dom']['title'] = "PHP DOM XML extension library"; + // Test for DOM + $requirements['dom']['title'] = $t("PHP DOM XML extension library"); if (!method_exists('DOMDocument', 'loadHTML')) { - $requirements['dom']['value'] = t("Not installed"); + $requirements['dom']['value'] = $t("Not installed"); $requirements['dom']['severity'] = REQUIREMENT_ERROR; - $requirements['dom']['description'] = t("Ensure that the PHP DOM XML extension is installed."); + $requirements['dom']['description'] = $t("Ensure that the PHP DOM XML extension is installed."); } else { - $requirements['dom']['value'] = t("Installed"); + $requirements['dom']['value'] = $t("Installed"); $requirements['dom']['severity'] = REQUIREMENT_OK; } // Test for XSLT - $requirements['xsl']['title'] = "PHP XSL extension library"; + $requirements['xsl']['title'] = $t("PHP XSL extension library"); if (!class_exists('XSLTProcessor')) { - $requirements['xslt']['value'] = t("Not installed"); + $requirements['xslt']['value'] = $t("Not installed"); $requirements['xslt']['severity'] = REQUIREMENT_ERROR; - $requirements['xslt']['description'] = t("Ensure that the PHP XSL extension is installed."); + $requirements['xslt']['description'] = $t("Ensure that the PHP XSL extension is installed."); } else { - $requirements['xslt']['value'] = t("Installed"); + $requirements['xslt']['value'] = $t("Installed"); $requirements['xslt']['severity'] = REQUIREMENT_OK; } } elseif ($phase == 'runtime') { module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); - $requirements['fedora-repository']['title'] = t("Fedora server"); + $requirements['fedora-repository']['title'] = $t("Fedora server"); if (!fedora_available()) { - $requirements['fedora-repository']['value'] = t("Not available"); + $requirements['fedora-repository']['value'] = $t("Not available"); $requirements['fedora-repository']['severity'] = REQUIREMENT_ERROR; - $requirements['fedora-repository']['description'] = t('Ensure that Fedora is running and that the collection settings are correct.', array('@collection-settings' => $base_url . '/admin/settings/fedora_repository')); + $requirements['fedora-repository']['description'] = $t('Ensure that Fedora is running and that the collection settings are correct.', array('@collection-settings' => url('admin/settings/fedora_repository'))); } else { - $requirements['fedora-repository']['value'] = t("Available"); + $requirements['fedora-repository']['value'] = $t("Available"); $requirements['fedora-repository']['severity'] = REQUIREMENT_OK; } } diff --git a/fedora_repository.module b/fedora_repository.module index abec4b9e..2dc986f8 100644 --- a/fedora_repository.module +++ b/fedora_repository.module @@ -2,8 +2,7 @@ /** * Drupal hook for admin form - * fedora_repository_name is the name of the top level collection this module will query - * fedora_repository_pid is the name of the top level pid. + * * Stores this info in the drupal variables table. * the name and pid can also be passed as url parameters */ @@ -378,41 +377,30 @@ function add_stream_form_submit($form, &$form_state) { $form_state['rebuild'] = TRUE; return; } - module_load_include('inc', 'fedora_repository', 'MimeClass'); + module_load_include('inc', 'fedora_repository', 'ObjectHelper'); module_load_include('inc', 'fedora_repository', 'api/fedora_item'); $pathToModule = drupal_get_path('module', 'fedora_repository'); - $file = $form_state['values']['add-stream-file-location']; - $pid = $form_state['values']['pid']; $dsid = $form_state['values']['stream_id']; - $dsLabel = $form_state['values']['stream_label'] . substr($file, strrpos($file, '.')); // Add the file extention to the end of the label.; - $file_basename = basename($file); - $file_directory = dirname($file); - $streamUrl = $base_url . '/' . $file_directory . '/' . drupal_urlencode($file_basename); + $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.; - /* ----------------------------------------------------------------- - * need a better way to get mimetypes - */ - $mimetype = new MimeClass(); - $dformat = $mimetype->getType($file); - $controlGroup = "M"; - if ($dformat == 'text/xml') { - $controlGroup = 'X'; - } try { $item = new Fedora_Item($pid); - $item->add_datastream_from_url($streamUrl, $dsid, $dsLabel, $dformat, $controlGroup); + $item->add_datastream_from_url($form_state['storage']['stream_url'], $dsid, $dsLabel, $form_state['storage']['ds_mimetype'], $form_state['storage']['control_group']); - $object_helper = new ObjectHelper(); - $object_helper->get_and_do_datastream_rules($pid, $dsid, $file); + if ($file = $form_state['values']['add-stream-file-location']) { + $object_helper = new ObjectHelper(); + $object_helper->get_and_do_datastream_rules($pid, $dsid, $file); - file_delete($file); + file_delete($file); + } } catch (exception $e) { drupal_set_message(t('@message', array('@message' => check_plain($e->getMessage()))), 'error'); return; } + unset($form_state['storage']); //Using storage; need to unset it for forms to work properly... $form_state['rebuild'] = TRUE; } @@ -435,6 +423,7 @@ function add_stream_form(&$form_state, $pid) { * @return type */ function add_stream_form_validate($form, &$form_state) { + module_load_include('inc', 'fedora_repository', 'MimeClass'); if ($form_state['clicked_button']['#value'] == 'OK') { $form_state['rebuild'] = TRUE; return; @@ -445,15 +434,15 @@ function add_stream_form_validate($form, &$form_state) { form_set_error('', t('Data stream ID cannot be more than 64 characters.')); return FALSE; } - if (!(preg_match("/^[a-zA-Z]/", $dsid))) { - form_set_error('', t("Data stream ID (@dsid) has to start with a letter.", array('@dsid' => check_plain($dsid)))); + elseif (!(preg_match("/^[a-zA-Z]/", $dsid))) { + form_set_error('', t("Data stream ID (@dsid) has to start with a letter.", array('@dsid' => $dsid))); return FALSE; } - if (strlen($dsLabel) > 64) { + elseif (strlen($dsLabel) > 64) { form_set_error('', t('Data stream Label cannot be more than 64 characters.')); return FALSE; } - if (strpos($dsLabel, '/')) { + elseif (strpos($dsLabel, '/') !== FALSE) { form_set_error('', t('Data stream Label cannot contain a "/".')); return FALSE; } @@ -462,13 +451,36 @@ function add_stream_form_validate($form, &$form_state) { // 'file_validate_image_resolution' => array('85x85'), // 'file_validate_size' => array(30 * 1024), ); - - $fileObject = file_save_upload('add-stream-file-location', $validators); - -// Move the uploaded file to Drupal's files directory. - file_move($fileObject->filepath, 0, 'FILE_EXISTS_RENAME'); - $form_state['values']['add-stream-file-location'] = $fileObject->filepath; -// TODO: Add error checking here. + + $controlGroup = $form_state['storage']['control_group'] = $form_state['values']['control_group']; + if ((($controlGroup && in_array($controlGroup, array('X', 'M'))) || !$controlGroup) && (($fileObject = file_save_upload('add-stream-file-location', $validators)))) { + // 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; } @@ -605,7 +617,44 @@ function fedora_repository_purge_stream_form_submit($form, &$form_state) { } catch (exception $e) { drupal_set_message(t('@message', array('@message' => check_plain($e->getMessage()))), 'error'); } - $form_state['redirect'] = $base_url . "/fedora/repository/$pid"; + $form_state['redirect'] = "fedora/repository/$pid"; +} + +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; } /** @@ -635,7 +684,7 @@ function fedora_repository_replace_stream($pid, $dsId, $dsLabel = '', $collectio * @return type */ function fedora_repository_replace_stream_form(&$form_state, $pid, $dsId, $dsLabel) { - module_load_include('inc', 'Fedora_Repository', 'formClass'); + module_load_include('inc', 'fedora_repository', 'formClass'); $replaceDataStreamForm = new formClass(); return $replaceDataStreamForm->createReplaceDataStreamForm($pid, $dsId, $dsLabel, $form_state); } @@ -647,29 +696,37 @@ function fedora_repository_replace_stream_form(&$form_state, $pid, $dsId, $dsLab * @return type */ function fedora_repository_replace_stream_form_validate($form, &$form_state) { -// If a file was uploaded, process it. + // If a file was uploaded, process it. if (isset($_FILES['files']) && is_uploaded_file($_FILES['files']['tmp_name']['file'])) { -// attempt to save the uploaded file + // attempt to save the uploaded file $file = file_save_upload('file', array(), file_directory_path()); -// set error is file was not uploaded + // set error is file was not uploaded if (!$file) { form_set_error('file', 'Error uploading file.'); return; } - + + /* ----------------------------------------------------------------- + * TODO: need a better way to get mimetypes + */ $doc = new DOMDocument(); - module_load_include('inc', 'Fedora_Repository', 'MimeClass'); + module_load_include('inc', 'fedora_repository', 'MimeClass'); $mime = new MimeClass(); - if ($mime->getType($file->filepath) == 'text/xml' && !$doc->load($file->filepath)) { - form_set_error('file', 'Invalid XML format.'); + $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 + // 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!'); + } } /** @@ -679,46 +736,30 @@ function fedora_repository_replace_stream_form_validate($form, &$form_state) { * @param array $form_state */ function fedora_repository_replace_stream_form_submit($form, &$form_state) { - global $base_url; $file = $form_state['values']['file']; + $pid = $form_state['values']['pid']; $dsid = $form_state['values']['dsId']; $dsLabel = $form_state['values']['dsLabel']; -// Remove the original file extension from the label and add the new one - $indexOfDot = strrpos($dsLabel, '.'); //use strrpos to get the last dot - if ($indexOfDot !== FALSE) { - $dsLabel = substr($dsLabel, 0, $indexOfDot); - $dsLabel .= substr($file->filename, strrpos($file->filename, '.')); // Add the file extention to the end of the label.; + + $streamUrl = ($file !== NULL) ? + 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. } - module_load_include('inc', 'Fedora_Repository', 'MimeClass'); - module_load_include('inc', 'fedora_repository', 'api/fedora_item'); - - $file_basename = basename($file->filepath); - $file_directory = dirname($file->filepath); - $streamUrl = $base_url . '/' . $file_directory . '/' . urlencode($file_basename); - /* ----------------------------------------------------------------- - * TODO: need a better way to get mimetypes - */ - $mimetype = new MimeClass(); - $dformat = $mimetype->getType($file->filepath); + $dformat = $form_state['storage']['mime_type']; + module_load_include('inc', 'fedora_repository', 'api/fedora_item'); $item = new Fedora_Item($pid); - $info = $item->get_datastream_info($dsid); - - if($info->datastream->controlGroup == 'M') { - $item->modify_datastream_by_reference($streamUrl, $dsid, $dsLabel, $dformat); - } elseif ($info->datastream->controlGroup == 'X') { - if($dformat == 'text/xml') { - $item->modify_datastream_by_value(file_get_contents($file->filepath), $dsid, $dsLabel, $dformat); - } - else { - drupal_set_message('File must be of mimetype text/xml in order to replace inline XML datastream.', 'error'); - } - } else { - drupal_set_message('Cannot replace Redirect or Managed Datastream.', 'error'); - } + $item->modify_datastream($streamUrl, $dsid, $dsLabel, $dformat); + unset($form_state['storage']); $form_state['redirect'] = 'fedora/repository/' . $pid; } @@ -870,7 +911,7 @@ function fedora_repository_perm() { * @param type $account * @return type */ -function fedora_repository_access($op, $node, $account) { +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); @@ -913,17 +954,97 @@ function makeObject($pid, $dsID) { } /** - * Sends an ITQL query to the Fedora Resource index (can only communicate with Kowari or mulgara) - * Reads the pid and datastream id as url parameters. Queries the collection object for the query - * if there is no query datastream falls back to the query shipped with the module. + * 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 type $user - * @param type $pid - * @param type $dsId - * @param type $collection - * @param type $page_number - * @param type $limit - * @return type + * @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'); @@ -945,7 +1066,7 @@ function fedora_repository_get_items($pid = NULL, $dsId = NULL, $collection = NU $pid = variable_get('fedora_repository_pid', 'islandora:root'); } - $item = new fedora_item($pid); + $item = new Fedora_Item($pid); if (!$item->exists()) { drupal_not_found(); exit(); @@ -984,57 +1105,32 @@ function fedora_repository_get_items($pid = NULL, $dsId = NULL, $collection = NU return makeObject($pid, $dsId); } - $content = '
'; - - module_load_include('inc', 'fedora_repository', 'CollectionClass'); - $collectionClass = new CollectionClass(); - module_load_include('inc', 'fedora_repository', 'ContentModel'); - module_load_include('inc', 'fedora_repository', 'plugins/FedoraObjectDetailedContent'); $breadcrumbs = array(); $objectHelper->getBreadcrumbs($pid, $breadcrumbs); drupal_set_breadcrumb(array_reverse($breadcrumbs)); + + drupal_set_title(truncate_utf8($item->objectProfile->objLabel, 56, TRUE, TRUE)); - $offset = $limit * $page_number; $content_models = $objectHelper->get_content_models_list($pid); -// Each content model may return either a tabset array or plain HTML. If it's HTML, stick it in a tab. - $cmodels_tabs = array( - '#type' => 'tabset', + + //Get the tabs from all modules... + $hook_tabs = module_invoke_all('islandora_tabs', $content_models, $pid, $page_number); + + $cmodels_tabs = array( + '#type' => 'tabset', ); - foreach ($content_models as $content_model) { - $content_model_fieldset = $content_model->displayExtraFieldset($pid, $page_number); - 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, - ); - } - } + $cmodels_tabs += $hook_tabs; -// Add a 'manage object' tab for all objects, where detailed list of content is shown. - $obj = new FedoraObjectDetailedContent($pid); + //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); - //can disable showing the object details tab in admin UI - if (variable_get('fedora_repository_show_object_details_tab', TRUE)) { - $object_details = $obj->showFieldSets(); - if ($object_details['fedora_object_details']['#selected'] == TRUE) { - foreach ($cmodels_tabs as &$cmodel_tab) { - if (is_array($cmodel_tab)) { - $cmodel_tab['#selected'] = FALSE; - } - } - } - } - else { - $object_details = array(); - } - - $hook_tabs = module_invoke_all('islandora_tabs', $content_models, $pid); - $cmodels_tabs = array_merge($cmodels_tabs, $object_details, $hook_tabs); - return tabs_render($cmodels_tabs); } @@ -1060,7 +1156,6 @@ function fedora_repository_urlencode_string($str) { * @return type */ function fedora_object_as_attachment($pid, $dsId, $label=NULL, $version=NULL) { - global $user; module_load_include('inc', 'fedora_repository', 'ObjectHelper'); if ($pid == NULL || $dsId == NULL) { @@ -1069,7 +1164,7 @@ function fedora_object_as_attachment($pid, $dsId, $label=NULL, $version=NULL) { } $objectHelper = new ObjectHelper(); - $objectHelper->makeObject($pid, $dsId, 1, $label, FALSE, $version); + $objectHelper->makeObject($pid, $dsId, TRUE, $label, FALSE, $version); } /** @@ -2111,19 +2206,19 @@ function theme_add_to_basket_link($pid, $type = 'object') { $save = "export_big.png"; $saved = "exported_big.png"; -// $path = drupal_get_path('module', 'Fedora_Repository').'/images/'.$save ; +// $path = drupal_get_path('module', 'fedora_repository').'/images/'.$save ; /* var_dump($path); - var_dump(theme('image',drupal_get_path('module', 'Fedora_Repository').'/images/'.$save)); + 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) + 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))); + 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))); } /** @@ -2274,9 +2369,6 @@ function theme_fedora_repository_solution_packs_list($solution_packs) { $header = array(); $rows = array(); - - - drupal_add_css(drupal_get_path('module', 'update') . '/update.css'); return $output; } @@ -2295,3 +2387,87 @@ function fedora_repository_forms($form_id) { } return $forms; } + +/** + * Implementation of 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') { + $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() + * @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); +} diff --git a/formClass.inc b/formClass.inc index 99decc08..06d840de 100644 --- a/formClass.inc +++ b/formClass.inc @@ -13,7 +13,6 @@ class formClass { function formClass() { - module_load_include('inc', 'formClass', ''); drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); } @@ -70,9 +69,7 @@ class formClass { 'access arguments' => array('view fedora collection'), ); $items['fedora/repository'] = array( - 'title' => '', - 'title callback' => 'variable_get', - 'title arguments' => array('fedora_repository_name', 'Digital Repository'), + 'title' => 'Digital Repository', 'page callback' => 'repository_page', 'type' => MENU_NORMAL_ITEM, 'access arguments' => array('view fedora collection'), @@ -130,7 +127,7 @@ class formClass { 'title' => t('Collection view'), 'page callback' => 'fedora_collection_view', 'type' => MENU_CALLBACK, - 'access argruments' => array('view fedora collection') + 'access argruments' => array('view fedora collection'), ); //new for mnpl****************************************** @@ -182,29 +179,38 @@ class formClass { 'access arguments' => array('view fedora collection'), ); + $items['admin/settings/fedora_repository/object_details_xslt'] = array( + 'title' => "", + 'type' => MENU_CALLBACK, + 'page callback' => 'drupal_get_form', + 'page arguments' => array('fedora_repository_object_details_XSLT_config'), + 'file' => 'ObjectDetails.inc', + 'access arguments' => array('administer site configuration'), + ); + $items['admin/settings/fedora_repository/object_details_table'] = array( + 'title' => "", + 'type' => MENU_CALLBACK, + 'page callback' => 'drupal_get_form', + 'page arguments' => array('fedora_repository_object_details_table_config'), + 'file' => 'ObjectDetails.inc', + 'access arguments' => array('administer site configuration'), + ); + return $items; } /** * Create admin form - * @return type + * @return array */ function createAdminForm() { if (!user_access('administer site configuration')) { - drupal_set_message(t('You must be a site administrator to edit the Fedora collecitons list.'), 'error'); + drupal_set_message(t('You must be a site administrator to edit the Fedora collections list.'), 'error'); return; } module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); module_load_include('inc', 'fedora_repository', 'ObjectHelper'); $form = array(); - $form['fedora_repository_name'] = array( - '#type' => 'textfield', - '#title' => t('Root Collection Name'), - '#default_value' => variable_get('fedora_repository_name', 'Islandora demos collection'), - '#description' => t('The Name of the Root Collection Object'), - '#required' => TRUE, - '#weight' => -20 - ); $form['fedora_repository_pid'] = array( '#type' => 'textfield', '#title' => t('Root Collection PID'), @@ -239,9 +245,12 @@ class formClass { '#description' => t('The URL to use for SOAP connections'), '#required' => TRUE, '#weight' => -12, - '#suffix' => '

' . (fedora_available() ? '' . t('Successfully connected to Fedora server at !fedora_soap_url', array('!fedora_soap_url' => variable_get('fedora_soap_url', ''))) : ' ' . t('Unable to connect to Fedora server at !fedora_soap_url

', array('!fedora_soap_url' => variable_get('fedora_soap_url', '')))), + '#suffix' => '

' . ( + fedora_available() ? + theme('image', 'misc/watchdog-ok.png') . t('Successfully connected to Fedora server at @fedora_soap_url', array('@fedora_soap_url' => variable_get('fedora_soap_url', ''))) : + theme('image', 'misc/watchdog-error.png') . t('Unable to connect to Fedora server at @fedora_soap_url', array('@fedora_soap_url' => variable_get('fedora_soap_url', '')))) . '

', ); - + $form['fedora_soap_manage_url'] = array( '#type' => 'textfield', '#title' => t('Fedora SOAP management URL'), @@ -249,7 +258,7 @@ class formClass { '#required' => TRUE, '#weight' => -10 ); - + // will allow admin user to remove namepsace restrictions if not explicitly disallowed in settings.php if (variable_get('allow_open_namespace', TRUE)) { $form['fedora_namespace'] = array( @@ -285,20 +294,16 @@ class formClass { '#weight' => 0 ); } - $form['fedora_repository_title'] = array( - '#type' => 'textfield', - '#title' => t('Digital Repository Title'), - '#default_value' => variable_get('fedora_repository_name', 'Digital Repository'), - '#description' => t('The title displayed when viewing collections and objects in /fedora/repository. Leave blank to display no title. Note that the menus must be rebuilt after changing this variable.'), - ); + //have tabs options (like disable) $form['tabs'] = array( '#type' => 'fieldset', '#title' => t('Tabs Configuration'), - '#description' => t('Configure the tabs avaialble when viewing Fedora objects.'), + '#description' => t('Configure the tabs available when viewing Fedora objects.'), '#collapsible' => TRUE, '#collapsed' => TRUE, ); + //when checked show object details tab $form['tabs']['fedora_repository_show_object_details_tab'] = array( '#type' => 'checkbox', @@ -306,7 +311,35 @@ class formClass { '#default_value' => variable_get('fedora_repository_show_object_details_tab', TRUE), '#description' => t("When enabled, the 'Object Details' tab will be visible to users with the correct permissions when viewing an object in the repository"), ); - + + module_load_include('inc', 'fedora_repository', 'ObjectDetails'); + $primary_display_mode = variable_get('islandora_object_details_display_table', 'xslt'); + $profiles = module_invoke_all("islandora_object_details_display"); + + $display_options = array(); + // suppress php warnings from empty lists + if ($profiles) { + foreach ($profiles as $machine_name => $profile) { + // make sure the name exists (the bare minimum) + if (array_key_exists('name', $profile)) { + $display_options[$machine_name] = $profile['name']; + if (array_key_exists('config', $profile)) { + $config_path = $profile['config']; + if (isset($config_path) && $config_path != "") { + $display_options[$machine_name] .= " (". l("config", $config_path, array()) .")"; + } + } + } + } + } + $form['tabs']['islandora_object_details_display_table'] = array( + '#type' => 'radios', + '#title' => t('Show object details as'), + '#options' => $display_options, + '#default_value' => $primary_display_mode, + '#description' => t("Tells Islandora how to display the object details page for each object"), + ); + $form['advanced'] = array( '#type' => 'fieldset', '#title' => t('Advanced configuration options'), @@ -336,6 +369,21 @@ class formClass { '#default_value' => variable_get('fedora_object_restrict_datastreams', FALSE), '#description' => t('When enabled, restricts access to fedora object datastreams that are not listed in the Islandora Content Model for the object (unless the user is an administrator).'), ); + + $form['advanced']['fedora_repository_use_imagecache_external_in_collection_view'] = array( + '#type' => 'checkbox', + '#title' => t('Allow imagecache_external use for thumbnails in collection view'), + '#default_value' => variable_get('fedora_repository_use_imagecache_external_in_collection_view', FALSE), + '#description' => t('If enabled, the default collection list view (or ' . + 'anywhere the function "@function" is used) will try to use ' . + 'imagecache_external, defaulting to the "@preset" preset. XSLTs may ' . + 'be updated to use this function.', + array( + '@function' => '_fedora_repository_render_image()', + '@preset' => 'fedora_repository_collection_thumbnail', + '@xsl' => 'sparql_to_html.xsl', + )), + ); $form['advanced']['fedora_collection_display_list'] = array( '#type' => 'select', @@ -344,6 +392,13 @@ class formClass { '#options' => array(ObjectHelper::$DISPLAY_ALWAYS => t('Always'), ObjectHelper::$DISPLAY_NEVER => t('Never'), ObjectHelper::$DISPLAY_NO_MODEL_OUTPUT => t('Only if no Content Model display output.')), '#description' => t('Determines when to display the list of objects when viewing a collection page.'), ); + + $form['advanced']['fedora_control_group_control_during_ingest'] = array( + '#type' => 'checkbox', + '#title' => t('Allow control groups select in datastream ingest'), + '#description' => t('Whether or not we should allow the user to select which control group to ingest a stream as, or to follow the old paradigm--to add stream IDed as XML as inline, and everything else as managed.'), + '#default_value' => variable_get('fedora_control_group_control_during_ingest', FALSE), + ); //Export functionality $form['advanced']['module']['export_area'] = array( @@ -669,17 +724,21 @@ class formClass { } } - $form['add_datastream_label'] = array( - '#value' => t('

Add Datastream:

'), - '#weight' => -10, + $form['fieldset'] = array( + '#type' => 'fieldset', + '#title' => t('Add datastream'), ); + //$form['add_datastream_label'] = array( + // '#value' => t('

Add Datastream:

'), + // '#weight' => -10, + //); - $form['pid'] = array( + $form['fieldset']['pid'] = array( '#type' => 'hidden', '#value' => "$pid" ); - $form['stream_label'] = array( + $form['fieldset']['stream_label'] = array( '#title' => 'Datastream Label', '#required' => 'TRUE', '#description' => t('A Human readable label'), @@ -687,35 +746,41 @@ class formClass { ); $form['#attributes']['enctype'] = 'multipart/form-data'; - $form['add-stream-file-location'] = array( + $form['fieldset']['add-stream-file-location'] = array( '#type' => 'file', '#title' => t('Upload Document'), '#size' => 48, // '#required'=>'TRUE', - '#description' => t('The file to upload.') + '#description' => t('The file to upload. (Only for Managed and Inline)') ); + + if (variable_get('fedora_control_group_control_during_ingest', FALSE)) { + $form['fieldset']['ds_reference'] = array( + '#type' => 'textfield', + '#title' => t('Datastream reference'), + '#size' => 48, + '#description' => t('A URL reference to resolve for the contents of the datastream. (Required for External and Redirect, but will still work for Managed and Inline.)'), + ); + } + $form['#redirect'] = "fedora/repository/$pid/"; - $form['submit'] = array( + $form['fieldset']['submit'] = array( '#type' => 'submit', '#value' => t('Add Datastream') ); if (!empty($unused_dsids)) { - $dsidsForForm = array(); - foreach ($unused_dsids as $dsid) { - $dsidsForForm[$dsid] = $dsid; - } - $form['stream_id'] = array( + $form['fieldset']['stream_id'] = array( '#type' => 'select', '#title' => t('Datastream ID'), '#default_value' => variable_get('feed_item_length', 'teaser'), - '#weight' => '-1', + '#weight' => -1, '#description' => t('Datastream IDs defined by the content model.'), + '#options' => array_combine($unused_dsids, $unused_dsids), ); - $form['stream_id']['#options'] = array_combine($unused_dsids, $unused_dsids); } else { - $form['stream_id'] = array( + $form['fieldset']['stream_id'] = array( '#title' => 'Datastream ID', '#required' => 'TRUE', '#description' => t('An ID for this stream that is unique to this object. Must start with a letter and contain only alphanumeric characters and dashes and underscores.'), @@ -723,6 +788,21 @@ class formClass { '#weight' => -1, ); } + + if (variable_get('fedora_control_group_control_during_ingest', FALSE)) { + $form['fieldset']['control_group'] = array( + '#type' => 'select', + '#title' => t('Control group'), + '#options' => array( + 'X' => t('Inline XML'), + 'M' => t('Managed datastream'), + 'E' => t('Externally Referenced/managed datastream'), + 'R' => t('Redirect datastream'), + ), + '#description' => t('The manner in which the datastream will be stored. "Inline XML" must be XML and will be placed directly into the FOXML for the object. "Managed" datastreams are made to live on the filesystem as discrete files in the Fedora data directory. Both "Redirect" and "External" streams are URL references; the difference being the redirect stream instruct clients to perform an HTTP redirect, such that the data does not pass though Fedora (useful for streaming). External streams are mediated (by which I mean loaded and streamed from) the Fedora server.'), + '#weight' => 0, + ); + } return $form; } @@ -737,15 +817,12 @@ class formClass { * @return string */ function createQDCEditForm($pid, $dsid, $client, &$form_state) { + module_load_include('inc', 'fedora_repository', 'api/fedora_item'); $dsid = empty($dsid) ? 'QDC' : $dsid; - try { - $params = array('pid' => "$pid", 'dsID' => "$dsid", 'asOfDateTime' => ""); - $object = $client->__soapCall('getDatastreamDissemination', array('parameters' => $params)); - } catch (Exception $e) { - return array(); - } - $content = $object->dissemination->stream; - $content = trim($content); + + $item = new fedora_item($pid); + $content = trim($item->get_datastream_dissemination($dsid)); + $doc = new DOMDocument(); if (!$doc->loadXML($content)) { echo "error loading xml"; @@ -849,12 +926,33 @@ class formClass { $form = array(); $form['#attributes']['enctype'] = 'multipart/form-data'; - $form['file'] = array( - '#type' => 'file', - '#title' => t('Upload Document'), - '#description' => t('The file to upload.') - ); - + + module_load_include('inc', 'fedora_repository', 'api/fedora_item'); + $item = new Fedora_Item($pid); + $info = $item->get_datastream_info($dsId); + $control_group = $info->datastream->controlGroup; + if (in_array($control_group, array('M', 'X'))) { + $form['file'] = array( + '#type' => 'file', + '#title' => t('Upload Document'), + '#description' => t('A file with which to replace the contents of this datastream.'), + ); + } + if ($control_group != 'X') { + $form['reference'] = array( + '#type' => 'textfield', + '#title' => t('Reference to object'), + '#description' => t('A URL the datastream will be updated to reference.'), + ); + } + if ($control_group == 'M') { + $form['note'] = array( + '#type' => 'item', + '#title' => t('NOTE'), + '#value' => t('If both a file and a reference are given, the file will be given preference.'), + ); + } + $form['pid'] = array( '#type' => 'value', '#value' => $pid, diff --git a/xsl/convertQDC.xsl b/object_details_xslts/convertQDC.xsl similarity index 68% rename from xsl/convertQDC.xsl rename to object_details_xslts/convertQDC.xsl index c2bb50f0..5d881e35 100644 --- a/xsl/convertQDC.xsl +++ b/object_details_xslts/convertQDC.xsl @@ -12,13 +12,13 @@
- + - diff --git a/object_details_xslts/mods2html.xsl b/object_details_xslts/mods2html.xsl new file mode 100644 index 00000000..3f794523 --- /dev/null +++ b/object_details_xslts/mods2html.xsl @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

' . t("Belongs to these collections:") . '

' . $parent_collections_HTML . '

MetaData

+
- = + =
+ +
+ + + + + + + + + + + : + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + : + + + + + + + + ( + + + + + + + Edition + ) + + + + ="", + + + + + () + + + diff --git a/plugins/DarwinCore.inc b/plugins/DarwinCore.inc index 2d66d60a..2b25ef7e 100644 --- a/plugins/DarwinCore.inc +++ b/plugins/DarwinCore.inc @@ -247,7 +247,7 @@ class DarwinCore { * @return type */ public function asHTML() { - $path = drupal_get_path('module', 'Fedora_Repository'); + $path = drupal_get_path('module', 'fedora_repository'); module_load_include('inc', 'fedora_repository', 'ObjectHelper'); module_load_include('inc', 'fedora_repository', 'CollectionClass'); diff --git a/plugins/FedoraObjectDetailedContent.inc b/plugins/FedoraObjectDetailedContent.inc index 9283acb2..f1d7949b 100644 --- a/plugins/FedoraObjectDetailedContent.inc +++ b/plugins/FedoraObjectDetailedContent.inc @@ -32,7 +32,6 @@ class FedoraObjectDetailedContent { */ public function showFieldSets() { global $user; - drupal_set_title($this->item->objectProfile->objLabel); $objectHelper = new ObjectHelper(); $tabset = array(); $show_purge_tab = (!empty($_POST['form_id']) && $_POST['form_id'] == 'fedora_repository_purge_object_form'); @@ -48,9 +47,28 @@ class FedoraObjectDetailedContent { $tabset['fedora_object_details']['tabset'] = array( '#type' => 'tabset', ); - $dc_html = $objectHelper->getFormattedDC($this->item); - $ds_list = $objectHelper->get_formatted_datastream_list($this->pid, NULL, $this->item); + module_load_include('inc', 'fedora_repository', 'ObjectDetails'); + $object_details_profile = variable_get('islandora_object_details_display_table', 'xslt'); + $profiles = module_invoke_all("islandora_object_details_display"); + $profile = $profiles[$object_details_profile]; + if (!isset($profile)) { + // default behaviour + watchdog('fedora_repository', "Error while reading the default object details display profile: @e", array("@e" => $e->getMessage()), WATCHDOG_WARNING); + $dc_html = $objectHelper->getFormattedDC($this->item); + } + else { + // invoke the requested display profile + require_once(drupal_get_path('module', $profile['module']) ."/". $profile['file']); + $details_function = $profile['function']; + if (function_exists($details_function)) { + $dc_html = $details_function($this->item); + } + else { + // problem - display profile not found + watchdog('fedora_repository', "Error - could not find object details display function @function", array('@function' => $details_function), WATCHDOG_WARNING); + } + } $i = 0; if (fedora_repository_access(OBJECTHELPER :: $VIEW_DETAILED_CONTENT_LIST, $this->pid, $user)) { @@ -63,9 +81,24 @@ class FedoraObjectDetailedContent { '#weight' => $i++ ), 'list' => array( - '#type' => 'markup', - '#value' => $ds_list, //XXX: The function called here could be cleaned up a fair bit as well... - '#weight' => $i++ + '#type' => 'fieldset', + '#title' => t('Detailed List of Content'), + '#attributes' => array( + 'class' => 'fedora_detailed_list', + ), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#weight' => $i++, + 'parents' => array( + '#type' => 'markup', + '#value' => $objectHelper->get_parent_objects_asHTML($this->pid), + '#weight' => $i++, + ), + 'datastreams' => array( + '#type' => 'markup', + '#value' => $objectHelper->get_formatted_datastream_list($this->pid, NULL, $this->item), //XXX: The function called here could be cleaned up a fair bit as well... + '#weight' => $i++, + ), ), 'purge' => array( '#type' => 'markup', diff --git a/plugins/FlvFormBuilder.inc b/plugins/FlvFormBuilder.inc index 8c2b5777..57a8058c 100644 --- a/plugins/FlvFormBuilder.inc +++ b/plugins/FlvFormBuilder.inc @@ -58,7 +58,7 @@ class FlvFormBuilder extends FormBuilder { $ds1v->appendChild($ds1content); $rootElement->appendChild($ds1); - $createdFile = drupal_get_path('module', 'Fedora_Repository') . '/images/flashThumb.jpg'; + $createdFile = drupal_get_path('module', 'fedora_repository') . '/images/flashThumb.jpg'; $fileUrl = $base_url . '/' . drupal_urlencode($createdFile); //'http://'.$_SERVER['HTTP_HOST'].'/'.$createdFile; $ds1 = $dom->createElement("foxml:datastream"); $ds1->setAttribute("ID", "TN"); diff --git a/plugins/FormBuilder.inc b/plugins/FormBuilder.inc index 715ca6af..edc3e919 100644 --- a/plugins/FormBuilder.inc +++ b/plugins/FormBuilder.inc @@ -95,21 +95,21 @@ class FormBuilder { try { $xml = new SimpleXMLElement($policyStreamDoc); } catch (Exception $e) { - watchdog(t("Fedora_Repository"), "Problem getting security policy.", NULL, WATCHDOG_ERROR); + watchdog(t("fedora_repository"), "Problem getting security policy.", NULL, WATCHDOG_ERROR); drupal_set_message(t('Problem getting security policy: @e', array('@e' => check_plain($e->getMessage()))), 'error'); return FALSE; } $policyElement = $dom->createDocumentFragment(); if (!$policyElement) { drupal_set_message(t('Error parsing security policy stream.')); - watchdog(t("Fedora_Repository"), "Error parsing security policy stream, could not parse policy stream.", NULL, WATCHDOG_NOTICE); + watchdog(t("fedora_repository"), "Error parsing security policy stream, could not parse policy stream.", NULL, WATCHDOG_NOTICE); return FALSE; } $dom->importNode($policyElement, TRUE); $value = $policyElement->appendXML($policyStreamDoc); if (!$value) { drupal_set_message(t('Error creating security policy stream.')); - watchdog(t("Fedora_Repository"), "Error creating security policy stream, could not parse collection policy template file.", NULL, WATCHDOG_NOTICE); + watchdog(t("fedora_repository"), "Error creating security policy stream, could not parse collection policy template file.", NULL, WATCHDOG_NOTICE); return FALSE; } @@ -183,7 +183,7 @@ class FormBuilder { file_delete($form_values['ingest-file-location']); } catch (exception $e) { drupal_set_message(t('Error ingesting object: @e', array('@e' => check_plain($e->getMessage()))), 'error'); - watchdog(t("Fedora_Repository"), "Error ingesting object: @e", array('@e' => check_plain($e->getMessage())), NULL, WATCHDOG_ERROR); + watchdog(t("fedora_repository"), "Error ingesting object: @e", array('@e' => check_plain($e->getMessage())), NULL, WATCHDOG_ERROR); return; } } diff --git a/plugins/ModsFormBuilder.inc b/plugins/ModsFormBuilder.inc index aa0f6f92..e6376a14 100644 --- a/plugins/ModsFormBuilder.inc +++ b/plugins/ModsFormBuilder.inc @@ -317,7 +317,7 @@ class ModsFormBuilder extends FormBuilder { file_delete($form_values['ingest-file-location']); } catch (exception $e) { drupal_set_message(t('Error ingesting object: @e', array('@e' => check_plain($e->getMessage()))), 'error'); - watchdog(t("Fedora_Repository"), "Error ingesting object: @e", array('@e' => check_plain($e->getMessage())), NULL, WATCHDOG_ERROR); + watchdog(t("fedora_repository"), "Error ingesting object: @e", array('@e' => check_plain($e->getMessage())), NULL, WATCHDOG_ERROR); return; } } diff --git a/plugins/PersonalCollectionClass.inc b/plugins/PersonalCollectionClass.inc index 9ed6af07..3e23f1a0 100644 --- a/plugins/PersonalCollectionClass.inc +++ b/plugins/PersonalCollectionClass.inc @@ -71,11 +71,11 @@ class PersonalCollectionClass { * @return type */ function createCollectionPolicyStream($user, $dom, $rootElement) { - $collectionTemplate = file_get_contents(drupal_get_path('module', 'Fedora_Repository') . '/collection_policies/PERSONAL-COLLECTION-POLICY.xml'); + $collectionTemplate = file_get_contents(drupal_get_path('module', 'fedora_repository') . '/collection_policies/PERSONAL-COLLECTION-POLICY.xml'); try { $xml = new SimpleXMLElement($collectionTemplate); } catch (Exception $e) { - watchdog(t("Fedora_Repository"), "Problem creating personal collection policy, could not parse collection policy stream.", NULL, WATCHDOG_ERROR); + watchdog(t("fedora_repository"), "Problem creating personal collection policy, could not parse collection policy stream.", NULL, WATCHDOG_ERROR); drupal_set_message(t('Problem creating personal collection policy, could not parse collection policy stream: @e', array('@e' => check_plain($e->getMessage()))), 'error'); return FALSE; } @@ -83,7 +83,7 @@ class PersonalCollectionClass { if (!$policyElement) { drupal_set_message(t('Error parsing policy stream.')); - watchdog(t("Fedora_Repository"), "Error parsing policy stream, could not parse policy stream.", NULL, WATCHDOG_NOTICE); + watchdog(t("fedora_repository"), "Error parsing policy stream, could not parse policy stream.", NULL, WATCHDOG_NOTICE); return FALSE; } $dom->importNode($policyElement, TRUE); @@ -91,7 +91,7 @@ class PersonalCollectionClass { $value = $policyElement->appendXML($collectionTemplate); if (!$value) { drupal_set_message(t('Error creating collection policy stream.')); - watchdog(t("Fedora_Repository"), "Error creating collection policy stream, could not parse collection policy template file.", NULL, WATCHDOG_NOTICE); + watchdog(t("fedora_repository"), "Error creating collection policy stream, could not parse collection policy template file.", NULL, WATCHDOG_NOTICE); return FALSE; } diff --git a/plugins/QtFormBuilder.php b/plugins/QtFormBuilder.php index 28645d6b..262f1a98 100644 --- a/plugins/QtFormBuilder.php +++ b/plugins/QtFormBuilder.php @@ -18,7 +18,7 @@ class QtFormBuilder extends FormBuilder { * Constructor */ function QtFormBuilder() { - module_load_include('php', 'Fedora_Repository', 'plugins/FormBuilder'); + module_load_include('php', 'fedora_repository', 'plugins/FormBuilder'); drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); } @@ -57,7 +57,7 @@ class QtFormBuilder extends FormBuilder { $rootElement->appendChild($ds1); if (empty($_SESSION['fedora_ingest_files']) || !isset($_SESSION['fedora_ingest_files']['TN'])) { - $createdFile = drupal_get_path('module', 'Fedora_Repository') . '/images/qtThumb.jpg'; + $createdFile = drupal_get_path('module', 'fedora_repository') . '/images/qtThumb.jpg'; $fileUrl = $base_url . '/' . drupal_urlencode($createdFile); //'http://'.$_SERVER['HTTP_HOST'].'/'.$createdFile; $ds1 = $dom->createElement("foxml:datastream"); $ds1->setAttribute("ID", "TN"); diff --git a/plugins/Refworks.inc b/plugins/Refworks.inc index 70b0abeb..b1688292 100644 --- a/plugins/Refworks.inc +++ b/plugins/Refworks.inc @@ -290,13 +290,13 @@ class Refworks { if ($client == NULL) { drupal_set_message(t('Error getting SOAP client.'), 'error'); - watchdog(t("FEDORA_REPOSITORY"), "Error getting SOAP client: @e", array('@e' => $e), NULL, WATCHDOG_ERROR); + watchdog(t("fedora_repository"), "Error getting SOAP client: @e", array('@e' => $e), NULL, WATCHDOG_ERROR); return; } $object = $client->__soapCall('ingest', array( $params )); - watchdog(t("FEDORA_REPOSITORY"), "Successfully added repository item " . $pid . " - ". $item_title, NULL, WATCHDOG_INFO); + watchdog(t("fedora_repository"), "Successfully added repository item " . $pid . " - ". $item_title, NULL, WATCHDOG_INFO); $deleteFiles = $form_values['delete_file']; //remove files from drupal file system if ($deleteFiles > 0) { @@ -305,7 +305,7 @@ class Refworks { } catch (exception $e) { $errors++; $errorMessage = 'yes'; - watchdog(t("FEDORA_REPOSITORY"), t("Error during ingest !it @e", array('!it' => $item_title, '@e' => $e)), NULL, WATCHDOG_ERROR); + watchdog(t("fedora_repository"), t("Error during ingest !it @e", array('!it' => $item_title, '@e' => $e)), NULL, WATCHDOG_ERROR); } $success++; } diff --git a/plugins/ShowDemoStreamsInFieldSets.inc b/plugins/ShowDemoStreamsInFieldSets.inc index 80f8017c..9d210d2a 100644 --- a/plugins/ShowDemoStreamsInFieldSets.inc +++ b/plugins/ShowDemoStreamsInFieldSets.inc @@ -29,11 +29,10 @@ class ShowDemoStreamsInFieldSets { * @return type */ function showMediumSize() { - global $base_url; + $path = "fedora/repository/{$this->pid}/MEDIUM_SIZE"; $collection_fieldset = array( '#collapsible' => FALSE, - '#value' => '', + '#value' => l(theme('image', $path), $path, array('html' => TRUE)), ); return theme('fieldset', $collection_fieldset); } diff --git a/plugins/ShowStreamsInFieldSets.inc b/plugins/ShowStreamsInFieldSets.inc index 9e20ca5a..e75ddec1 100644 --- a/plugins/ShowStreamsInFieldSets.inc +++ b/plugins/ShowStreamsInFieldSets.inc @@ -28,16 +28,22 @@ class ShowStreamsInFieldSets { */ function showFlv() { //FLV is the datastream id - $path = drupal_get_path('module', 'Fedora_Repository'); - $fullPath = base_path() . $path; + $path = drupal_get_path('module', 'fedora_repository'); + $fullPath = url($path); $content = ""; - $pathTojs = drupal_get_path('module', 'Fedora_Repository') . '/js/swfobject.js'; + $pathTojs = drupal_get_path('module', 'fedora_repository') . '/js/swfobject.js'; drupal_add_js("$pathTojs"); - $content .= '
Get the Flash Player to see this player.
'; - drupal_add_js('var s1 = new SWFObject("' . $fullPath . '/flash/flvplayer.swf","single","320","240","7"); - s1.addParam("allowfullscreen","TRUE"); - s1.addVariable("file","' . base_path() . 'fedora/repository/' . $this->pid . '/FLV/FLV.flv"); - s1.write("player' . $this->pid . 'FLV");', 'inline', 'footer'); + $div_id = "player' . $this->pid . 'FLV"; + $content .= <<Get the Flash Player to see this player. +EOH; + drupal_add_js(<<pid}/FLV/FLV.flv"); +s1.write("$div_id"); +EOJS +, 'inline', 'footer'); $collection_fieldset = array( '#title' => t('Flash Video'), '#collapsible' => TRUE, @@ -48,30 +54,26 @@ class ShowStreamsInFieldSets { /** * Show the TN ?? - * @global type $base_url * @return type */ function showTN() { - global $base_url; $collection_fieldset = array( '#title' => '', '#attributes' => array(), '#collapsible' => FALSE, - '#value' => '', + '#value' => l(theme('image', "fedora/repository/{$this->pid}/TN/TN", '', '', NULL, FALSE), "fedora/repository/{$this->pid}/OBJ", array('html' => TRUE)), ); return theme('fieldset', $collection_fieldset); } /** * Same as showTN but artinventory stores the image in a dsid of IMAGE instead of OBJ - * @global type $base_url * @return type */ function showArtInventoryTN() { - global $base_url; $collection_fieldset = array( '#collapsible' => FALSE, - '#value' => '', + '#value' => l(theme('image', "fedora/repository/{$this->pid}/TN/TN", '', '', NULL, FALSE), "fedora/repository/{$this->pid}/IMAGE/image.jpg", array('html' => TRUE)), ); return theme('fieldset', $collection_fieldset); } @@ -102,14 +104,16 @@ class ShowStreamsInFieldSets { $objectHelper = new ObjectHelper(); $item = new Fedora_Item($this->pid); if (key_exists('TN', $item->datastreams)) { - $tn_url = $base_url . '/fedora/repository/' . $item->pid . '/TN'; + $tn_url = "fedora/repository/{$item->pid}/TN"; } else { - $tn_url = $base_path . drupal_get_path('module', 'fedora_repository') . '/images/Crystal_Clear_app_download_manager.png'; + $tn_url = drupal_get_path('module', 'fedora_repository') . '/images/Crystal_Clear_app_download_manager.png'; } + $tn_url = url($tn_url); + $dc_html = $objectHelper->getFormattedDC($item); - $dl_link = l('

' . t('View Document') .'
', 'fedora/repository/' . $this->pid . '/OBJ', array('html' => TRUE)); + $dl_link = l('
' . theme('image', $tn_url, '', '', NULL, FALSE) . '
' . t('View Document') .'
', "fedora/repository/{$this->pid}/OBJ", array('html' => TRUE)); $tabset['first_tab']['tabs']['view'] = array( '#type' => 'tabpage', @@ -126,11 +130,13 @@ class ShowStreamsInFieldSets { ); } + $viewer_url = 'http://docs.google.com/viewer?url=' . url("fedora/repository/{$this->pid}/OBJ/preview.pdf", array('absolute' => TRUE)) . '&embedded=TRUE'; $tabset['second_tab'] = array( '#type' => 'tabpage', '#title' => t('Read Online'), - '#content' => "" + '#content' => <<" +EOM ); // Render the tabset. @@ -164,7 +170,7 @@ class ShowStreamsInFieldSets { module_load_include('inc', 'fedora_repository', 'api/fedora_item'); $item = new Fedora_Item($this->pid); $streams = $item->get_datastreams_list_as_array(); - return "" . $streams['OBJ']['label'] . ""; + return l($streams['OBJ']['label'], "fedora/repository/{$this->pid}/OBJ"); } /** @@ -225,7 +231,7 @@ class ShowStreamsInFieldSets { * @return type */ function showRomeo($collapsed = FALSE) { - $path = drupal_get_path('module', 'Fedora_Repository'); + $path = drupal_get_path('module', 'fedora_repository'); module_load_include('inc', 'fedora_repository', 'CollectionClass'); $collectionHelper = new CollectionClass(); $xmlstr = $collectionHelper->getStream($this->pid, "ROMEO", 0); diff --git a/plugins/fedora_imageapi.module b/plugins/fedora_imageapi.module index f3bd4481..9f5d6e41 100644 --- a/plugins/fedora_imageapi.module +++ b/plugins/fedora_imageapi.module @@ -22,7 +22,7 @@ function fedora_imageapi_menu() { * @param string $params */ function fedora_repository_image_manip($pid = '', $dsid = '', $op = '', $params = '') { - module_load_include('inc', 'Fedora_Repository', 'ObjectHelper'); + module_load_include('inc', 'fedora_repository', 'ObjectHelper'); module_load_include('module', 'imageapi'); $obj = new ObjectHelper(); $mimetype = $obj->getMimeType($pid, $dsid); diff --git a/plugins/herbarium.inc b/plugins/herbarium.inc index f7a6d685..0ad13fd6 100644 --- a/plugins/herbarium.inc +++ b/plugins/herbarium.inc @@ -161,13 +161,13 @@ class Herbarium { '#title' => t('Full-size'), '#content' => $html ); + $image = theme('image', "fedora/imageapi/{$this->pid}/JPG/JPG.jpg", '', '', NULL, FALSE); $tabset['first_tab'] = array( // #type and #title are the minimum requirements. '#type' => 'tabpage', '#title' => t('View'), // This will be the content of the tab. - '#content' => '' . '

' . drupal_get_form('fedora_repository_image_tagging_form', $this->pid) . '

', + '#content' => l($image, "fedora/repository/{$this->pid}/FULL_JPG", array('html' => TRUE)), '

' . drupal_get_form('fedora_repository_image_tagging_form', $this->pid) . '

', ); $dwc = new DarwinCore($this->item); diff --git a/plugins/qt_viewer.inc b/plugins/qt_viewer.inc index e52e4363..74f34a3e 100644 --- a/plugins/qt_viewer.inc +++ b/plugins/qt_viewer.inc @@ -125,59 +125,76 @@ class ShowQtStreamsInFieldSets { if ($media === FALSE) { return ''; } - global $base_url; - $path = drupal_get_path('module', 'Fedora_Repository'); - $fullPath = base_path() . $path; - $content = ''; - $pathTojs = drupal_get_path('module', 'Fedora_Repository') . '/js/AC_Quicktime.js'; - drupal_add_js($pathTojs); + + $path = drupal_get_path('module', 'fedora_repository'); + + drupal_add_js("$path/js/AC_Quicktime.js"); $divid = 'player' . md5($this->pid) . 'MOV'; - $content .= '
'; + + $collection_fieldset = array( + '#title' => t('Quicktime'), + '#collapsible' => TRUE, + '#collapsed' => FALSE, + 'player' => array( + '#type' => 'markup', + '#prefix' => '
', + '#suffix' => '
', + ), + ); + if ($pframe !== FALSE) { - $content .= '
'; - $content .= ''; - $content .= '
'; - $content .= '
'; + $collection_fieldset['player']['poster_container'] = array( + '#type' => 'markup', + '#prefix' => '
', + '#suffix' => '
', + 'poster' => array( + '#type' => 'markup', + '#value' => theme('image', "fedora/repository/{$this->pid}/{$pframe->ID}/poster.jpg", '', '', NULL, FALSE) + ) + 'play' => array( + '#type' => 'markup', + '#prefix' => '
', + '#suffix' => '
', + '#value' => ' ', + ), + ); } - $content .= '
'; if ($this->enableDownload()) { - $url = base_path() . 'fedora/repository/' . $this->pid . '/OBJ/MOV.mov'; - $content .= 'Download Media File'; + //$url = url(); + $collection_fieldset['download_link'] = array( + '#type' => 'markup', + '#value' => l(t('Download Media File'), "fedora/repository/{$this->pid}/OBJ/MOV.mov", array('attributes' => array('class' => 'download'))), + ); } - $src = base_path() . 'fedora/repository/' . $this->pid . '/' . $media->ID . '/MOV.mov'; - $qtparams = ''; - $qtparams .= "'autostart', '" . ($pframe !== FALSE ? 'TRUE' : 'FALSE') . "', "; + $src = url("fedora/repository/{$this->pid}/{$media->ID}/MOV.mov"; + + $qtparams = "'autostart', '" . ($pframe !== FALSE ? 'TRUE' : 'FALSE') . "', "; $init = << t('Quicktime'), - '#collapsible' => TRUE, - '#collapsed' => FALSE, - '#value' => $content); return theme('fieldset', $collection_fieldset); } diff --git a/plugins/slide_viewer.inc b/plugins/slide_viewer.inc index f3bdd6b9..729e824e 100644 --- a/plugins/slide_viewer.inc +++ b/plugins/slide_viewer.inc @@ -30,14 +30,13 @@ class ShowSlideStreamsInFieldSets { function showJPG() { module_load_include('inc', 'fedora_repository', 'plugins/tagging_form'); module_load_include('inc', 'fedora_repository', 'plugins/ShowStreamsInFieldSets'); - global $base_url; global $user; $tabset = array(); $qs = ''; if ($user->uid != 0) { - $qs = '?uid=' . base64_encode($user->name . ':' . $user->pass); + $qs = '?uid=' . base64_encode($user->name . ':' . $user->pass); //XXX: Base64 encoding is not encryption; SSL would be nice... } $viewer_url = variable_get('fedora_base_url', 'http://localhost:8080/fedora') . '/get/' . $this->pid . '/ilives:viewerSdef/getViewer' . $qs; @@ -55,8 +54,7 @@ class ShowSlideStreamsInFieldSets { '#type' => 'tabpage', '#title' => t('View'), // This will be the content of the tab. - '#content' => '' . '

' . drupal_get_form('fedora_repository_image_tagging_form', $this->pid) . '

', + '#content' => theme('image', "fedora/imageapi/{$this->pid}/JPG/JPG.jpg", '', '', NULL, FALSE) . '

' . drupal_get_form('fedora_repository_image_tagging_form', $this->pid) . '

', ); return $tabset; diff --git a/plugins/tagging_form.inc b/plugins/tagging_form.inc index 390bf36c..9b7c4658 100644 --- a/plugins/tagging_form.inc +++ b/plugins/tagging_form.inc @@ -19,13 +19,15 @@ function _show_subject_tags($pid) { $obj = new Fedora_Item($pid); $tags = new TagSet($obj); if (!empty($tags->tags)) { - $output = "
    "; + $items = array(); foreach ($tags->tags as $tag) { - $output .= "
  • "; + return theme('item_list', $items); } - return $output; } /** @@ -57,21 +59,28 @@ function fedora_repository_image_tagging_form($form_state, $pid) { // Add the current tags to the form. $tagset = new TagSet($obj); + $tags = array(); foreach ($tagset->tags as $tag) { $form['tags-wrapper']['tags'][$tag['name']] = array( '#prefix' => '
  • ', '#suffix' => '
  • ', ); - $form['tags-wrapper']['tags'][$tag['name']]['tag'] = array( - '#prefix' => '', - '#value' => $tag['name'], - '#suffix' => '', + $form_tag =& $form['tags-wrapper']['tags'][$tag['name']]; + + $tag_title_text = t('Added by @creator.', array( + '@creator' => $tag['creator'], + )); + $tag_mnpl_search_path = "fedora/repository/mnpl_advanced_search/tag:{$tag['name']}"; + $form_tag['tag'] = array( + '#value' => l($tag['name'], $tag_mnpl_search_path, array('attributes' => array( + 'title' => $tag_title_text + ))), ); if (user_access('modify fedora datastreams') || user_access('add fedora tags')) { // Delete button for each existing tag. - $form['tags-wrapper']['tags'][$tag['name']]['delete'] = array( + $form_tag['delete'] = array( '#type' => 'imagebutton', - '#image' => $base_url . '/' . drupal_get_path('module', 'fedora_repository') . '/images/remove_icon.png', + '#image' => drupal_get_path('module', 'fedora_repository') . '/images/remove_icon.png', '#default_value' => $tag['name'], '#title' => t('Delete this tag'), ); diff --git a/xsl/convertQDC.xsl.deprecated b/xsl/convertQDC.xsl.deprecated new file mode 100644 index 00000000..724f7c70 --- /dev/null +++ b/xsl/convertQDC.xsl.deprecated @@ -0,0 +1,34 @@ + + + + + + + + +
    + + + + + + + + + + + + + + + + + +

    MetaData

    + +
    +
    +
    +
    +
    +
    diff --git a/xsl/sparql_to_html.xsl b/xsl/sparql_to_html.xsl index 99045659..0c9c5bcc 100644 --- a/xsl/sparql_to_html.xsl +++ b/xsl/sparql_to_html.xsl @@ -1,248 +1,186 @@ - - - - - - - - - - - - + + + + + + + fedora_repository_collection_thumbnail + + + + - - - - - + + + +
    - - - - -
    -
    + +

    + +
    +
    - - -
    - -
    - -
    - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - /fedora/repository//-/ - - - - /fedora/repository/ - - - - - - - - - - /fedora/repository//TN - - - -
    - - - - - - + + + + + + +
    - - - - - - - - - -   - - - - - - - - - - + + +   + + + + + + - - + + + + - - - + + - - - - - - - - - - - - - -
    + + + + + + + + + + + + + + + + +