@ -0,0 +1,400 @@
|
||||
<?php |
||||
|
||||
// $Id$ |
||||
|
||||
/* |
||||
* Created on 18-Feb-08 |
||||
* |
||||
* To change the template for this generated file go to |
||||
* Window - Preferences - PHPeclipse - PHP - Code Templates |
||||
*/ |
||||
// module_load_include('nc', 'CollectionClass', ''); |
||||
// 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 prevent mutiple hits to fedora. maybe a bit confusing though if this class is used in a different context. |
||||
class CollectionClass { |
||||
|
||||
public static $COLLECTION_CLASS_COLLECTION_POLICY_STREAM = 'COLLECTION_POLICY'; |
||||
public static $COLLECTION_CLASS_COLLECTION_VIEW_STREAM = 'COLLECTION_VIEW'; |
||||
private $contentModelStream = NULL; |
||||
private $collectionPolicyStream = NULL; |
||||
private $collectionViewStream = NULL; |
||||
public $collectionObject = NULL; |
||||
|
||||
/** |
||||
* Creates a collection object. Optionally can associate it with a single collection with parameter $pid. |
||||
* |
||||
* @param string $pid The pid of the collection to represent. |
||||
* @return CollectionClass |
||||
*/ |
||||
function CollectionClass($pid = NULL) { |
||||
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); |
||||
if (!empty($pid)) { |
||||
module_load_include('inc', 'fedora_repository', 'ObjectHelper'); |
||||
$this->collectionObject = new ObjectHelper($pid); |
||||
} |
||||
} |
||||
|
||||
/* gets objects related to this object. must include offset and limit |
||||
* calls getRelatedItems but enforces limit and offset |
||||
*/ |
||||
|
||||
function getRelatedObjects($pid, $limit, $offset, $itqlquery=NULL) { |
||||
module_load_include('inc', 'fedora_repository', 'ObjectHelper'); |
||||
$objectHelper = new ObjectHelper(); |
||||
if (!isset($itqlquery)) { |
||||
// $query_string = $objectHelper->getStream($pid, 'QUERY', 0); |
||||
$itqlquery = $objectHelper->getStream($pid, 'QUERY', 0); |
||||
} |
||||
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 |
||||
*/ |
||||
function getRelatedItems($pid, $itqlquery = NULL, $limit = NULL, $offset = NULL) { |
||||
module_load_include('inc', 'fedora_repository', 'ObjectHelper'); |
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); |
||||
if (!isset($limit)) { |
||||
$limit = 1000; |
||||
} |
||||
if (!isset($offset)) { |
||||
$offset = 0; |
||||
} |
||||
global $user; |
||||
if (!fedora_repository_access(OBJECTHELPER :: $OBJECT_HELPER_VIEW_FEDORA, $pid, $user)) { |
||||
drupal_set_message(t("You do not have access to Fedora objects within the attempted namespace or access to Fedora denied."), 'error'); |
||||
return ' '; |
||||
} |
||||
$objectHelper = new ObjectHelper(); |
||||
$query_string = $itqlquery; |
||||
if (!isset($query_string)) { |
||||
$query_string = $objectHelper->getStream($pid, 'QUERY', 0); |
||||
if ($query_string == NULL) { |
||||
$query_string = 'select $object $title $content from <#ri> |
||||
where ($object <dc:title> $title |
||||
and $object <fedora-model:hasModel> $content |
||||
and ($object <fedora-rels-ext:isMemberOfCollection> <info:fedora/' . $pid . '> |
||||
or $object <fedora-rels-ext:isMemberOf> <info:fedora/' . $pid . '>) |
||||
and $object <fedora-model:state> <info:fedora/fedora-system:def/model#Active>) |
||||
minus $content <mulgara:is> <info:fedora/fedora-system:FedoraObject-3.0> |
||||
order by $title'; |
||||
} |
||||
} |
||||
|
||||
$query_string = htmlentities(urlencode($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); |
||||
|
||||
return $content; |
||||
} |
||||
|
||||
function getCollectionPolicyStream($collection_pid) { |
||||
if ($this->collectionPolicyStream != NULL) { |
||||
return $this->collectionPolicyStream; |
||||
} |
||||
$this->collectionPolicyStream = $this->getStream($collection_pid, CollectionClass :: $COLLECTION_CLASS_COLLECTION_POLICY_STREAM, 0); |
||||
return $this->collectionPolicyStream; |
||||
} |
||||
|
||||
function getRelationshipElement($collection_pid) { |
||||
$stream = $this->getCollectionPolicyStream($collection_pid); |
||||
try { |
||||
$xml = new SimpleXMLElement($stream); |
||||
} catch (Exception $e) { |
||||
drupal_set_message(t('Error getting relationship element from policy stream !e', array('!e' => $e->getMessage())), 'error'); |
||||
return; |
||||
} |
||||
$relationship = $xml->relationship[0]; |
||||
return $relationship; |
||||
} |
||||
|
||||
function getCollectionViewStream($collection_pid) { |
||||
$this->collectionViewStream = $this->getStream($collection_pid, CollectionClass :: $COLLECTION_CLASS_COLLECTION_VIEW_STREAM, 0); |
||||
return $this->collectionViewStream; |
||||
} |
||||
|
||||
function getStream($pid, $dsid, $showError = 1) { |
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_item'); |
||||
$item = new fedora_item($pid); |
||||
return isset($item->datastreams[$dsid]) ? $item->get_datastream_dissemination($dsid) : NULL; |
||||
} |
||||
|
||||
function getPidNameSpace($pid, $dsid) { |
||||
$stream = $this->getCollectionPolicyStream($pid); |
||||
try { |
||||
$xml = new SimpleXMLElement($stream); |
||||
} catch (Exception $e) { |
||||
drupal_set_message(t('Error getting PID namespace !e', array('!e' => $e->getMessage())), 'error'); |
||||
return; |
||||
} |
||||
foreach ($xml->contentmodels->contentmodel as $contentModel) { |
||||
// $contentModelName=strip_tags($contentModel['name']); |
||||
$contentdsid = strip_tags($contentModel->dsid); |
||||
if (strtolower($contentdsid) == strtolower($dsid)) { |
||||
return strip_tags($contentModel->pid_namespace->asXML()); |
||||
} |
||||
} |
||||
drupal_set_message(t('Error getting PID namespace! using collection pid of !pid and content model of !dsid', array('!pid' => $pid, '!dsid' => $dsid)), 'error'); |
||||
return NULL; |
||||
} |
||||
|
||||
/** |
||||
* gets a list of content models from a collection policy |
||||
*/ |
||||
function getContentModels($collection_pid, $showError = TRUE) { |
||||
module_load_include('inc', 'Fedora_Repository', 'ContentModel'); |
||||
$collection_stream = $this->getCollectionPolicyStream($collection_pid); |
||||
try { |
||||
$xml = new SimpleXMLElement($collection_stream); |
||||
} catch (Exception $e) { |
||||
if ($showError) { |
||||
drupal_set_message(t("!e", array('!e' => $e->getMessage())), 'error'); |
||||
} |
||||
return NULL; |
||||
} |
||||
foreach ($xml->contentmodels->contentmodel as $content_model) { |
||||
$contentModel = new ContentModel(); |
||||
$contentModel->contentModelDsid = $content_model->dsid; |
||||
$contentModel->contentModelPid = $content_model->pid; |
||||
$contentModel->pidNamespace = $content_model->pidNamespace; |
||||
$contentModel->contentModelName = $content_model['name']; |
||||
$models[] = $contentModel; |
||||
} |
||||
return $models; |
||||
} |
||||
|
||||
/** |
||||
* using the collection policies pid namespace get a new pid by calling fedora' get next pid and appending it to the namespace |
||||
* $pid is the $pid of the content model |
||||
* $dsid is the datastream id of the content model. |
||||
*/ |
||||
function getNextPid($pid, $dsid) { |
||||
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'); |
||||
return Fedora_Item::get_next_pid_in_namespace($pname); |
||||
} |
||||
|
||||
/** |
||||
* gets the form handler file, class and method and returns them in an array |
||||
* |
||||
* @param string $pid The content model PID |
||||
* @param string $dsid The content model DSID |
||||
* @return array The file, class and method name to handle the ingest form. |
||||
*/ |
||||
function getFormHandler($pid, $dsid) { |
||||
$stream = $this->getContentModelStream($pid, $dsid); |
||||
try { |
||||
$xml = new SimpleXMLElement($stream); |
||||
} catch (Exception $e) { |
||||
drupal_set_message(t('Error Getting FormHandler: !e', array('!e' => $e->getMessage())), 'error'); |
||||
return NULL; |
||||
} |
||||
$formHandler = $xml->ingest_form; |
||||
if ($formHandler != NULL) { |
||||
$handlerDsid = strip_tags($formHandler['dsid']); |
||||
$handlerMethod = strip_tags($formHandler->form_builder_method->form_handler->asXML()); |
||||
$handlerFile = strip_tags($formHandler->form_builder_method->file->asXML()); |
||||
$handlerClass = strip_tags($formHandler->form_builder_method->class_name->asXML()); |
||||
$handlerModule = strip_tags($formHandler->form_builder_method->module->asXML()); |
||||
$returnArray = array(); |
||||
$returnArray['module'] = $handlerModule; |
||||
$returnArray['method'] = $handlerMethod; |
||||
$returnArray['class'] = $handlerClass; |
||||
$returnArray['file'] = $handlerFile; |
||||
return $returnArray; |
||||
} |
||||
|
||||
drupal_set_message(t("Error getting form handler. No handler found for !pid - !dsid", array('!pid' => $pid, '!dsid' => $dsid)), 'error'); |
||||
return NULL; |
||||
} |
||||
|
||||
function getAllowedMimeTypes($contentModelPid, $contentModel_dsid) { |
||||
$stream = $this->getContentModelStream($contentModelPid, $contentModel_dsid); |
||||
try { |
||||
$xml = new SimpleXMLElement($stream); |
||||
} catch (Exception $e) { |
||||
drupal_set_message(t('Error getting content model stream for mime types !e', array('!e' => $e->getMessage())), 'error'); |
||||
return; |
||||
} |
||||
foreach ($xml->mimetypes->type as $type) { |
||||
$types[] = $type; |
||||
} |
||||
return $types; |
||||
} |
||||
|
||||
/** |
||||
* Grabs the rules from the content model stream |
||||
* file the file that has been uploaded |
||||
*/ |
||||
function getAndDoRules($file, $mimetype, $pid, $dsid) { |
||||
if (!user_access('ingest new fedora objects')) { |
||||
drupal_set_message(t('You do not have permission to ingest objects.')); |
||||
return FALSE; |
||||
} |
||||
|
||||
$stream = $this->getContentModelStream($pid, $dsid); |
||||
|
||||
try { |
||||
$xml = new SimpleXMLElement($stream); |
||||
} catch (Exception $e) { |
||||
drupal_set_message(t('Error getting content model stream !e', array('!e' => $e->getMessage())), 'error'); |
||||
return FALSE; |
||||
} |
||||
foreach ($xml->ingest_rules->rule as $rule) { |
||||
foreach ($rule->applies_to as $type) { |
||||
if (!strcmp(trim($type), trim($mimetype))) { |
||||
$methods = $rule->methods->method; |
||||
return $this->callMethods($file, $methods); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* calls the methods defined in the content model rules .xml file stored in a Fedora object |
||||
*/ |
||||
function callMethods($file, $methods) { |
||||
foreach ($methods as $method) { |
||||
$phpFile = strip_tags($method->file->asXML()); |
||||
$phpClass = strip_tags($method->class_name->asXML()); |
||||
$phpMethod = strip_tags($method->method_name->asXML()); |
||||
$file_ext = strip_tags($method->modified_files_ext->asXML()); |
||||
$parameters = $method->parameters->parameter; |
||||
$dsid = strip_tags($method->datastream_id); |
||||
$parametersArray = array(); |
||||
if (isset($parameters)) { |
||||
foreach ($parameters as $parameter) { |
||||
$name = strip_tags($parameter['name']); |
||||
$value = strip_tags($parameter->asXML()); |
||||
$parametersArray["$name"] = $value; |
||||
} |
||||
} |
||||
// 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); |
||||
if (!$returnValue) { |
||||
drupal_set_message('Error! Failed running content model method !m !rv', array('!m' => $phpMethod, '!rv' => $returnValue)); |
||||
return FALSE; |
||||
} |
||||
} |
||||
return TRUE; |
||||
} |
||||
|
||||
/** |
||||
* grabs a xml form definition from a content model and builds |
||||
* the form using drupals forms api |
||||
*/ |
||||
function build_ingest_form(&$form, &$form_state, $contentModelPid, $contentModelDsid) { |
||||
$stream = $this->getContentModelStream($contentModelPid, $contentModelDsid); |
||||
try { |
||||
$xml = new SimpleXMLElement($stream); |
||||
} catch (Exception $e) { |
||||
drupal_set_message(t('Error getting ingest form stream !e', array('!e' => $e->getMessage())), 'error'); |
||||
return FALSE; |
||||
} |
||||
$docRoot = $_SERVER['DOCUMENT_ROOT']; |
||||
|
||||
$file = (isset($form_state['values']['ingest-file-location']) ? $form_state['values']['ingest-file-location'] : ''); |
||||
// $fullPath = $docRoot . '' . $file; |
||||
$fullpath = $file; |
||||
// $form = array(); |
||||
$form['step'] = array( |
||||
'#type' => 'hidden', |
||||
'#value' => (isset($form_state['values']['step']) ? $form_state['values']['step'] : 0) + 1, |
||||
); |
||||
$form['ingest-file-location'] = array( |
||||
'#type' => 'hidden', |
||||
'#value' => $file, |
||||
); |
||||
|
||||
$form['content_model_name'] = array( |
||||
'#type' => 'hidden', |
||||
'#value' => $contentModelDsid |
||||
); |
||||
$form['models'] = array(//content models available |
||||
'#type' => 'hidden', |
||||
'#value' => $form_state['values']['models'], |
||||
); |
||||
$form['fullpath'] = array( |
||||
'#type' => 'hidden', |
||||
'#value' => $fullpath, |
||||
); |
||||
|
||||
$form['#attributes']['enctype'] = 'multipart/form-data'; |
||||
$form['indicator']['ingest-file-location'] = array( |
||||
'#type' => 'file', |
||||
'#title' => t('Upload Document'), |
||||
'#size' => 48, |
||||
'#description' => t('Full text'), |
||||
); |
||||
if ($xml->ingest_form->hide_file_chooser == 'TRUE') { |
||||
$form['indicator']['ingest-file-location']['#type'] = 'hidden'; |
||||
} |
||||
$ingest_form = $xml->ingest_form; //should only be one |
||||
$drupal_module = strip_tags($ingest_form->form_builder_method->module->asXML()); |
||||
if (empty($drupal_module)) { |
||||
$drupal_module = 'fedora_repository'; |
||||
} |
||||
$phpFile = strip_tags($ingest_form->form_builder_method->file->asXML()); |
||||
$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); |
||||
require_once(drupal_get_path('module', $drupal_module) . '/' . $phpFile); |
||||
$thisClass = new $phpClass (); |
||||
|
||||
return $thisClass->$phpMethod($form, $ingest_form, $form_state['values'], $form_state); |
||||
} |
||||
|
||||
//this will also create a personal collection for an existing user if they don't have one |
||||
//not using this function currently |
||||
function createUserCollection(& $user) { |
||||
if (isset($user->fedora_personal_pid)) { |
||||
return; |
||||
} |
||||
$username = array( |
||||
'name' => variable_get('fedora_admin_user', 'fedoraAdmin') |
||||
); |
||||
$admin_user = user_load($username); |
||||
module_load_include('inc', 'fedora_repository', 'ConnectionHelper'); |
||||
$connectionHelper = new ConnectionHelper(); |
||||
try { |
||||
$soapClient = $connectionHelper->getSoapClient(variable_get('fedora_soap_manage_url', 'http://localhost:8080/fedora/services/management?wsdl')); |
||||
$pidNameSpace = variable_get('fedora_repository_pid', 'vre:'); |
||||
$pidNameSpace = substr($pidNameSpace, 0, strpos($pidNameSpace, ":")); |
||||
$params = array( |
||||
'numPIDs' => '', |
||||
'pidNamespace' => $pidNameSpace |
||||
); |
||||
$object = $soapClient->__soapCall('getNextPID', array( |
||||
$params |
||||
)); |
||||
} catch (exception $e) { |
||||
drupal_set_message(t('Error getting Next PID: !e', array('!e' => $e->getMessage())), 'error'); |
||||
return FALSE; |
||||
} |
||||
$pid = implode(get_object_vars($object)); |
||||
$pidNumber = strstr($pid, ":"); |
||||
$pid = $pidNameSpace . ':' . 'USER-' . $user->name . '-' . substr($pidNumber, 1); |
||||
$personal_collection_pid = array( |
||||
'fedora_personal_pid' => $pid |
||||
); |
||||
module_load_include('inc', 'fedora_repository', 'plugins/PersonalCollectionClass'); |
||||
$personalCollectionClass = new PersonalCollectionClass(); |
||||
if (!$personalCollectionClass->createCollection($user, $pid, $soapClient)) { |
||||
drupal_set_message("Did not create a personal collection object for !u", array('!u' => $user->name)); |
||||
return FALSE; //creation failed don't save the collection pid in drupal db |
||||
} |
||||
user_save($user, $personal_collection_pid); |
||||
return TRUE; |
||||
} |
||||
|
||||
} |
||||
|
@ -0,0 +1,602 @@
|
||||
<?php |
||||
|
||||
// $Id$ |
||||
|
||||
module_load_include('inc', 'fedora_repository', 'XMLDatastream'); |
||||
|
||||
class CollectionPolicy extends XMLDatastream { |
||||
|
||||
static $SCHEMA_URI = 'http://syn.lib.umanitoba.ca/collection_policy.xsd'; |
||||
static $DEFAULT_DSID = 'COLLECTION_POLICY'; |
||||
|
||||
private $staging_area=NULL; |
||||
|
||||
/** |
||||
* Gets the default DSID to use for ContentModel datastreams. |
||||
* |
||||
* @return string $default_dsid |
||||
*/ |
||||
static function getDefaultDSID() { |
||||
return variable_get('Islandora_Collection_Policy_DSID', CollectionPolicy::$DEFAULT_DSID); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a new CollectionPolicy object from the specified |
||||
* collection PID. If preFetch is disabled, then Islandora will not get the datastream until needed. |
||||
* (useful when cacheing) |
||||
* Returns FALSE on failure. |
||||
* |
||||
* @param string $pid |
||||
* @param boolean $preFetch = TRUE |
||||
* @return CollectionPolicy $ret |
||||
*/ |
||||
static function loadFromCollection($pid, $preFetch=TRUE) { |
||||
$ret = FALSE; |
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_item'); |
||||
|
||||
try { |
||||
if (self::validPid($pid)) { |
||||
$dsid=CollectionPolicy::getDefaultDSID(); |
||||
|
||||
if ($preFetch) { |
||||
$fedoraItem = new Fedora_Item($pid); |
||||
$ds = $fedoraItem->get_datastream_dissemination($dsid); |
||||
} else { |
||||
$ds=null; |
||||
} |
||||
|
||||
} |
||||
|
||||
if (!empty($ds) || !$preFetch) { |
||||
$ret=new CollectionPolicy($ds, $pid, $dsid); |
||||
} |
||||
} |
||||
catch (SOAPException $e) { |
||||
|
||||
$ret = FALSE; |
||||
} |
||||
return $ret; |
||||
} |
||||
|
||||
/** |
||||
* Ingests a new Collection Policy datastream to the specified |
||||
* PID with the DSID specified. The file should be a valid collection |
||||
* policy XML. Returns false on failure. |
||||
* |
||||
* @param string $pid |
||||
* @param string $name |
||||
* @param string $cpDsid |
||||
* @param string $file |
||||
* @return CollectionPolicy $ret |
||||
*/ |
||||
public static function ingestFromFile($pid, $name, $cpDsid, $file) { |
||||
$ret = FALSE; |
||||
|
||||
if (($cp = self::loadFromCollection($pid, $cpDsid)) === FALSE && file_exists($file)) { |
||||
$cp = new ContentModel(file_get_contents($file), $pid, $cpDsid); |
||||
$rootEl = $cp->xml->getElementsByTagName('collection_policy')->item(0); |
||||
$rootEl->setAttribute('name', $name); |
||||
|
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_item'); |
||||
$fedoraItem = new Fedora_Item($pid); |
||||
$fedoraItem->add_datastream_from_string($cp->dumpXml(), $cpDsid, $name, 'text/xml', 'X'); |
||||
$ret = $cp; |
||||
} |
||||
|
||||
return $ret; |
||||
} |
||||
|
||||
/** |
||||
* Ingests a new Collection Policy datastream to the specified |
||||
* PID with the DSID specified. Clones the collection policy from the |
||||
* source collection pid. Returns false on failure. |
||||
* |
||||
* @param string $pid |
||||
* @param string $name |
||||
* @param string $cpDsid |
||||
* @param string $copy_collection_pid |
||||
* @return CollectionPolicy $ret |
||||
*/ |
||||
public static function ingestFromCollection($pid, $name, $cpDsid, $copy_collection_pid) { |
||||
$ret = FALSE; |
||||
|
||||
if (($cp = self::loadFromCollection($pid, $cpDsid)) === FALSE && ($copy_cp = self::loadFromCollection($copy_collection_pid)) !== FALSE && $copy_cp->validate()) { |
||||
$newDom = $copy_cp->xml; |
||||
$rootEl = $newDom->getElementsByTagName('collection_policy')->item(0); |
||||
$rootEl->setAttribute('name', $name); |
||||
|
||||
$cp = new CollectionPolicy($newDom, $pid, $cpDsid); |
||||
|
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_item'); |
||||
$fedoraItem = new Fedora_Item($pid); |
||||
$fedoraItem->add_datastream_from_string($cp->dumpXml(), $cpDsid, $name, 'text/xml', 'X'); |
||||
$ret = $cp; |
||||
} |
||||
|
||||
return $ret; |
||||
} |
||||
|
||||
/** |
||||
* Ingests a new minimum Collection Policy datastream to the specified |
||||
* PID with the DSID specified. Initializes the policy with the specified values. |
||||
* Returns false on failure |
||||
* |
||||
* @param string $pid |
||||
* @param string $name |
||||
* @param string $cpDsid |
||||
* @param string $model_pid |
||||
* @param string $model_namespace |
||||
* @param string $relationshiop |
||||
* @param string $searchField |
||||
* @param string $searchValue |
||||
* @return CollectionPolicy $ret |
||||
*/ |
||||
public static function ingestBlankPolicy($pid, $name, $policyDsid, $model_pid, $model_namespace, $relationship, $searchField, $searchValue) { |
||||
$ret = FALSE; |
||||
if (($cp = self::loadFromCollection($pid, $modelDsid)) === FALSE) { |
||||
module_load_include('inc', 'fedora_repository', 'ContentModel'); |
||||
if (($cm = ContentModel::loadFromModel($model_pid)) !== FALSE && $cm->validate()) { |
||||
$newDom = new DOMDocument('1.0', 'utf-8'); |
||||
$newDom->formatOutput = TRUE; |
||||
$rootEl = $newDom->createElement('collection_policy'); |
||||
$rootEl->setAttribute('name', $name); |
||||
$rootEl->setAttribute('xmlns', self::$XMLNS); |
||||
$rootEl->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); |
||||
$rootEl->setAttribute('xsi:schemaLocation', self::$XMLNS .' '. self::$SCHEMA_URI); |
||||
|
||||
$modelsEl = $newDom->createElement('content_models'); |
||||
|
||||
$cmEl = $newDom->createElement('content_model'); |
||||
$cmEl->setAttribute('name', $cm->getName()); |
||||
$cmEl->setAttribute('dsid', $cm->dsid); |
||||
$cmEl->setAttribute('namespace', $model_namespace); |
||||
$cmEl->setAttribute('pid', $cm->pid); |
||||
|
||||
$modelsEl->appendChild($cmEl); |
||||
$rootEl->appendChild($modelsEl); |
||||
|
||||
$relEl = $newDom->createElement('relationship', $relationship); |
||||
$rootEl->appendChild($relEl); |
||||
|
||||
$searchTermsEl = $newDom->createElement('search_terms'); |
||||
$newTermEl = $newDom->createElement('term', $searchValue); |
||||
$newTermEl->setAttribute('field', $searchField); |
||||
$searchTermsEl->appendChild($newTermEl); |
||||
$rootEl->appendChild($searchTermsEl); |
||||
|
||||
$newDom->appendChild($rootEl); |
||||
|
||||
$cp = new CollectionPolicy($newDom, $pid, $policyDsid); |
||||
|
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_item'); |
||||
|
||||
|
||||
$fedoraItem = new Fedora_Item($pid); |
||||
$fedoraItem->add_datastream_from_string($cp->dumpXml(), $policyDsid, $name, 'text/xml', 'X'); |
||||
$ret = $cp; |
||||
} |
||||
|
||||
} |
||||
|
||||
return $ret; |
||||
} |
||||
|
||||
/** |
||||
* Attempts to convert from the old XML schema to the new by |
||||
* traversing the XML DOM and building a new DOM. When done |
||||
* $this->xml is replaced by the newly created DOM.. |
||||
* |
||||
* @return void |
||||
*/ |
||||
protected function convertFromOldSchema() { |
||||
if ($this->xml == NULL) { |
||||
$this->fetchXml(); |
||||
} |
||||
$sXml = simplexml_load_string($this->xml->saveXML()); |
||||
$newDom = new DOMDocument('1.0', 'utf-8'); |
||||
$newDom->formatOutput = TRUE; |
||||
|
||||
$rootEl = $newDom->createElement('collection_policy'); |
||||
$rootEl->setAttribute('name', $sXml['name']); |
||||
$rootEl->setAttribute('xmlns', self::$XMLNS); |
||||
$rootEl->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); |
||||
$rootEl->setAttribute('xsi:schemaLocation', self::$XMLNS .' '. self::$SCHEMA_URI); |
||||
|
||||
$content_modelsEl = $newDom->createElement('content_models'); |
||||
foreach ($sXml->contentmodels->contentmodel as $contentmodel) { |
||||
$content_modelEl = $newDom->createElement('content_model'); |
||||
$content_modelEl->setAttribute('name', $contentmodel['name']); |
||||
$content_modelEl->setAttribute('dsid', $contentmodel->dsid); |
||||
$content_modelEl->setAttribute('namespace', $contentmodel->pid_namespace); |
||||
$content_modelEl->setAttribute('pid', $contentmodel->pid); |
||||
$content_modelsEl->appendChild($content_modelEl); |
||||
} |
||||
$rootEl->appendChild($content_modelsEl); |
||||
|
||||
$search_termsEl = $newDom->createElement('search_terms'); |
||||
foreach ($sXml->search_terms->term as $term) { |
||||
$termEl = $newDom->createElement('term', $term->value); |
||||
$termEl->setAttribute('field', $term->field); |
||||
if (strval($sXml->search_terms->default) == $term->field) { |
||||
$termEl->setAttribute('default', 'true'); |
||||
} |
||||
$search_termsEl->appendChild($termEl); |
||||
} |
||||
$rootEl->appendChild($search_termsEl); |
||||
|
||||
$relationshipEl = $newDom->createElement('relationship', $sXml->relationship); |
||||
$rootEl->appendChild($relationshipEl); |
||||
|
||||
$newDom->appendChild($rootEl); |
||||
|
||||
$this->xml = DOMDocument::loadXML($newDom->saveXml()); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Gets the name of the relationship to use |
||||
* for members of this collection. |
||||
* Returns FALSE on failure. |
||||
* |
||||
* @return string $relationship |
||||
*/ |
||||
public function getRelationship() { |
||||
$ret=FALSE; |
||||
if ($this->validate()) { |
||||
$ret=trim($this->xml->getElementsByTagName('relationship')->item(0)->nodeValue); |
||||
} |
||||
return $ret; |
||||
} |
||||
|
||||
/** |
||||
* Sets the name of the relationship to use |
||||
* for members of this collection. |
||||
* Returns FALSE on failure. |
||||
* |
||||
* @param string $relationship |
||||
* @return boolean $ret |
||||
*/ |
||||
public function setRelationship($relationship) { |
||||
$ret=FALSE; |
||||
if ($this->validate()) { |
||||
$relationshipEl=$this->xml->getElementsByTagName('relationship')->item(0); |
||||
$relationshipEl->nodeValue=trim($relationship); |
||||
$ret = TRUE; |
||||
} |
||||
return $ret; |
||||
} |
||||
|
||||
/** |
||||
* Gets the path to the staging area to use for this |
||||
* collection. By default recurses to the parent collection |
||||
* if the staging area is undefined |
||||
* |
||||
* @param BOOLEAN $recurse |
||||
* @return string $path |
||||
*/ |
||||
public function getStagingArea($recurse=TRUE) { |
||||
$ret=FALSE; |
||||
if ($this->validate()) { |
||||
if ($this->staging_area === NULL) { |
||||
$stagingEl=$this->xml->getElementsByTagName('staging_area'); |
||||
|
||||
if ($stagingEl->length > 0) { |
||||
$this->staging_area = trim($stagingEl->item(0)->nodeValue); |
||||
} elseif ($recurse) { |
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_item'); |
||||
$item=new Fedora_Item($this->pid); |
||||
$rels=$item->get_relationships(); |
||||
if (count($rels) > 0) { |
||||
foreach ($rels as $rel) { |
||||
$cp = CollectionPolicy::loadFromCollection($rel['object']); |
||||
if ($cp !== FALSE) { |
||||
$this->staging_area = $cp->getStagingArea(); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
$ret = $this->staging_area; |
||||
|
||||
} |
||||
return $ret; |
||||
} |
||||
|
||||
/** |
||||
* Sets the path to the staging area to use for this |
||||
* collection. If specified path is blank (or false) it will |
||||
* remove the staging are path element from the collection policy. |
||||
* |
||||
* @param string $path |
||||
* |
||||
* @return string $relationship |
||||
*/ |
||||
public function setStagingArea($path) { |
||||
$ret=FALSE; |
||||
if ($this->validate()) { |
||||
$rootEl=$this->xml->getElementsByTagName('collection_policy')->item(0); |
||||
$stagingEl=$this->xml->getElementsByTagName('staging_area'); |
||||
if ($stagingEl->length > 0) { |
||||
$stagingEl=$stagingEl->item(0); |
||||
if (trim($path) == '') { |
||||
$rootEl->removeChild($stagingEl); |
||||
} |
||||
else { |
||||
$stagingEl->nodeValue=trim($path); |
||||
} |
||||
} |
||||
elseif (trim($path) != '') { |
||||
$stagingEl=$this->xml->createElement('staging_area', trim($path)); |
||||
$rootEl->appendChild($stagingEl); |
||||
} |
||||
|
||||
$ret = TRUE; |
||||
} |
||||
return $ret; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Gets the next available PID for the |
||||
* content model specified by the DSID |
||||
* parameter. |
||||
* |
||||
* @param string $dsid |
||||
* @return string $nextPid |
||||
*/ |
||||
public function getNextPid($dsid) { |
||||
$ret = FALSE; |
||||
if (self::validDsid($dsid) && $this->validate()) { |
||||
$content_models = $this->xml->getElementsByTagName('content_models')->item(0)->getElementsByTagName('content_model'); |
||||
$namespace = FALSE; |
||||
for ($i=0; $namespace === FALSE && $i<$content_models->length;$i++) { |
||||
if (strtolower($content_models->item($i)->getAttribute('dsid')) == strtolower($dsid)) { |
||||
$namespace = $content_models->item($i)->getAttribute('namespace'); |
||||
} |
||||
} |
||||
|
||||
$pname = substr($namespace, 0, strpos($namespace, ":")); |
||||
|
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_item'); |
||||
$ret = Fedora_Item::get_next_pid_in_namespace($pname); |
||||
} |
||||
return $ret; |
||||
} |
||||
|
||||
/** |
||||
* Gets a list of ContentModel objects supported by this collection. |
||||
* |
||||
* @return ContentModel[] $models |
||||
*/ |
||||
function getContentModels() { |
||||
$ret=FALSE; |
||||
if ($this->validate()) { |
||||
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++) { |
||||
$cm=ContentModel::loadFromModel($content_models->item($i)->getAttribute('pid'), |
||||
$content_models->item($i)->getAttribute('dsid'), |
||||
$content_models->item($i)->getAttribute('namespace'), |
||||
$content_models->item($i)->getAttribute('name')); |
||||
if ($cm !== FALSE) { |
||||
$ret[]=$cm; |
||||
} |
||||
|
||||
} |
||||
} |
||||
return $ret; |
||||
} |
||||
|
||||
|
||||
|
||||
/** |
||||
* Gets a list of search terms from the Collection Policy. If asArray is set |
||||
* it will return an associative array with the value, field name, and the default value. |
||||
* If not set, an array of just the values will be returned. If $recurse is TRUE, it will |
||||
* recurseively return the parents search terms if it has none until it returns a set of terms or reaches |
||||
* the top level collection. If $cache is TRUE, it will return a cached version (if available). |
||||
* |
||||
* @param boolean $asArray |
||||
* @param boolean $recurse |
||||
* @param boolean $cache |
||||
* @return string[] $ret |
||||
*/ |
||||
function getSearchTerms($asArray = FALSE, $recurse = FALSE, $cache = FALSE) { |
||||
$ret = FALSE; |
||||
|
||||
if ($cache == TRUE && ($cache = cache_get('collection_policy_search_terms-'.$this->pid)) !== 0 ) { |
||||
$ret=$cache->data; |
||||
} else { |
||||
|
||||
if ($this->xml == NULL) { |
||||
$fedoraItem = new Fedora_Item($this->pid); |
||||
$ds = $fedoraItem->get_datastream_dissemination($this->dsid); |
||||
$this->xml = DOMDocument::loadXML($ds); |
||||
} |
||||
|
||||
|
||||
if ($this->validate()) { |
||||
$ret=array(); |
||||
$terms= $this->xml->getElementsByTagName('search_terms')->item(0)->getElementsByTagName('term'); |
||||
for ($i=0;$i<$terms->length;$i++) { |
||||
$default = $terms->item($i)->attributes->getNamedItem('default'); |
||||
$default = ($default !== NULL) ? (strtolower($default->nodeValue) == 'true') : FALSE; |
||||
$ret[] = ($asArray)?array( 'value' => $terms->item($i)->nodeValue, |
||||
'field' => $terms->item($i)->getAttribute('field'), |
||||
'default' => $default): $terms->item($i)->nodeValue; |
||||
} |
||||
|
||||
|
||||
if ($recurse && count($ret) == 0) { |
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_item'); |
||||
$item=new Fedora_Item($this->pid); |
||||
$rels=$item->get_relationships(); |
||||
if (count($rels) > 0) { |
||||
foreach ($rels as $rel) { |
||||
$cp = CollectionPolicy::loadFromCollection($rel['object']); |
||||
if ($cp !== FALSE) { |
||||
$ret = $cp->getSearchTerms($asArray, $recurse); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
cache_set('collection_policy_search_terms-'.$this->pid, $ret, 'cache', time()+3600); |
||||
|
||||
} |
||||
} |
||||
return $ret; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Adds a search term to the collection policy. |
||||
* Returns fase on failure. |
||||
* |
||||
* @param string $field |
||||
* @param string $value |
||||
* @return boolean $success |
||||
*/ |
||||
function addTerm($field, $value) { |
||||
$ret=FALSE; |
||||
if ($this->validate()) { |
||||
$search_termsEl = $this->xml->getElementsByTagName('search_terms')->item(0); |
||||
$terms= $search_termsEl->getElementsByTagName('term'); |
||||
$found=FALSE; |
||||
for ($i=0;!$found && $i<$terms->length;$i++) { |
||||
if ($terms->item($i)->getAttribute('field') == $field) { |
||||
$found = TRUE; |
||||
} |
||||
} |
||||
|
||||
if (!$found) { |
||||
$newTermEl = $this->xml->createElement('term', $value); |
||||
$newTermEl->setAttribute('field', $field); |
||||
$search_termsEl->appendChild($newTermEl); |
||||
$ret = TRUE; |
||||
} |
||||
} |
||||
return $ret; |
||||
} |
||||
|
||||
/** |
||||
* Removes the search term specified by the field parameter from the collection policy. |
||||
* |
||||
* @param string $field |
||||
* @return boolean $success |
||||
*/ |
||||
function removeTerm($field) { |
||||
$ret=FALSE; |
||||
if ($this->validate()) { |
||||
$search_termsEl = $this->xml->getElementsByTagName('search_terms')->item(0); |
||||
$terms = $search_termsEl->getElementsByTagName('term'); |
||||
$found = FALSE; |
||||
for ($i=0; !$found && $i < $terms->length; $i++) { |
||||
if ($terms->item($i)->getAttribute('field') == $field) { |
||||
$found = $terms->item($i); |
||||
} |
||||
} |
||||
|
||||
if ($found !== FALSE) { |
||||
$search_termsEl->removeChild($found); |
||||
$ret = TRUE; |
||||
} |
||||
} |
||||
return $ret; |
||||
} |
||||
|
||||
|
||||
function setDefaultTerm($field) { |
||||
$ret = FALSE; |
||||
if ($this->validate()) { |
||||
$search_termsEl = $this->xml->getElementsByTagName('search_terms')->item(0); |
||||
$terms= $search_termsEl->getElementsByTagName('term'); |
||||
$found=FALSE; |
||||
for ($i=0;!$found && $i<$terms->length;$i++) { |
||||
if ($terms->item($i)->getAttribute('field') == $field) { |
||||
$found = $terms->item($i); |
||||
} |
||||
} |
||||
|
||||
if ($found !== FALSE) { |
||||
for ($i=0;$i<$terms->length;$i++) |
||||
if ($terms->item($i)->attributes->getNamedItem('default') !== NULL) { |
||||
$terms->item($i)->removeAttribute('default'); |
||||
} |
||||
$found->setAttribute('default', 'true'); |
||||
$ret = TRUE; |
||||
} |
||||
} |
||||
return $ret; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Removes the specified content model from the collection policy. This will only |
||||
* prevent future ingests of the removed model to the collection. $cm should be |
||||
* a valid ContentModel object. Returns false on failure or when the CM was not found in |
||||
* the collection policy. |
||||
* |
||||
* @param ContentModel $cm |
||||
* @return boolean $valid |
||||
*/ |
||||
function removeModel($cm) { |
||||
$ret=FALSE; |
||||
if ($this->validate() && $cm->validate()) { |
||||
$contentmodelsEl = $this->xml->getElementsByTagName('content_models'); |
||||
$models = $contentmodelsEl->item(0)->getElementsByTagName('content_model'); |
||||
$found = FALSE; |
||||
for ($i=0; $found === FALSE && $i < $models->length; $i++) { |
||||
if ($models->item($i)->getAttribute('pid') == $cm->pid) { |
||||
$found=$models->item($i); |
||||
} |
||||
} |
||||
|
||||
if ($found !== FALSE && $models->length > 1) { |
||||
$contentmodelsEl->item(0)->removeChild($found); |
||||
$ret = TRUE; |
||||
} |
||||
} |
||||
return $ret; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
function addModel($cm, $namespace) { |
||||
$ret = FALSE; |
||||
if (self::validPid($namespace) && $this->validate() && $cm->validate()) { |
||||
$contentmodelsEl = $this->xml->getElementsByTagName('content_models'); |
||||
$models = $contentmodelsEl->item(0)->getElementsByTagName('content_model'); |
||||
$found = FALSE; |
||||
for ($i=0;!$found && $i<$models->length;$i++) { |
||||
if ($models->item($i)->getAttribute('pid') == $cm->pid) |
||||
$found = TRUE; |
||||
} |
||||
|
||||
if (!$found) { |
||||
$cmEl = $this->xml->createElement('content_model'); |
||||
$cmEl->setAttribute('name', $cm->getName()); |
||||
$cmEl->setAttribute('dsid', $cm->dsid); |
||||
$cmEl->setAttribute('namespace', $namespace); |
||||
$cmEl->setAttribute('pid', $cm->pid); |
||||
$contentmodelsEl->item(0)->appendChild($cmEl); |
||||
} |
||||
|
||||
$ret = !$found; |
||||
} |
||||
return $ret; |
||||
} |
||||
|
||||
function getName() { |
||||
$ret=FALSE; |
||||
if ($this->validate()) { |
||||
$ret=$this->xml->getElementsByTagName('collection_policy')->item(0)->getAttribute('name'); |
||||
} |
||||
return $ret; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,79 @@
|
||||
<?php |
||||
// $Id$ |
||||
|
||||
/* |
||||
* Created on Jan 24, 2008 |
||||
* |
||||
* To change the template for this generated file go to |
||||
* Window - Preferences - PHPeclipse - PHP - Code Templates |
||||
*/ |
||||
|
||||
module_load_include('inc', 'ConnectionHelper', ''); |
||||
class ConnectionHelper { |
||||
function ConnectionHelper() { |
||||
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); |
||||
} |
||||
|
||||
function _fixURL($url, $_name, $_pass) { |
||||
if ($url == NULL) { |
||||
$url=variable_get('fedora_soap_url', 'http://localhost:8080/fedora/services/access?wsdl'); |
||||
} |
||||
|
||||
if ($_name == '' || $_pass == '') { |
||||
drupal_set_message(t('No credentials provided.')); |
||||
return NULL; |
||||
} |
||||
|
||||
$creds = urlencode($_name) . ':'. urlencode($_pass); |
||||
|
||||
if (strpos($url, 'http://') == 0) { |
||||
$new_url = 'http://'. $creds . '@'. substr($url, 7); |
||||
} |
||||
elseif (strpos($url, 'https://') == 0) { |
||||
$new_url = 'https://'. $creds . '@'. substr($url, 8); |
||||
} |
||||
else { |
||||
drupal_set_message(t('Invalid URL: !url', array('!url' => $url))); |
||||
return NULL; |
||||
} |
||||
|
||||
return $new_url; |
||||
} |
||||
|
||||
function getSoapClient($url = NULL) { |
||||
if ($url == NULL) { |
||||
$url=variable_get('fedora_soap_url', 'http://localhost:8080/fedora/services/access?wsdl'); |
||||
} |
||||
global $user; |
||||
if ($user->uid == 0) { |
||||
//anonymous user. We will need an entry in the fedora users.xml file |
||||
//with the appropriate entry for a username of anonymous password of anonymous |
||||
try { |
||||
$client = new SoapClient($this->_fixURL($url, 'anonymous', 'anonymous'), array( |
||||
'login' => 'anonymous', |
||||
'password' => 'anonymous', |
||||
'exceptions' => TRUE, |
||||
)); |
||||
} |
||||
catch (SoapFault $e) { |
||||
drupal_set_message(t("!e", array('!e' => $e->getMessage()))); |
||||
return NULL; |
||||
} |
||||
} |
||||
else { |
||||
try { |
||||
$client = new SoapClient($this->_fixURL($url, $user->name, $user->pass), array( |
||||
'login' => $user->name, |
||||
'password' => $user->pass, |
||||
'exceptions' => TRUE, |
||||
)); |
||||
} |
||||
catch (SoapFault $e) { |
||||
drupal_set_message(t("!e", array('!e' => $e->getMessage()))); |
||||
return NULL; |
||||
} |
||||
} |
||||
return $client; |
||||
} |
||||
} |
||||
|
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE |
||||
Version 3, 29 June 2007 |
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> |
||||
Everyone is permitted to copy and distribute verbatim copies |
||||
of this license document, but changing it is not allowed. |
||||
|
||||
Preamble |
||||
|
||||
The GNU General Public License is a free, copyleft license for |
||||
software and other kinds of works. |
||||
|
||||
The licenses for most software and other practical works are designed |
||||
to take away your freedom to share and change the works. By contrast, |
||||
the GNU General Public License is intended to guarantee your freedom to |
||||
share and change all versions of a program--to make sure it remains free |
||||
software for all its users. We, the Free Software Foundation, use the |
||||
GNU General Public License for most of our software; it applies also to |
||||
any other work released this way by its authors. You can apply it to |
||||
your programs, too. |
||||
|
||||
When we speak of free software, we are referring to freedom, not |
||||
price. Our General Public Licenses are designed to make sure that you |
||||
have the freedom to distribute copies of free software (and charge for |
||||
them if you wish), that you receive source code or can get it if you |
||||
want it, that you can change the software or use pieces of it in new |
||||
free programs, and that you know you can do these things. |
||||
|
||||
To protect your rights, we need to prevent others from denying you |
||||
these rights or asking you to surrender the rights. Therefore, you have |
||||
certain responsibilities if you distribute copies of the software, or if |
||||
you modify it: responsibilities to respect the freedom of others. |
||||
|
||||
For example, if you distribute copies of such a program, whether |
||||
gratis or for a fee, you must pass on to the recipients the same |
||||
freedoms that you received. You must make sure that they, too, receive |
||||
or can get the source code. And you must show them these terms so they |
||||
know their rights. |
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps: |
||||
(1) assert copyright on the software, and (2) offer you this License |
||||
giving you legal permission to copy, distribute and/or modify it. |
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains |
||||
that there is no warranty for this free software. For both users' and |
||||
authors' sake, the GPL requires that modified versions be marked as |
||||
changed, so that their problems will not be attributed erroneously to |
||||
authors of previous versions. |
||||
|
||||
Some devices are designed to deny users access to install or run |
||||
modified versions of the software inside them, although the manufacturer |
||||
can do so. This is fundamentally incompatible with the aim of |
||||
protecting users' freedom to change the software. The systematic |
||||
pattern of such abuse occurs in the area of products for individuals to |
||||
use, which is precisely where it is most unacceptable. Therefore, we |
||||
have designed this version of the GPL to prohibit the practice for those |
||||
products. If such problems arise substantially in other domains, we |
||||
stand ready to extend this provision to those domains in future versions |
||||
of the GPL, as needed to protect the freedom of users. |
||||
|
||||
Finally, every program is threatened constantly by software patents. |
||||
States should not allow patents to restrict development and use of |
||||
software on general-purpose computers, but in those that do, we wish to |
||||
avoid the special danger that patents applied to a free program could |
||||
make it effectively proprietary. To prevent this, the GPL assures that |
||||
patents cannot be used to render the program non-free. |
||||
|
||||
The precise terms and conditions for copying, distribution and |
||||
modification follow. |
||||
|
||||
TERMS AND CONDITIONS |
||||
|
||||
0. Definitions. |
||||
|
||||
"This License" refers to version 3 of the GNU General Public License. |
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of |
||||
works, such as semiconductor masks. |
||||
|
||||
"The Program" refers to any copyrightable work licensed under this |
||||
License. Each licensee is addressed as "you". "Licensees" and |
||||
"recipients" may be individuals or organizations. |
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work |
||||
in a fashion requiring copyright permission, other than the making of an |
||||
exact copy. The resulting work is called a "modified version" of the |
||||
earlier work or a work "based on" the earlier work. |
||||
|
||||
A "covered work" means either the unmodified Program or a work based |
||||
on the Program. |
||||
|
||||
To "propagate" a work means to do anything with it that, without |
||||
permission, would make you directly or secondarily liable for |
||||
infringement under applicable copyright law, except executing it on a |
||||
computer or modifying a private copy. Propagation includes copying, |
||||
distribution (with or without modification), making available to the |
||||
public, and in some countries other activities as well. |
||||
|
||||
To "convey" a work means any kind of propagation that enables other |
||||
parties to make or receive copies. Mere interaction with a user through |
||||
a computer network, with no transfer of a copy, is not conveying. |
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices" |
||||
to the extent that it includes a convenient and prominently visible |
||||
feature that (1) displays an appropriate copyright notice, and (2) |
||||
tells the user that there is no warranty for the work (except to the |
||||
extent that warranties are provided), that licensees may convey the |
||||
work under this License, and how to view a copy of this License. If |
||||
the interface presents a list of user commands or options, such as a |
||||
menu, a prominent item in the list meets this criterion. |
||||
|
||||
1. Source Code. |
||||
|
||||
The "source code" for a work means the preferred form of the work |
||||
for making modifications to it. "Object code" means any non-source |
||||
form of a work. |
||||
|
||||
A "Standard Interface" means an interface that either is an official |
||||
standard defined by a recognized standards body, or, in the case of |
||||
interfaces specified for a particular programming language, one that |
||||
is widely used among developers working in that language. |
||||
|
||||
The "System Libraries" of an executable work include anything, other |
||||
than the work as a whole, that (a) is included in the normal form of |
||||
packaging a Major Component, but which is not part of that Major |
||||
Component, and (b) serves only to enable use of the work with that |
||||
Major Component, or to implement a Standard Interface for which an |
||||
implementation is available to the public in source code form. A |
||||
"Major Component", in this context, means a major essential component |
||||
(kernel, window system, and so on) of the specific operating system |
||||
(if any) on which the executable work runs, or a compiler used to |
||||
produce the work, or an object code interpreter used to run it. |
||||
|
||||
The "Corresponding Source" for a work in object code form means all |
||||
the source code needed to generate, install, and (for an executable |
||||
work) run the object code and to modify the work, including scripts to |
||||
control those activities. However, it does not include the work's |
||||
System Libraries, or general-purpose tools or generally available free |
||||
programs which are used unmodified in performing those activities but |
||||
which are not part of the work. For example, Corresponding Source |
||||
includes interface definition files associated with source files for |
||||
the work, and the source code for shared libraries and dynamically |
||||
linked subprograms that the work is specifically designed to require, |
||||
such as by intimate data communication or control flow between those |
||||
subprograms and other parts of the work. |
||||
|
||||
The Corresponding Source need not include anything that users |
||||
can regenerate automatically from other parts of the Corresponding |
||||
Source. |
||||
|
||||
The Corresponding Source for a work in source code form is that |
||||
same work. |
||||
|
||||
2. Basic Permissions. |
||||
|
||||
All rights granted under this License are granted for the term of |
||||
copyright on the Program, and are irrevocable provided the stated |
||||
conditions are met. This License explicitly affirms your unlimited |
||||
permission to run the unmodified Program. The output from running a |
||||
covered work is covered by this License only if the output, given its |
||||
content, constitutes a covered work. This License acknowledges your |
||||
rights of fair use or other equivalent, as provided by copyright law. |
||||
|
||||
You may make, run and propagate covered works that you do not |
||||
convey, without conditions so long as your license otherwise remains |
||||
in force. You may convey covered works to others for the sole purpose |
||||
of having them make modifications exclusively for you, or provide you |
||||
with facilities for running those works, provided that you comply with |
||||
the terms of this License in conveying all material for which you do |
||||
not control copyright. Those thus making or running the covered works |
||||
for you must do so exclusively on your behalf, under your direction |
||||
and control, on terms that prohibit them from making any copies of |
||||
your copyrighted material outside their relationship with you. |
||||
|
||||
Conveying under any other circumstances is permitted solely under |
||||
the conditions stated below. Sublicensing is not allowed; section 10 |
||||
makes it unnecessary. |
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law. |
||||
|
||||
No covered work shall be deemed part of an effective technological |
||||
measure under any applicable law fulfilling obligations under article |
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or |
||||
similar laws prohibiting or restricting circumvention of such |
||||
measures. |
||||
|
||||
When you convey a covered work, you waive any legal power to forbid |
||||
circumvention of technological measures to the extent such circumvention |
||||
is effected by exercising rights under this License with respect to |
||||
the covered work, and you disclaim any intention to limit operation or |
||||
modification of the work as a means of enforcing, against the work's |
||||
users, your or third parties' legal rights to forbid circumvention of |
||||
technological measures. |
||||
|
||||
4. Conveying Verbatim Copies. |
||||
|
||||
You may convey verbatim copies of the Program's source code as you |
||||
receive it, in any medium, provided that you conspicuously and |
||||
appropriately publish on each copy an appropriate copyright notice; |
||||
keep intact all notices stating that this License and any |
||||
non-permissive terms added in accord with section 7 apply to the code; |
||||
keep intact all notices of the absence of any warranty; and give all |
||||
recipients a copy of this License along with the Program. |
||||
|
||||
You may charge any price or no price for each copy that you convey, |
||||
and you may offer support or warranty protection for a fee. |
||||
|
||||
5. Conveying Modified Source Versions. |
||||
|
||||
You may convey a work based on the Program, or the modifications to |
||||
produce it from the Program, in the form of source code under the |
||||
terms of section 4, provided that you also meet all of these conditions: |
||||
|
||||
a) The work must carry prominent notices stating that you modified |
||||
it, and giving a relevant date. |
||||
|
||||
b) The work must carry prominent notices stating that it is |
||||
released under this License and any conditions added under section |
||||
7. This requirement modifies the requirement in section 4 to |
||||
"keep intact all notices". |
||||
|
||||
c) You must license the entire work, as a whole, under this |
||||
License to anyone who comes into possession of a copy. This |
||||
License will therefore apply, along with any applicable section 7 |
||||
additional terms, to the whole of the work, and all its parts, |
||||
regardless of how they are packaged. This License gives no |
||||
permission to license the work in any other way, but it does not |
||||
invalidate such permission if you have separately received it. |
||||
|
||||
d) If the work has interactive user interfaces, each must display |
||||
Appropriate Legal Notices; however, if the Program has interactive |
||||
interfaces that do not display Appropriate Legal Notices, your |
||||
work need not make them do so. |
||||
|
||||
A compilation of a covered work with other separate and independent |
||||
works, which are not by their nature extensions of the covered work, |
||||
and which are not combined with it such as to form a larger program, |
||||
in or on a volume of a storage or distribution medium, is called an |
||||
"aggregate" if the compilation and its resulting copyright are not |
||||
used to limit the access or legal rights of the compilation's users |
||||
beyond what the individual works permit. Inclusion of a covered work |
||||
in an aggregate does not cause this License to apply to the other |
||||
parts of the aggregate. |
||||
|
||||
6. Conveying Non-Source Forms. |
||||
|
||||
You may convey a covered work in object code form under the terms |
||||
of sections 4 and 5, provided that you also convey the |
||||
machine-readable Corresponding Source under the terms of this License, |
||||
in one of these ways: |
||||
|
||||
a) Convey the object code in, or embodied in, a physical product |
||||
(including a physical distribution medium), accompanied by the |
||||
Corresponding Source fixed on a durable physical medium |
||||
customarily used for software interchange. |
||||
|
||||
b) Convey the object code in, or embodied in, a physical product |
||||
(including a physical distribution medium), accompanied by a |
||||
written offer, valid for at least three years and valid for as |
||||
long as you offer spare parts or customer support for that product |
||||
model, to give anyone who possesses the object code either (1) a |
||||
copy of the Corresponding Source for all the software in the |
||||
product that is covered by this License, on a durable physical |
||||
medium customarily used for software interchange, for a price no |
||||
more than your reasonable cost of physically performing this |
||||
conveying of source, or (2) access to copy the |
||||
Corresponding Source from a network server at no charge. |
||||
|
||||
c) Convey individual copies of the object code with a copy of the |
||||
written offer to provide the Corresponding Source. This |
||||
alternative is allowed only occasionally and noncommercially, and |
||||
only if you received the object code with such an offer, in accord |
||||
with subsection 6b. |
||||
|
||||
d) Convey the object code by offering access from a designated |
||||
place (gratis or for a charge), and offer equivalent access to the |
||||
Corresponding Source in the same way through the same place at no |
||||
further charge. You need not require recipients to copy the |
||||
Corresponding Source along with the object code. If the place to |
||||
copy the object code is a network server, the Corresponding Source |
||||
may be on a different server (operated by you or a third party) |
||||
that supports equivalent copying facilities, provided you maintain |
||||
clear directions next to the object code saying where to find the |
||||
Corresponding Source. Regardless of what server hosts the |
||||
Corresponding Source, you remain obligated to ensure that it is |
||||
available for as long as needed to satisfy these requirements. |
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided |
||||
you inform other peers where the object code and Corresponding |
||||
Source of the work are being offered to the general public at no |
||||
charge under subsection 6d. |
||||
|
||||
A separable portion of the object code, whose source code is excluded |
||||
from the Corresponding Source as a System Library, need not be |
||||
included in conveying the object code work. |
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any |
||||
tangible personal property which is normally used for personal, family, |
||||
or household purposes, or (2) anything designed or sold for incorporation |
||||
into a dwelling. In determining whether a product is a consumer product, |
||||
doubtful cases shall be resolved in favor of coverage. For a particular |
||||
product received by a particular user, "normally used" refers to a |
||||
typical or common use of that class of product, regardless of the status |
||||
of the particular user or of the way in which the particular user |
||||
actually uses, or expects or is expected to use, the product. A product |
||||
is a consumer product regardless of whether the product has substantial |
||||
commercial, industrial or non-consumer uses, unless such uses represent |
||||
the only significant mode of use of the product. |
||||
|
||||
"Installation Information" for a User Product means any methods, |
||||
procedures, authorization keys, or other information required to install |
||||
and execute modified versions of a covered work in that User Product from |
||||
a modified version of its Corresponding Source. The information must |
||||
suffice to ensure that the continued functioning of the modified object |
||||
code is in no case prevented or interfered with solely because |
||||
modification has been made. |
||||
|
||||
If you convey an object code work under this section in, or with, or |
||||
specifically for use in, a User Product, and the conveying occurs as |
||||
part of a transaction in which the right of possession and use of the |
||||
User Product is transferred to the recipient in perpetuity or for a |
||||
fixed term (regardless of how the transaction is characterized), the |
||||
Corresponding Source conveyed under this section must be accompanied |
||||
by the Installation Information. But this requirement does not apply |
||||
if neither you nor any third party retains the ability to install |
||||
modified object code on the User Product (for example, the work has |
||||
been installed in ROM). |
||||
|
||||
The requirement to provide Installation Information does not include a |
||||
requirement to continue to provide support service, warranty, or updates |
||||
for a work that has been modified or installed by the recipient, or for |
||||
the User Product in which it has been modified or installed. Access to a |
||||
network may be denied when the modification itself materially and |
||||
adversely affects the operation of the network or violates the rules and |
||||
protocols for communication across the network. |
||||
|
||||
Corresponding Source conveyed, and Installation Information provided, |
||||
in accord with this section must be in a format that is publicly |
||||
documented (and with an implementation available to the public in |
||||
source code form), and must require no special password or key for |
||||
unpacking, reading or copying. |
||||
|
||||
7. Additional Terms. |
||||
|
||||
"Additional permissions" are terms that supplement the terms of this |
||||
License by making exceptions from one or more of its conditions. |
||||
Additional permissions that are applicable to the entire Program shall |
||||
be treated as though they were included in this License, to the extent |
||||
that they are valid under applicable law. If additional permissions |
||||
apply only to part of the Program, that part may be used separately |
||||
under those permissions, but the entire Program remains governed by |
||||
this License without regard to the additional permissions. |
||||
|
||||
When you convey a copy of a covered work, you may at your option |
||||
remove any additional permissions from that copy, or from any part of |
||||
it. (Additional permissions may be written to require their own |
||||
removal in certain cases when you modify the work.) You may place |
||||
additional permissions on material, added by you to a covered work, |
||||
for which you have or can give appropriate copyright permission. |
||||
|
||||
Notwithstanding any other provision of this License, for material you |
||||
add to a covered work, you may (if authorized by the copyright holders of |
||||
that material) supplement the terms of this License with terms: |
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the |
||||
terms of sections 15 and 16 of this License; or |
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or |
||||
author attributions in that material or in the Appropriate Legal |
||||
Notices displayed by works containing it; or |
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or |
||||
requiring that modified versions of such material be marked in |
||||
reasonable ways as different from the original version; or |
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or |
||||
authors of the material; or |
||||
|
||||
e) Declining to grant rights under trademark law for use of some |
||||
trade names, trademarks, or service marks; or |
||||
|
||||
f) Requiring indemnification of licensors and authors of that |
||||
material by anyone who conveys the material (or modified versions of |
||||
it) with contractual assumptions of liability to the recipient, for |
||||
any liability that these contractual assumptions directly impose on |
||||
those licensors and authors. |
||||
|
||||
All other non-permissive additional terms are considered "further |
||||
restrictions" within the meaning of section 10. If the Program as you |
||||
received it, or any part of it, contains a notice stating that it is |
||||
governed by this License along with a term that is a further |
||||
restriction, you may remove that term. If a license document contains |
||||
a further restriction but permits relicensing or conveying under this |
||||
License, you may add to a covered work material governed by the terms |
||||
of that license document, provided that the further restriction does |
||||
not survive such relicensing or conveying. |
||||
|
||||
If you add terms to a covered work in accord with this section, you |
||||
must place, in the relevant source files, a statement of the |
||||
additional terms that apply to those files, or a notice indicating |
||||
where to find the applicable terms. |
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the |
||||
form of a separately written license, or stated as exceptions; |
||||
the above requirements apply either way. |
||||
|
||||
8. Termination. |
||||
|
||||
You may not propagate or modify a covered work except as expressly |
||||
provided under this License. Any attempt otherwise to propagate or |
||||
modify it is void, and will automatically terminate your rights under |
||||
this License (including any patent licenses granted under the third |
||||
paragraph of section 11). |
||||
|
||||
However, if you cease all violation of this License, then your |
||||
license from a particular copyright holder is reinstated (a) |
||||
provisionally, unless and until the copyright holder explicitly and |
||||
finally terminates your license, and (b) permanently, if the copyright |
||||
holder fails to notify you of the violation by some reasonable means |
||||
prior to 60 days after the cessation. |
||||
|
||||
Moreover, your license from a particular copyright holder is |
||||
reinstated permanently if the copyright holder notifies you of the |
||||
violation by some reasonable means, this is the first time you have |
||||
received notice of violation of this License (for any work) from that |
||||
copyright holder, and you cure the violation prior to 30 days after |
||||
your receipt of the notice. |
||||
|
||||
Termination of your rights under this section does not terminate the |
||||
licenses of parties who have received copies or rights from you under |
||||
this License. If your rights have been terminated and not permanently |
||||
reinstated, you do not qualify to receive new licenses for the same |
||||
material under section 10. |
||||
|
||||
9. Acceptance Not Required for Having Copies. |
||||
|
||||
You are not required to accept this License in order to receive or |
||||
run a copy of the Program. Ancillary propagation of a covered work |
||||
occurring solely as a consequence of using peer-to-peer transmission |
||||
to receive a copy likewise does not require acceptance. However, |
||||
nothing other than this License grants you permission to propagate or |
||||
modify any covered work. These actions infringe copyright if you do |
||||
not accept this License. Therefore, by modifying or propagating a |
||||
covered work, you indicate your acceptance of this License to do so. |
||||
|
||||
10. Automatic Licensing of Downstream Recipients. |
||||
|
||||
Each time you convey a covered work, the recipient automatically |
||||
receives a license from the original licensors, to run, modify and |
||||
propagate that work, subject to this License. You are not responsible |
||||
for enforcing compliance by third parties with this License. |
||||
|
||||
An "entity transaction" is a transaction transferring control of an |
||||
organization, or substantially all assets of one, or subdividing an |
||||
organization, or merging organizations. If propagation of a covered |
||||
work results from an entity transaction, each party to that |
||||
transaction who receives a copy of the work also receives whatever |
||||
licenses to the work the party's predecessor in interest had or could |
||||
give under the previous paragraph, plus a right to possession of the |
||||
Corresponding Source of the work from the predecessor in interest, if |
||||
the predecessor has it or can get it with reasonable efforts. |
||||
|
||||
You may not impose any further restrictions on the exercise of the |
||||
rights granted or affirmed under this License. For example, you may |
||||
not impose a license fee, royalty, or other charge for exercise of |
||||
rights granted under this License, and you may not initiate litigation |
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that |
||||
any patent claim is infringed by making, using, selling, offering for |
||||
sale, or importing the Program or any portion of it. |
||||
|
||||
11. Patents. |
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this |
||||
License of the Program or a work on which the Program is based. The |
||||
work thus licensed is called the contributor's "contributor version". |
||||
|
||||
A contributor's "essential patent claims" are all patent claims |
||||
owned or controlled by the contributor, whether already acquired or |
||||
hereafter acquired, that would be infringed by some manner, permitted |
||||
by this License, of making, using, or selling its contributor version, |
||||
but do not include claims that would be infringed only as a |
||||
consequence of further modification of the contributor version. For |
||||
purposes of this definition, "control" includes the right to grant |
||||
patent sublicenses in a manner consistent with the requirements of |
||||
this License. |
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free |
||||
patent license under the contributor's essential patent claims, to |
||||
make, use, sell, offer for sale, import and otherwise run, modify and |
||||
propagate the contents of its contributor version. |
||||
|
||||
In the following three paragraphs, a "patent license" is any express |
||||
agreement or commitment, however denominated, not to enforce a patent |
||||
(such as an express permission to practice a patent or covenant not to |
||||
sue for patent infringement). To "grant" such a patent license to a |
||||
party means to make such an agreement or commitment not to enforce a |
||||
patent against the party. |
||||
|
||||
If you convey a covered work, knowingly relying on a patent license, |
||||
and the Corresponding Source of the work is not available for anyone |
||||
to copy, free of charge and under the terms of this License, through a |
||||
publicly available network server or other readily accessible means, |
||||
then you must either (1) cause the Corresponding Source to be so |
||||
available, or (2) arrange to deprive yourself of the benefit of the |
||||
patent license for this particular work, or (3) arrange, in a manner |
||||
consistent with the requirements of this License, to extend the patent |
||||
license to downstream recipients. "Knowingly relying" means you have |
||||
actual knowledge that, but for the patent license, your conveying the |
||||
covered work in a country, or your recipient's use of the covered work |
||||
in a country, would infringe one or more identifiable patents in that |
||||
country that you have reason to believe are valid. |
||||
|
||||
If, pursuant to or in connection with a single transaction or |
||||
arrangement, you convey, or propagate by procuring conveyance of, a |
||||
covered work, and grant a patent license to some of the parties |
||||
receiving the covered work authorizing them to use, propagate, modify |
||||
or convey a specific copy of the covered work, then the patent license |
||||
you grant is automatically extended to all recipients of the covered |
||||
work and works based on it. |
||||
|
||||
A patent license is "discriminatory" if it does not include within |
||||
the scope of its coverage, prohibits the exercise of, or is |
||||
conditioned on the non-exercise of one or more of the rights that are |
||||
specifically granted under this License. You may not convey a covered |
||||
work if you are a party to an arrangement with a third party that is |
||||
in the business of distributing software, under which you make payment |
||||
to the third party based on the extent of your activity of conveying |
||||
the work, and under which the third party grants, to any of the |
||||
parties who would receive the covered work from you, a discriminatory |
||||
patent license (a) in connection with copies of the covered work |
||||
conveyed by you (or copies made from those copies), or (b) primarily |
||||
for and in connection with specific products or compilations that |
||||
contain the covered work, unless you entered into that arrangement, |
||||
or that patent license was granted, prior to 28 March 2007. |
||||
|
||||
Nothing in this License shall be construed as excluding or limiting |
||||
any implied license or other defenses to infringement that may |
||||
otherwise be available to you under applicable patent law. |
||||
|
||||
12. No Surrender of Others' Freedom. |
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or |
||||
otherwise) that contradict the conditions of this License, they do not |
||||
excuse you from the conditions of this License. If you cannot convey a |
||||
covered work so as to satisfy simultaneously your obligations under this |
||||
License and any other pertinent obligations, then as a consequence you may |
||||
not convey it at all. For example, if you agree to terms that obligate you |
||||
to collect a royalty for further conveying from those to whom you convey |
||||
the Program, the only way you could satisfy both those terms and this |
||||
License would be to refrain entirely from conveying the Program. |
||||
|
||||
13. Use with the GNU Affero General Public License. |
||||
|
||||
Notwithstanding any other provision of this License, you have |
||||
permission to link or combine any covered work with a work licensed |
||||
under version 3 of the GNU Affero General Public License into a single |
||||
combined work, and to convey the resulting work. The terms of this |
||||
License will continue to apply to the part which is the covered work, |
||||
but the special requirements of the GNU Affero General Public License, |
||||
section 13, concerning interaction through a network will apply to the |
||||
combination as such. |
||||
|
||||
14. Revised Versions of this License. |
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of |
||||
the GNU General Public License from time to time. Such new versions will |
||||
be similar in spirit to the present version, but may differ in detail to |
||||
address new problems or concerns. |
||||
|
||||
Each version is given a distinguishing version number. If the |
||||
Program specifies that a certain numbered version of the GNU General |
||||
Public License "or any later version" applies to it, you have the |
||||
option of following the terms and conditions either of that numbered |
||||
version or of any later version published by the Free Software |
||||
Foundation. If the Program does not specify a version number of the |
||||
GNU General Public License, you may choose any version ever published |
||||
by the Free Software Foundation. |
||||
|
||||
If the Program specifies that a proxy can decide which future |
||||
versions of the GNU General Public License can be used, that proxy's |
||||
public statement of acceptance of a version permanently authorizes you |
||||
to choose that version for the Program. |
||||
|
||||
Later license versions may give you additional or different |
||||
permissions. However, no additional obligations are imposed on any |
||||
author or copyright holder as a result of your choosing to follow a |
||||
later version. |
||||
|
||||
15. Disclaimer of Warranty. |
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY |
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT |
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY |
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, |
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM |
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF |
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION. |
||||
|
||||
16. Limitation of Liability. |
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS |
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY |
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE |
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF |
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD |
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), |
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF |
||||
SUCH DAMAGES. |
||||
|
||||
17. Interpretation of Sections 15 and 16. |
||||
|
||||
If the disclaimer of warranty and limitation of liability provided |
||||
above cannot be given local legal effect according to their terms, |
||||
reviewing courts shall apply local law that most closely approximates |
||||
an absolute waiver of all civil liability in connection with the |
||||
Program, unless a warranty or assumption of liability accompanies a |
||||
copy of the Program in return for a fee. |
||||
|
||||
END OF TERMS AND CONDITIONS |
||||
|
||||
How to Apply These Terms to Your New Programs |
||||
|
||||
If you develop a new program, and you want it to be of the greatest |
||||
possible use to the public, the best way to achieve this is to make it |
||||
free software which everyone can redistribute and change under these terms. |
||||
|
||||
To do so, attach the following notices to the program. It is safest |
||||
to attach them to the start of each source file to most effectively |
||||
state the exclusion of warranty; and each file should have at least |
||||
the "copyright" line and a pointer to where the full notice is found. |
||||
|
||||
<one line to give the program's name and a brief idea of what it does.> |
||||
Copyright (C) <year> <name of author> |
||||
|
||||
This program is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
||||
Also add information on how to contact you by electronic and paper mail. |
||||
|
||||
If the program does terminal interaction, make it output a short |
||||
notice like this when it starts in an interactive mode: |
||||
|
||||
<program> Copyright (C) <year> <name of author> |
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
||||
This is free software, and you are welcome to redistribute it |
||||
under certain conditions; type `show c' for details. |
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate |
||||
parts of the General Public License. Of course, your program's commands |
||||
might be different; for a GUI interface, you would use an "about box". |
||||
|
||||
You should also get your employer (if you work as a programmer) or school, |
||||
if any, to sign a "copyright disclaimer" for the program, if necessary. |
||||
For more information on this, and how to apply and follow the GNU GPL, see |
||||
<http://www.gnu.org/licenses/>. |
||||
|
||||
The GNU General Public License does not permit incorporating your program |
||||
into proprietary programs. If your program is a subroutine library, you |
||||
may consider it more useful to permit linking proprietary applications with |
||||
the library. If this is what you want to do, use the GNU Lesser General |
||||
Public License instead of this License. But first, please read |
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>. |
@ -0,0 +1,336 @@
|
||||
<?php |
||||
// $Id$ |
||||
|
||||
/** |
||||
* |
||||
* This class inspired by Chris Jean's work, here: |
||||
* http://chrisjean.com/2009/02/14/generating-mime-type-in-php-is-not-magic/ |
||||
* |
||||
* It does some MIME trickery, inspired by the need to to deal with Openoffice |
||||
* and MS Office 2007 file formats -- which are often mis-interpreted by |
||||
* mime-magic, fileinfo, and the *nix `file` command. |
||||
* |
||||
* In Drupal 6, we also make use of file_get_mimetype. See: |
||||
* http://api.drupal.org/api/function/file_get_mimetype/6 |
||||
* ... however this only provides a uni-directional lookup (ext->mime). |
||||
* While I don't have a specific use case for a mime->extension lookup, I think |
||||
* it's good to have in here. |
||||
* |
||||
* Drupal 7 will have better mime handlers. See: |
||||
* http://api.drupal.org/api/function/file_default_mimetype_mapping/7 |
||||
* |
||||
*/ |
||||
|
||||
class MimeClass { |
||||
private $private_mime_types = array( |
||||
/** |
||||
* This is a shortlist of mimetypes which should catch most |
||||
* mimetype<-->extension lookups in the context of Islandora collections. |
||||
* |
||||
* It has been cut from a much longer list. |
||||
* |
||||
* Two types of mimetypes should be put in this list: |
||||
* 1) Special emerging formats which may not yet be expressed in the system |
||||
* mime.types file. |
||||
* 2) Heavily used mimetypes of particular importance to the Islandora |
||||
* project, as lookups against this list will be quicker and less |
||||
* resource intensive than other methods. |
||||
* |
||||
* Lookups are first checked against this short list. If no results are found, |
||||
* then the lookup function may move on to check other sources, namely the |
||||
* system's mime.types file. |
||||
* |
||||
* In most cases though, this short list should suffice. |
||||
* |
||||
* If modifying this list, please note that for promiscuous mimetypes |
||||
* (those which map to multiple extensions, such as text/plain) |
||||
* The function get_extension will always return the *LAST* extension in this list, |
||||
* so you should put your preferred extension *LAST*. |
||||
* |
||||
* e.g... |
||||
* "jpeg" => "image/jpeg", |
||||
* "jpe" => "image/jpeg", |
||||
* "jpg" => "image/jpeg", |
||||
* |
||||
* $this->get_extension('image/jpeg') will always return 'jpg'. |
||||
* |
||||
*/ |
||||
// openoffice: |
||||
'odb' => 'application/vnd.oasis.opendocument.database', |
||||
'odc' => 'application/vnd.oasis.opendocument.chart', |
||||
'odf' => 'application/vnd.oasis.opendocument.formula', |
||||
'odg' => 'application/vnd.oasis.opendocument.graphics', |
||||
'odi' => 'application/vnd.oasis.opendocument.image', |
||||
'odm' => 'application/vnd.oasis.opendocument.text-master', |
||||
'odp' => 'application/vnd.oasis.opendocument.presentation', |
||||
'ods' => 'application/vnd.oasis.opendocument.spreadsheet', |
||||
'odt' => 'application/vnd.oasis.opendocument.text', |
||||
'otg' => 'application/vnd.oasis.opendocument.graphics-template', |
||||
'oth' => 'application/vnd.oasis.opendocument.text-web', |
||||
'otp' => 'application/vnd.oasis.opendocument.presentation-template', |
||||
'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', |
||||
'ott' => 'application/vnd.oasis.opendocument.text-template', |
||||
// staroffice: |
||||
'stc' => 'application/vnd.sun.xml.calc.template', |
||||
'std' => 'application/vnd.sun.xml.draw.template', |
||||
'sti' => 'application/vnd.sun.xml.impress.template', |
||||
'stw' => 'application/vnd.sun.xml.writer.template', |
||||
'sxc' => 'application/vnd.sun.xml.calc', |
||||
'sxd' => 'application/vnd.sun.xml.draw', |
||||
'sxg' => 'application/vnd.sun.xml.writer.global', |
||||
'sxi' => 'application/vnd.sun.xml.impress', |
||||
'sxm' => 'application/vnd.sun.xml.math', |
||||
'sxw' => 'application/vnd.sun.xml.writer', |
||||
// k-office: |
||||
'kil' => 'application/x-killustrator', |
||||
'kpt' => 'application/x-kpresenter', |
||||
'kpr' => 'application/x-kpresenter', |
||||
'ksp' => 'application/x-kspread', |
||||
'kwt' => 'application/x-kword', |
||||
'kwd' => 'application/x-kword', |
||||
// ms office 97: |
||||
'doc' => 'application/msword', |
||||
'xls' => 'application/vnd.ms-excel', |
||||
'ppt' => 'application/vnd.ms-powerpoint', |
||||
// office2007: |
||||
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', |
||||
'docm' => 'application/vnd.ms-word.document.macroEnabled.12', |
||||
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', |
||||
'dotm' => 'application/vnd.ms-word.template.macroEnabled.12', |
||||
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', |
||||
'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', |
||||
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', |
||||
'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12', |
||||
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', |
||||
'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', |
||||
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', |
||||
'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', |
||||
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', |
||||
'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', |
||||
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', |
||||
'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12', |
||||
'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12', |
||||
'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', |
||||
'sldm' => 'application/vnd.ms-powerpoint.slide.macroEnabled.12', |
||||
// wordperfect (who cares?): |
||||
'wpd' => 'application/wordperfect', |
||||
// common and generic containers: |
||||
'pdf' => 'application/pdf', |
||||
'eps' => 'application/postscript', |
||||
'ps' => 'application/postscript', |
||||
'rtf' => 'text/rtf', |
||||
'rtx' => 'text/richtext', |
||||
'latex' => 'application/x-latex', |
||||
'tex' => 'application/x-tex', |
||||
'texi' => 'application/x-texinfo', |
||||
'texinfo' => 'application/x-texinfo', |
||||
// *ml: |
||||
'css' => 'text/css', |
||||
'htm' => 'text/html', |
||||
'html' => 'text/html', |
||||
'wbxml' => 'application/vnd.wap.wbxml', |
||||
'xht' => 'application/xhtml+xml', |
||||
'xhtml' => 'application/xhtml+xml', |
||||
'xsl' => 'text/xml', |
||||
'xml' => 'text/xml', |
||||
'csv' => 'text/csv', |
||||
'tsv' => 'text/tab-separated-values', |
||||
'txt' => 'text/plain', |
||||
// images: |
||||
"bmp" => "image/bmp", |
||||
"gif" => "image/gif", |
||||
"ief" => "image/ief", |
||||
"jpeg" => "image/jpeg", |
||||
"jpe" => "image/jpeg", |
||||
"jpg" => "image/jpeg", |
||||
"jp2" => "image/jp2", |
||||
"png" => "image/png", |
||||
"tiff" => "image/tiff", |
||||
"tif" => "image/tif", |
||||
"djvu" => "image/vnd.djvu", |
||||
"djv" => "image/vnd.djvu", |
||||
"wbmp" => "image/vnd.wap.wbmp", |
||||
"ras" => "image/x-cmu-raster", |
||||
"pnm" => "image/x-portable-anymap", |
||||
"pbm" => "image/x-portable-bitmap", |
||||
"pgm" => "image/x-portable-graymap", |
||||
"ppm" => "image/x-portable-pixmap", |
||||
"rgb" => "image/x-rgb", |
||||
"xbm" => "image/x-xbitmap", |
||||
"xpm" => "image/x-xpixmap", |
||||
"xwd" => "image/x-windowdump", |
||||
// videos: |
||||
"mpeg" => "video/mpeg", |
||||
"mpe" => "video/mpeg", |
||||
"mpg" => "video/mpeg", |
||||
"qt" => "video/quicktime", |
||||
"mov" => "video/quicktime", |
||||
"mxu" => "video/vnd.mpegurl", |
||||
"avi" => "video/x-msvideo", |
||||
"movie" => "video/x-sgi-movie", |
||||
"flv" => "video/x-flv", |
||||
"swf" => "application/x-shockwave-flash", |
||||
// compressed formats: (note: http://svn.cleancode.org/svn/email/trunk/mime.types) |
||||
"tgz" => "application/x-gzip", |
||||
"gz" => "application/x-gzip", |
||||
"tar" => "application/x-tar", |
||||
"gtar" => "application/x-gtar", |
||||
"zip" => "application/x-zip", |
||||
// others: |
||||
'bin' => 'application/octet-stream', |
||||
); |
||||
|
||||
private $private_file_extensions; |
||||
private $system_types; |
||||
private $system_exts; |
||||
private $etc_mime_types = '/etc/mime.types'; |
||||
|
||||
public function __construct() { |
||||
|
||||
// populate the reverse shortlist: |
||||
$this->private_file_extensions = array_flip( $this->private_mime_types ); |
||||
|
||||
// pick up a local mime.types file if it is available |
||||
if (is_readable('mime.types') ) { |
||||
$this->etc_mime_types = 'mime.types'; |
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* function: getType |
||||
* description: An alias to get_mimetype, |
||||
* for backwards-compatibility with our old mimetype class. |
||||
*/ |
||||
public function getType( $filename ) { |
||||
return $this->get_mimetype( $filename ); |
||||
} |
||||
|
||||
/** |
||||
* function: get_mimetype |
||||
* description: returns a mimetype associated with the file extension of $filename |
||||
*/ |
||||
public function get_mimetype( $filename, $debug = FALSE ) { |
||||
|
||||
$ext = strtolower( array_pop( explode( '.', $filename ) ) ); |
||||
|
||||
if ( ! empty( $this->private_mime_types[$ext] ) ) { |
||||
if ( TRUE === $debug ) |
||||
return array( 'mime_type' => $this->private_mime_types[$ext], 'method' => 'from_array' ); |
||||
return $this->private_mime_types[$ext]; |
||||
} |
||||
|
||||
if (function_exists('file_get_mimetype')) { |
||||
$drupal_mimetype = file_get_mimetype( $filename ); |
||||
if ('application/octet-stream' != $drupal_mimetype) { |
||||
if (TRUE == $debug) |
||||
return array('mime_type' => $drupal_mimetype, 'method' => 'file_get_mimetype'); |
||||
return $drupal_mimetype; |
||||
} |
||||
} |
||||
|
||||
if (!isset( $this->system_types)) |
||||
$this->system_types = $this->system_extension_mime_types(); |
||||
if (isset( $this->system_types[$ext])) { |
||||
if (TRUE == $debug) |
||||
return array('mime_type' => $this->system_types[$ext], 'method' => 'mime.types'); |
||||
return $this->system_types[$ext]; |
||||
} |
||||
|
||||
if ( TRUE === $debug ) |
||||
return array( 'mime_type' => 'application/octet-stream', 'method' => 'last_resort' ); |
||||
return 'application/octet-stream'; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* function: get_extension |
||||
* description: returns *one* valid file extension for a given $mime_type |
||||
*/ |
||||
public function get_extension( $mime_type, $debug = FALSE ) { |
||||
|
||||
if (!empty( $this->private_file_extensions[$mime_type])) { |
||||
if (TRUE == $debug) |
||||
return array( 'extension' => $this->private_file_extensions[$mime_type], 'method' => 'from_array' ); |
||||
return $this->private_file_extensions[$mime_type]; |
||||
} |
||||
|
||||
if (!isset ( $this->system_exts)) |
||||
$this->system_exts = $this->system_mime_type_extensions(); |
||||
if (isset( $this->system_exts[$mime_type])) { |
||||
if (TRUE == $debug) |
||||
return array( 'extension' => $this->system_exts[$mime_type], 'method' => 'mime.types' ); |
||||
return $this->system_exts[$mime_type]; |
||||
} |
||||
|
||||
if (TRUE == $debug) |
||||
return array( 'extension' => 'bin', 'method' => 'last_resort' ); |
||||
return 'bin'; |
||||
} |
||||
|
||||
/** |
||||
* function: system_mime_type_extensions |
||||
* description: populates an internal array of mimetype/extension associations |
||||
* from the system mime.types file, or a local mime.types if one is found (see |
||||
* __constuctor). |
||||
* return: array of mimetype => extension |
||||
*/ |
||||
private function system_mime_type_extensions() { |
||||
$out = array(); |
||||
$file = fopen($this->etc_mime_types, 'r'); |
||||
while (($line = fgets($file)) !== FALSE) { |
||||
$line = trim(preg_replace('/#.*/', '', $line)); |
||||
if (!$line) |
||||
continue; |
||||
$parts = preg_split('/\s+/', $line); |
||||
if (count($parts) == 1) |
||||
continue; |
||||
// A single part means a mimetype without extensions, which we ignore. |
||||
$type = array_shift($parts); |
||||
if (!isset($out[$type])) |
||||
$out[$type] = array_shift($parts); |
||||
// We take the first ext from the line if many are present. |
||||
} |
||||
fclose($file); |
||||
return $out; |
||||
} |
||||
|
||||
/** |
||||
* function: system_mime_type_extensions |
||||
* description: populates an internal array of mimetype/extension associations |
||||
* from the system mime.types file, or a local mime.types if one is found (see |
||||
* __constuctor). |
||||
* return: array of extension => mimetype |
||||
*/ |
||||
private function system_extension_mime_types() { |
||||
$out = array(); |
||||
$file = fopen($this->etc_mime_types, 'r'); |
||||
while (($line = fgets($file)) !== FALSE) { |
||||
$line = trim(preg_replace('/#.*/', '', $line)); |
||||
if (!$line) |
||||
continue; |
||||
$parts = preg_split('/\s+/', $line); |
||||
if (count($parts) == 1) |
||||
continue; |
||||
// A single part means a mimetype without extensions, which we ignore. |
||||
$type = array_shift($parts); |
||||
foreach ($parts as $part) |
||||
$out[$part] = $type; |
||||
} |
||||
fclose($file); |
||||
return $out; |
||||
} |
||||
|
||||
} |
||||
|
||||
/* |
||||
$helper = new MimeClass(); |
||||
print "get_extension('application/x-gzip'): \n"; |
||||
echo print_r( $helper->get_extension('application/x-gzip', true), true ) . "\n"; |
||||
print "get_extension('text/plain'): \n"; |
||||
echo print_r( $helper->get_extension('text/plain', true), true ) . "\n"; |
||||
print "get_mimetype('fucker/asdf.tar.gz'): \n"; |
||||
echo print_r( $helper->get_mimetype('fucker/asdf.tar.gz', true), true ) . "\n"; |
||||
print "get_mimetype('blah.tsp'): \n"; |
||||
echo print_r( $helper->get_mimetype('blah.tsp', true), true ) . "\n"; |
||||
/* */ |
@ -0,0 +1,601 @@
|
||||
<?php |
||||
// $Id$ |
||||
|
||||
class SearchClass { |
||||
public static $SEARCH_CLASS_ADVANCED_SEARCH_NUMBER_FIELDS = 5; |
||||
function solr_search($query, $startPage=1, $fq = NULL, $dismax = NULL) { |
||||
$solrFile = trim(variable_get('islandora_solr_search_block_handler_file', 'plugins/SolrResults.inc')); |
||||
if (strpos($solrField, '../')) { // Don't let us bust out of fedora_repository modules directory when looking for a handler |
||||
drupal_set_message(t('You have illegal characters in your solr handler function in the Islandora solr block config.'), 'error'); |
||||
} |
||||
$solrClass = trim(variable_get('islandora_solr_search_block_handler_class', 'SolrResults')); |
||||
$solrFunction = trim(variable_get('islandora_solr_search_block_handler_function', 'SearchAndDisplay')); |
||||
require_once(drupal_get_path('module', 'fedora_repository') . '/'. $solrFile); |
||||
try { |
||||
$implementation = new $solrClass(); |
||||
} catch (Exception $e) { |
||||
watchdog(t("Fedora_Repository"), t("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); |
||||
} |
||||
function build_solr_search_form($repeat = NULL, $pathToSearchTerms = NULL, $query = NULL) { |
||||
$types = $this->get_search_terms_array(NULL, 'solrSearchTerms.xml'); |
||||
$queryArray=NULL; |
||||
if (isset($query)) { |
||||
$queryArray = explode('AND', $query); |
||||
} |
||||
|
||||
$andOrArray = array( |
||||
'AND' => 'and', |
||||
//'OR' => 'or' //removed or for now as it would be a pain to parse |
||||
); |
||||
$form = array(); |
||||
|
||||
if (!isset($repeat)) { |
||||
$repeat = variable_get('islandora_solr_search_block_repeat', t('3')); |
||||
} |
||||
$var0 = explode(':', $queryArray[0]); |
||||
$var1 = explode(':', $queryArray[1]); |
||||
$form['search_type']['type1'] = array( |
||||
'#title' => t(''), |
||||
'#type' => 'select', |
||||
'#options' => $types, |
||||
'#default_value' => trim($var0[0]) |
||||
); |
||||
$form['fedora_terms1'] = array( |
||||
'#size' => '24', |
||||
'#type' => 'textfield', |
||||
'#title' => t(''), |
||||
'#required' => TRUE, |
||||
'#default_value' => (count($var0) >= 2 ? trim($var0[1]) : ''), |
||||
); |
||||
$form['andor1'] = array( |
||||
'#title' => t(''), |
||||
'#type' => 'select', |
||||
'#default_value' => 'AND', |
||||
'#options' => $andOrArray |
||||
); |
||||
$form['search_type']['type2'] = array( |
||||
'#title' => t(''), |
||||
'#type' => 'select', |
||||
'#options' => $types, |
||||
'#default_value' => (count($var1) >= 2 ? trim($var1[0]) : ''), |
||||
); |
||||
$form['fedora_terms2'] = array( |
||||
'#size' => '24', |
||||
'#type' => 'textfield', |
||||
'#title' => t(''), |
||||
'#default_value' => (count($var1) >= 2 ? $var1[1] : ''), |
||||
); |
||||
if ($repeat>2 && $repeat < 9) { //don't want less then 2 or more then 9 |
||||
for ($i = 3; $i < $repeat + 1; $i++) { |
||||
$t = $i - 1; |
||||
$field_and_term = explode(':', $queryArray[$t]); |
||||
$form["andor$t"] = array( |
||||
'#title' => t(''), |
||||
'#type' => 'select', |
||||
'#default_value' => 'AND', |
||||
'#options' => $andOrArray |
||||
); |
||||
$form['search_type']["type$i"] = array( |
||||
'#title' => t(''), |
||||
'#type' => 'select', |
||||
'#options' => $types, |
||||
'#default_value' => trim($field_and_term[0]) |
||||
); |
||||
$form["fedora_terms$i"] = array( |
||||
'#size' => '24', |
||||
'#type' => 'textfield', |
||||
'#title' => t(''), |
||||
'#default_value' => (count($field_and_term) >= 2 ? trim($field_and_term[1]) : ''), |
||||
); |
||||
} |
||||
} |
||||
|
||||
$form['submit'] = array( |
||||
'#type' => 'submit', |
||||
'#value' => t('search') |
||||
); |
||||
return $form; |
||||
} |
||||
|
||||
function build_simple_solr_form() { |
||||
//$form = array(); |
||||
$form["search_query"] = array( |
||||
'#size' => '30', |
||||
'#type' => 'textfield', |
||||
'#title' => t(''), |
||||
// '#default_value' => (count($field_and_term) >= 2 ? trim($field_and_term[1]) : ''), |
||||
); |
||||
$form['submit'] = array( |
||||
'#type' => 'submit', |
||||
'#value' => t('search') |
||||
); |
||||
return $form; |
||||
} |
||||
function theme_solr_search_form($form) { |
||||
if (!isset($repeat)) { |
||||
$repeat = variable_get('islandora_solr_search_block_repeat', t('3')); |
||||
} |
||||
|
||||
$output = drupal_render($form['search_type']['type1']) ; |
||||
$output .= drupal_render($form['fedora_terms1']) ; |
||||
$output .= drupal_render($form['andor1']) . drupal_render($form['search_type']['type2']) ; |
||||
$output .= drupal_render($form['fedora_terms2']); |
||||
if ($repeat>2 && $repeat < 9) { |
||||
for ($i=3;$i<$repeat+1;$i++) { |
||||
$t = $i - 1; |
||||
$output .= drupal_render($form["andor$t"]) . drupal_render($form['search_type']["type$i"]) ; |
||||
$output .= drupal_render($form["fedora_terms$i"]) ; |
||||
} |
||||
} |
||||
$output .= drupal_render($form['submit']) ; |
||||
$output .= drupal_render($form); |
||||
return $output; |
||||
|
||||
|
||||
} |
||||
function quickSearch($type, $query, $showForm = 1, $orderBy = 0, & $userArray) { |
||||
module_load_include('inc', 'fedora_repository', 'ObjectHelper'); |
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); |
||||
if (user_access('view fedora collection')) { |
||||
$numberOfHistPerPage = '5000'; //hack for IR they do not want next button |
||||
$luceneQuery = NULL; |
||||
// Demo search string ?operation=gfindObjects&indexName=DemoOnLucene&query=fgs.DS.first.text%3Achristmas&hitPageStart=11&hitPageSize=10 |
||||
$keywords = explode(' ', $query); |
||||
|
||||
foreach ($keywords as $keyword) { |
||||
$luceneQuery .= $type . ':'. $keyword . '+AND+'; |
||||
} |
||||
$luceneQuery = substr($luceneQuery, 0, strlen($luceneQuery) - 5); |
||||
|
||||
$indexName = variable_get('fedora_index_name', 'DemoOnLucene'); |
||||
$keys = htmlentities(urlencode($query)); |
||||
$searchUrl = variable_get('fedora_fgsearch_url', 'http://localhost:8080/fedoragsearch/rest'); |
||||
$searchString = '?operation=gfindObjects&indexName='. $indexName . '&restXslt=copyXml&query='. $luceneQuery; |
||||
$searchString .= '&hitPageSize='. $numberOfHistPerPage . '&hitPageStart=1'; |
||||
//$searchString = htmlentities($searchString); |
||||
$searchUrl .= $searchString; |
||||
|
||||
// $objectHelper = new ObjectHelper(); |
||||
|
||||
$resultData = do_curl($searchUrl, 1); |
||||
if (isset($userArray)) { |
||||
$doc = new DOMDocument(); |
||||
$doc->loadXML($resultData); |
||||
$xPath = new DOMXPath($doc); |
||||
// Add users to department list. This is a hack as not all users will be in dupal |
||||
$nodeList = $xPath->query('//field[@name="refworks.u1"]'); |
||||
foreach ($nodeList as $node) { |
||||
if (!in_array($node->nodeValue, $userArray)) { |
||||
$userArray[]=$node->nodeValue; |
||||
} |
||||
} |
||||
} |
||||
if ($showForm) { |
||||
$output = '<Strong>Quick Search</strong><br /><table class="table-form"><tr>'. drupal_get_form('fedora_repository_quick_search_form') . '</tr></table>'; |
||||
} |
||||
$output .= $this->applyXSLT($resultData, $orderBy); |
||||
return $output; |
||||
} |
||||
} |
||||
|
||||
|
||||
// gets term from a lucene index and displays them in a list |
||||
function getTerms($fieldName, $startTerm, $displayName = NULL) { |
||||
module_load_include('inc', 'fedora_repository', 'ObjectHelper'); |
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); |
||||
$indexName = variable_get('fedora_index_name', 'DemoOnLucene'); |
||||
$searchUrl = variable_get('fedora_fgsearch_url', 'http://localhost:8080/fedoragsearch/rest'); |
||||
if ($startTerm == NULL) { |
||||
$startTerm = ""; |
||||
} |
||||
$startTerm = drupal_urlencode($startTerm); |
||||
$query = 'operation=browseIndex&startTerm='. $startTerm . '&fieldName='. $fieldName . '&termPageSize=20&indexName='. $indexName . '&restXslt=copyXml&resultPageXslt=copyXml'; |
||||
// $query=drupal_urlencode($query); |
||||
$query = '?'. $query; |
||||
$searchString=$searchUrl . $query; |
||||
|
||||
$objectHelper = new ObjectHelper(); |
||||
|
||||
$resultData = do_curl($searchString, 1); |
||||
$path = drupal_get_path('module', 'Fedora_Repository'); |
||||
|
||||
$output .= $this->applySpecifiedXSLT($resultData, $path . '/xsl/browseIndexToResultPage.xslt', $displayName); |
||||
//$output .= '<br />'.$alpha_out; |
||||
return $output; |
||||
|
||||
} |
||||
|
||||
/* |
||||
function custom_search($query,$pathToXslt=NULL){ |
||||
module_load_include('php', 'Fedora_Repository', 'ObjectHelper'); |
||||
module_load_include('inc', 'Fedora_Repository', 'api/fedora_utils'); |
||||
if (user_access('view fedora collection')) { |
||||
$numberOfHistPerPage = '1000';//hack for IR they do not want next button |
||||
$luceneQuery = NULL; |
||||
//demo search string ?operation=gfindObjects&indexName=DemoOnLucene&query=fgs.DS.first.text%3Achristmas&hitPageStart=11&hitPageSize=10 |
||||
|
||||
|
||||
$indexName = variable_get('fedora_index_name', 'DemoOnLucene'); |
||||
$query=htmlentities(urlencode($query)); |
||||
|
||||
$searchUrl = variable_get('fedora_fgsearch_url', 'http://localhost:8080/fedoragsearch/rest'); |
||||
$searchString = '?operation=gfindObjects&indexName=' . $indexName . '&restXslt=copyXml&query=' . $query; |
||||
$searchString .= '&hitPageSize='.$numberOfHistPerPage.'&hitPageStart=1'; |
||||
//$searchString = htmlentities($searchString); |
||||
$searchUrl .= $searchString; |
||||
|
||||
$objectHelper = new ObjectHelper(); |
||||
|
||||
$resultData = do_curl($searchUrl,1); |
||||
//var_dump($resultData);exit(0); |
||||
// $doc = new DOMDocument(); |
||||
// $doc->loadXML($resultData); |
||||
if($pathToXslt==NULL) { |
||||
$output.=$this->applyLuceneXSLT($resultData,$query); |
||||
}else{ |
||||
$output.=$this->applySpecifiedXSLT($resultData,$pathToXslt); |
||||
} |
||||
|
||||
return $output; |
||||
|
||||
} |
||||
} |
||||
*/ |
||||
|
||||
function custom_search($query, $startPage=1, $xslt= '/xsl/advanced_search_results.xsl', $numberOfHistPerPage = 50) { |
||||
module_load_include('inc', 'fedora_repository', 'ObjectHelper'); |
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); |
||||
|
||||
if (user_access('view fedora collection')) { |
||||
//$numberOfHistPerPage = '50';//hack for IR they do not want next button |
||||
$luceneQuery = NULL; |
||||
$indexName = variable_get('fedora_index_name', 'DemoOnLucene'); |
||||
$copyXMLFile = 'copyXml'; |
||||
// if($indexName=='ilives' || $indexName=='BasicIndex'){ |
||||
// $copyXMLFile = 'copyXmliLives'; |
||||
// } |
||||
$query = trim($query); |
||||
$query = htmlentities(urlencode($query)); |
||||
$searchUrl = variable_get('fedora_fgsearch_url', 'http://localhost:8080/fedoragsearch/rest'); |
||||
$searchString = '?operation=gfindObjects&indexName=' . $indexName . '&restXslt='. $copyXMLFile . '&query=' . $query; |
||||
$searchString .= '&hitPageSize='. $numberOfHistPerPage . '&hitPageStart='. $startPage; |
||||
//$searchString = htmlentities($searchString); |
||||
$searchUrl .= $searchString; |
||||
|
||||
//$objectHelper = new ObjectHelper(); |
||||
|
||||
$resultData = do_curl($searchUrl, 1); |
||||
//var_dump($resultData);exit(0); |
||||
// $doc = new DOMDocument(); |
||||
// $doc->loadXML($resultData); |
||||
|
||||
$output .= $this->applyLuceneXSLT($resultData, $startPage, $xslt, $query); |
||||
return $output; |
||||
} |
||||
} |
||||
|
||||
|
||||
function applySpecifiedXSLT($resultData, $pathToXSLT, $displayName = NULL) { |
||||
$proc = NULL; |
||||
global $user; |
||||
if (!$resultData) { |
||||
drupal_set_message(t('No data found!')); |
||||
return ' '; //no results |
||||
} |
||||
try { |
||||
$proc = new XsltProcessor(); |
||||
} |
||||
catch (Exception $e) { |
||||
drupal_set_message(t('Error loading '. $pathToXSLT . ' xslt!') . $e->getMessage()); |
||||
return ' '; |
||||
} |
||||
|
||||
//$proc->setParameter('', 'searchUrl', url('search') . '/fedora_repository'); //needed in our xsl |
||||
$proc->setParameter('', 'objectsPage', base_path()); |
||||
$proc->setParameter('', 'userID', $user->uid); |
||||
if (isset($displayName)) { |
||||
$proc->setParameter('', 'displayName', $displayName); |
||||
} |
||||
else { |
||||
$proc->setParameter('', 'displayName', "test"); |
||||
} |
||||
|
||||
$xsl = new DomDocument(); |
||||
|
||||
$test= $xsl->load($pathToXSLT); |
||||
|
||||
if (!isset($test)) { |
||||
drupal_set_message(t('Error loading '. $pathToXSLT . ' xslt!')); |
||||
return t('Error loading !pathToXSLT xslt.', array('!pathToXSLT' => $pathToXSLT)); |
||||
} |
||||
|
||||
$input = new DomDocument(); |
||||
|
||||
$didLoadOk = $input->loadXML($resultData); |
||||
|
||||
if (!isset($didLoadOk)) { |
||||
drupal_set_message(t('Error loading XML data!')); |
||||
return t('Error loading XML data.'); |
||||
} |
||||
else { |
||||
$proc->importStylesheet($xsl); |
||||
$newdom = $proc->transformToDoc($input); |
||||
return $newdom->saveXML(); |
||||
} |
||||
} |
||||
//default function for lucene results |
||||
/* |
||||
function applyLuceneXSLT($resultData, $query = NULL){ |
||||
$path = drupal_get_path('module', 'Fedora_Repository'); |
||||
$proc = NULL; |
||||
if (!$resultData) { |
||||
drupal_set_message(t('No Results!')); |
||||
return ' '; //no results |
||||
} |
||||
try { |
||||
$proc = new XsltProcessor(); |
||||
} |
||||
catch (Exception $e) { |
||||
drupal_set_message(t('Error loading results xslt! ') . $e->getMessage()) ; |
||||
return ' '; |
||||
} |
||||
|
||||
//inject into xsl stylesheet |
||||
if(isset($query)){ |
||||
$proc->setParameter('', 'fullQuery', $query); |
||||
} |
||||
$proc->setParameter('', 'searchToken', drupal_get_token('fedora_repository_advanced_search')); //token generated by Drupal, keeps tack of what tab etc we are on |
||||
$proc->setParameter('', 'searchUrl', url('search') . '/fedora_repository'); //needed in our xsl |
||||
$proc->setParameter('', 'objectsPage', base_path()); |
||||
$proc->setParameter('', 'allowedPidNameSpaces', variable_get('fedora_pids_allowed', 'demo: changeme:')); |
||||
$proc->registerPHPFunctions(); |
||||
$xsl = new DomDocument(); |
||||
|
||||
$test= $xsl->load($path . '/xsl/results.xsl'); |
||||
if (!isset($test)) { |
||||
drupal_set_message(t('Error loading search results XSLT!')); |
||||
return t('Error loading search results XSLT.'); |
||||
} |
||||
|
||||
$input = new DomDocument(); |
||||
$didLoadOk = $input->loadXML($resultData); |
||||
|
||||
if (!isset($didLoadOk)) { |
||||
drupal_set_message(t('Error loading search results!')); |
||||
return t('Error loading search results.'); |
||||
} |
||||
else { |
||||
$proc->importStylesheet($xsl); |
||||
$newdom = $proc->transformToDoc($input); |
||||
return $newdom->saveXML(); |
||||
} |
||||
} |
||||
*/ |
||||
|
||||
/** |
||||
* apply an xslt to lucene gsearch search results |
||||
* |
||||
* @param <type> $resultData |
||||
* @param <type> $startPage |
||||
* @param <type> $xslt_file |
||||
* @param <type> $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'); |
||||
$proc = NULL; |
||||
if (!$resultData) { |
||||
//drupal_set_message(t('No Results!')); |
||||
return ' '; //no results |
||||
} |
||||
try { |
||||
$proc = new XsltProcessor(); |
||||
} catch (Exception $e) { |
||||
drupal_set_message(t('Error loading results xslt!') . $e->getMessage()); |
||||
return ' '; |
||||
} |
||||
if (isset($query)) { |
||||
$proc->setParameter('', 'fullQuery', $query); |
||||
} |
||||
//inject into xsl stylesheet |
||||
global $user; |
||||
$proc->setParameter('', 'userID', $user->uid); |
||||
$proc->setParameter('', 'searchToken', drupal_get_token('fedora_repository_advanced_search')); //token generated by Drupal, keeps tack of what tab etc we are on |
||||
$proc->setParameter('', 'searchUrl', url('search') . '/fedora_repository'); //needed in our xsl |
||||
$proc->setParameter('', 'objectsPage', base_path()); |
||||
$proc->setParameter('', 'allowedPidNameSpaces', variable_get('fedora_pids_allowed', 'default: demo: changeme: Islandora: ilives: ')); |
||||
$proc->setParameter('', 'hitPageStart', $startPage); |
||||
$proc->registerPHPFunctions(); |
||||
$xsl = new DomDocument(); |
||||
|
||||
$test = $xsl->load($path . $xslt_file); |
||||
if (!isset($test)) { |
||||
drupal_set_message(t('Error loading search results xslt!')); |
||||
return t('Error loading search results XSLT.'); |
||||
} |
||||
|
||||
$input = new DomDocument(); |
||||
$didLoadOk = $input->loadXML($resultData); |
||||
|
||||
if (!isset($didLoadOk)) { |
||||
drupal_set_message(t('Error loading search results!')); |
||||
return t('Error loading search results.'); |
||||
} |
||||
else { |
||||
$proc->importStylesheet($xsl); |
||||
$newdom = $proc->transformToDoc($input); |
||||
return $newdom->saveXML(); |
||||
} |
||||
} |
||||
|
||||
//xslt for islandscholar these xslt functions can probably be pulled into one |
||||
function applyXSLT($resultData, $orderBy = 0) { |
||||
$path = drupal_get_path('module', 'Fedora_Repository'); |
||||
$proc = NULL; |
||||
if (!$resultData) { |
||||
//drupal_set_message(t('No Results!')); |
||||
return ' '; //no results |
||||
} |
||||
try { |
||||
$proc = new XsltProcessor(); |
||||
} catch (Exception $e) { |
||||
drupal_set_message(t('Error loading results xslt! ') . $e->getMessage()); |
||||
return ' '; |
||||
} |
||||
|
||||
//inject into xsl stylesheet |
||||
//$proc->setParameter('', 'searchToken', drupal_get_token('search_form')); //token generated by Drupal, keeps tack of what tab etc we are on |
||||
$proc->setParameter('', 'userID', $user->uid); |
||||
$proc->setParameter('', 'searchUrl', url('search') . '/fedora_repository'); //needed in our xsl |
||||
$proc->setParameter('', 'objectsPage', base_path()); |
||||
$proc->setParameter('', 'allowedPidNameSpaces', variable_get('fedora_pids_allowed', 'default: demo: changeme: Islandora: ilives: ')); |
||||
$proc->setParameter('', 'orderBy', $orderBy); |
||||
$xsl = new DomDocument(); |
||||
|
||||
$test=$xsl->load($path . '/ir/xsl/results.xsl'); |
||||
if (!isset($test)) { |
||||
drupal_set_message(t('Error loading search results xslt!')); |
||||
return t('Error loading search results XSLT.'); |
||||
} |
||||
|
||||
$input = new DomDocument(); |
||||
$didLoadOk = $input->loadXML($resultData); |
||||
|
||||
if (!isset($didLoadOk)) { |
||||
drupal_set_message(t('Error loading search results!')); |
||||
return t('Error loading search results.'); |
||||
} |
||||
else { |
||||
$xsl = $proc->importStylesheet($xsl); |
||||
$newdom = $proc->transformToDoc($input); |
||||
return $newdom->saveXML(); |
||||
} |
||||
} |
||||
|
||||
function theme_advanced_search_form($form, $repeat=NULL) { |
||||
if (!isset($repeat)) { |
||||
$repeat = variable_get('fedora_repository_advanced_block_repeat', t('3')); |
||||
} |
||||
|
||||
$output = drupal_render($form['search_type']['type1']) ; |
||||
$output .= drupal_render($form['fedora_terms1']) ; |
||||
$output .= drupal_render($form['andor1']) . drupal_render($form['search_type']['type2']) ; |
||||
$output .= drupal_render($form['fedora_terms2']); |
||||
if ($repeat>2 && $repeat < 9) { |
||||
for ($i=3;$i<$repeat+1;$i++) { |
||||
$t = $i - 1; |
||||
$output .= drupal_render($form["andor$t"]) . drupal_render($form['search_type']["type$i"]) ; |
||||
$output .= drupal_render($form["fedora_terms$i"]) ; |
||||
} |
||||
} |
||||
$output .= drupal_render($form['submit']) ; |
||||
$output .= drupal_render($form); |
||||
return $output; |
||||
} |
||||
|
||||
//build search form, custom blocks should set the number of repeats or it will use the default |
||||
function build_advanced_search_form($repeat = NULL, $pathToSearchTerms = NULL, $query = NULL) { |
||||
$types = $this->get_search_terms_array($pathToSearchTerms); |
||||
$queryArray=NULL; |
||||
if (isset($query)) { |
||||
$queryArray = explode('AND', $query); |
||||
} |
||||
|
||||
$andOrArray = array( |
||||
'AND' => 'and', |
||||
//'OR' => 'or' //removed or for now as it would be a pain to parse |
||||
); |
||||
$form = array(); |
||||
|
||||
if (!isset($repeat)) { |
||||
$repeat = variable_get('fedora_repository_advanced_block_repeat', t('3')); |
||||
} |
||||
$var0 = explode(':', $queryArray[0]); |
||||
$var1 = explode(':', $queryArray[1]); |
||||
$form['search_type']['type1'] = array( |
||||
'#title' => t(''), |
||||
'#type' => 'select', |
||||
'#options' => $types, |
||||
'#default_value' => trim($var0[0]) |
||||
); |
||||
$form['fedora_terms1'] = array( |
||||
'#size' => '24', |
||||
'#type' => 'textfield', |
||||
'#title' => t(''), |
||||
'#required' => TRUE, |
||||
'#default_value' => (count($var0) >= 2 ? trim($var0[1]) : ''), |
||||
); |
||||
$form['andor1'] = array( |
||||
'#title' => t(''), |
||||
'#type' => 'select', |
||||
'#default_value' => 'AND', |
||||
'#options' => $andOrArray |
||||
); |
||||
$form['search_type']['type2'] = array( |
||||
'#title' => t(''), |
||||
'#type' => 'select', |
||||
'#options' => $types, |
||||
'#default_value' => (count($var1) >= 2 ? trim($var1[0]) : ''), |
||||
); |
||||
$form['fedora_terms2'] = array( |
||||
'#size' => '24', |
||||
'#type' => 'textfield', |
||||
'#title' => t(''), |
||||
'#default_value' => (count($var1) >= 2 ? $var1[1] : ''), |
||||
); |
||||
if ($repeat>2 && $repeat < 9) { //don't want less then 2 or more then 9 |
||||
for ($i = 3; $i < $repeat + 1; $i++) { |
||||
$t = $i - 1; |
||||
$field_and_term = explode(':', $queryArray[$t]); |
||||
$form["andor$t"] = array( |
||||
'#title' => t(''), |
||||
'#type' => 'select', |
||||
'#default_value' => 'AND', |
||||
'#options' => $andOrArray |
||||
); |
||||
$form['search_type']["type$i"] = array( |
||||
'#title' => t(''), |
||||
'#type' => 'select', |
||||
'#options' => $types, |
||||
'#default_value' => trim($field_and_term[0]) |
||||
); |
||||
$form["fedora_terms$i"] = array( |
||||
'#size' => '24', |
||||
'#type' => 'textfield', |
||||
'#title' => t(''), |
||||
'#default_value' => (count($field_and_term) >= 2 ? trim($field_and_term[1]) : ''), |
||||
); |
||||
} |
||||
} |
||||
|
||||
$form['submit'] = array( |
||||
'#type' => 'submit', |
||||
'#value' => t('search') |
||||
); |
||||
return $form; |
||||
} |
||||
|
||||
|
||||
function get_search_terms_array($path = NULL, $file = NULL) { |
||||
if (!isset($path)) { |
||||
$path = drupal_get_path('module', 'Fedora_Repository'); |
||||
} |
||||
$xmlDoc = new DomDocument(); |
||||
if (!isset($file)) { |
||||
$file = 'searchTerms.xml'; |
||||
} |
||||
$xmlDoc->load($path . '/'. $file); |
||||
$nodeList = $xmlDoc->getElementsByTagName('term'); |
||||
$types = array(); |
||||
for ($i = 0; $i < $nodeList->length; $i++) { |
||||
$field = $nodeList->item($i)->getElementsByTagName('field'); |
||||
$value = $nodeList->item($i)->getElementsByTagName('value'); |
||||
$fieldValue = $field->item(0)->nodeValue; |
||||
$valueValue = $value->item(0)->nodeValue; |
||||
$types["$fieldValue"] = "$valueValue"; |
||||
} |
||||
return $types; |
||||
} |
||||
} |
@ -0,0 +1,203 @@
|
||||
<?php |
||||
// $Id$ |
||||
|
||||
/* |
||||
* Created on 22-Oct-08 |
||||
* |
||||
* To change the template for this generated file go to |
||||
* Window - Preferences - PHPeclipse - PHP - Code Templates |
||||
*/ |
||||
|
||||
class SecurityClass { |
||||
public static $SECURITY_CLASS_SECURITY_STREAM = 'CHILD_SECURITY'; |
||||
function SecurityClass() { |
||||
module_load_include('inc', 'SecurityClass', ''); |
||||
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); |
||||
} |
||||
|
||||
function canIngestHere($collection_pid) { |
||||
global $user; |
||||
module_load_include('inc', 'fedora_repository', 'ObjectHelper'); |
||||
$objectHelper = new ObjectHelper(); |
||||
// get the childsecurity policy from the collection. |
||||
$policyStream = $objectHelper->getStream($collection_pid, SECURITYCLASS :: $SECURITY_CLASS_SECURITY_STREAM, FALSE); |
||||
|
||||
if ($policyStream == NULL) { |
||||
// no child policy stream so collection is wide open to anyone to ingest, that has the permission ingest in Drupal. |
||||
// maybe we should return FALSE here?? would be more secure. |
||||
return TRUE; |
||||
} |
||||
$allowedUsersAndRoles = $this->getAllowedUsersAndRoles($policyStream); |
||||
if (!$allowedUsersAndRoles) { |
||||
// error processing stream so don't let them ingest here. |
||||
return FALSE; |
||||
} |
||||
$allowedUsers = $allowedUsersAndRoles["users"]; |
||||
$allowedRoles = $allowedUsersAndRoles["roles"]; |
||||
|
||||
foreach ($user->roles as $role) { |
||||
if (in_array($role, $allowedRoles)) { |
||||
return TRUE; |
||||
} |
||||
} |
||||
|
||||
if (in_array($user->name, $allowedUsers)) { |
||||
return TRUE; |
||||
} |
||||
return FALSE; |
||||
} |
||||
|
||||
//parses our simple xacml policies checking for users or roles that are allowed to ingest |
||||
function getAllowedUsersAndRoles($policyStream) { |
||||
$allowedRoles = array(); |
||||
$allowedUsers = array(); |
||||
$usersAndRoles = array(); |
||||
try { |
||||
$xml = new SimpleXMLElement($policyStream); |
||||
} |
||||
catch (Exception $e) { |
||||
watchdog(t("Fedora_Repository"), t("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' => $e->getMessage())), 'error'); |
||||
return NULL; |
||||
} |
||||
$xml->registerXPathNamespace('default', 'urn:oasis:names:tc:xacml:1.0:policy'); |
||||
|
||||
$conditions = $xml->xpath("//default:Condition"); |
||||
|
||||
foreach ($conditions as $condition) { |
||||
$designator = $condition->Apply->SubjectAttributeDesignator; |
||||
if (empty($designator)) {//$disignator may be wrapped by an or |
||||
$designator=$condition->Apply->Apply->SubjectAttributeDesignator; |
||||
} |
||||
$attributeId = strip_tags($designator['AttributeId']); |
||||
|
||||
if ($attributeId == "fedoraRole") { |
||||
foreach ($condition->Apply->Apply->AttributeValue as $attributeValue) { |
||||
$allowedRoles[] = strip_tags($attributeValue->asXML()); |
||||
} |
||||
foreach ($condition->Apply->Apply->Apply->AttributeValue as $attributeValue) { |
||||
$allowedRoles[] = strip_tags($attributeValue->asXML()); |
||||
} |
||||
} |
||||
if ($attributeId == "urn:fedora:names:fedora:2.1:subject:loginId") { |
||||
foreach ($condition->Apply->Apply->AttributeValue as $attributeValue) { |
||||
$allowedUsers[] = strip_tags($attributeValue->asXML()); |
||||
} |
||||
foreach ($condition->Apply->Apply->Apply->AttributeValue as $attributeValue) { |
||||
$allowedUsers[] = strip_tags($attributeValue->asXML()); |
||||
} |
||||
} |
||||
} |
||||
$usersAndRoles['users'] = $allowedUsers; |
||||
$usersAndRoles['roles'] = $allowedRoles; |
||||
return $usersAndRoles; |
||||
|
||||
} |
||||
// When a user's profile is saved in drupal we will attempt to create a collection for them in Fedora |
||||
// this will be their personal space. In the IR it is editable by users with the same role in the VRE |
||||
// it probably would not be. |
||||
function createPersonalPolicy($user) { |
||||
$doc = new DOMDocument(); |
||||
try { |
||||
$doc->load(drupal_get_path('module', 'Fedora_Repository') . '/policies/noObjectEditPolicy.xml'); |
||||
} |
||||
catch (exception $e) { |
||||
watchdog(t("Fedora_Repository"), t("Problem loading policy file."), NULL, WATCHDOG_ERROR); |
||||
} |
||||
$conditions = $doc->getElementsByTagName('Condition'); |
||||
foreach ($conditions as $condition) { |
||||
$designator = $condition->getElementsByTagName('SubjectAttributeDesignator'); |
||||
foreach ($designator as $des) { |
||||
$attributeId = $des->getAttribute('AttributeId'); |
||||
if ($attributeId == 'fedoraRole') { |
||||
$applies = $condition->getElementsByTagName('Apply'); |
||||
foreach ($applies as $apply) { |
||||
$functionId = $apply->getAttribute('FunctionId'); |
||||
if ($functionId == 'urn:oasis:names:tc:xacml:1.0:function:string-bag') { |
||||
foreach ($user->roles as $role) { |
||||
if (!($role == 'authenticated user' || $role == 'administrator')) { //don't want authenticated user included administrator already is included' |
||||
$newAttributeValue=$doc->createElement('AttributeValue', '<![CDATA['. $role . ']]>'); |
||||
$newAttributeValue->setAttribute('DataType', 'http://www.w3.org/2001/XMLSchema#string'); |
||||
// $newAttributeValue->setAttribute('MustBePresent', 'FALSE'); |
||||
$apply->appendChild($newAttributeValue); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
if ($attributeId == 'urn:fedora:names:fedora:2.1:subject:loginId') { |
||||
$applies = $condition->getElementsByTagName('Apply'); |
||||
foreach ($applies as $apply) { |
||||
$functionId = $apply->getAttribute('FunctionId'); |
||||
if ($functionId == 'urn:oasis:names:tc:xacml:1.0:function:string-bag') { |
||||
$newAttributeValue=$doc->createElement('AttributeValue', $user->name); |
||||
$newAttributeValue->setAttribute('DataType', 'http://www.w3.org/2001/XMLSchema#string'); |
||||
//$newAttributeValue->setAttribute('MustBePresent', 'FALSE'); |
||||
$apply->appendChild($newAttributeValue); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
return $doc; //NULL; //$xml; |
||||
} |
||||
|
||||
/** |
||||
* Add a list of allowed users and roles to the given policy stream and return it. |
||||
* |
||||
* @param string $policy_stream |
||||
* @param array $users_and_roles |
||||
* @return DOMDocument |
||||
*/ |
||||
function set_allowed_users_and_roles(&$policy_stream, $users_and_roles) { |
||||
$allowed_roles = $users_and_roles['roles']; |
||||
$allowed_users = $users_and_roles['users']; |
||||
$dom = new DOMDocument(); |
||||
$dom->loadXML($policy_stream); |
||||
$conditions = $dom->getElementsByTagName('Condition'); |
||||
foreach ($conditions as $condition) { |
||||
$designator = $condition->getElementsByTagName('SubjectAttributeDesignator'); |
||||
foreach ($designator as $des) { |
||||
$attributeId = $des->getAttribute('AttributeId'); |
||||
if ($attributeId == 'fedoraRole') { |
||||
// $applies = $condition->getElementsByTagName('Apply'); |
||||
$applies = $des->parentNode->getElementsByTagName('Apply'); |
||||
foreach ($applies as $apply) { |
||||
$functionId = $apply->getAttribute('FunctionId'); |
||||
if ($functionId == 'urn:oasis:names:tc:xacml:1.0:function:string-bag') { |
||||
foreach ($allowed_roles as $role) { |
||||
if (!($role == 'authenticated user' || $role == 'administrator')) { //don't want authenticated user included administrator already is included' |
||||
$newAttributeValue=$dom->createElement('AttributeValue', $role); |
||||
$newAttributeValue->setAttribute('DataType', 'http://www.w3.org/2001/XMLSchema#string'); |
||||
//$newAttributeValue->setAttribute('MustBePresent', 'FALSE'); |
||||
$apply->appendChild($newAttributeValue); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
if ($attributeId == 'urn:fedora:names:fedora:2.1:subject:loginId') { |
||||
// $applies = $condition->getElementsByTagName('Apply'); |
||||
$applies = $des->parentNode->getElementsByTagName('Apply'); |
||||
foreach ($applies as $apply) { |
||||
$functionId = $apply->getAttribute('FunctionId'); |
||||
if ($functionId == 'urn:oasis:names:tc:xacml:1.0:function:string-bag') { |
||||
foreach ( $allowed_users as $username ) { |
||||
$newAttributeValue=$dom->createElement('AttributeValue', $username ); |
||||
$newAttributeValue->setAttribute('DataType', 'http://www.w3.org/2001/XMLSchema#string'); |
||||
//$newAttributeValue->setAttribute('MustBePresent', 'FALSE'); |
||||
$apply->appendChild($newAttributeValue); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
// $this->collection_policy_stream = $dom->saveXML(); |
||||
return $dom->saveXML(); |
||||
} |
||||
} |
@ -0,0 +1,277 @@
|
||||
<?php |
||||
|
||||
// $Id$ |
||||
|
||||
abstract class XMLDatastream { |
||||
|
||||
static $XMLNS = 'http://www.islandora.ca'; |
||||
static $errors = NULL; |
||||
|
||||
protected $xml = NULL; |
||||
private $valid = NULL; |
||||
|
||||
protected $forceSchema = FALSE; // if set, the datastream will be validated against the specified schema in self::$SCHEMA_URI instead of |
||||
// reading the schema URI from the datastream. |
||||
|
||||
public $pid; |
||||
public $dsid; |
||||
|
||||
|
||||
/** |
||||
* Parses an PID from an identifier. |
||||
* @param string $identifier |
||||
* @return string $pid |
||||
*/ |
||||
public static function getPidFromIdentifier($identifier) { |
||||
return substr($identifier, 0, strpos($identifier, "/")); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* validPid |
||||
* Validates a fedora PID based on the regexp provided in the fedora |
||||
* 3.3 documentation. |
||||
* http://www.fedora-commons.org/confluence/display/FCR30/Fedora+Identifiers |
||||
* |
||||
* @param String $pid |
||||
* @return boolean $valid |
||||
*/ |
||||
public static function validPid($pid) { |
||||
$valid = FALSE; |
||||
if (strlen(trim($pid)) <= 64 && preg_match('/^([A-Za-z0-9]|-|\.)+:(([A-Za-z0-9])|-|\.|~|_|(%[0-9A-F]{2}))+$/', trim($pid))) { |
||||
$valid = TRUE; |
||||
} |
||||
|
||||
return $valid; |
||||
} |
||||
|
||||
/** |
||||
* validDsid |
||||
* Validates a fedora Dsid based on the the allowed XML standard NCName. |
||||
* The regexp is a "regular" subset of names allowed, it excludes some extended hex characters that are |
||||
* technically permitted. |
||||
* http://www.fedora-commons.org/confluence/display/FCR30/Fedora+Identifiers |
||||
* |
||||
* @param String $pid |
||||
* @return boolean $valid |
||||
*/ |
||||
public static function validDsid($dsid) { |
||||
$valid = FALSE; |
||||
if (strlen(trim($dsid)) <= 64 && preg_match('/^[a-zA-Z0-9\_\-\.]+$/', trim($dsid))) { |
||||
$valid = TRUE; |
||||
} |
||||
|
||||
return $valid; |
||||
} |
||||
|
||||
|
||||
|
||||
/** |
||||
* Parses the DSID from an identifier. |
||||
* TODO: combine this method with getPidFromIdentifier? |
||||
* @param string $identifier |
||||
* @return string $dsid |
||||
*/ |
||||
public static function getDSIDFromIdentifier($identifier) { |
||||
$temp = strstr($identifier, "/"); |
||||
return substr($temp, 1); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Constructs an XMLDatastream object from the XML file specified. |
||||
* Returns FALSE on failure. |
||||
* |
||||
* @param string $filename |
||||
* @return XMLDatastream $cm |
||||
*/ |
||||
public static function loadFromFile($filename) { |
||||
return new self(file_get_contents($filename)); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Constructor |
||||
* NOTE: Use the static constructor methods whenever possible. |
||||
* |
||||
* @param string $xmlStr |
||||
* @param string $pid |
||||
* @param string $dsid |
||||
* @return XMLDatastream $cm |
||||
*/ |
||||
public function __construct($xmlStr, $pid = NULL, $dsid = NULL) { |
||||
libxml_use_internal_errors(true); |
||||
$this->pid=$pid; |
||||
$this->dsid=$dsid; |
||||
|
||||
if ($xmlStr !== NULL) { |
||||
$this->xml = (is_object($xmlStr) && get_class($xmlStr) == DOMDocument)?$xmlStr : DOMDocument::loadXML($xmlStr); |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Gets the identifier for this XMLDatastream |
||||
* Returns FALSE on failure. |
||||
* |
||||
* NOTE: not available if constructed directly from file. |
||||
* |
||||
* @return string identifier |
||||
*/ |
||||
public function getIdentifier() { |
||||
return ($this->pid != NULL && $this->dsid != NULL) ? $this->pid . '/'. $this->dsid : FALSE; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Dumps the XMLDatastream as an XML String |
||||
* |
||||
* |
||||
* @return string xml |
||||
*/ |
||||
public function dumpXml() { |
||||
if ($this->xml == NULL) { |
||||
$this->fetchXml(); |
||||
} |
||||
return $this->xml->saveXml(); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Validates the XMLDatastream against the schema location |
||||
* defined by the xmlns:schemaLocation attribute of the root |
||||
* element. If the xmlns:schemaLocation attribute does not exist, |
||||
* then it is assumed to be the old schema and it attempts to convert |
||||
* using the convertFromOldSchema method. |
||||
* |
||||
* TODO: Maybe change it so that it always validates against a known |
||||
* schema. This makes more sense because this class assumes the structure |
||||
* to be known after it has been validated. |
||||
* |
||||
* @return boolean $valid |
||||
*/ |
||||
public function validate() { |
||||
if ($this->valid === NULL) { |
||||
$ret = TRUE; |
||||
if ($this->xml == NULL) { |
||||
$this->fetchXml(); |
||||
} |
||||
// figure out if we're dealing with a new or old schema |
||||
$rootEl = $this->xml->firstChild; |
||||
if (!$rootEl->hasAttributes() || $rootEl->attributes->getNamedItem('schemaLocation') === NULL ) { |
||||
//$tmpname = substr($this->pid, strpos($this->pid, ':') + 1); |
||||
$tmpname = user_password(10); |
||||
$this->convertFromOldSchema(); |
||||
drupal_add_js("fedora_repository_print_new_schema_$tmpname = function(tagID) { |
||||
var target = document.getElementById(tagID); |
||||
var content = target.innerHTML; |
||||
var text = '<html><head><title>Title' + |
||||
'</title><body>' + content +'</body></html>'; |
||||
printerWindow = window.open('', '', 'toolbar=no,location=no,' + 'status=no,menu=no,scrollbars=yes,width=650,height=400'); |
||||
printerWindow.document.open(); |
||||
printerWindow.document.write(text); |
||||
} ", 'inline'); |
||||
|
||||
drupal_set_message('<span id="new_schema_'. $tmpname .'" style="display: none;">'. htmlentities($this->xml->saveXML()) .'</span>Warning: XMLDatastream performed conversion of \''. $this->getIdentifier() .'\' from old schema. Please update the datastream. The new datastream contents are <a href="javascript:fedora_repository_print_new_schema_'. $tmpname .'(\'new_schema_'. $tmpname .'\')">here.</a> '); |
||||
$rootEl = $this->xml->firstChild; |
||||
} |
||||
|
||||
$schemaLocation = NULL; |
||||
if ($this->forceSchema) { |
||||
// hack because you cant easily get the static property value from |
||||
// a subclass. |
||||
$vars = get_class_vars(get_class($this)); |
||||
$schemaLocation = $vars['SCHEMA_URI']; |
||||
|
||||
} |
||||
elseif ($rootEl->attributes->getNamedItem('schemaLocation') !== NULL) { |
||||
//figure out where the schema is located and validate. |
||||
list(, $schemaLocation) = preg_split('/\s+/', $rootEl->attributes->getNamedItem('schemaLocation')->nodeValue); |
||||
} |
||||
$schemaLocation = NULL; |
||||
return TRUE; |
||||
if ($schemaLocation !== NULL) { |
||||
if (!$this->xml->schemaValidate($schemaLocation)) { |
||||
$ret = FALSE; |
||||
$errors=libxml_get_errors(); |
||||
foreach ($errors as $err) { |
||||
self::$errors[] = 'XML Error: Line '. $err->line .': '. $err->message; |
||||
} |
||||
} |
||||
else { |
||||
$this->name=$rootEl->attributes->getNamedItem('name')->nodeValue; |
||||
} |
||||
} |
||||
else { |
||||
$ret = FALSE; |
||||
self::$errors[] = 'Unable to load schema.'; |
||||
} |
||||
|
||||
$this->valid = $ret; |
||||
} |
||||
|
||||
return $this->valid; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Saves the current XML datastream back to fedora. The XML must validate. |
||||
* |
||||
* @return boolean $success |
||||
*/ |
||||
public function saveToFedora() { |
||||
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, NULL); |
||||
return TRUE; |
||||
} |
||||
return FALSE; |
||||
} |
||||
|
||||
/** |
||||
* Purges veersions of the datastream newer than and including the start_date. If |
||||
* End date is specified, it can be used to purge a range of versions instead. Date should be in |
||||
* DATE_RFC822 format |
||||
* |
||||
* @param string $start_date |
||||
* @param string $end_date |
||||
* @return boolean $valid |
||||
*/ |
||||
public function purgeVersions($start_date, $end_date = NULL) { |
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_item'); |
||||
$fedora_item = new Fedora_Item($this->pid); |
||||
return $fedora_item->purge_datastream( $this->dsid, $start_date, $end_date); |
||||
} |
||||
|
||||
/** |
||||
* Gets the history of the datastream from fedora. |
||||
* Returns false on failure. |
||||
* |
||||
* @return string[] $ret |
||||
*/ |
||||
public function getHistory() { |
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_item'); |
||||
$fedora_item = new Fedora_Item($this->pid); |
||||
$history = $fedora_item->get_datastream_history($this->dsid); |
||||
|
||||
$ret = FALSE; |
||||
if ($history !== FALSE) { |
||||
$ret = array(); |
||||
foreach ($history as $version) { |
||||
if ($version->versionID !== NULL) $ret[] = array('versionID' => $version->versionID, 'createDate' => $version->createDate); |
||||
} |
||||
} |
||||
return $ret; |
||||
} |
||||
|
||||
/** |
||||
* Attempts to convert from the old XML schema to the new by |
||||
* traversing the XML DOM and building a new DOM. When done |
||||
* $this->xml is replaced by the newly created DOM.. |
||||
* |
||||
* @return void |
||||
*/ |
||||
abstract protected function convertFromOldSchema(); |
||||
|
||||
} |
@ -0,0 +1,124 @@
|
||||
<?php |
||||
// $Id$ |
||||
|
||||
/* |
||||
* Implements a simple class for working with Dublin Core data and exporting it |
||||
* back to XML. Inspiration and design shamelessly stolen from the pyfedora |
||||
* project at http://pypi.python.org/pypi/pyfedora/0.1.0 |
||||
*/ |
||||
|
||||
class Dublin_Core { |
||||
public $dc = array( |
||||
'dc:title' => array(), |
||||
'dc:creator' => array(), |
||||
'dc:subject' => array(), |
||||
'dc:description' => array(), |
||||
'dc:publisher' => array(), |
||||
'dc:contributor' => array(), |
||||
'dc:date' => array(), |
||||
'dc:type' => array(), |
||||
'dc:format' => array(), |
||||
'dc:identifier' => array(), |
||||
'dc:source' => array(), |
||||
'dc:language' => array(), |
||||
'dc:relation' => array(), |
||||
'dc:coverage' => array(), |
||||
'dc:rights' => array(), |
||||
); |
||||
public $owner; |
||||
|
||||
/** |
||||
* Constructs a Dublin_Core object from a Fedora_Item object and populates |
||||
* the $dc array. |
||||
* @param <type> $item |
||||
*/ |
||||
function Dublin_Core($item = NULL) { |
||||
if (!empty($item)) { |
||||
$this->owner = $item; |
||||
$dc_xml = $item->get_datastream_dissemination('DC'); |
||||
$this->dc = self::import_from_xml_string($dc_xml)->dc; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* |
||||
* @param <type> $element_name |
||||
* @param <type> $value |
||||
*/ |
||||
function add_element( $element_name, $value ) { |
||||
if (is_string($value) && is_array($this->dc[$element_name])) { |
||||
$this->dc[$element_name][] = $value; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Replace the given DC element with the values in $values |
||||
* @param string $elemnt_name |
||||
* @param array $values |
||||
*/ |
||||
function set_element($element_name, $values) { |
||||
if (is_array($values)) { |
||||
$this->dc[$element_name] = $values; |
||||
} |
||||
elseif (is_string($values)) { |
||||
$this->dc[$element_name] = array($values); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Serialize this object to XML and return it. |
||||
*/ |
||||
function as_xml( $with_preamble = FALSE ) { |
||||
$dc_xml = new DomDocument(); |
||||
$oai_dc = $dc_xml->createElementNS('http://www.openarchives.org/OAI/2.0/oai_dc/', 'oai_dc:dc'); |
||||
$oai_dc->setAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); |
||||
foreach ($this->dc as $dc_element => $values) { |
||||
if (is_array($values) && !empty($values)) { |
||||
foreach ($values as $value) { |
||||
$new_item = $dc_xml->createElement($dc_element, $value); |
||||
$oai_dc->appendChild($new_item); |
||||
} |
||||
} |
||||
else { |
||||
$new_item = $dc_xml->createElement($dc_element); |
||||
$oai_dc->appendChild($new_item); |
||||
} |
||||
} |
||||
$dc_xml->appendChild($oai_dc); |
||||
return $dc_xml->saveXML(); |
||||
} |
||||
|
||||
static function create_dc_from_dict() { |
||||
|
||||
} |
||||
|
||||
function save($alt_owner = NULL) { |
||||
$item_to_update = (!empty($alt_owner) ? $alt_owner : $this->owner); |
||||
// My Java roots showing, trying to do polymorphism in PHP. |
||||
if (!empty($item_to_update)) { |
||||
$item_to_update->modify_datastream_by_value($this->as_xml(), 'DC', 'Default Dublin Core Metadata', 'text/xml'); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Creates a new instance of the class by parsing dc_xml |
||||
* @param string $dc_xml |
||||
* @return Dublin_Core |
||||
*/ |
||||
static function import_from_xml_string($dc_xml) { |
||||
$dc_doc = new DomDocument(); |
||||
if ($dc_doc->loadXML($dc_xml)) { |
||||
$oai_dc = $dc_doc->getElementsByTagNameNS('http://purl.org/dc/elements/1.1/', '*'); |
||||
$new_dc = new Dublin_Core(); |
||||
foreach ($oai_dc as $child) { |
||||
array_push($new_dc->dc[$child->nodeName], $child->nodeValue); |
||||
} |
||||
return $new_dc; |
||||
} |
||||
else { |
||||
return NULL; |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
@ -0,0 +1,133 @@
|
||||
<?php |
||||
// $Id$ |
||||
|
||||
/* |
||||
* Operations that affect a Fedora repository at a collection level. |
||||
*/ |
||||
|
||||
module_load_include('inc', 'fedora_repository', 'CollectionClass'); |
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_item'); |
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); |
||||
module_load_include('module', 'fedora_repository'); |
||||
|
||||
/** |
||||
* Exports a fedora collection object and all of its children in a format |
||||
* that will let you import them into another repository. |
||||
* @param <type> $format |
||||
*/ |
||||
function export_collection($collection_pid, $relationship = 'isMemberOfCollection', $format = 'info:fedora/fedora-system:FOXML-1.1' ) { |
||||
$collection_item = new Fedora_Item($collection_pid); |
||||
$foxml = $collection_item->export_as_foxml(); |
||||
|
||||
$file_dir = file_directory_path(); |
||||
|
||||
// Create a temporary directory to contain the exported FOXML files. |
||||
$container = tempnam($file_dir, 'export_'); |
||||
file_delete($container); |
||||
print $container; |
||||
if (mkdir($container) && mkdir($container . '/'. $collection_pid)) { |
||||
$foxml_dir = $container . '/'. $collection_pid; |
||||
$file = fopen($foxml_dir . '/'. $collection_pid . '.xml', 'w'); |
||||
fwrite($file, $foxml); |
||||
fclose($file); |
||||
|
||||
$member_pids = get_related_items_as_array($collection_pid, $relationship); |
||||
foreach ($member_pids as $member) { |
||||
$file = fopen($foxml_dir . '/'. $member . '.xml', 'w'); |
||||
$item = new Fedora_Item($member); |
||||
$item_foxml = $item->export_as_foxml(); |
||||
fwrite($file, $item_foxml); |
||||
fclose($file); |
||||
} |
||||
if (system("cd $container;zip -r $collection_pid.zip $collection_pid/* >/dev/NULL") == 0) { |
||||
header("Content-type: application/zip"); |
||||
header('Content-Disposition: attachment; filename="' . $collection_pid . '.zip'. '"'); |
||||
$fh = fopen($container . '/'. $collection_pid . '.zip', 'r'); |
||||
$the_data = fread($fh, filesize($container . '/'. $collection_pid . '.zip')); |
||||
fclose($fh); |
||||
echo $the_data; |
||||
} |
||||
if (file_exists($container . '/'. $collection_pid)) { |
||||
system("rm -rf $container"); // I'm sorry. |
||||
} |
||||
} |
||||
else { |
||||
drupal_set_message("Error creating temp directory for batch export.", 'error'); |
||||
return FALSE; |
||||
} |
||||
return TRUE; |
||||
} |
||||
|
||||
/** |
||||
* Returns an array of pids that match the query contained in teh collection |
||||
* object's QUERY datastream or in the suppled $query parameter. |
||||
* @param <type> $collection_pid |
||||
* @param <type> $query |
||||
* @param <type> $query_format R |
||||
*/ |
||||
function get_related_items_as_xml($collection_pid, $relationship = array('isMemberOfCollection'), $limit = 10000, $offset = 0, $active_objects_only = TRUE, $cmodel = NULL) { |
||||
module_load_include('inc', 'fedora_repository', 'ObjectHelper'); |
||||
$collection_item = new Fedora_Item($collection_pid); |
||||
|
||||
global $user; |
||||
if (!fedora_repository_access(OBJECTHELPER :: $OBJECT_HELPER_VIEW_FEDORA, $pid, $user)) { |
||||
drupal_set_message(t("You do not have access to Fedora objects within the attempted namespace or access to Fedora denied."), 'error'); |
||||
return array(); |
||||
} |
||||
|
||||
$query_string = 'select $object $title $content from <#ri> |
||||
where ($object <dc:title> $title |
||||
and $object <fedora-model:hasModel> $content |
||||
and ('; |
||||
|
||||
if (is_array($relationship)) { |
||||
foreach ($relationship as $rel) { |
||||
$query_string .= '$object <fedora-rels-ext:'. $rel . '> <info:fedora/'. $collection_pid . '>'; |
||||
if (next($relationship)) { |
||||
$query_string .= ' OR '; |
||||
} |
||||
} |
||||
} |
||||
elseif (is_string($relationship)) { |
||||
$query_string .= '$object <fedora-rels-ext:'. $relationship . '> <info:fedora/'. $collection_pid . '>'; |
||||
} |
||||
else { |
||||
return ''; |
||||
} |
||||
|
||||
$query_string .= ') '; |
||||
$query_string .= $active_objects_only ? 'and $object <fedora-model:state> <info:fedora/fedora-system:def/model#Active>' : ''; |
||||
|
||||
if ($cmodel) { |
||||
$query_string .= ' and $content <mulgara:is> <info:fedora/' . $cmodel . '>'; |
||||
} |
||||
|
||||
$query_string .= ') |
||||
minus $content <mulgara:is> <info:fedora/fedora-system:FedoraObject-3.0> |
||||
order by $title'; |
||||
|
||||
$query_string = htmlentities(urlencode($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); |
||||
|
||||
return $content; |
||||
} |
||||
|
||||
function get_related_items_as_array($collection_pid, $relationship = 'isMemberOfCollection', $limit = 10000, $offset = 0, $active_objects_only = TRUE, $cmodel = NULL) { |
||||
$content = get_related_items_as_xml($collection_pid, $relationship, $limit, $offset, $active_objects_only, $cmodel); |
||||
if (empty($content)) { |
||||
return array(); |
||||
} |
||||
|
||||
$content = new SimpleXMLElement($content); |
||||
|
||||
$resultsarray = array(); |
||||
foreach ($content->results->result as $result) { |
||||
$resultsarray[] = substr($result->object->attributes()->uri, 12); // Remove 'info:fedora/'. |
||||
} |
||||
return $resultsarray; |
||||
} |
@ -0,0 +1,179 @@
|
||||
<?php |
||||
|
||||
// $Id$ |
||||
|
||||
define('FOXML_10', 'info:fedora/fedora-system:FOXML-1.0'); |
||||
define('FOXML_11', 'info:fedora/fedora-system:FOXML-1.1'); |
||||
define('METS_10', 'info:fedora/fedora-system:METSFedoraExt-1.0'); |
||||
define('METS_11', 'info:fedora/fedora-system:METSFedoraExt-1.1'); |
||||
define('ATOM_11', 'info:fedora/fedora-system:ATOM-1.1'); |
||||
define('ATOMZip_11', 'info:fedora/fedora-system:ATOMZip-1.1'); |
||||
|
||||
/** |
||||
* Function to to export all objects assocoiated with a given pid to the export area |
||||
*/ |
||||
function export_to_export_area($pid, $foxml_dir, $ob_dir, &$log = array()) { |
||||
if (!$paths = export_objects_for_pid($pid, $ob_dir, $log)) { |
||||
return FALSE; |
||||
} |
||||
|
||||
if (!export_foxml_for_pid($pid, $foxml_dir, $paths, $log)) { |
||||
return FALSE; |
||||
} |
||||
|
||||
return TRUE; |
||||
} |
||||
|
||||
function export_objects_for_pid($pid, $dir, &$log) { |
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_item'); |
||||
$item = new Fedora_Item($pid); |
||||
if (!$object = $item->get_datastreams_list_as_SimpleXML($pid)) { |
||||
$log[] = log_line(t("Failed to get datastream %dsid for pid %pid", array('%dsid' => $ds->ID, '%pid' => $pid)), 'error'); |
||||
return FALSE; |
||||
} |
||||
|
||||
// Datastreams added as a result of the ingest process |
||||
$ignore_dsids = array('QUERY'); |
||||
|
||||
$paths = array(); |
||||
foreach ($object->datastreamDef as $ds) { |
||||
if (!in_array($ds->ID, $ignore_dsids)) { |
||||
$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'); |
||||
return FALSE; |
||||
} |
||||
fwrite($fp, $content); |
||||
fclose($fp); |
||||
} |
||||
else { |
||||
$log[] = log_line(t("Failed to get datastream %dsid for pid %pid", array('%dsid' => $ds->ID, '%pid' => $pid)), 'error'); |
||||
} |
||||
} |
||||
} |
||||
return $paths; |
||||
} |
||||
|
||||
function export_foxml_for_pid($pid, $dir, $paths, &$log, $format = FOXML_11, $remove_islandora = FALSE) { |
||||
module_load_include('inc', 'fedora_repository', 'ObjectHelper'); |
||||
$ob_helper = new ObjectHelper(); |
||||
if (!$object_xml = $ob_helper->getObject($pid, 'migrate', $format)) { |
||||
$log[] = log_line(t("Failed to get foxml for %pid", array('%pid' => $pid)), 'error'); |
||||
return FALSE; |
||||
} |
||||
|
||||
$foxml = new DOMDocument(); |
||||
$foxml->loadXML($object_xml); |
||||
|
||||
$xpath = new DOMXpath($foxml); |
||||
|
||||
// Remove rdf elements added during ingest (if present) |
||||
if ($remove_islandora) { |
||||
$xpath->registerNamespace('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'); |
||||
$descNode = $xpath->query("//rdf:RDF/rdf:Description")->item(0); |
||||
|
||||
if ($model = $descNode->getElementsByTagName('hasModel')->item(0)) { |
||||
$descNode->removeChild($model); |
||||
} |
||||
|
||||
if ($member = $descNode->getElementsByTagName('rel:isMemberOfCollection')->item(0)) { |
||||
$descNode->removeChild($member); |
||||
} |
||||
} |
||||
|
||||
if ($remove_islandora) { |
||||
// Update object paths in the foxml for this pid |
||||
switch ($format) { |
||||
case FOXML_10: |
||||
case FOXML_11: |
||||
|
||||
$disallowed_groups = array('E', 'R'); |
||||
|
||||
// Update datastream uris |
||||
$xpath->registerNamespace('foxml', 'info:fedora/fedora-system:def/foxml#'); |
||||
foreach ($xpath->query("//foxml:datastream[@ID]") as $dsNode) { |
||||
|
||||
// Don't update datastreams having external uris |
||||
if (in_array($dsNode->getAttribute('CONTROL_GROUP'), $disallowed_groups)) { |
||||
continue; |
||||
} |
||||
|
||||
$dsId = $dsNode->getAttribute('ID'); |
||||
|
||||
// Remove QUERY datastream |
||||
if ($dsId == "QUERY") { |
||||
$parentNode = $xpath->query('/foxml:digitalObject')->item(0); |
||||
$parentNode->removeChild($dsNode); |
||||
} |
||||
|
||||
foreach ($dsNode->getElementsByTagName('*') as $contentNode) { |
||||
if ($str = $contentNode->getAttribute('REF')) { |
||||
$contentNode->setAttribute('REF', url($paths[$dsId], array('absolute' => TRUE))); |
||||
} |
||||
} |
||||
} |
||||
break; |
||||
|
||||
case METS_10: |
||||
case METS_11: |
||||
// Update datastream uris |
||||
$xpath->registerNamespace('METS', 'http://www.loc.gov/METS/'); |
||||
foreach ($xpath->query('//METS:fileGrp[@ID="DATASTREAMS"]/METS:fileGrp') as $dsNode) { |
||||
|
||||
$dsId = $dsNode->getAttribute('ID'); |
||||
|
||||
// Remove QUERY datastream |
||||
if ($dsId == "QUERY") { |
||||
$parentNode = $xpath->query('//METS:fileGrp[@ID="DATASTREAMS"]')->item(0); |
||||
$parentNode->removeChild($dsNode); |
||||
} |
||||
|
||||
$xpath->registerNamespace('xlink', 'http://www.loc.gov/METS/'); |
||||
foreach ($xpath->query('METS:file[@OWNERID!="E"][@OWNERID!="R"]/METS:FLocat[@xlink:href]', $dsNode) as $Floc) { |
||||
$Floc->setAttribute('xlink:href', url($paths[$dsId], array('absolute' => TRUE))); |
||||
} |
||||
/* |
||||
foreach ($dsNode->getElementsByTagName('METS:file') as $contentNode) { |
||||
// Don't update datastreams having external uris |
||||
if (in_array($dsNode->getAttribute('OWNERID'), $disallowed_groups)) { |
||||
continue; |
||||
} |
||||
|
||||
foreach ($xpath->('METS:FLocat[@xlink:href]', $contentNode) as $Floc) { |
||||
$Floc->setAttribute('xlink:href', url($paths[$dsId], array('absolute' => true))); |
||||
} |
||||
`} |
||||
*/ |
||||
} |
||||
|
||||
break; |
||||
|
||||
default: |
||||
$log[] = log_line(t("Unknown or invalid format: ". $format), 'error'); |
||||
return FALSE; |
||||
} |
||||
} //if $remove_islandora |
||||
|
||||
$file = $dir .'/'. $pid .'.xml'; |
||||
if (!$foxml->save($file)) { |
||||
$log[] = log_line(t("Failed to write datastream %dsid for pid %pid to %file", array('%dsid' => $ds->ID, '%pid' => $pid, '%file' => $file)), 'error'); |
||||
return FALSE; |
||||
} |
||||
else { |
||||
$log[] = log_line(t("Exported %pid to %file", array('%pid' => $pid, '%file' => $file)), 'info'); |
||||
} |
||||
|
||||
return TRUE; |
||||
} |
||||
|
||||
function get_file_extension($mimeType) { |
||||
return substr(strstr($mimeType, '/'), 1); |
||||
} |
||||
|
||||
function log_line($msg, $severity = 'info', $sep = "\t") { |
||||
return date("Y-m-d H:i:s") . $sep . ucfirst($severity) . $sep . $msg; |
||||
} |
@ -0,0 +1,780 @@
|
||||
<?php |
||||
|
||||
// $Id$ |
||||
|
||||
define ('RELS_EXT_URI', 'info:fedora/fedora-system:def/relations-external#'); |
||||
define ("FEDORA_MODEL_URI", 'info:fedora/fedora-system:def/model#'); |
||||
|
||||
class Fedora_Item { |
||||
public $pid = NULL; // The $pid of the fedora object represented by an instance of this class. |
||||
public $objectProfile = NULL; |
||||
private $datastreams_list = NULL; // A SimpleXML object to store a list of this item's datastreams |
||||
public $datastreams = NULL; |
||||
|
||||
private static $connection_helper = NULL; |
||||
private static $instantiated_pids = array(); |
||||
|
||||
|
||||
/** |
||||
* Create an object to represent an item in the Fedora repository. |
||||
* Throws a SOAPException if the PID is not in the repository. |
||||
* |
||||
* @param string $pid |
||||
* @return Fedora_Item |
||||
*/ |
||||
function __construct($pid) { |
||||
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); |
||||
module_load_include('inc', 'fedora_repository', 'ConnectionHelper'); |
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); |
||||
|
||||
$this->pid = $pid; |
||||
if (isset(Fedora_Item::$instantiated_pids[$pid])) { |
||||
$this->objectProfile =& Fedora_Item::$instantiated_pids[$pid]->objectProfile; |
||||
$this->datastreams =& Fedora_Item::$instantiated_pids[$pid]->datastreams; |
||||
$this->datastreams_list =& Fedora_Item::$instantiated_pids[$pid]->datastreams_list; |
||||
} else { |
||||
if (empty(self::$connection_helper)) { |
||||
self::$connection_helper = new ConnectionHelper(); |
||||
} |
||||
|
||||
$raw_objprofile = $this->soap_call('getObjectProfile', array('pid' => $this->pid, 'asOfDateTime' => "")); |
||||
|
||||
if (!empty($raw_objprofile)) { |
||||
$this->objectProfile = $raw_objprofile->objectProfile; |
||||
$this->datastreams = $this->get_datastreams_list_as_array(); |
||||
} else { |
||||
$this->objectProfile = ''; |
||||
$this->datastreams = array(); |
||||
} |
||||
Fedora_Item::$instantiated_pids[$pid]=&$this; |
||||
} |
||||
} |
||||
|
||||
function exists() { |
||||
return (!empty($this->objectProfile)); |
||||
} |
||||
|
||||
function add_datastream_from_file($datastream_file, $datastream_id, $datastream_label = NULL, $datastream_mimetype = '', $controlGroup = 'M',$logMessage = null) { |
||||
module_load_include('inc', 'fedora_repository', 'MimeClass'); |
||||
if (empty($datastream_mimetype)) { |
||||
// Get mime type from the file extension. |
||||
$mimetype_helper = new MimeClass(); |
||||
$datastream_mimetype = $mimetype_helper->getType($datastream_file); |
||||
} |
||||
$original_path = $datastream_file; |
||||
// Temporarily move file to a web-accessible location. |
||||
file_copy($datastream_file, file_directory_path()); |
||||
$datastream_url = drupal_urlencode($datastream_file); |
||||
$url = file_create_url($datastream_url); |
||||
|
||||
$return_value = $this->add_datastream_from_url($url, $datastream_id, $datastream_label, $datastream_mimetype, $controlGroup,$logMessage); |
||||
|
||||
if ($original_path != $datastream_file) { |
||||
file_delete($datastream_file); |
||||
} |
||||
return $return_value; |
||||
} |
||||
|
||||
function add_datastream_from_url($datastream_url, $datastream_id, $datastream_label = NULL, $datastream_mimetype = '', $controlGroup = 'M',$logMessage = null) { |
||||
if (empty( $datastream_label)) { |
||||
$datastream_label = $datastream_id; |
||||
} |
||||
|
||||
$params = array( |
||||
'pid' => $this->pid, |
||||
'dsID' => $datastream_id, |
||||
'altIDs' => NULL, |
||||
'dsLabel' => $datastream_label, |
||||
'versionable' => TRUE, |
||||
'MIMEType' => $datastream_mimetype, |
||||
'formatURI' => NULL, |
||||
'dsLocation' => $datastream_url, |
||||
'controlGroup' => $controlGroup, |
||||
'dsState' => 'A', |
||||
'checksumType' => 'DISABLED', |
||||
'checksum' => 'none', |
||||
'logMessage' => ($logMessage != null)?$logMessage: 'Ingested object '. $datastream_id |
||||
); |
||||
|
||||
return $this->soap_call( 'addDataStream', $params )->datastreamID; |
||||
} |
||||
|
||||
function add_datastream_from_string($str, $datastream_id, $datastream_label = NULL, $datastream_mimetype = 'text/xml', $controlGroup = 'M',$logMessage = null) { |
||||
$dir = sys_get_temp_dir(); |
||||
$tmpfilename = tempnam($dir, 'fedoratmp'); |
||||
$tmpfile = fopen($tmpfilename, 'w'); |
||||
fwrite($tmpfile, $str, strlen($str)); |
||||
fclose($tmpfile); |
||||
$returnvalue = $this->add_datastream_from_file($tmpfilename, $datastream_id, $datastream_label, $datastream_mimetype, $controlGroup,$logMessage); |
||||
unlink($tmpfilename); |
||||
return $returnvalue; |
||||
} |
||||
|
||||
/** |
||||
* Add a relationship string to this object's RELS-EXT. |
||||
* does not support rels-int yet. |
||||
* @param string $relationship |
||||
* @param <type> $object |
||||
*/ |
||||
function add_relationship($relationship, $object, $namespaceURI = RELS_EXT_URI) { |
||||
$ds_list = $this->get_datastreams_list_as_array(); |
||||
|
||||
if (empty($ds_list['RELS-EXT'])) { |
||||
$this->add_datastream_from_string(' <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> |
||||
<rdf:Description rdf:about="info:fedora/'. $this->pid . '"> |
||||
</rdf:Description> |
||||
</rdf:RDF>', 'RELS-EXT', 'Fedora object-to-object relationship metadata', 'text/xml', 'X'); |
||||
} |
||||
|
||||
$relsext = $this->get_datastream_dissemination('RELS-EXT'); |
||||
|
||||
if (substr($object, 0, 12) != 'info:fedora/') { |
||||
$object = "info:fedora/$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) { |
||||
$description = $relsextxml->getElementsByTagNameNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'description'); |
||||
} |
||||
$description=$description->item(0); |
||||
|
||||
// Create the new relationship node. |
||||
$newrel = $relsextxml->createElementNS($namespaceURI, $relationship); |
||||
|
||||
$newrel->setAttribute('rdf:resource', $object); |
||||
|
||||
$description->appendChild($newrel); |
||||
$this->modify_datastream_by_value( $relsextxml->saveXML(), 'RELS-EXT', "Fedora Object-to-Object Relationship Metadata", 'text/xml'); |
||||
//print ($description->dump_node()); |
||||
/* |
||||
$params = array( 'pid' => $this->pid, |
||||
'relationship' => $relationship, |
||||
'object' => $object, |
||||
'isLiteral' => FALSE, |
||||
'datatype' => '', |
||||
); |
||||
|
||||
return $this->soap_call( 'addRelationship', $params ); |
||||
*/ |
||||
} |
||||
|
||||
/** |
||||
* Removes the given relationship from the item's RELS-EXT and re-saves it. |
||||
* @param string $relationship |
||||
* @param string $object |
||||
*/ |
||||
function purge_relationship($relationship, $object) { |
||||
$relsext = $this->get_datastream_dissemination('RELS-EXT'); |
||||
$namespaceURI = 'info:fedora/fedora-system:def/relations-external#'; |
||||
// Pre-pend a namespace prefix to recognized relationships |
||||
|
||||
switch ($relationship) { |
||||
case 'rel:isMemberOf': |
||||
case 'fedora:isMemberOf': |
||||
$relationship = "isMemberOf"; |
||||
$namespaceURI = 'info:fedora/fedora-system:def/relations-external#'; |
||||
break; |
||||
case "rel:isMemberOfCollection": |
||||
case "fedora:isMemberOfCollection": |
||||
$relationship = "isMemberOfCollection"; |
||||
$namespaceURI = 'info:fedora/fedora-system:def/relations-external#'; |
||||
break; |
||||
case "fedora:isPartOf": |
||||
$relationship = "isPartOf"; |
||||
$namespaceURI = 'info:fedora/fedora-system:def/relations-external#'; |
||||
break; |
||||
} |
||||
|
||||
if (substr($object, 0, 12) != 'info:fedora/') { |
||||
$object = "info:fedora/$object"; |
||||
} |
||||
|
||||
$relsextxml = new DomDocument(); |
||||
$relsextxml->loadXML($relsext); |
||||
$modified = FALSE; |
||||
$rels = $relsextxml->getElementsByTagNameNS($namespaceURI, $relationship); |
||||
if (!empty($rels)) { |
||||
foreach ($rels as $rel) { |
||||
if ($rel->getAttributeNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'resource') == $object) { |
||||
$rel->parentNode->removeChild($rel); |
||||
$modified = TRUE; |
||||
} |
||||
} |
||||
} |
||||
if ($modified) { |
||||
$this->modify_datastream_by_value( $relsextxml->saveXML(), 'RELS-EXT', "Fedora Object-to-Object Relationship Metadata", 'text/xml'); |
||||
} |
||||
return $modified; |
||||
//print ($description->dump_node()); |
||||
} |
||||
|
||||
function export_as_foxml() { |
||||
$params = array( |
||||
'pid' => $this->pid, |
||||
'format' => 'info:fedora/fedora-system:FOXML-1.1', |
||||
'context' => 'migrate', |
||||
); |
||||
$result = self::soap_call('export', $params); |
||||
return $result->objectXML; |
||||
} |
||||
|
||||
/** |
||||
* Does a search using the "query" format followed by the Fedora REST APi. |
||||
* |
||||
* @param string $pattern to search for, including wildcards. |
||||
* @param string $field The field to search on, e.g. pid, title, cDate. See http://www.fedora-commons.org/confluence/display/FCR30/REST+API#RESTAPI-findObjects for details |
||||
* @param int $max_results not used at this time |
||||
* @return Array of pid => title pairs that match the results |
||||
*/ |
||||
static function find_objects_by_pattern($pattern = '*', $field = 'pid', $max_results = 100, $resultFields = array()) { |
||||
module_load_include('inc', 'fedora_repository', 'api/fedora_utils'); |
||||
|
||||
$pattern = drupal_urlencode($pattern); |
||||
$done = FALSE; |
||||
$cursor = 0; |
||||
$session_token = ''; |
||||
$i = 0; |
||||
$results = array(); |
||||
while (!$done && $i < 5) { |
||||
$i++; |
||||
$url = variable_get('fedora_base_url', 'http://localhost:8080/fedora'); |
||||
if ($cursor == 0) { |
||||
$url .= "/objects?query=$field~$pattern&pid=true&title=true&resultFormat=xml&maxResults=$max_results"; |
||||
} |
||||
else { |
||||
$url .= "/objects?pid=true&title=truesessionToken=$session_token&resultFormat=xml&maxResults=$max_results"; |
||||
} |
||||
|
||||
if (count($resultFields) > 0) { |
||||
$url .= '&'.join('=true&',$resultFields).'=true'; |
||||
} |
||||
|
||||
$resultxml = do_curl($url); |
||||
|
||||
libxml_use_internal_errors(TRUE); |
||||
$resultelements = simplexml_load_string($resultxml); |
||||
if ($resultelements === FALSE) { |
||||
libxml_clear_errors(); |
||||
break; |
||||
} |
||||
$cursor += count($resultelements->resultList->objectFields); |
||||
if (count($resultelements->resultList->objectFields) < $max_results |
||||
|| count($resultelements->resultList->objectFields) == 0) { |
||||
$done = TRUE; |
||||
} |
||||
foreach ($resultelements->resultList->objectFields as $obj) { |
||||
|
||||
$ret = (string)$obj->title; |
||||
if (count($resultFields) > 0) { |
||||
$ret = array('title' => $ret); |
||||
foreach ($resultFields as $field) { |
||||
$ret[$field]=(string)$obj->$field; |
||||
} |
||||
} |
||||
$results[(string)$obj->pid] = $ret; |
||||
$cursor++; |
||||
if ($cursor >= $max_results) { |
||||
$done = TRUE; |
||||
break; |
||||
} |
||||
} |
||||
$session_token = $resultelements->listSession->token; |
||||
$done = !empty($session_token); |
||||
} |
||||
return $results; |
||||
} |
||||
|
||||
function get_datastream_dissemination($dsid, $as_of_date_time = "") { |
||||
$params = array( |
||||
'pid' => $this->pid, |
||||
'dsID' => $dsid, |
||||
'asOfDateTime' => $as_of_date_time, |
||||
); |
||||
$object = self::soap_call('getDataStreamDissemination', $params); |
||||
if (!empty($object)) { |
||||
$content = $object->dissemination->stream; |
||||
$content = trim($content); |
||||
} |
||||
else { |
||||
$content = ""; |
||||
} |
||||
return $content; |
||||
} |
||||
|
||||
function get_datastream($dsid, $as_of_date_time = "") { |
||||
$params = array( |
||||
'pid' => $this->pid, |
||||
'dsID' => $dsid, |
||||
'asOfDateTime' => $as_of_date_time, |
||||
); |
||||
$object = self::soap_call('getDatastream', $params); |
||||
|
||||
return $object->datastream; |
||||
} |
||||
|
||||
function get_datastream_history($dsid) { |
||||
$params = array( |
||||
'pid' => $this->pid, |
||||
'dsID' => $dsid |
||||
); |
||||
$object = self::soap_call('getDatastreamHistory', $params); |
||||
$ret = FALSE; |
||||
if (!empty($object)) { |
||||
$ret = $object->datastream; |
||||
} |
||||
|
||||
return $ret; |
||||
} |
||||
|
||||
function get_dissemination($service_definition_pid, $method_name, $parameters = array(), $as_of_date_time = null) { |
||||
$params = array( |
||||
'pid' => $this->pid, |
||||
'serviceDefinitionPid' => $service_definition_pid, |
||||
'methodName' => $method_name, |
||||
'parameters' => $parameters, |
||||
'asOfDateTime' => $as_of_date_time, |
||||
); |
||||
$object = self::soap_call('getDissemination', $params); |
||||
if (!empty($object)) { |
||||
$content = $object->dissemination->stream; |
||||
$content = trim($content); |
||||
} |
||||
else { |
||||
$content = ""; |
||||
} |
||||
return $content; |
||||
} |
||||
|
||||
/** |
||||
* Retrieves and returns a SimpleXML list of this item's datastreams, and stores them |
||||
* as an instance variable for caching purposes. |
||||
* |
||||
* @return SimpleXMLElement |
||||
*/ |
||||
function get_datastreams_list_as_SimpleXML() { |
||||
//if ( empty( $this->datastreams_list ) ) { |
||||
$params = array( |
||||
'pid' => $this->pid, |
||||
'asOfDateTime' => "" |
||||
); |
||||
|
||||
$this->datastreams_list = $this->soap_call('listDataStreams', $params); |
||||
//} |
||||
return $this->datastreams_list; |
||||
} |
||||
/** |
||||
* * DatastreamControlGroup controlGroup - String restricted to the values of "X", "M", "R", or "E" (InlineXML,Managed Content,Redirect, or External Referenced). |
||||
* String ID - The datastream ID (64 characters max). |
||||
* String versionID - The ID of the most recent datastream version |
||||
* String[] altIDs - Alternative IDs for the datastream, if any. |
||||
* String label - The Label of the datastream. |
||||
* boolean versionable - Whether the datastream is versionable. |
||||
* String MIMEType - The mime-type for the datastream, if set. |
||||
* String formatURI - The format uri for the datastream, if set. |
||||
* String createDate - The date the first version of the datastream was created. |
||||
* long size - The size of the datastream in Fedora. Only valid for inline XML metadata and managed content datastreams. |
||||
* String state - The state of the datastream. Will be "A" (active), "I" (inactive) or "D" (deleted). |
||||
* String location - If the datastream is an external reference or redirect, the url to the contents. TODO: Managed? |
||||
* String checksumType - The algorithm used to compute the checksum. One of "DEFAULT", "DISABLED", "MD5", "SHA-1", "SHA-256", "SHA-385", "SHA-512". |
||||
* String checksum - The value of the checksum represented as a hexadecimal string. |
||||
|
||||
* |
||||
* @param string $dsid |
||||
* @return datastream object |
||||
* get the mimetype size etc. in one shot. instead of iterating throught the datastream list for what we need |
||||
*/ |
||||
function get_datastream_info($dsid,$as_of_date_time = ""){ |
||||
$params = array( |
||||
'pid' => $this->pid, |
||||
'dsID' => $dsid, |
||||
'asOfDateTime' => $as_of_date_time |
||||
); |
||||
|
||||
return $this->soap_call('getDatastream', $params); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Returns an associative array of this object's datastreams. Results look like this: |
||||
* |
||||
* 'DC' => |
||||
* array |
||||
* 'label' => string 'Dublin Core Record for this object' (length=34) |
||||
* 'MIMEType' => string 'text/xml' (length=8) |
||||
* 'RELS-EXT' => |
||||
* array |
||||
* 'label' => string 'RDF Statements about this object' (length=32) |
||||
* 'MIMEType' => string 'application/rdf+xml' (length=19) |
||||
* |
||||
* @return array |
||||
*/ |
||||
function get_datastreams_list_as_array() { |
||||
$this->get_datastreams_list_as_SimpleXML(); |
||||
$ds_list = array(); |
||||
if ($this->datastreams_list != FALSE) { |
||||
|
||||
// This is a really annoying edge case: if there is only one |
||||
// 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) >= 2) { |
||||
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); |
||||
} |
||||
} |
||||
else { |
||||
$ds = $this->datastreams_list->datastreamDef; |
||||
$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); |
||||
} |
||||
} |
||||
|
||||
return $ds_list; |
||||
} |
||||
|
||||
/** |
||||
* Returns a MIME type string for the given Datastream ID. |
||||
* |
||||
* @param string $dsid |
||||
* @return string |
||||
*/ |
||||
function get_mimetype_of_datastream($dsid) { |
||||
$this->get_datastreams_list_as_SimpleXML(); |
||||
|
||||
$mimetype = ''; |
||||
foreach ($datastream_list as $datastream) { |
||||
foreach ($datastream as $datastreamValue) { |
||||
if ($datastreamValue->ID == $dsid) { |
||||
return $datastreamValue->MIMEType; |
||||
} |
||||
} |
||||
} |
||||
|
||||
return ''; |
||||
} |
||||
|
||||
/** |
||||
* Currently the Fedora API call getRelationships is reporting an uncaught |
||||
* exception so we will parse the RELS-EXT ourselves and simulate the |
||||
* documented behaviour. |
||||
* @param String $relationship - filter the results to match this string. |
||||
*/ |
||||
function get_relationships($relationship = NULL) { |
||||
$relationships = array(); |
||||
try { |
||||
$relsext = $this->get_datastream_dissemination('RELS-EXT'); |
||||
} |
||||
catch (exception $e) { |
||||
drupal_set_message("Error retrieving RELS-EXT of object $pid", 'error'); |
||||
return $relationships; |
||||
} |
||||
|
||||
// Parse the RELS-EXT into an associative array. |
||||
$relsextxml = new DOMDocument(); |
||||
$relsextxml->loadXML($relsext); |
||||
$relsextxml->normalizeDocument(); |
||||
$rels = $relsextxml->getElementsByTagNameNS('info:fedora/fedora-system:def/relations-external#', '*'); |
||||
|
||||
foreach ($rels as $child) { |
||||
if (empty($relationship) || preg_match("/$relationship/", $child->tagName)) { |
||||
$relationships[] = array( |
||||
'subject' => $this->pid, |
||||
'predicate' => $child->tagName, |
||||
'object' => substr($child->getAttributeNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'resource'), 12), |
||||
); |
||||
} |
||||
} |
||||
return $relationships; |
||||
//$children = $relsextxml->RDF->description; |
||||
//$children = $relsextxml->RDF->description; |
||||
//$params = array( 'pid' => $this->pid, |
||||
// 'relationship' => 'NULL' ); |
||||
//return $this->soap_call( 'getRelationships', $params ); |
||||
} |
||||
|
||||
/** |
||||
* Creates a RELS-EXT XML stream from the supplied array and saves it to |
||||
* the item on the server. |
||||
* @param <type> $relationships |
||||
*/ |
||||
function save_relationships($relationships) { |
||||
// Verify the array format and that it isn't empty. |
||||
if (!empty($relationships)) { |
||||
$relsextxml = '<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:fedora="info:fedora/fedora-system:def/relations-external#" xmlns:fedora-model="info:fedora/fedora-system:def/model#" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">' |
||||
. '<rdf:description rdf:about="'. $this->pid . '">'; |
||||
|
||||
foreach ($relationships as $rel) { |
||||
if (empty($rel['subject']) || empty($rel['predicate']) || empty($rel['object']) || $rel['subject'] != 'info:fedora/'. $this->pid) { |
||||
// drupal_set_message should use parameterized variables, not interpolated. |
||||
drupal_set_message("Error with relationship format: ". $rel['subject'] . " - ". $rel['predicate'] . ' - '. $rel['object'], "error"); |
||||
return FALSE; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Do the messy work constructing the RELS-EXT XML. Because addRelationship is broken. |
||||
|
||||
return FALSE; |
||||
} |
||||
|
||||
/** |
||||
* Removes this object form the repository. |
||||
*/ |
||||
function purge($log_message = 'Purged using Islandora API.', $force = FALSE) { |
||||
$params = array( |
||||
'pid' => $this->pid, |
||||
'logMessage' => $log_message, |
||||
'force' => $force |
||||
); |
||||
|
||||
return $this->soap_call('purgeObject', $params); |
||||
} |
||||
|
||||
function purge_datastream( $dsID, $start_date = NULL, $end_date = NULL, $log_message = 'Purged datastream using Islandora API', $force = FALSE) { |
||||
$params = array( |
||||
'pid' => $this->pid, |
||||
'dsID' => $dsID, |
||||
'startDT' => $start_date, |
||||
'endDT' => $end_date, |
||||
'logMessage' => $log_message, |
||||
'force' => $force, |
||||
); |
||||
return $this->soap_call('purgeDatastream', $params); |
||||
} |
||||
|
||||
function url() { |
||||
global $base_url; |
||||
return $base_url . '/fedora/repository/'. $this->pid . (!empty($this->objectProfile) ? '/-/'. drupal_urlencode($this->objectProfile->objLabel) : ''); |
||||
} |
||||
|
||||
static function get_next_PID_in_namespace( $pid_namespace = '') { |
||||
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: ')); |
||||
$pid_namespace = $allowed_namespaces[0]; |
||||
if (!empty($pid_namespace)) { |
||||
$pid_namespace = substr($pid_namespace, 0, strpos($pid_namespace, ":")); |
||||
} |
||||
else { |
||||
$pid_namespace = 'default'; |
||||
} |
||||
} |
||||
|
||||
$params = array( |
||||
'numPIDs' => '', |
||||
'pidNamespace' => $pid_namespace, |
||||
); |
||||
|
||||
$result = self::soap_call('getNextPID', $params); |
||||
return $result->pid; |
||||
} |
||||
|
||||
static function ingest_from_FOXML($foxml) { |
||||
$params = array('objectXML' => $foxml->saveXML(), 'format' => "info:fedora/fedora-system:FOXML-1.1", 'logMessage' => "Fedora Object Ingested"); |
||||
$object = self::soap_call('ingest', $params); |
||||
return new Fedora_Item($object->objectPID); |
||||
} |
||||
|
||||
static function ingest_from_FOXML_file($foxml_file) { |
||||
$foxml = new DOMDocument(); |
||||
$foxml->load( $foxml_file ); |
||||
return self::ingest_from_FOXML($foxml); |
||||
} |
||||
|
||||
static function ingest_from_FOXML_files_in_directory($path) { |
||||
// Open the directory |
||||
$dir_handle = @opendir($path); |
||||
// Loop through the files |
||||
while ($file = readdir($dir_handle)) { |
||||
if ($file == "." || $file == ".." || strtolower(substr($file, strlen($file) - 4)) != '.xml') { |
||||
continue; |
||||
} |
||||
|
||||
try { |
||||
self::ingest_from_FOXML_file( $path . '/'. $file ); |
||||
} |
||||
catch (exception $e) { |
||||
} |
||||
} |
||||
// Close |
||||
closedir($dir_handle); |
||||
} |
||||
|
||||
function modify_object($label = '', $state = null, $ownerId = null, $logMessage = 'Modified by Islandora API', $quiet=TRUE) { |
||||
|
||||
$params = array( |
||||
'pid' => $this->pid, |
||||
'ownerId' => $ownerId, |
||||
'state' => $state, |
||||
'label' => $label, |
||||
'logMessage' => $logMessage |
||||
); |
||||
|
||||
return self::soap_call('modifyObject', $params, $quiet); |
||||
} |
||||
|
||||
function modify_datastream_by_value($content, $dsid, $label, $mime_type, $force = FALSE, $logMessage = 'Modified by Islandora API',$quiet=FALSE) { |
||||
$params = array( |
||||
'pid' => $this->pid, |
||||
'dsID' => $dsid, |
||||
'altIDs' => NULL, |
||||
'dsLabel' => $label, |
||||
'MIMEType' => $mime_type, |
||||
'formatURI' => NULL, |
||||
'dsContent' => $content, |
||||
'checksumType' => 'DISABLED', |
||||
'checksum' => 'none', |
||||
'logMessage' => $logMessage, |
||||
'force' => $force |
||||
); |
||||
return self::soap_call('modifyDatastreamByValue', $params,$quiet); |
||||
} |
||||
|
||||
static function soap_call( $function_name, $params_array, $quiet = FALSE ) { |
||||
if (!self::$connection_helper) { |
||||
module_load_include('inc', 'fedora_repository', 'ConnectionHelper'); |
||||
self::$connection_helper = new ConnectionHelper(); |
||||
} |
||||
switch ($function_name) { |
||||
case 'ingest': |
||||
case 'addDataStream': |
||||
case 'addRelationship': |
||||
case 'export': |
||||
case 'getDatastream': |
||||
case 'getDatastreamHistory': |
||||
case 'getNextPID': |
||||
case 'getRelationships': |
||||
case 'modifyDatastreamByValue': |
||||
case 'purgeDatastream': |
||||
case 'purgeObject': |
||||
case 'modifyObject': |
||||
$soap_client = self::$connection_helper->getSoapClient(variable_get('fedora_soap_manage_url', 'http://localhost:8080/fedora/services/management?wsdl')); |
||||
try { |
||||
if (!empty($soap_client)) { |
||||
$result = $soap_client->__soapCall($function_name, array('parameters' => $params_array)); |
||||
} |
||||
else { |
||||
watchdog(t("FEDORA_REPOSITORY"), t("Error trying to get SOAP client connection.")); |
||||
return NULL; |
||||
} |
||||
} |
||||
catch (exception $e) { |
||||
if (!$quiet) { |
||||
|
||||
if (preg_match('/org\.fcrepo\.server\.security\.xacml\.pep\.AuthzDeniedException/',$e->getMessage())) { |
||||
drupal_set_message(t('Error: Insufficient permissions to call SOAP function !fn.', array('!fn' => $function_name) ), 'error'); |
||||
} else { |
||||
drupal_set_message(t("Error trying to call SOAP function $function_name. Check watchdog logs for more information."), 'error'); |
||||
} |
||||
|
||||
watchdog(t("FEDORA_REPOSITORY"), t("Error Trying to call SOAP function !fn: !e", array('!fn' => $function_name, '!e' => $e)), NULL, WATCHDOG_ERROR); |
||||
} |
||||
return NULL; |
||||
} |
||||
break; |
||||
|
||||
default: |
||||
try { |
||||
$soap_client = self::$connection_helper->getSoapClient( variable_get('fedora_soap_url', 'http://localhost:8080/fedora/services/access?wsdl')); |
||||
if (!empty($soap_client)) { |
||||
$result = $soap_client->__soapCall($function_name, array('parameters' => $params_array)); |
||||
} |
||||
else { |
||||
watchdog(t("FEDORA_REPOSITORY"), t("Error trying to get SOAP client connection.")); |
||||
return NULL; |
||||
} |
||||
} |
||||
catch (exception $e) { |
||||
|
||||
if (!$quiet) { |
||||
watchdog(t("FEDORA_REPOSITORY"), t("Error trying to call SOAP function !fn: !e", array('!fn' => $function_name, '!e' => $e)), NULL, WATCHDOG_ERROR); |
||||
} |
||||
return NULL; |
||||
} |
||||
} |
||||
return $result; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Creates the minimal FOXML for a new Fedora object, which is then passed to |
||||
* ingest_from_FOXML to be added to the repository. |
||||
* |
||||
* @param string $pid if none given, getnextpid will be called. |
||||
* @param string $state The initial state, A - Active, I - Inactive, D - Deleted |
||||
*/ |
||||
static function create_object_FOXML($pid = '', $state = 'A', $label = 'Untitled', $owner = '') { |
||||
$foxml = new DOMDocument("1.0", "UTF-8"); |
||||
$foxml->formatOutput = TRUE; |
||||
if (empty($pid)) { |
||||
// Call getNextPid |
||||
$pid = self::get_next_PID_in_namespace(); |
||||
} |
||||
if (empty($owner)) { |
||||
if (!empty($user->uid)) { // Default to current Drupal user. |
||||
$owner = $user->uid; |
||||
} |
||||
else { // We are not inside Drupal |
||||
$owner = 'fedoraAdmin'; |
||||
} |
||||
} |
||||
|
||||
$root_element = $foxml->createElement("foxml:digitalObject"); |
||||
$root_element->setAttribute("VERSION", "1.1"); |
||||
$root_element->setAttribute("PID", $pid); |
||||
$root_element->setAttribute("xmlns:foxml", "info:fedora/fedora-system:def/foxml#"); |
||||
$root_element->setAttribute("xmlns:xsl", "http://www.w3.org/2001/XMLSchema-instance"); |
||||
$root_element->setAttribute("xsl:schemaLocation", "info:fedora/fedora-system:def/foxml# http://www.fedora.info/definitions/1/0/foxml1-1.xsd"); |
||||
$foxml->appendChild($root_element); |
||||
|
||||
// FOXML object properties section |
||||
$object_properties = $foxml->createElement("foxml:objectProperties"); |
||||
$state_property = $foxml->createElement("foxml:property"); |
||||
$state_property->setAttribute("NAME", "info:fedora/fedora-system:def/model#state"); |
||||
$state_property->setAttribute("VALUE", $state); |
||||
|
||||
$label_property = $foxml->createElement("foxml:property"); |
||||
$label_property->setAttribute("NAME", "info:fedora/fedora-system:def/model#label"); |
||||
$label_property->setAttribute("VALUE", $label); |
||||
|
||||
$owner_property = $foxml->createElement("foxml:property"); |
||||
$owner_property->setAttribute("NAME", "info:fedora/fedora-system:def/model#ownerId"); |
||||
$owner_property->setAttribute("VALUE", $owner ); |
||||
|
||||
$object_properties->appendChild($state_property); |
||||
$object_properties->appendChild($label_property); |
||||
$object_properties->appendChild($owner_property); |
||||
$root_element->appendChild($object_properties); |
||||
$foxml->appendChild($root_element); |
||||
|
||||
return $foxml; |
||||
} |
||||
|
||||
static function ingest_new_item($pid = '', $state = 'A', $label = '', $owner = '') { |
||||
return self::ingest_from_FOXML(self::create_object_FOXML( $pid, $state, $label, $owner)); |
||||
} |
||||
|
||||
static function fedora_item_exists($pid) { |
||||
$item = new Fedora_Item($pid); |
||||
return $item->exists(); |
||||
} |
||||
|
||||
/******************************************************** |
||||
* Relationship Functions |
||||
********************************************************/ |
||||
|
||||
/** |
||||
* Returns an associative array of relationships that this item has |
||||
* in its RELS-EXT. |
||||
*/ |
||||
} |
||||
|
@ -0,0 +1,88 @@
|
||||
<?php |
||||
// $Id$ |
||||
|
||||
// @file fedora_utils.inc |
||||
// Base utilities used by the Islansora fedora module. |
||||
|
||||
/* |
||||
* Static functions used by the Fedora PHP API. |
||||
*/ |
||||
|
||||
|
||||
function do_curl($url, $return_to_variable = 1, $number_of_post_vars = 0, $post = NULL) { |
||||
global $user; |
||||
// Check if we are inside Drupal and there is a valid user. |
||||
if ((!isset ($user)) || $user->uid == 0) { |
||||
$fedora_user = 'anonymous'; |
||||
$fedora_pass = 'anonymous'; |
||||
} |
||||
else { |
||||
$fedora_user = $user->name; |
||||
$fedora_pass = $user->pass; |
||||
} |
||||
|
||||
if (function_exists("curl_init")) { |
||||
$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, TRUE); // Fail on errors |
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 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 |
||||
curl_setopt($ch, CURLOPT_URL, $url); |
||||
curl_setopt($ch, CURLOPT_USERPWD, "$fedora_user:$fedora_pass"); |
||||
//curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); |
||||
if ($number_of_post_vars>0&&$post) { |
||||
curl_setopt($ch, CURLOPT_POST, $number_of_post_vars); |
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, "$post"); |
||||
} |
||||
return curl_exec($ch); |
||||
} |
||||
else { |
||||
if (function_exists(drupal_set_message)) { |
||||
drupal_set_message(t('No curl support.'), 'error'); |
||||
} |
||||
return NULL; |
||||
} |
||||
} |
||||
|
||||
function fedora_available() { |
||||
$ret = do_curl(variable_get('fedora_soap_url', 'http://localhost:8080/fedora/services/management?wsdl'), 1); |
||||
// A bit of a hack but the SOAP parser will cause a fatal error if you give it the wrong URL. |
||||
return (strpos($ret, 'wsdl:definitions') != FALSE); |
||||
} |
||||
|
||||
/** |
||||
* Returns a UTF-8-encoded transcripiton of the string given in $in_str. |
||||
* @param string $in_str |
||||
* @return string A UTF-8 encoded string. |
||||
*/ |
||||
function fix_encoding($in_str) { |
||||
$cur_encoding = mb_detect_encoding($in_str) ; |
||||
if ($cur_encoding == "UTF-8" && mb_check_encoding($in_str, "UTF-8")) { |
||||
return $in_str; |
||||
} |
||||
else { |
||||
return utf8_encode($in_str); |
||||
} |
||||
} |
||||
|
||||
function validPid($pid) { |
||||
$valid = FALSE; |
||||
if (strlen(trim($pid)) <= 64 && preg_match('/^([A-Za-z0-9]|-|\.)+:(([A-Za-z0-9])|-|\.|~|_|(%[0-9A-F]{2}))+$/', trim($pid))) { |
||||
$valid = TRUE; |
||||
} |
||||
|
||||
return $valid; |
||||
} |
||||
|
||||
function validDsid($dsid) { |
||||
$valid = FALSE; |
||||
if (strlen(trim($dsid)) <= 64 && preg_match('/^[a-zA-Z0-9\_\-\.]+$/', trim($dsid))) { |
||||
$valid = TRUE; |
||||
} |
||||
|
||||
return $valid; |
||||
} |
@ -0,0 +1,43 @@
|
||||
<?php |
||||
// $Id$ |
||||
|
||||
/* |
||||
* To change this template, choose Tools | Templates |
||||
* and open the template in the editor. |
||||
*/ |
||||
|
||||
/** |
||||
* Description of relsext |
||||
* |
||||
* @author aoneill |
||||
*/ |
||||
class RelsExt { |
||||
// Instance variables |
||||
public $relsExtArray = array(); |
||||
private $originalRelsExtArray = array(); // Used to determine the result of modified() funciton. |
||||
// Member functions |
||||
|
||||
/** |
||||
* Constructor that builds itself by retrieving the RELS-EXT stream from |
||||
* the repository for the given Fedora_Item. |
||||
* @param Fedora_Item $item |
||||
*/ |
||||
function RelsExt( $item ) { |
||||
$relsextxml = $item->get_datastream_dissemination('RELS-EXT'); |
||||
|
||||
} |
||||
|
||||
function modified() { |
||||
return !(empty(array_diff($this->relsExtArray, $this->originalRelsExtArray)) && |
||||
empty(array_diff($this->originalRelsExtArray, $this->relsExtArray))); |
||||
} |
||||
|
||||
/** |
||||
* Save the current state of the RELS-EXT array out to the repository item |
||||
* as a datastream. |
||||
*/ |
||||
function save() { |
||||
|
||||
} |
||||
} |
||||
|
@ -0,0 +1,69 @@
|
||||
<?php |
||||
// $Id$ |
||||
|
||||
/* |
||||
* @file tagging.inc |
||||
*/ |
||||
|
||||
/** |
||||
* Description of tagging |
||||
* |
||||
* @author aoneill |
||||
*/ |
||||
class TagSet { |
||||
public $tags = array(); |
||||
public $item = NULL; |
||||
public $tagsDSID = 'TAGS'; |
||||
|
||||
function TagSet($item = NULL) { |
||||
if (!empty($item) && get_class($item) == 'Fedora_Item') { |
||||
$this->item = $item; |
||||
$this->load(); |
||||
} |
||||
} |
||||
|
||||
function load() { |
||||
$tagsxml = isset($this->item->datastreams[$this->tagsDSID])? $this->item->get_datastream_dissemination($this->tagsDSID) : NULL; |
||||
if (empty($tagsxml)) { |
||||
$this->tags = array(); |
||||
return FALSE; |
||||
} |
||||
$tagsdoc = new DOMDocument(); |
||||
$tagsdoc->loadXML($tagsxml); |
||||
$tags = $tagsdoc->getElementsByTagName('tag'); |
||||
foreach ($tags as $tag) { |
||||
$this->tags[] = array( |
||||
'name' => $tag->nodeValue, |
||||
'creator' => $tag->getAttribute('creator') |
||||
); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Saves an associative array of tags to a datastream. |
||||
*/ |
||||
function save() { |
||||
$tagdoc = new DomDocument(); |
||||
$e_tags = new DomElement('tags'); |
||||
$tagdoc->appendChild($e_tags); |
||||
foreach ($this->tags as $tag) { |
||||
$e_tag = $tagdoc->createElement('tag', $tag['name']); |
||||
$e_tag->setAttribute('creator', (!empty($tag['creator'])) ? $tag['creator'] : ''); |
||||
$e_tags->appendChild($e_tag); |
||||
} |
||||
try { |
||||
$datastreams = $this->item->get_datastreams_list_as_array(); |
||||
if (empty($datastreams[$this->tagsDSID])) { |
||||
$this->item->add_datastream_from_string($tagdoc->saveXML(), $this->tagsDSID, 'Tags', 'text/xml', 'X'); |
||||
} |
||||
else { |
||||
$this->item->modify_datastream_by_value($tagdoc->saveXML(), $this->tagsDSID, 'Tags', 'text/xml', 'X'); |
||||
} |
||||
} |
||||
catch (exception $e) { |
||||
drupal_set_message('There was an error saving the tags datastream: !e', array('!e' => $e), 'error'); |
||||
return FALSE; |
||||
} |
||||
return TRUE; |
||||
} |
||||
} |
@ -0,0 +1,21 @@
|
||||
<collection_policy name="" xmlns="http://www.islandora.ca" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.islandora.ca http://syn.lib.umanitoba.ca/collection_policy.xsd"> |
||||
<content_models> |
||||
<content_model dsid="ISLANDORACM" name="Collection" namespace="islandora:collection" pid="islandora:collectionCModel"/> |
||||
</content_models> |
||||
<search_terms> |
||||
<term field="dc.title">dc.title</term> |
||||
<term field="dc.creator">dc.creator</term> |
||||
<term default="true" field="dc.description">dc.description</term> |
||||
<term field="dc.date">dc.date</term> |
||||
<term field="dc.identifier">dc.identifier</term> |
||||
<term field="dc.language">dc.language</term> |
||||
<term field="dc.publisher">dc.publisher</term> |
||||
<term field="dc.rights">dc.rights</term> |
||||
<term field="dc.subject">dc.subject</term> |
||||
<term field="dc.relation">dc.relation</term> |
||||
<term field="dcterms.temporal">dcterms.temporal</term> |
||||
<term field="dcterms.spatial">dcterms.spatial</term> |
||||
<term field="fgs.DS.first.text">Full Text</term> |
||||
</search_terms> |
||||
<relationship>isMemberOfCollection</relationship> |
||||
</collection_policy> |
@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<collection_policy> |
||||
<!---we will define allowed mimetypes and what to do with various types as part of the content model--> |
||||
<contentmodels> |
||||
<contentmodel name="standard_flv"> |
||||
<pid_namespace>vre:test</pid_namespace> |
||||
<pid>vre:contentmodel</pid> |
||||
<dsid>STANDARD_FLV</dsid> |
||||
</contentmodel> |
||||
</contentmodels> |
||||
<search_terms> |
||||
<!--define what fields we can query as part of the advanced search for this collection--> |
||||
<default>dc.description</default> |
||||
<term> |
||||
<field>dc.title</field> |
||||
<value>dc.title</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.creator</field> |
||||
<value>dc.creator</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.description</field> |
||||
<value>dc.description</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.date</field> |
||||
<value>dc.date</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.identifier</field> |
||||
<value>dc.identifier</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.language</field> |
||||
<value>dc.language</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.publisher</field> |
||||
<value>dc.publisher</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.rights</field> |
||||
<value>dc.rights</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.subject</field> |
||||
<value>dc.subject</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.relation</field> |
||||
<value>dc.relation</value> |
||||
</term> |
||||
<term> |
||||
<field>dcterms.temporal</field> |
||||
<value>dcterms.temporal</value> |
||||
</term> |
||||
<term> |
||||
<field>dcterms.spatial</field> |
||||
<value>dcterms.spatial</value> |
||||
</term> |
||||
<term> |
||||
<field>fgs.DS.first.text</field> |
||||
<value>Full Text</value> |
||||
</term> |
||||
</search_terms> |
||||
</collection_policy> |
@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<collection_policy> |
||||
<!---we will define allowed mimetypes and what to do with various types as part of the content model--> |
||||
<contentmodels> |
||||
<contentmodel name="STANDARD_IMAGE"> |
||||
<pid_namespace>vre:spdf</pid_namespace> |
||||
<pid>vre:contentmodel</pid> |
||||
<dsid>STANDARD_IMAGE</dsid> |
||||
</contentmodel> |
||||
</contentmodels> |
||||
<!--if we define a query for an object the relationship we ask for may not be isMemberOfCollection. So when we ingest in th |
||||
Collection we will want the relationship to match the query. If this element is null we will use the isMemberOfCollection relationship--> |
||||
<relationship>isMemberOfCollection</relationship> |
||||
<search_terms> |
||||
<!--define what fields we can query as part of the advanced search for this collection--> |
||||
<default>dc.description</default> |
||||
<term> |
||||
<field>dc.title</field> |
||||
<value>dc.title</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.creator</field> |
||||
<value>dc.creator</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.description</field> |
||||
<value>dc.description</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.date</field> |
||||
<value>dc.date</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.identifier</field> |
||||
<value>dc.identifier</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.language</field> |
||||
<value>dc.language</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.publisher</field> |
||||
<value>dc.publisher</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.rights</field> |
||||
<value>dc.rights</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.subject</field> |
||||
<value>dc.subject</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.relation</field> |
||||
<value>dc.relation</value> |
||||
</term> |
||||
<term> |
||||
<field>dcterms.temporal</field> |
||||
<value>dcterms.temporal</value> |
||||
</term> |
||||
<term> |
||||
<field>dcterms.spatial</field> |
||||
<value>dcterms.spatial</value> |
||||
</term> |
||||
<term> |
||||
<field>fgs.DS.first.text</field> |
||||
<value>Full Text</value> |
||||
</term> |
||||
</search_terms> |
||||
</collection_policy> |
@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<collection_policy> |
||||
<!---we will define allowed mimetypes and what to do with various types as part of the content model--> |
||||
<contentmodels> |
||||
<contentmodel name="STANDARD_JPEG"> |
||||
<pid_namespace>demo:Smiley</pid_namespace> |
||||
<pid>demo:DualResImage</pid> |
||||
<dsid>ISLANDORACM</dsid> |
||||
</contentmodel> |
||||
</contentmodels> |
||||
<!--if we define a query for an object the relationship we ask for may not be isMemberOfCollection. So when we ingest in th |
||||
Collection we will want the relationship to match the query. If this element is null we will use the isMemberOfCollection relationship--> |
||||
<relationship>isMemberOf</relationship> |
||||
<search_terms> |
||||
<!--define what fields we can query as part of the advanced search for this collection, not used yet--> |
||||
<default>dc.description</default> |
||||
<term> |
||||
<field>dc.title</field> |
||||
<value>dc.title</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.creator</field> |
||||
<value>dc.creator</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.description</field> |
||||
<value>dc.description</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.date</field> |
||||
<value>dc.date</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.identifier</field> |
||||
<value>dc.identifier</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.language</field> |
||||
<value>dc.language</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.publisher</field> |
||||
<value>dc.publisher</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.rights</field> |
||||
<value>dc.rights</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.subject</field> |
||||
<value>dc.subject</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.relation</field> |
||||
<value>dc.relation</value> |
||||
</term> |
||||
<term> |
||||
<field>dcterms.temporal</field> |
||||
<value>dcterms.temporal</value> |
||||
</term> |
||||
<term> |
||||
<field>dcterms.spatial</field> |
||||
<value>dcterms.spatial</value> |
||||
</term> |
||||
<term> |
||||
<field>fgs.DS.first.text</field> |
||||
<value>Full Text</value> |
||||
</term> |
||||
</search_terms> |
||||
</collection_policy> |
@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> <collection_policy xmlns="http://www.islandora.ca" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="" xsi:schemaLocation="http://www.islandora.ca http://syn.lib.umanitoba.ca/collection_policy.xsd"> <content_models> <content_model name="STANDARD_PDF" dsid="ISLANDORACM" namespace="islandora:spdf" pid="islandora:standard_pdf"/> <content_model name="STRICT_PDF" dsid="ISLANDORACM" namespace="islandora:strictpdf" pid="islandora:strict_pdf"/> <content_model name="REFWORKS_BATCH" dsid="ISLANDORACM" namespace="islandora:ref" pid="islandora:refworks_cm"/> </content_models> <search_terms> <term field="dc.title">dc.title</term> <term field="dc.creator">dc.creator</term> <term field="dc.description" default="true">dc.description</term> <term field="dc.date">dc.date</term> <term field="dc.identifier">dc.identifier</term> <term field="dc.language">dc.language</term> <term field="dc.publisher">dc.publisher</term> <term field="dc.rights">dc.rights</term> <term field="dc.subject">dc.subject</term> <term field="dc.relation">dc.relation</term> <term field="dcterms.temporal">dcterms.temporal</term> <term field="dcterms.spatial">dcterms.spatial</term> <term field="fgs.DS.first.text">Full Text</term> </search_terms> <relationship>isMemberOfCollection</relationship> </collection_policy> |
@ -0,0 +1,79 @@
|
||||
<collection_policy> |
||||
<!---we will define allowed mimetypes and what to do with various types as part of the content model--> |
||||
<contentmodels> |
||||
<contentmodel name="REFWORKS"> |
||||
<pid_namespace>ir:ref</pid_namespace> |
||||
<pid>vre:contentmodel</pid> |
||||
<dsid>REFWORKS</dsid> |
||||
</contentmodel> |
||||
<contentmodel name="STANDARD_PDF"> |
||||
<pid_namespace>ir:ref</pid_namespace> |
||||
<pid>vre:contentmodel</pid> |
||||
<dsid>STANDARD_PDF</dsid> |
||||
</contentmodel> |
||||
<contentmodel name="STANDARD_IMAGE"> |
||||
<pid_namespace>ir:image</pid_namespace> |
||||
<pid>vre:contentmodel</pid> |
||||
<dsid>STANDARD_IMAGE</dsid> |
||||
</contentmodel> |
||||
</contentmodels> |
||||
<!--if we define a query for an object the relationship we ask for may not be isMemberOfCollection. So when we ingest in th |
||||
Collection we will want the relationship to match the query. If this element is null we will use the isMemberOfCollection relationship--> |
||||
<relationship>isMemberOfCollection</relationship> |
||||
<search_terms> |
||||
<!--define what fields we can query as part of the advanced search for this collection--> |
||||
<default>dc.description</default> |
||||
<term> |
||||
<field>dc.title</field> |
||||
<value>dc.title</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.creator</field> |
||||
<value>dc.creator</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.description</field> |
||||
<value>dc.description</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.date</field> |
||||
<value>dc.date</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.identifier</field> |
||||
<value>dc.identifier</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.language</field> |
||||
<value>dc.language</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.publisher</field> |
||||
<value>dc.publisher</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.rights</field> |
||||
<value>dc.rights</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.subject</field> |
||||
<value>dc.subject</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.relation</field> |
||||
<value>dc.relation</value> |
||||
</term> |
||||
<term> |
||||
<field>dcterms.temporal</field> |
||||
<value>dcterms.temporal</value> |
||||
</term> |
||||
<term> |
||||
<field>dcterms.spatial</field> |
||||
<value>dcterms.spatial</value> |
||||
</term> |
||||
<term> |
||||
<field>fgs.DS.first.text</field> |
||||
<value>Full Text</value> |
||||
</term> |
||||
</search_terms> |
||||
</collection_policy> |
@ -0,0 +1,7 @@
|
||||
This folder holds sample collection policy xml files. |
||||
|
||||
These are not used by the module directly from this location but should |
||||
be added as datatreams to objects with a content model property of Collection or |
||||
Community. The datastream id should be COLLECTION_POLICY. |
||||
|
||||
PERSONAL-COLLECTION-POLCIY is referenced from code do not remove |
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<collection_policy> |
||||
<!---we will define allowed mimetypes and what to do with various types as part of the content model--> |
||||
<contentmodels> |
||||
<contentmodel name="REFWORKS"> |
||||
<pid_namespace>ir:ref</pid_namespace> |
||||
<pid>islandora:refworksCModel</pid> |
||||
<dsid>ISLANDORACM</dsid> |
||||
</contentmodel> |
||||
</contentmodels> |
||||
</collection_policy> |
@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<collection_policy> |
||||
<!---we will define allowed mimetypes and what to do with various types as part of the content model--> |
||||
<contentmodels> |
||||
<contentmodel name="STANDARD_PDF"> |
||||
<pid_namespace>vre:riri-</pid_namespace> |
||||
<pid>vre:contentmodel</pid> |
||||
<dsid>STANDARD_PDF</dsid> |
||||
</contentmodel> |
||||
</contentmodels> |
||||
<search_terms> |
||||
<!--define what fields we can query as part of the advanced search for this collection--> |
||||
<default>dc.description</default> |
||||
<term> |
||||
<field>dc.title</field> |
||||
<value>dc.title</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.creator</field> |
||||
<value>dc.creator</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.description</field> |
||||
<value>dc.description</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.date</field> |
||||
<value>dc.date</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.identifier</field> |
||||
<value>dc.identifier</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.language</field> |
||||
<value>dc.language</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.publisher</field> |
||||
<value>dc.publisher</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.rights</field> |
||||
<value>dc.rights</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.subject</field> |
||||
<value>dc.subject</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.relation</field> |
||||
<value>dc.relation</value> |
||||
</term> |
||||
<term> |
||||
<field>dcterms.temporal</field> |
||||
<value>dcterms.temporal</value> |
||||
</term> |
||||
<term> |
||||
<field>dcterms.spatial</field> |
||||
<value>dcterms.spatial</value> |
||||
</term> |
||||
<term> |
||||
<field>fgs.DS.first.text</field> |
||||
<value>Full Text</value> |
||||
</term> |
||||
</search_terms> |
||||
</collection_policy> |
@ -0,0 +1,69 @@
|
||||
<collection_policy> |
||||
<!---we will define allowed mimetypes and what to do with various types as part of the content model--> |
||||
<contentmodels> |
||||
<contentmodel name="Book"> |
||||
<pid_namespace>islandora</pid_namespace> |
||||
<pid>ilives:bookCModel</pid> |
||||
<dsid>ISLANDORACM</dsid> |
||||
</contentmodel> |
||||
</contentmodels> |
||||
<!--if we define a query for an object the relationship we ask for may not be isMemberOfCollection. So when we ingest in th |
||||
Collection we will want the relationship to match the query. If this element is null we will use the isMemberOfCollection relationship--> |
||||
<relationship>isMemberOfCollection</relationship> |
||||
<search_terms> |
||||
<!--define what fields we can query as part of the advanced search for this collection--> |
||||
<default>dc.description</default> |
||||
<term> |
||||
<field>dc.title</field> |
||||
<value>dc.title</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.creator</field> |
||||
<value>dc.creator</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.description</field> |
||||
<value>dc.description</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.date</field> |
||||
<value>dc.date</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.identifier</field> |
||||
<value>dc.identifier</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.language</field> |
||||
<value>dc.language</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.publisher</field> |
||||
<value>dc.publisher</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.rights</field> |
||||
<value>dc.rights</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.subject</field> |
||||
<value>dc.subject</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.relation</field> |
||||
<value>dc.relation</value> |
||||
</term> |
||||
<term> |
||||
<field>dcterms.temporal</field> |
||||
<value>dcterms.temporal</value> |
||||
</term> |
||||
<term> |
||||
<field>dcterms.spatial</field> |
||||
<value>dcterms.spatial</value> |
||||
</term> |
||||
<term> |
||||
<field>fgs.DS.first.text</field> |
||||
<value>Full Text</value> |
||||
</term> |
||||
</search_terms> |
||||
</collection_policy> |
@ -0,0 +1,84 @@
|
||||
<!-- |
||||
Document : slide_collection_policy.xml |
||||
Created on : January 12, 2010, 4:02 PM |
||||
Author : aoneill |
||||
Description: |
||||
Purpose of the document follows. |
||||
--> |
||||
<collection_policy> |
||||
<contentmodels> |
||||
<contentmodel name="SLIDE_CMODEL"> |
||||
<pid_namespace>islandora:slide</pid_namespace> |
||||
<pid>islandora:slideCModel</pid> |
||||
<dsid>ISLANDORACM</dsid> |
||||
</contentmodel> |
||||
<contentmodel name="MAP_CMODEL"> |
||||
<pid_namespace>islandora:map</pid_namespace> |
||||
<pid>islandora:mapCModel</pid> |
||||
<dsid>ISLANDORACM</dsid> |
||||
</contentmodel> |
||||
<contentmodel name="HERB_CMODEL"> |
||||
<pid_namespace>islandora:herb</pid_namespace> |
||||
<pid>islandora:herbCModel</pid> |
||||
<dsid>ISLANDORACM</dsid> |
||||
</contentmodel> |
||||
</contentmodels> |
||||
<!--if we define a query for an object the relationship we ask for may not be isMemberOfCollection. So when we ingest in th |
||||
Collection we will want the relationship to match the query.--> |
||||
<relationship>isMemberOfCollection</relationship> |
||||
<search_terms> |
||||
<default>dc.description</default> |
||||
<term> |
||||
<field>dc.title</field> |
||||
<value>dc.title</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.creator</field> |
||||
<value>dc.creator</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.description</field> |
||||
<value>dc.description</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.date</field> |
||||
<value>dc.date</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.identifier</field> |
||||
<value>dc.identifier</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.language</field> |
||||
<value>dc.language</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.publisher</field> |
||||
<value>dc.publisher</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.rights</field> |
||||
<value>dc.rights</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.subject</field> |
||||
<value>dc.subject</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.relation</field> |
||||
<value>dc.relation</value> |
||||
</term> |
||||
<term> |
||||
<field>dcterms.temporal</field> |
||||
<value>dcterms.temporal</value> |
||||
</term> |
||||
<term> |
||||
<field>dcterms.spatial</field> |
||||
<value>dcterms.spatial</value> |
||||
</term> |
||||
<term> |
||||
<field>fgs.DS.first.text</field> |
||||
<value>Full Text</value> |
||||
</term> |
||||
</search_terms> |
||||
</collection_policy> |
@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
||||
<!-- |
||||
Document : slide_collection_policy.xml |
||||
Created on : January 12, 2010, 4:02 PM |
||||
Author : aoneill |
||||
Description: |
||||
Purpose of the document follows. |
||||
--> |
||||
<collection_policy> |
||||
<contentmodels> |
||||
<contentmodel name="SLIDE_CMODEL"> |
||||
<pid_namespace>islandora:slide</pid_namespace> |
||||
<pid>islandora:slideCModel</pid> |
||||
<dsid>ISLANDORACM</dsid> |
||||
</contentmodel> |
||||
</contentmodels> |
||||
<!--if we define a query for an object the relationship we ask for may not be isMemberOfCollection. So when we ingest in th |
||||
Collection we will want the relationship to match the query.--> |
||||
<relationship>isMemberOfCollection</relationship> |
||||
<search_terms> |
||||
<default>dc.description</default> |
||||
<term> |
||||
<field>dc.title</field> |
||||
<value>dc.title</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.creator</field> |
||||
<value>dc.creator</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.description</field> |
||||
<value>dc.description</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.date</field> |
||||
<value>dc.date</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.identifier</field> |
||||
<value>dc.identifier</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.language</field> |
||||
<value>dc.language</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.publisher</field> |
||||
<value>dc.publisher</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.rights</field> |
||||
<value>dc.rights</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.subject</field> |
||||
<value>dc.subject</value> |
||||
</term> |
||||
<term> |
||||
<field>dc.relation</field> |
||||
<value>dc.relation</value> |
||||
</term> |
||||
<term> |
||||
<field>dcterms.temporal</field> |
||||
<value>dcterms.temporal</value> |
||||
</term> |
||||
<term> |
||||
<field>dcterms.spatial</field> |
||||
<value>dcterms.spatial</value> |
||||
</term> |
||||
<term> |
||||
<field>fgs.DS.first.text</field> |
||||
<value>Full Text</value> |
||||
</term> |
||||
</search_terms> |
||||
</collection_policy> |
@ -0,0 +1,47 @@
|
||||
<xsd:schema xmlns="http://www.islandora.ca" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.islandora.ca" elementFormDefault="qualified" > |
||||
<xsd:annotation> |
||||
<xsd:documentation xml:lang="en"> |
||||
Islandora Collection Policy Schema |
||||
Islandora, Robertson Library, University of Prince Edward Island, 550 University Ave., Charlottetown, Prince Edward Island |
||||
</xsd:documentation> |
||||
</xsd:annotation> |
||||
|
||||
<xsd:element name="collection_policy" type="collection_policyType"/> |
||||
<xsd:complexType name="collection_policyType"> |
||||
<xsd:all> |
||||
<xsd:element name="content_models" type="content_modelsType"/> |
||||
<xsd:element name="search_terms" type="search_termsType"/> |
||||
<xsd:element name="relationship" type="xsd:string"/> |
||||
<xsd:element name="staging_area" type="xsd:string" minOccurs="0" maxOccurs="1"/> |
||||
</xsd:all> |
||||
<xsd:attribute name="name" type="xsd:normalizedString" use="required"/> |
||||
</xsd:complexType> |
||||
|
||||
<xsd:complexType name="content_modelsType"> |
||||
<xsd:sequence> |
||||
<xsd:element name="content_model" type="content_modelType" minOccurs="1" maxOccurs="unbounded"/> |
||||
</xsd:sequence> |
||||
</xsd:complexType> |
||||
|
||||
<xsd:complexType name="content_modelType"> |
||||
<xsd:attribute name="name" type="xsd:normalizedString" use="required"/> |
||||
<xsd:attribute name="dsid" type="xsd:normalizedString" use="required"/> |
||||
<xsd:attribute name="namespace" type="xsd:normalizedString" use="required"/> |
||||
<xsd:attribute name="pid" type="xsd:normalizedString" use="required"/> |
||||
</xsd:complexType> |
||||
|
||||
<xsd:complexType name="search_termsType"> |
||||
<xsd:sequence> |
||||
<xsd:element name="term" type="termType" minOccurs="0" maxOccurs="unbounded"/> |
||||
</xsd:sequence> |
||||
</xsd:complexType> |
||||
|
||||
<xsd:complexType name="termType"> |
||||
<xsd:simpleContent> |
||||
<xsd:extension base="xsd:string"> |
||||
<xsd:attribute name="field" type="xsd:string" use="optional"/> |
||||
<xsd:attribute name="default" type="xsd:boolean" default="false"/> |
||||
</xsd:extension> |
||||
</xsd:simpleContent> |
||||
</xsd:complexType> |
||||
</xsd:schema> |
@ -0,0 +1,264 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s="http://www.w3.org/2001/sw/DataAccess/rf1/result" version="1.0"> |
||||
<!-- Red and White XSLT --> |
||||
<xsl:variable name="BASEURL"> |
||||
<xsl:value-of select="$baseUrl"/> |
||||
</xsl:variable> |
||||
<xsl:variable name="PATH"> |
||||
<xsl:value-of select="$path"/> |
||||
</xsl:variable> |
||||
<xsl:variable name="thisPid" select="$collectionPid"/> |
||||
<xsl:variable name="thisTitle" select="$collectionTitle"/> |
||||
<xsl:variable name="size" select="20"/> |
||||
<xsl:variable name="page" select="$hitPage"/> |
||||
<xsl:variable name="start" select="((number($page) - 1) * number($size)) + 1"/> |
||||
<xsl:variable name="end" select="($start - 1) + number($size)"/> |
||||
<xsl:variable name="cellsPerRow" select="4"/> |
||||
<xsl:variable name="count" select="count(s:sparql/s:results/s:result)"/> |
||||
<xsl:template match="/"> |
||||
<xsl:if test="$count>0"> |
||||
<table cellpadding="3" cellspacing="3"> |
||||
<tr> |
||||
<td colspan="{$cellsPerRow}"> |
||||
<div align="center"> |
||||
<xsl:choose> |
||||
<xsl:when test="$end >= $count and $start = 1"> |
||||
<xsl:value-of select="$start"/>- |
||||
<xsl:value-of select="$count"/> |
||||
of |
||||
<xsl:value-of select="$count"/>  |
||||
<br /> |
||||
</xsl:when> |
||||
<xsl:when test="$end >= $count"> |
||||
<xsl:value-of select="$start"/>- |
||||
<xsl:value-of select="$count"/> |
||||
of |
||||
<xsl:value-of select="$count"/>  |
||||
<br /> |
||||
<a> |
||||
<xsl:attribute name="href"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/ |
||||
<xsl:value-of select="$thisPid"/>/-/ |
||||
<xsl:value-of select="$thisTitle"/>/ |
||||
<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:when test="$start = 1"> |
||||
<xsl:value-of select="$start"/>- |
||||
<xsl:value-of select="$end"/> |
||||
of |
||||
<xsl:value-of select="$count"/>  |
||||
<br /> |
||||
<a> |
||||
<xsl:attribute name="href"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/ |
||||
<xsl:value-of select="$thisPid"/>/-/ |
||||
<xsl:value-of select="$thisTitle"/>/ |
||||
<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$start"/>- |
||||
<xsl:value-of select="$end"/> |
||||
of |
||||
<xsl:value-of select="$count"/>  |
||||
<br /> |
||||
<a> |
||||
<xsl:attribute name="href"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/ |
||||
<xsl:value-of select="$thisPid"/>/-/ |
||||
<xsl:value-of select="$thisTitle"/>/ |
||||
<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a>  |
||||
<a> |
||||
<xsl:attribute name="href"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/ |
||||
<xsl:value-of select="$thisPid"/>/-/ |
||||
<xsl:value-of select="$thisTitle"/>/ |
||||
<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
</div> |
||||
<br clear="all" /> |
||||
</td> |
||||
</tr> |
||||
<xsl:apply-templates select="s:sparql/s:results"/> |
||||
</table> |
||||
<br clear="all" /> |
||||
<div align="center"> |
||||
<xsl:choose> |
||||
<xsl:when test="$end >= $count and $start = 1"> |
||||
<xsl:value-of select="$start"/>- |
||||
<xsl:value-of select="$count"/> |
||||
of |
||||
<xsl:value-of select="$count"/>  |
||||
<br /> |
||||
</xsl:when> |
||||
<xsl:when test="$end >= $count"> |
||||
<xsl:value-of select="$start"/>- |
||||
<xsl:value-of select="$count"/> |
||||
of |
||||
<xsl:value-of select="$count"/>  |
||||
<br /> |
||||
<a> |
||||
<xsl:attribute name="href"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/ |
||||
<xsl:value-of select="$thisPid"/>/-/ |
||||
<xsl:value-of select="$thisTitle"/>/ |
||||
<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:when test="$start = 1"> |
||||
<xsl:value-of select="$start"/>- |
||||
<xsl:value-of select="$end"/> |
||||
of |
||||
<xsl:value-of select="$count"/>  |
||||
<br /> |
||||
<a> |
||||
<xsl:attribute name="href"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/ |
||||
<xsl:value-of select="$thisPid"/>/-/ |
||||
<xsl:value-of select="$thisTitle"/>/ |
||||
<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$start"/>- |
||||
<xsl:value-of select="$end"/> |
||||
of |
||||
<xsl:value-of select="$count"/>  |
||||
<br /> |
||||
<a> |
||||
<xsl:attribute name="href"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/ |
||||
<xsl:value-of select="$thisPid"/>/-/ |
||||
<xsl:value-of select="$thisTitle"/>/ |
||||
<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a>  |
||||
<a> |
||||
<xsl:attribute name="href"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/ |
||||
<xsl:value-of select="$thisPid"/>/-/ |
||||
<xsl:value-of select="$thisTitle"/>/ |
||||
<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
</div> |
||||
</xsl:if> |
||||
</xsl:template> |
||||
<xsl:template match="s:sparql/s:results"> |
||||
<xsl:for-each select="s:result[position() mod $cellsPerRow = 1 and position()>=$start and position() <=$end]"> |
||||
<tr> |
||||
<xsl:apply-templates select=". | following-sibling::s:result[position() < $cellsPerRow]"/> |
||||
</tr> |
||||
</xsl:for-each> |
||||
</xsl:template> |
||||
<xsl:template match="s:result"> |
||||
<xsl:variable name='OBJECTURI' select="s:object/@uri"/> |
||||
<xsl:variable name='PID' select="substring-after($OBJECTURI,'/')"/> |
||||
<xsl:variable name="newTitle" > |
||||
<xsl:call-template name="replace-string"> |
||||
<xsl:with-param name="text" select="s:title"/> |
||||
<xsl:with-param name="from" select="'_'"/> |
||||
<xsl:with-param name="to" select="' '"/> |
||||
</xsl:call-template> |
||||
</xsl:variable> |
||||
<xsl:variable name="linkUrl"> |
||||
<xsl:choose> |
||||
<xsl:when test="(content='Collection' or content='Community')"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/ |
||||
<xsl:copy-of select="$PID"/>/-/ |
||||
<xsl:value-of select="s:title"/> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/ |
||||
<xsl:copy-of select="$PID"/>/ |
||||
<xsl:value-of select="s:title"/>/ |
||||
<xsl:value-of select="s:title"/> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
</xsl:variable> |
||||
<td valign="top" width="25%"> |
||||
|
||||
<img> |
||||
<xsl:attribute name="src"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/ |
||||
<xsl:value-of select="$PID"/>/TN |
||||
</xsl:attribute> |
||||
</img> |
||||
<br clear="all" /> |
||||
|
||||
|
||||
<xsl:value-of select="$newTitle"/> |
||||
|
||||
<xsl:if test="($CONTENTMODEL!='islandora:collectionCModel')"> |
||||
<br />-- |
||||
<a> |
||||
<xsl:attribute name="href"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/ |
||||
<xsl:copy-of select="$PID"/>/-/ |
||||
<xsl:value-of select="s:title"/> |
||||
</xsl:attribute> |
||||
DETAILS |
||||
</a>-- |
||||
</xsl:if> |
||||
</td> |
||||
<xsl:if test="(position() = last()) and (position() < $cellsPerRow)"> |
||||
<xsl:call-template name="FillerCells"> |
||||
<xsl:with-param name="cellCount" select="$cellsPerRow - position()"/> |
||||
</xsl:call-template> |
||||
</xsl:if> |
||||
</xsl:template> |
||||
<xsl:template name="FillerCells"> |
||||
<xsl:param name="cellCount"/> |
||||
<td> </td> |
||||
<xsl:if test="$cellCount > 1"> |
||||
<xsl:call-template name="FillerCells"> |
||||
<xsl:with-param name="cellCount" select="$cellCount - 1"/> |
||||
</xsl:call-template> |
||||
</xsl:if> |
||||
</xsl:template> |
||||
<xsl:template name="replace-string"> |
||||
<xsl:param name="text"/> |
||||
<xsl:param name="from"/> |
||||
<xsl:param name="to"/> |
||||
|
||||
<xsl:choose> |
||||
<xsl:when test="contains($text, $from)"> |
||||
|
||||
<xsl:variable name="before" select="substring-before($text, $from)"/> |
||||
<xsl:variable name="after" select="substring-after($text, $from)"/> |
||||
<xsl:variable name="prefix" select="concat($before, $to)"/> |
||||
|
||||
<xsl:value-of select="$before"/> |
||||
<xsl:value-of select="$to"/> |
||||
<xsl:call-template name="replace-string"> |
||||
<xsl:with-param name="text" select="$after"/> |
||||
<xsl:with-param name="from" select="$from"/> |
||||
<xsl:with-param name="to" select="$to"/> |
||||
</xsl:call-template> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$text"/> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
</xsl:template> |
||||
</xsl:stylesheet> |
@ -0,0 +1,7 @@
|
||||
select $object $title from <#ri> |
||||
where ($object <dc:title> $title |
||||
and $object <fedora-model:hasModel> $content |
||||
and $object <fedora-rels-ext:isMemberOfCollection> <info:fedora/islandora:demos> |
||||
and $object <fedora-model:state> <info:fedora/fedora-system:def/model#Active>) |
||||
|
||||
order by $title |
@ -0,0 +1,79 @@
|
||||
<xsl:stylesheet exclude-result-prefixes="php" version="1.0" xmlns:php="http://php.net/xsl" |
||||
xmlns:s="http://www.w3.org/2001/sw/DataAccess/rf1/result" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
||||
<xsl:template match="/"> |
||||
<xsl:variable name="BASEURL"> |
||||
<xsl:value-of select="$baseUrl"/> |
||||
</xsl:variable> |
||||
<xsl:variable name="PATH"> |
||||
<xsl:value-of select="$path"/> |
||||
</xsl:variable> |
||||
<xsl:variable name="collTitle" select="/s:sparql/s:results/s:result/s:collTitle"/> |
||||
<xsl:variable name="collDesc" select="/s:sparql/s:results/s:result/s:collDesc"/> |
||||
<script src="http://yui.yahooapis.com/2.7.0/build/yahoo-dom-event/yahoo-dom-event.js" type="text/javascript"> |
||||
<xsl:comment>Comment added so script is recognised</xsl:comment> |
||||
</script> |
||||
<script src="http://yui.yahooapis.com/2.7.0/build/animation/animation-min.js" type="text/javascript"> |
||||
<xsl:comment>Comment added so script is recognised</xsl:comment> |
||||
</script> |
||||
<script src="http://yui.yahooapis.com/2.7.0/build/element/element-min.js" type="text/javascript"> |
||||
<xsl:comment>Comment added so script is recognised</xsl:comment> |
||||
</script> |
||||
<script src="http://yui.yahooapis.com/2.7.0/build/container/container_core-min.js" type="text/javascript"> |
||||
<xsl:comment>Comment added so script is recognised</xsl:comment> |
||||
</script> |
||||
<script src="http://yui.yahooapis.com/2.7.0/build/menu/menu-min.js" type="text/javascript"> |
||||
<xsl:comment>Comment added so script is recognised</xsl:comment> |
||||
</script> |
||||
<script src="http://yui.yahooapis.com/2.7.0/build/button/button-min.js" type="text/javascript"> |
||||
<xsl:comment>Comment added so script is recognised</xsl:comment> |
||||
</script> |
||||
<script type="text/javascript"> |
||||
<xsl:attribute name="src"> |
||||
<xsl:value-of select="$PATH"/> |
||||
<xsl:text>/collection_views/yui_coverflow/js/CoverFlow.js</xsl:text> |
||||
</xsl:attribute> |
||||
<xsl:comment>Comment added so script is recognised</xsl:comment> |
||||
</script> |
||||
<script type="text/javascript"> |
||||
<xsl:text> |
||||
|
||||
// YAHOO.util.Event.onDOMReady(function(){ |
||||
//$(document).ready(function(){ |
||||
window.onload = function(){ |
||||
var images = [</xsl:text> |
||||
<xsl:for-each select="/s:sparql/s:results/s:result"> |
||||
<xsl:variable name="OBJECTURI" select="s:object/@uri"/> |
||||
<xsl:variable name="pid" select="substring-after($OBJECTURI,'/')"/> |
||||
<xsl:text>{src: '</xsl:text> |
||||
<xsl:value-of select="$BASEURL"/> |
||||
<xsl:text>/fedora/repository/</xsl:text> |
||||
<xsl:value-of select="$pid"/> |
||||
<xsl:text>/TN', label: '</xsl:text> |
||||
<xsl:value-of select="s:memberTitle"/> |
||||
<xsl:text>', onclick: function(){alert('image1');}}, |
||||
</xsl:text> |
||||
</xsl:for-each> |
||||
<xsl:text> |
||||
]; |
||||
|
||||
var myCoverFlow = new YAHOO.ext.CoverFlow('coverFlowTest', {height: 200, width: 600, images: images}); |
||||
|
||||
function moveLeft(e, coverFlow){ |
||||
coverFlow.selectNext(); |
||||
} |
||||
function moveRight(e, coverFlow){ |
||||
coverFlow.selectPrevious(); |
||||
} |
||||
var myMoveLeftBtn = new YAHOO.widget.Button('moveLeftButton', {onclick: {fn: moveLeft, obj: myCoverFlow}}); |
||||
var myMoveRightBtn = new YAHOO.widget.Button('moveRightButton', {onclick: {fn: moveRight, obj: myCoverFlow}}); |
||||
|
||||
};</xsl:text> |
||||
</script> |
||||
<div class="title">Testing YUI's CoverFlow version 0.1 (beta)</div> |
||||
<div id="coverFlowTest"/> |
||||
<input id="moveLeftButton" type="button" value="Select Next"/> |
||||
<input id="moveRightButton" type="button" value="Select Previous"/> |
||||
<br/> |
||||
<br/> |
||||
</xsl:template> |
||||
</xsl:stylesheet> |
@ -0,0 +1,83 @@
|
||||
<xsl:stylesheet exclude-result-prefixes="php" version="1.0" xmlns:php="http://php.net/xsl" |
||||
xmlns:s="http://www.w3.org/2001/sw/DataAccess/rf1/result" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
||||
<xsl:template match="/"> |
||||
<xsl:variable name="BASEURL"> |
||||
<xsl:value-of select="$baseUrl"/> |
||||
</xsl:variable> |
||||
<xsl:variable name="PATH"> |
||||
<xsl:value-of select="$path"/> |
||||
</xsl:variable> |
||||
<xsl:variable name="collTitle" select="/s:sparql/s:results/s:result/s:collTitle"/> |
||||
<xsl:variable name="collDesc" select="/s:sparql/s:results/s:result/s:collDesc"/> |
||||
<script src="http://yui.yahooapis.com/2.7.0/build/yahoo-dom-event/yahoo-dom-event.js" type="text/javascript"> |
||||
<xsl:comment>Comment added so script is recognised</xsl:comment> |
||||
</script> |
||||
<script src="http://yui.yahooapis.com/2.7.0/build/animation/animation-min.js" type="text/javascript"> |
||||
<xsl:comment>Comment added so script is recognised</xsl:comment> |
||||
</script> |
||||
<script src="http://yui.yahooapis.com/2.7.0/build/element/element-min.js" type="text/javascript"> |
||||
<xsl:comment>Comment added so script is recognised</xsl:comment> |
||||
</script> |
||||
<script src="http://yui.yahooapis.com/2.7.0/build/container/container_core-min.js" type="text/javascript"> |
||||
<xsl:comment>Comment added so script is recognised</xsl:comment> |
||||
</script> |
||||
<script src="http://yui.yahooapis.com/2.7.0/build/menu/menu-min.js" type="text/javascript"> |
||||
<xsl:comment>Comment added so script is recognised</xsl:comment> |
||||
</script> |
||||
<script src="http://yui.yahooapis.com/2.7.0/build/button/button-min.js" type="text/javascript"> |
||||
<xsl:comment>Comment added so script is recognised</xsl:comment> |
||||
</script> |
||||
<script type="text/javascript"> |
||||
<xsl:attribute name="src"> |
||||
<xsl:value-of select="$PATH"/> |
||||
<xsl:text>/collection_views/yui_coverflow/js/CoverFlow.js</xsl:text> |
||||
</xsl:attribute> |
||||
<xsl:comment>Comment added so script is recognised</xsl:comment> |
||||
</script> |
||||
<script type="text/javascript"> |
||||
<xsl:text> |
||||
|
||||
// YAHOO.util.Event.onDOMReady(function(){ |
||||
//$(document).ready(function(){ |
||||
window.onload = function(){ |
||||
var images = [</xsl:text> |
||||
<xsl:for-each select="/s:sparql/s:results/s:result"> |
||||
<xsl:variable name="OBJECTURI" select="s:object/@uri"/> |
||||
<xsl:variable name="pid" select="substring-after($OBJECTURI,'/')"/> |
||||
<xsl:text>{src: '</xsl:text> |
||||
<xsl:value-of select="$BASEURL"/> |
||||
<xsl:text>/fedora/repository/</xsl:text> |
||||
<xsl:value-of select="$pid"/> |
||||
<xsl:text>/PRE', label: '</xsl:text> |
||||
<xsl:value-of select="s:memberTitle"/> |
||||
<xsl:text>', onclick: function(){ window.location='</xsl:text> |
||||
<xsl:value-of select="$BASEURL" /> |
||||
<xsl:text>/fedora/repository/</xsl:text> |
||||
<xsl:value-of select="$pid"/> |
||||
<xsl:text>';}}, |
||||
</xsl:text> |
||||
</xsl:for-each> |
||||
<xsl:text> |
||||
]; |
||||
|
||||
var myCoverFlow = new YAHOO.ext.CoverFlow('coverFlowTest', {height: 300, width: 650, images: images}); |
||||
|
||||
function moveLeft(e, coverFlow){ |
||||
coverFlow.selectNext(); |
||||
} |
||||
function moveRight(e, coverFlow){ |
||||
coverFlow.selectPrevious(); |
||||
} |
||||
var myMoveLeftBtn = new YAHOO.widget.Button('moveLeftButton', {onclick: {fn: moveLeft, obj: myCoverFlow}}); |
||||
var myMoveRightBtn = new YAHOO.widget.Button('moveRightButton', {onclick: {fn: moveRight, obj: myCoverFlow}}); |
||||
|
||||
};</xsl:text> |
||||
</script> |
||||
<div class="title">Testing YUI's CoverFlow version 0.1 (beta)</div> |
||||
<div id="coverFlowTest"/> |
||||
<input id="moveLeftButton" type="button" value="Select Next"/> |
||||
<input id="moveRightButton" type="button" value="Select Previous"/> |
||||
<br/> |
||||
<br/> |
||||
</xsl:template> |
||||
</xsl:stylesheet> |
@ -0,0 +1,212 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> |
||||
<!-- Red and White XSLT --> |
||||
<xsl:variable name="BASEURL"> |
||||
<xsl:value-of select="$baseUrl"/> |
||||
</xsl:variable> |
||||
<xsl:variable name="PATH"> |
||||
<xsl:value-of select="$path"/> |
||||
</xsl:variable> |
||||
<xsl:variable name="thisPid" select="$collectionPid"/> |
||||
<xsl:variable name="thisTitle" select="$collectionTitle"/> |
||||
<xsl:variable name="size" select="20"/> |
||||
<xsl:variable name="page" select="$hitPage"/> |
||||
<xsl:variable name="start" select="((number($page) - 1) * number($size)) + 1"/> |
||||
<xsl:variable name="end" select="($start - 1) + number($size)"/> |
||||
<xsl:variable name="cellsPerRow" select="4"/> |
||||
<xsl:variable name="count" select="count(sparql/results/result)"/> |
||||
<xsl:template match="/"> |
||||
<xsl:if test="$count>0"> |
||||
<table cellpadding="3" cellspacing="3" width="90%"> |
||||
<tr><td colspan="{$cellsPerRow}"> |
||||
<div STYLE="text-align: center;"> |
||||
<xsl:choose> |
||||
<xsl:when test="$end >= $count and $start = 1"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$count"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
</xsl:when> |
||||
<xsl:when test="$end >= $count"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$count"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:when test="$start = 1"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$end"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$end"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a>  |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
</div> <br clear="all" /> |
||||
</td></tr> |
||||
|
||||
<!--<xsl:for-each select="/sparql/results/result[position()>=$start and position() <=$end]"> |
||||
<xsl:variable name='OBJECTURI' select="object/@uri"/> |
||||
<xsl:variable name='PID' select="substring-after($OBJECTURI,'/')"/> |
||||
<tr> |
||||
<td> |
||||
<img> |
||||
<xsl:attribute name="src"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$PID"/>/TN |
||||
</xsl:attribute> |
||||
</img> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:copy-of select="$PID"/>/-/<xsl:value-of select="title"/> |
||||
</xsl:attribute> |
||||
<xsl:value-of select="title"/> |
||||
</a> |
||||
</td> |
||||
</tr> |
||||
</xsl:for-each>- |
||||
--> |
||||
<xsl:apply-templates select="sparql/results"/> |
||||
</table><br clear="all" /> |
||||
<div STYLE="text-align: center;"> |
||||
<xsl:choose> |
||||
<xsl:when test="$end >= $count and $start = 1"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$count"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
</xsl:when> |
||||
<xsl:when test="$end >= $count"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$count"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:when test="$start = 1"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$end"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$end"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a>  |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
</div> |
||||
</xsl:if> |
||||
</xsl:template> |
||||
<xsl:template match="sparql/results"> |
||||
<xsl:for-each select="result[position() mod $cellsPerRow = 1 and position()>=$start and position() <=$end]"> |
||||
<tr> |
||||
<xsl:apply-templates select=". | following-sibling::result[position() < $cellsPerRow]"/> |
||||
</tr> |
||||
</xsl:for-each> |
||||
</xsl:template> |
||||
<xsl:template match="result"> |
||||
<xsl:variable name='OBJECTURI' select="object/@uri"/> |
||||
<xsl:variable name='PID' select="substring-after($OBJECTURI,'/')"/> |
||||
<xsl:variable name="newTitle" > |
||||
<xsl:call-template name="replace-string"> |
||||
<xsl:with-param name="text" select="title"/> |
||||
<xsl:with-param name="from" select="'_'"/> |
||||
<xsl:with-param name="to" select="' '"/> |
||||
</xsl:call-template> |
||||
</xsl:variable> |
||||
<xsl:variable name="linkUrl"> |
||||
<xsl:choose> |
||||
<xsl:when test="(content='Collection' or content='Community')"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:copy-of select="$PID"/>/-/<xsl:value-of select="title"/> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:copy-of select="$PID"/>/OBJ/<xsl:value-of select="title"/> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
</xsl:variable> |
||||
<td valign="top" width="25%"> |
||||
<a> |
||||
<xsl:attribute name="href"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:copy-of select="$PID"/>/-/<xsl:value-of select="title"/> |
||||
</xsl:attribute> |
||||
<img> |
||||
<xsl:attribute name="src"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$PID"/>/TN |
||||
</xsl:attribute> |
||||
<xsl:attribute name="alt"><xsl:value-of select="$newTitle"/> |
||||
</xsl:attribute> |
||||
</img> </a> <br clear="all" /> |
||||
<a> |
||||
<xsl:attribute name="href"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:copy-of select="$PID"/>/-/<xsl:value-of select="title"/> |
||||
</xsl:attribute> |
||||
<xsl:value-of select="$newTitle"/> |
||||
</a> |
||||
|
||||
</td> |
||||
<xsl:if test="(position() = last()) and (position() < $cellsPerRow)"> |
||||
<xsl:call-template name="FillerCells"> |
||||
<xsl:with-param name="cellCount" select="$cellsPerRow - position()"/> |
||||
</xsl:call-template> |
||||
</xsl:if> |
||||
</xsl:template> |
||||
<xsl:template name="FillerCells"> |
||||
<xsl:param name="cellCount"/> |
||||
<td> </td> |
||||
<xsl:if test="$cellCount > 1"> |
||||
<xsl:call-template name="FillerCells"> |
||||
<xsl:with-param name="cellCount" select="$cellCount - 1"/> |
||||
</xsl:call-template> |
||||
</xsl:if> |
||||
</xsl:template> |
||||
<xsl:template name="replace-string"> |
||||
<xsl:param name="text"/> |
||||
<xsl:param name="from"/> |
||||
<xsl:param name="to"/> |
||||
|
||||
<xsl:choose> |
||||
<xsl:when test="contains($text, $from)"> |
||||
|
||||
<xsl:variable name="before" select="substring-before($text, $from)"/> |
||||
<xsl:variable name="after" select="substring-after($text, $from)"/> |
||||
<xsl:variable name="prefix" select="concat($before, $to)"/> |
||||
|
||||
<xsl:value-of select="$before"/> |
||||
<xsl:value-of select="$to"/> |
||||
<xsl:call-template name="replace-string"> |
||||
<xsl:with-param name="text" select="$after"/> |
||||
<xsl:with-param name="from" select="$from"/> |
||||
<xsl:with-param name="to" select="$to"/> |
||||
</xsl:call-template> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$text"/> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
</xsl:template> |
||||
</xsl:stylesheet> |
@ -0,0 +1,11 @@
|
||||
This folder holds xslt files that can be used to transform the |
||||
display of a collection. These files are not used by the module from |
||||
this location but should be added as datastreams to objects that have a |
||||
content model of Collection. |
||||
|
||||
The datastream id should be COLLECTION_VIEW |
||||
|
||||
NOTE: If you add a invalid xslt to a as a collection view you will |
||||
no longer have access to that object or collection. You may have to |
||||
fire up the fedora-admin utility and move or modify the Collection_View datastream. This |
||||
is a bug but not sure when it will be fixed. |
@ -0,0 +1,215 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s="http://www.w3.org/2001/sw/DataAccess/rf1/result" version="1.0"> |
||||
<!-- Red and White XSLT --> |
||||
<xsl:variable name="BASEURL"> |
||||
<xsl:value-of select="$baseUrl"/> |
||||
</xsl:variable> |
||||
<xsl:variable name="PATH"> |
||||
<xsl:value-of select="$path"/> |
||||
</xsl:variable> |
||||
<xsl:variable name="thisPid" select="$collectionPid"/> |
||||
<xsl:variable name="thisTitle" select="$collectionTitle"/> |
||||
<xsl:variable name="size" select="20"/> |
||||
<xsl:variable name="page" select="$hitPage"/> |
||||
<xsl:variable name="start" select="((number($page) - 1) * number($size)) + 1"/> |
||||
<xsl:variable name="end" select="($start - 1) + number($size)"/> |
||||
<xsl:variable name="cellsPerRow" select="4"/> |
||||
<xsl:variable name="count" select="count(s:sparql/s:results/s:result)"/> |
||||
<xsl:template match="/"> |
||||
<xsl:if test="$count>0"> |
||||
<table cellpadding="3" cellspacing="3" width="90%"> |
||||
<tr><td colspan="{$cellsPerRow}"> |
||||
<div STYLE="text-align: center;"> |
||||
<xsl:choose> |
||||
<xsl:when test="$end >= $count and $start = 1"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$count"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
</xsl:when> |
||||
<xsl:when test="$end >= $count"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$count"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:when test="$start = 1"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$end"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$end"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a>  |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
</div> <br clear="all" /> |
||||
</td></tr> |
||||
|
||||
<!--<xsl:for-each select="/sparql/results/result[position()>=$start and position() <=$end]"> |
||||
<xsl:variable name='OBJECTURI' select="object/@uri"/> |
||||
<xsl:variable name='PID' select="substring-after($OBJECTURI,'/')"/> |
||||
<tr> |
||||
<td> |
||||
<img> |
||||
<xsl:attribute name="src"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$PID"/>/TN |
||||
</xsl:attribute> |
||||
</img> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:copy-of select="$PID"/>/-/<xsl:value-of select="title"/> |
||||
</xsl:attribute> |
||||
<xsl:value-of select="title"/> |
||||
</a> |
||||
</td> |
||||
</tr> |
||||
</xsl:for-each>- |
||||
--> |
||||
<xsl:apply-templates select="s:sparql/s:results"/> |
||||
</table><br clear="all" /> |
||||
<div STYLE="text-align: center;"> |
||||
<xsl:choose> |
||||
<xsl:when test="$end >= $count and $start = 1"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$count"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
</xsl:when> |
||||
<xsl:when test="$end >= $count"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$count"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:when test="$start = 1"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$end"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$end"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a>  |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
</div> |
||||
</xsl:if> |
||||
</xsl:template> |
||||
<xsl:template match="s:sparql/s:results"> |
||||
<xsl:for-each select="s:result[position() mod $cellsPerRow = 1 and position()>=$start and position() <=$end]"> |
||||
<tr> |
||||
<xsl:apply-templates select=". | following-sibling::s:result[position() < $cellsPerRow]"/> |
||||
</tr> |
||||
</xsl:for-each> |
||||
</xsl:template> |
||||
<xsl:template match="s:result"> |
||||
<xsl:variable name='OBJECTURI' select="s:object/@uri"/> |
||||
<xsl:variable name='CONTENTURI' select="s:content/@uri"/> |
||||
<xsl:variable name='CONTENTMODEL' select="substring-after($CONTENTURI,'/')"/> |
||||
<xsl:variable name='PID' select="substring-after($OBJECTURI,'/')"/> |
||||
<xsl:variable name="newTitle" > |
||||
<xsl:call-template name="replace-string"> |
||||
<xsl:with-param name="text" select="s:title"/> |
||||
<xsl:with-param name="from" select="'_'"/> |
||||
<xsl:with-param name="to" select="' '"/> |
||||
</xsl:call-template> |
||||
</xsl:variable> |
||||
<xsl:variable name="linkUrl"> |
||||
<xsl:choose> |
||||
<xsl:when test="($CONTENTMODEL='islandora:collectionCModel')"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:copy-of select="$PID"/>/-/<xsl:value-of select="s:title"/> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:copy-of select="$PID"/>/OBJ/<xsl:value-of select="s:title"/> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
<xsl:value-of select="s:content"/> |
||||
</xsl:variable> |
||||
<td valign="top" width="25%"> |
||||
<!-- <a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$linkUrl"/> |
||||
</xsl:attribute> |
||||
<img> |
||||
<xsl:attribute name="src"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$PID"/>/TN |
||||
</xsl:attribute> |
||||
<xsl:attribute name="alt"><xsl:value-of select="$newTitle"/> |
||||
</xsl:attribute> |
||||
</img> </a> <br clear="all" />--> |
||||
|
||||
<br /><a> |
||||
<xsl:attribute name="href"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:copy-of select="$PID"/>/-/<xsl:value-of select="s:title"/> |
||||
</xsl:attribute> |
||||
<xsl:value-of select="$newTitle"/> |
||||
</a> |
||||
|
||||
</td> |
||||
<xsl:if test="(position() = last()) and (position() < $cellsPerRow)"> |
||||
<xsl:call-template name="FillerCells"> |
||||
<xsl:with-param name="cellCount" select="$cellsPerRow - position()"/> |
||||
</xsl:call-template> |
||||
</xsl:if> |
||||
</xsl:template> |
||||
<xsl:template name="FillerCells"> |
||||
<xsl:param name="cellCount"/> |
||||
<td> </td> |
||||
<xsl:if test="$cellCount > 1"> |
||||
<xsl:call-template name="FillerCells"> |
||||
<xsl:with-param name="cellCount" select="$cellCount - 1"/> |
||||
</xsl:call-template> |
||||
</xsl:if> |
||||
</xsl:template> |
||||
<xsl:template name="replace-string"> |
||||
<xsl:param name="text"/> |
||||
<xsl:param name="from"/> |
||||
<xsl:param name="to"/> |
||||
|
||||
<xsl:choose> |
||||
<xsl:when test="contains($text, $from)"> |
||||
|
||||
<xsl:variable name="before" select="substring-before($text, $from)"/> |
||||
<xsl:variable name="after" select="substring-after($text, $from)"/> |
||||
<xsl:variable name="prefix" select="concat($before, $to)"/> |
||||
|
||||
<xsl:value-of select="$before"/> |
||||
<xsl:value-of select="$to"/> |
||||
<xsl:call-template name="replace-string"> |
||||
<xsl:with-param name="text" select="$after"/> |
||||
<xsl:with-param name="from" select="$from"/> |
||||
<xsl:with-param name="to" select="$to"/> |
||||
</xsl:call-template> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$text"/> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
</xsl:template> |
||||
</xsl:stylesheet> |
@ -0,0 +1,215 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s="http://www.w3.org/2001/sw/DataAccess/rf1/result" version="1.0"> |
||||
<!-- Red and White XSLT --> |
||||
<xsl:variable name="BASEURL"> |
||||
<xsl:value-of select="$baseUrl"/> |
||||
</xsl:variable> |
||||
<xsl:variable name="PATH"> |
||||
<xsl:value-of select="$path"/> |
||||
</xsl:variable> |
||||
<xsl:variable name="thisPid" select="$collectionPid"/> |
||||
<xsl:variable name="thisTitle" select="$collectionTitle"/> |
||||
<xsl:variable name="size" select="20"/> |
||||
<xsl:variable name="page" select="$hitPage"/> |
||||
<xsl:variable name="start" select="((number($page) - 1) * number($size)) + 1"/> |
||||
<xsl:variable name="end" select="($start - 1) + number($size)"/> |
||||
<xsl:variable name="cellsPerRow" select="4"/> |
||||
<xsl:variable name="count" select="count(s:sparql/s:results/s:result)"/> |
||||
<xsl:template match="/"> |
||||
<xsl:if test="$count>0"> |
||||
<table cellpadding="3" cellspacing="3" width="90%"> |
||||
<tr><td colspan="{$cellsPerRow}"> |
||||
<div STYLE="text-align: center;"> |
||||
<xsl:choose> |
||||
<xsl:when test="$end >= $count and $start = 1"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$count"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
</xsl:when> |
||||
<xsl:when test="$end >= $count"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$count"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:when test="$start = 1"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$end"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$end"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a>  |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
</div> <br clear="all" /> |
||||
</td></tr> |
||||
|
||||
<!--<xsl:for-each select="/sparql/results/result[position()>=$start and position() <=$end]"> |
||||
<xsl:variable name='OBJECTURI' select="object/@uri"/> |
||||
<xsl:variable name='PID' select="substring-after($OBJECTURI,'/')"/> |
||||
<tr> |
||||
<td> |
||||
<img> |
||||
<xsl:attribute name="src"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$PID"/>/TN |
||||
</xsl:attribute> |
||||
</img> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:copy-of select="$PID"/>/-/<xsl:value-of select="title"/> |
||||
</xsl:attribute> |
||||
<xsl:value-of select="title"/> |
||||
</a> |
||||
</td> |
||||
</tr> |
||||
</xsl:for-each>- |
||||
--> |
||||
<xsl:apply-templates select="s:sparql/s:results"/> |
||||
</table><br clear="all" /> |
||||
<div STYLE="text-align: center;"> |
||||
<xsl:choose> |
||||
<xsl:when test="$end >= $count and $start = 1"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$count"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
</xsl:when> |
||||
<xsl:when test="$end >= $count"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$count"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:when test="$start = 1"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$end"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$end"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a>  |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
</div> |
||||
</xsl:if> |
||||
</xsl:template> |
||||
<xsl:template match="s:sparql/s:results"> |
||||
<xsl:for-each select="s:result[position() mod $cellsPerRow = 1 and position()>=$start and position() <=$end]"> |
||||
<tr> |
||||
<xsl:apply-templates select=". | following-sibling::s:result[position() < $cellsPerRow]"/> |
||||
</tr> |
||||
</xsl:for-each> |
||||
</xsl:template> |
||||
<xsl:template match="s:result"> |
||||
<xsl:variable name='OBJECTURI' select="s:object/@uri"/> |
||||
<xsl:variable name='CONTENTURI' select="s:content/@uri"/> |
||||
<xsl:variable name='CONTENTMODEL' select="substring-after($CONTENTURI,'/')"/> |
||||
<xsl:variable name='PID' select="substring-after($OBJECTURI,'/')"/> |
||||
<xsl:variable name="newTitle" > |
||||
<xsl:call-template name="replace-string"> |
||||
<xsl:with-param name="text" select="s:title"/> |
||||
<xsl:with-param name="from" select="'_'"/> |
||||
<xsl:with-param name="to" select="' '"/> |
||||
</xsl:call-template> |
||||
</xsl:variable> |
||||
<xsl:variable name="linkUrl"> |
||||
<xsl:choose> |
||||
<xsl:when test="($CONTENTMODEL='islandora:collectionCModel')"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:copy-of select="$PID"/>/-/<xsl:value-of select="s:title"/> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:copy-of select="$PID"/>/OBJ/<xsl:value-of select="s:title"/> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
<xsl:value-of select="s:content"/> |
||||
</xsl:variable> |
||||
<td valign="top" width="25%"> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$linkUrl"/> |
||||
</xsl:attribute> |
||||
<img> |
||||
<xsl:attribute name="src"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$PID"/>/TN |
||||
</xsl:attribute> |
||||
<xsl:attribute name="alt"><xsl:value-of select="$newTitle"/> |
||||
</xsl:attribute> |
||||
</img> </a> <br clear="all" /> |
||||
|
||||
<br /><a> |
||||
<xsl:attribute name="href"> |
||||
<xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:copy-of select="$PID"/>/-/<xsl:value-of select="s:title"/> |
||||
</xsl:attribute> |
||||
<xsl:value-of select="$newTitle"/> |
||||
</a> |
||||
|
||||
</td> |
||||
<xsl:if test="(position() = last()) and (position() < $cellsPerRow)"> |
||||
<xsl:call-template name="FillerCells"> |
||||
<xsl:with-param name="cellCount" select="$cellsPerRow - position()"/> |
||||
</xsl:call-template> |
||||
</xsl:if> |
||||
</xsl:template> |
||||
<xsl:template name="FillerCells"> |
||||
<xsl:param name="cellCount"/> |
||||
<td> </td> |
||||
<xsl:if test="$cellCount > 1"> |
||||
<xsl:call-template name="FillerCells"> |
||||
<xsl:with-param name="cellCount" select="$cellCount - 1"/> |
||||
</xsl:call-template> |
||||
</xsl:if> |
||||
</xsl:template> |
||||
<xsl:template name="replace-string"> |
||||
<xsl:param name="text"/> |
||||
<xsl:param name="from"/> |
||||
<xsl:param name="to"/> |
||||
|
||||
<xsl:choose> |
||||
<xsl:when test="contains($text, $from)"> |
||||
|
||||
<xsl:variable name="before" select="substring-before($text, $from)"/> |
||||
<xsl:variable name="after" select="substring-after($text, $from)"/> |
||||
<xsl:variable name="prefix" select="concat($before, $to)"/> |
||||
|
||||
<xsl:value-of select="$before"/> |
||||
<xsl:value-of select="$to"/> |
||||
<xsl:call-template name="replace-string"> |
||||
<xsl:with-param name="text" select="$after"/> |
||||
<xsl:with-param name="from" select="$from"/> |
||||
<xsl:with-param name="to" select="$to"/> |
||||
</xsl:call-template> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$text"/> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
</xsl:template> |
||||
</xsl:stylesheet> |
@ -0,0 +1,67 @@
|
||||
<xsl:stylesheet version="1.0" xmlns:s="http://www.w3.org/2001/sw/DataAccess/rf1/result" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
||||
<xsl:template match="/"> |
||||
<xsl:variable name="BASEURL"> |
||||
<xsl:value-of select="$baseUrl"/> |
||||
</xsl:variable> |
||||
<xsl:variable name="collTitle" select="/s:sparql/s:results/s:result/s:collTitle"/> |
||||
<xsl:variable name="collDesc" select="/s:sparql/s:results/s:result/s:collDesc"/> |
||||
|
||||
<center> |
||||
<font face="arial,helvetica"> |
||||
<h2> |
||||
<xsl:value-of select="$collTitle"/> |
||||
<br/> |
||||
<i> |
||||
<xsl:value-of select="$collDesc"/> |
||||
</i> |
||||
</h2> |
||||
</font> |
||||
</center> |
||||
<hr size="1"/> |
||||
<center> |
||||
<table border="0" cellpadding="5"> |
||||
<xsl:for-each select="/s:sparql/s:results/s:result"> |
||||
<xsl:variable name="pid" select="substring-after(s:member/@uri, '/')"/> |
||||
<tr> |
||||
<td> |
||||
<center> |
||||
<a> |
||||
<xsl:attribute name="href"> |
||||
<xsl:value-of select="$BASEURL"/> |
||||
<xsl:text>/fedora/repository/</xsl:text> |
||||
<xsl:value-of select="$pid"/> |
||||
<xsl:text>/FULL_SIZE</xsl:text> |
||||
</xsl:attribute> |
||||
<img height="120" width="160"> |
||||
<xsl:attribute name="src"> |
||||
<xsl:value-of select="$BASEURL"/> |
||||
<xsl:text>/fedora/repository/</xsl:text> |
||||
<xsl:value-of select="$pid"/> |
||||
<xsl:text>/MEDIUM_SIZE</xsl:text> |
||||
</xsl:attribute> |
||||
</img> |
||||
<br/> |
||||
( Full Size ) |
||||
</a> |
||||
</center> |
||||
</td> |
||||
<td> |
||||
<b> |
||||
<a> |
||||
<xsl:attribute name="href"> |
||||
<xsl:value-of select="$BASEURL"/> |
||||
<xsl:text>/fedora/repository/</xsl:text> |
||||
<xsl:value-of select="$pid"/>/-/<xsl:value-of select="s:memberTitle"/> |
||||
</xsl:attribute> |
||||
<xsl:value-of select="s:memberTitle"/> |
||||
</a> |
||||
</b> |
||||
<br/> |
||||
<xsl:value-of select="s:memberDesc"/> |
||||
</td> |
||||
</tr> |
||||
</xsl:for-each> |
||||
</table> |
||||
</center> |
||||
</xsl:template> |
||||
</xsl:stylesheet> |
@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> |
||||
<!-- DEFAULT XSLT FOR COLLECTIONS THAT DO NOT DEFINE THEIR OWN--> |
||||
<xsl:variable name="BASEURL"> |
||||
<xsl:value-of select="$baseUrl"/> |
||||
</xsl:variable> |
||||
<xsl:variable name="PATH"> |
||||
<xsl:value-of select="$path"/> |
||||
</xsl:variable> |
||||
<xsl:variable name="thisPid" select="$collectionPid"/> |
||||
<xsl:variable name="thisTitle" select="$collectionTitle"/> |
||||
<xsl:variable name="size" select="20"/> |
||||
<xsl:variable name="page" select="$hitPage"/> |
||||
<xsl:variable name="start" select="((number($page) - 1) * number($size)) + 1"/> |
||||
<xsl:variable name="end" select="($start - 1) + number($size)"/> |
||||
<xsl:variable name='columns' select="4"/> |
||||
<xsl:variable name="count" select="count(sparql/results/result)"/> |
||||
<xsl:template match="/"> |
||||
<xsl:if test="$count>0"> |
||||
|
||||
<table> |
||||
<tr><td colspan="2"> |
||||
<div align="center"> |
||||
<xsl:choose> |
||||
<xsl:when test="$end >= $count and $start = 1"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$count"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
</xsl:when> |
||||
<xsl:when test="$end >= $count"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$count"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:when test="$start = 1"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$end"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$end"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a>  |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
</div> |
||||
</td></tr> |
||||
<xsl:for-each select="/sparql/results/result[position()>=$start and position() <=$end]"> |
||||
<xsl:variable name='OBJECTURI' select="object/@uri"/> |
||||
<xsl:variable name='PID' select="substring-after($OBJECTURI,'/')"/> |
||||
<tr> |
||||
<td> |
||||
<img> |
||||
<xsl:attribute name="src"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$PID"/>/TN |
||||
</xsl:attribute> |
||||
</img> |
||||
</td><td> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:copy-of select="$PID"/>/-/<xsl:value-of select="title"/> |
||||
</xsl:attribute> |
||||
<xsl:value-of select="title"/> |
||||
</a> |
||||
</td></tr> |
||||
</xsl:for-each> |
||||
</table> |
||||
<div align="center"> |
||||
<xsl:choose> |
||||
<xsl:when test="$end >= $count and $start = 1"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$count"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
</xsl:when> |
||||
<xsl:when test="$end >= $count"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$count"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:when test="$start = 1"> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$end"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:when> |
||||
<xsl:otherwise> |
||||
<xsl:value-of select="$start"/>-<xsl:value-of select="$end"/> |
||||
of <xsl:value-of select="$count"/> <br /> |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page - 1"/> |
||||
</xsl:attribute> |
||||
<<Prev |
||||
</a>  |
||||
<a> |
||||
<xsl:attribute name="href"><xsl:value-of select="$BASEURL"/>/fedora/repository/<xsl:value-of select="$thisPid"/>/-/<xsl:value-of select="$thisTitle"/>/<xsl:value-of select="$page + 1"/> |
||||
</xsl:attribute> |
||||
Next>> |
||||
</a> |
||||
</xsl:otherwise> |
||||
</xsl:choose> |
||||
</div> |
||||
</xsl:if> |
||||
</xsl:template> |
||||
</xsl:stylesheet> |
@ -0,0 +1,28 @@
|
||||
<xsl:stylesheet version="1.0" xmlns:s="http://www.w3.org/2001/sw/DataAccess/rf1/result" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
||||
<!-- simple list view for a itql query that looks queries for $object and $title only --> |
||||
<xsl:template match="/"> |
||||
<xsl:variable name="BASEURL"> |
||||
<xsl:value-of select="$baseUrl"/> |
||||
</xsl:variable> |
||||
|
||||
<ul> |
||||
<xsl:for-each select="/s:sparql/s:results/s:result"> |
||||
<xsl:variable name="pid" select="substring-after(s:object/@uri, '/')"/> |
||||
<li> |
||||
|
||||
<a> |
||||
<xsl:attribute name="href"> |
||||
<xsl:value-of select="$BASEURL"/> |
||||
<xsl:text>/fedora/repository/</xsl:text> |
||||
<xsl:value-of select="$pid"/>/-/<xsl:value-of select="s:title"/> |
||||
</xsl:attribute> |
||||
<xsl:value-of select="s:title"/> |
||||
</a> |
||||
|
||||
|
||||
</li> |
||||
</xsl:for-each> |
||||
</ul> |
||||
|
||||
</xsl:template> |
||||
</xsl:stylesheet> |
@ -0,0 +1,18 @@
|
||||
body { |
||||
font-family: Arial; |
||||
font-size: 12px; |
||||
color: gray; |
||||
background: black; |
||||
} |
||||
|
||||
.title { |
||||
font-size: 18px; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
#coverFlowTest .coverFlowLabel { |
||||
margin-top: 10px; |
||||
font-size: 14px; |
||||
color: #C0C0C0; |
||||
font-weight: bold; |
||||
} |
@ -0,0 +1,936 @@
|
||||
/** |
||||
* @author elmasse (Maximiliano Fierro) |
||||
* @version 0.1 beta |
||||
* |
||||
* @usage: |
||||
* <code>
|
||||
* var images = [ |
||||
* {src: 'images/ardillitaMac.jpg'}, |
||||
* {src: 'http://farm2.static.flickr.com/1380/1426855399_b4b8eccbdb.jpg?v=0'}, |
||||
* {src: 'http://farm1.static.flickr.com/69/213130158_0d1aa23576_d.jpg'} |
||||
* ]; |
||||
* var myCoverFlow = new YAHOO.ext.CoverFlow('coverFlowTest', {height: 200, width: 800, images: images, bgColor: '#C0C0C0'}); |
||||
* </code> |
||||
* |
||||
*/ |
||||
|
||||
|
||||
YAHOO.namespace("ext"); |
||||
|
||||
//(function(){
|
||||
|
||||
/** |
||||
* @class CoverFlow
|
||||
* @namespace YAHOO.ext |
||||
* @constructor |
||||
* @param el {String|HTMLElement} Reference to element where CoverFlow will be rendered. |
||||
* @param config {Object} configuration object |
||||
* config.height {Number} Element height. Optional. Default: CoverFlow.DEFAULT_HEIGHT. |
||||
* config.width {Number} Element width. Optional. Default: CoverFlow.DEFAULT_WIDTH. |
||||
* config.images {Array} Array of Images. [{src:}] |
||||
* config.bgColor {String} Background color. Could be in the form #00000 or black. Optional. Default: CoverFlow.DEFAULT_BG_COLOR.
|
||||
*
|
||||
*/ |
||||
YAHOO.ext.CoverFlow = function(el, userConfig){ |
||||
if(el) |
||||
this.init(el, userConfig || {}); |
||||
}; |
||||
|
||||
//shortcuts
|
||||
var CoverFlow = YAHOO.ext.CoverFlow;
|
||||
var Dom = YAHOO.util.Dom; |
||||
|
||||
|
||||
/** |
||||
* Defaults |
||||
*/ |
||||
CoverFlow.DEFAULT_HEIGHT = 300; |
||||
CoverFlow.DEFAULT_WIDTH = 800; |
||||
CoverFlow.DEFAULT_BG_COLOR = '#000000';
|
||||
CoverFlow.IMAGE_SEPARATION = 50; |
||||
CoverFlow.RIGHT = 'right'; |
||||
CoverFlow.LEFT = 'left'; |
||||
CoverFlow.LABEL_CLASS = 'coverFlowLabel'; |
||||
|
||||
CoverFlow.prototype = { |
||||
//Images array (it's a sort of transient var)
|
||||
images: [],
|
||||
//Items array {CoverFlowItem[]}
|
||||
coverFlowItems: [], |
||||
|
||||
remainingImages: 9999, |
||||
|
||||
element: null, |
||||
labelElement: null, |
||||
containerHeight: 0, |
||||
containerWidth: 0, |
||||
|
||||
imageHeightRatio: 0.6, |
||||
imageWidthRatio: 0.2, |
||||
reflectionRatio: 0.6, // this causes: imageTotalHeightRatio = imageHeightRatio + imageHeightRatio*reflectionRatio
|
||||
topRatio: 0.1, |
||||
sideRatio: 0.4, |
||||
|
||||
perspectiveAngle: 20, |
||||
imageZIndex: 1000, |
||||
selectedImageZIndex: 9999, |
||||
selectedItem: 0, |
||||
|
||||
moveQueue: [], |
||||
animationWorking: false, |
||||
|
||||
init: function(el, userConfig){ |
||||
|
||||
this.element = Dom.get(el); |
||||
this.applyConfig(userConfig); |
||||
|
||||
if(userConfig.images) |
||||
this.addImages(userConfig.images); |
||||
|
||||
this.attachEventListeners(); |
||||
this.createLabelElement(); |
||||
}, |
||||
|
||||
applyConfig: function(config){ |
||||
this.containerHeight = config.height || CoverFlow.DEFAULT_HEIGHT; |
||||
this.containerWidth = config.width || CoverFlow.DEFAULT_WIDTH; |
||||
this.backgroundColor = config.bgColor || CoverFlow.DEFAULT_BG_COLOR; |
||||
|
||||
this.element.style.position = 'relative'; |
||||
this.element.style.height = this.containerHeight + 'px'; |
||||
this.element.style.width = this.containerWidth + 'px'; |
||||
this.element.style.background = this.backgroundColor; |
||||
this.element.style.overflow = 'hidden'; |
||||
}, |
||||
|
||||
addImages: function(images){ |
||||
this.images = []; |
||||
this.remainingImages = images.length; |
||||
|
||||
for(var i=0; i < images.length; i++){ |
||||
var img = images[i]; |
||||
var image = new Image(); |
||||
image.id = Dom.generateId(); |
||||
image.index = i; |
||||
image.onclick = img.onclick; |
||||
image.label = img.label; |
||||
|
||||
//hide images
|
||||
image.style.visibility = 'hidden'; |
||||
image.style.display = 'none'; |
||||
//this is to maintain image order since image.onload will be called randomly
|
||||
this.element.appendChild(image); |
||||
//a shortcut to not create another context to call onload
|
||||
var me = this; |
||||
// image.onload = function(){
|
||||
// CoverFlow.preloadImage(me, this); // this = image
|
||||
// };
|
||||
YAHOO.util.Event.on(image, 'load', this.preloadImage, image, this); |
||||
image.src = img.src; |
||||
|
||||
};
|
||||
|
||||
}, |
||||
|
||||
/** |
||||
* @function preloadImage |
||||
* @param event |
||||
* @param image |
||||
* @return void |
||||
*/ |
||||
preloadImage : function(e, image){ |
||||
this.images.push(image); |
||||
this.checkAllImagesLoaded(); |
||||
}, |
||||
|
||||
checkAllImagesLoaded: function(){ |
||||
this.remainingImages--; |
||||
if(!this.remainingImages){ |
||||
this.setup(); |
||||
} |
||||
}, |
||||
|
||||
setup: function(){ |
||||
this.createCoverFlowItems(); |
||||
this.sortCoverFlowItems(); |
||||
this.initCoverFlow(); |
||||
}, |
||||
|
||||
initCoverFlow: function(){ |
||||
|
||||
for(var i=0; i < this.coverFlowItems.length; i++){ |
||||
var coverFlowItem = this.coverFlowItems[i]; |
||||
|
||||
var angle = 0; |
||||
var direction; |
||||
|
||||
if(i==0){ |
||||
coverFlowItem.setZIndex(this.selectedImageZIndex); |
||||
coverFlowItem.setLeft(this.getCenter() - coverFlowItem.element.width/2); |
||||
coverFlowItem.isSelected(true); |
||||
this.selectedItem = 0; |
||||
this.showLabel(coverFlowItem.getLabel()); |
||||
}else{ |
||||
angle = this.perspectiveAngle; |
||||
direction = CoverFlow.LEFT; |
||||
coverFlowItem.setZIndex(this.imageZIndex - i); |
||||
coverFlowItem.setLeft( this.getRightStart()+ (i - 1)* CoverFlow.IMAGE_SEPARATION); |
||||
coverFlowItem.isSelected(false); |
||||
} |
||||
coverFlowItem.setAngle(angle); |
||||
coverFlowItem.drawInPerspective(direction); |
||||
} |
||||
}, |
||||
|
||||
createLabelElement: function(){ |
||||
var label = document.createElement('div'); |
||||
label.id = Dom.generateId(); |
||||
label.style.position = 'absolute'; |
||||
label.style.top = this.getFooterOffset() + 'px'; |
||||
label.innerHTML = ' '; |
||||
label.style.textAlign = 'center'; |
||||
label.style.width = this.containerWidth + 'px'; |
||||
label.style.zIndex = this.selectedImageZIndex + 10; |
||||
label.className = CoverFlow.LABEL_CLASS; |
||||
this.labelElement = this.element.appendChild(label); |
||||
}, |
||||
|
||||
showLabel: function(text){ |
||||
if(text) |
||||
this.labelElement.innerHTML = text; |
||||
else |
||||
this.labelElement.innerHTML = ''; |
||||
}, |
||||
|
||||
attachEventListeners: function(){ |
||||
new YAHOO.util.KeyListener(this.element, { keys:39 },
|
||||
{ fn:this.selectNext, |
||||
scope:this, |
||||
correctScope:true } ).enable(); |
||||
|
||||
new YAHOO.util.KeyListener(this.element, { keys:37 },
|
||||
{ fn:this.selectPrevious, |
||||
scope:this, |
||||
correctScope:true } ).enable(); |
||||
|
||||
|
||||
}, |
||||
|
||||
select: function(e,coverFlowItem){ |
||||
var distance = this.selectedItem - coverFlowItem.index; |
||||
if(distance < 0){ |
||||
for(var i=0; i < -distance; i++) |
||||
this.selectNext(); |
||||
}else{ |
||||
for(var i=0; i < distance; i++) |
||||
this.selectPrevious(); |
||||
} |
||||
}, |
||||
|
||||
|
||||
selectNext: function(){ |
||||
if(this.animationWorking){ |
||||
this.moveQueue.push('moveLeft'); |
||||
return; |
||||
} |
||||
|
||||
var animateItems = []; |
||||
|
||||
for(var i=0; i < this.coverFlowItems.length; i++){ |
||||
var coverFlowItem = this.coverFlowItems[i]; |
||||
var isLast = (this.selectedItem == this.coverFlowItems.length -1); |
||||
if(!isLast){ |
||||
var distance = i-this.selectedItem; |
||||
|
||||
if(distance == 0){// selected
|
||||
coverFlowItem.setZIndex(this.imageZIndex); |
||||
coverFlowItem.isSelected(false); |
||||
animateItems.push({item: coverFlowItem, attribute:{angle: {start: 0, end: this.perspectiveAngle} } }); |
||||
|
||||
coverFlowItem = this.coverFlowItems[++i]; |
||||
coverFlowItem.isSelected(true); |
||||
this.showLabel(coverFlowItem.getLabel()); |
||||
animateItems.push({item: coverFlowItem, attribute:{angle: {start: this.perspectiveAngle, end: 0} } }); |
||||
|
||||
}else{ |
||||
animateItems.push({item: coverFlowItem, attribute: {left: {start:coverFlowItem.getLeft(), end: coverFlowItem.getLeft() - CoverFlow.IMAGE_SEPARATION} }}); |
||||
} |
||||
} |
||||
} |
||||
|
||||
var animation = new CoverFlowAnimation({ |
||||
direction: CoverFlow.LEFT, |
||||
center: this.getCenter(), |
||||
startLeftPos: this.getLeftStart(), |
||||
startRightPos: this.getRightStart() |
||||
},
|
||||
animateItems, 0.5); |
||||
|
||||
animation.onStart.subscribe(this.handleAnimationWorking, this); |
||||
animation.onComplete.subscribe(this.handleQueuedMove, this); |
||||
|
||||
animation.animate(); |
||||
|
||||
if(this.selectedItem + 1 < this.coverFlowItems.length) |
||||
this.selectedItem++; |
||||
}, |
||||
|
||||
selectPrevious: function(){ |
||||
if(this.animationWorking){ |
||||
this.moveQueue.push('moveRight'); |
||||
return; |
||||
} |
||||
|
||||
var animateItems = []; |
||||
|
||||
for(var i=0; i < this.coverFlowItems.length; i++){ |
||||
var coverFlowItem = this.coverFlowItems[i]; |
||||
var isFirst = (this.selectedItem == 0); |
||||
var distance = i-this.selectedItem; |
||||
if(!isFirst){ |
||||
if(distance == - 1){ |
||||
coverFlowItem.setZIndex(this.selectedImageZIndex); |
||||
coverFlowItem.isSelected(true); |
||||
this.showLabel(coverFlowItem.getLabel()); |
||||
animateItems.push({item: coverFlowItem, attribute: {angle: {start: this.perspectiveAngle, end: 0}}}); |
||||
|
||||
coverFlowItem = this.coverFlowItems[++i]; |
||||
coverFlowItem.isSelected(false); |
||||
coverFlowItem.setZIndex(this.imageZIndex); |
||||
animateItems.push({item: coverFlowItem, attribute: {angle: {start: 0, end: this.perspectiveAngle}}}); |
||||
}else{ |
||||
coverFlowItem.setZIndex(coverFlowItem.getZIndex() - 1); |
||||
animateItems.push({item: coverFlowItem, attribute: {left: {start:coverFlowItem.getLeft(), end: coverFlowItem.getLeft() + CoverFlow.IMAGE_SEPARATION} }}); |
||||
} |
||||
} |
||||
} |
||||
var animation = new CoverFlowAnimation({ |
||||
direction: CoverFlow.RIGHT, |
||||
center: this.getCenter(), |
||||
startLeftPos: this.getLeftStart(), |
||||
startRightPos: this.getRightStart() |
||||
},
|
||||
animateItems, 0.5); |
||||
|
||||
animation.onStart.subscribe(this.handleAnimationWorking, this); |
||||
animation.onComplete.subscribe(this.handleQueuedMove, this); |
||||
|
||||
animation.animate(); |
||||
|
||||
if(this.selectedItem > 0) |
||||
this.selectedItem--; |
||||
}, |
||||
|
||||
handleAnimationWorking: function(a, b, cf){ |
||||
cf.animationWorking = true; |
||||
}, |
||||
|
||||
handleQueuedMove: function(msg, data, cf){ |
||||
cf.animationWorking = false; |
||||
|
||||
var next = cf.moveQueue.pop(); |
||||
if(next == 'moveLeft') |
||||
cf.selectNext(); |
||||
if(next == 'moveRight') |
||||
cf.selectPrevious(); |
||||
}, |
||||
|
||||
getCenter: function(){ |
||||
return this.containerWidth / 2; |
||||
}, |
||||
|
||||
getRightStart: function() { |
||||
return this.containerWidth - this.sideRatio * this.containerWidth; |
||||
}, |
||||
|
||||
getLeftStart: function() { |
||||
return this.sideRatio * this.containerWidth; |
||||
}, |
||||
|
||||
sortCoverFlowItems: function(){ |
||||
function sortFunction(aCoverFlowItem, bCoverFlowItem){ |
||||
return aCoverFlowItem.index - bCoverFlowItem.index; |
||||
} |
||||
|
||||
this.coverFlowItems.sort(sortFunction); |
||||
}, |
||||
|
||||
createCoverFlowItems: function(){ |
||||
this.coverFlowItems = []; |
||||
for(var i=0; i<this.images.length; i++){ |
||||
var image = this.images[i]; |
||||
var coverFlowItem = new CoverFlowItem(image, { |
||||
scaledWidth: this.scaleWidth(image),
|
||||
scaledHeight: this.scaleHeight(image),
|
||||
reflectionRatio: this.reflectionRatio, |
||||
bgColor: this.backgroundColor, |
||||
onclick: {fn: this.select, scope: this} |
||||
}); |
||||
this.alignCenterHeight(coverFlowItem); |
||||
this.coverFlowItems.push(coverFlowItem); |
||||
}; |
||||
delete this.images; |
||||
}, |
||||
|
||||
alignCenterHeight: function(coverFlowItem){//review!!!!!
|
||||
coverFlowItem.element.style.position = 'absolute'; |
||||
|
||||
var imageHeight = coverFlowItem.canvas.height / (1 + this.reflectionRatio); |
||||
var top = this.getMaxImageHeight() - imageHeight; |
||||
top += this.topRatio * this.containerHeight; |
||||
|
||||
coverFlowItem.setTop(top); |
||||
|
||||
}, |
||||
|
||||
scaleHeight: function(image){ |
||||
var height = 0; |
||||
if(image.height <= this.getMaxImageHeight() && image.width <= this.getMaxImageWidth()){ |
||||
height = image.height; |
||||
} |
||||
if(image.height > this.getMaxImageHeight() && image.width <= this.getMaxImageWidth()){ |
||||
height = ((image.height / this.getMaxImageHeight())) * image.height; |
||||
} |
||||
if(image.height <= this.getMaxImageHeight() && image.width > this.getMaxImageWidth()){ |
||||
height = ((image.width / this.getMaxImageWidth())) * image.height; |
||||
} |
||||
if(image.height > this.getMaxImageHeight() && image.width > this.getMaxImageWidth()){ |
||||
if(image.height > image.width) |
||||
height = ((this.getMaxImageHeight() / image.height)) * image.height; |
||||
else |
||||
height = ((this.getMaxImageWidth() / image.width)) * image.height; |
||||
} |
||||
return height; |
||||
}, |
||||
|
||||
scaleWidth: function(image){ |
||||
var width = 0; |
||||
if(image.height <= this.getMaxImageHeight() && image.width <= this.getMaxImageWidth()){ |
||||
width = image.width; |
||||
} |
||||
if(image.height > this.getMaxImageHeight() && image.width <= this.getMaxImageWidth()){ |
||||
width = ((image.height / this.getMaxImageHeight())) * image.width; |
||||
} |
||||
if(image.height <= this.getMaxImageHeight() && image.width > this.getMaxImageWidth()){ |
||||
width = ((image.width / this.getMaxImageWidth())) * image.width; |
||||
} |
||||
if(image.height > this.getMaxImageHeight() && image.width > this.getMaxImageWidth()){ |
||||
if(image.height > image.width) |
||||
width = ((this.getMaxImageHeight() / image.height)) * image.width; |
||||
else |
||||
width = ((this.getMaxImageWidth() / image.width)) * image.width; |
||||
} |
||||
return width; |
||||
}, |
||||
|
||||
|
||||
getMaxImageHeight: function(){ |
||||
return (this.containerHeight * this.imageHeightRatio); |
||||
}, |
||||
|
||||
getMaxImageWidth: function(){ |
||||
return (this.containerWidth * this.imageWidthRatio); |
||||
}, |
||||
|
||||
getTopOffset: function(){ |
||||
return this.containerHeight * this.topRatio; |
||||
}, |
||||
|
||||
getFooterOffset: function(){ |
||||
return this.containerHeight * (this.topRatio + this.imageHeightRatio); |
||||
} |
||||
}; |
||||
|
||||
|
||||
/** |
||||
* @class CoverFlowItem
|
||||
*
|
||||
*/ |
||||
CoverFlowItem = function(image, config){ |
||||
if(image) |
||||
this.init(image, config); |
||||
}; |
||||
|
||||
CoverFlowItem.prototype = { |
||||
canvas: null, |
||||
element: null, |
||||
index: null, |
||||
id: null, |
||||
angle: 0, |
||||
selected: false, |
||||
onclickFn: null, |
||||
selectedOnclickFn: null, |
||||
label: null, |
||||
|
||||
onSelected: null, |
||||
|
||||
init: function(image, config){ |
||||
var scaledWidth = config.scaledWidth; |
||||
var scaledHeight = config.scaledHeight; |
||||
var reflectionRatio = config.reflectionRatio; |
||||
var bgColor = config.bgColor; |
||||
|
||||
this.id = image.id; |
||||
this.index = image.index; |
||||
this.onclickFn = config.onclick; |
||||
this.selectedOnclickFn = image.onclick; |
||||
this.label = image.label; |
||||
var parent = image.parentNode; |
||||
this.canvas = this.createImageCanvas(image,scaledWidth,scaledHeight,reflectionRatio, bgColor); |
||||
this.element = this.canvas.cloneNode(false); |
||||
this.element.id = this.id; |
||||
parent.replaceChild(this.element, image); |
||||
|
||||
this.onSelected = new YAHOO.util.CustomEvent('onSelected', this); |
||||
this.onSelected.subscribe(this.handleOnclick); |
||||
|
||||
}, |
||||
|
||||
getLabel: function(){ |
||||
return this.label; |
||||
}, |
||||
|
||||
handleOnclick: function(){ |
||||
YAHOO.util.Event.removeListener(this.element, 'click'); |
||||
if(!this.selected){ |
||||
YAHOO.util.Event.addListener(this.element, 'click', this.onclickFn.fn, this, this.onclickFn.scope); |
||||
}else{ |
||||
if(this.selectedOnclickFn && this.selectedOnclickFn.fn) |
||||
YAHOO.util.Event.addListener(this.element, 'click', this.selectedOnclickFn.fn, this, this.selectedOnclickFn.scope); |
||||
else |
||||
YAHOO.util.Event.addListener(this.element, 'click', this.selectedOnclickFn); |
||||
} |
||||
}, |
||||
|
||||
isSelected: function(selected){ |
||||
this.selected = selected; |
||||
this.onSelected.fire(); |
||||
}, |
||||
|
||||
setAngle: function(angle){ |
||||
this.angle = angle; |
||||
}, |
||||
|
||||
getAngle: function(){ |
||||
return this.angle; |
||||
}, |
||||
|
||||
setTop: function(top){ |
||||
this.element.style.top = top + 'px';
|
||||
}, |
||||
|
||||
setLeft: function(left){ |
||||
this.element.style.left = left + 'px'; |
||||
}, |
||||
|
||||
getLeft: function(){ |
||||
var ret = this.element.style.left; |
||||
return new Number(ret.replace("px", "")); |
||||
}, |
||||
|
||||
getZIndex: function(){ |
||||
return this.element.style.zIndex; |
||||
}, |
||||
|
||||
setZIndex: function(zIndex){ |
||||
this.element.style.zIndex = zIndex; |
||||
}, |
||||
|
||||
createImageCanvas: function(image, sWidth, sHeight, reflectionRatio, bgColor){ |
||||
|
||||
var imageCanvas = document.createElement('canvas'); |
||||
|
||||
if(imageCanvas.getContext){ |
||||
|
||||
var scaledWidth = sWidth; |
||||
var scaledHeight = sHeight; |
||||
var reflectionHeight = scaledHeight * reflectionRatio; |
||||
|
||||
imageCanvas.height = scaledHeight + reflectionHeight; |
||||
imageCanvas.width = scaledWidth; |
||||
|
||||
var ctx = imageCanvas.getContext('2d'); |
||||
|
||||
ctx.clearRect(0, 0, imageCanvas.width, imageCanvas.height); |
||||
ctx.globalCompositeOperation = 'source-over'; |
||||
ctx.fillStyle = 'rgba(0, 0, 0, 1)'; |
||||
ctx.fillRect(0, 0, imageCanvas.width, imageCanvas.height); |
||||
|
||||
//draw the reflection image
|
||||
ctx.save(); |
||||
ctx.translate(0, (2*scaledHeight)); |
||||
ctx.scale(1, -1); |
||||
ctx.drawImage(image, 0, 0, scaledWidth, scaledHeight); |
||||
ctx.restore(); |
||||
//create the gradient effect
|
||||
ctx.save(); |
||||
ctx.translate(0, scaledHeight); |
||||
ctx.globalCompositeOperation = 'destination-out'; |
||||
var grad = ctx.createLinearGradient( 0, 0, 0, scaledHeight); |
||||
grad.addColorStop(1, 'rgba(0, 0, 0, 1)'); |
||||
grad.addColorStop(0, 'rgba(0, 0, 0, 0.75)'); |
||||
ctx.fillStyle = grad; |
||||
ctx.fillRect(0, 0, scaledWidth, scaledHeight); |
||||
//apply the background color to the gradient
|
||||
ctx.globalCompositeOperation = 'destination-over'; |
||||
ctx.fillStyle = bgColor; '#000'; |
||||
ctx.globalAlpha = 0.8; |
||||
ctx.fillRect(0, 0 , scaledWidth, scaledHeight); |
||||
ctx.restore(); |
||||
//draw the image
|
||||
ctx.save(); |
||||
ctx.translate(0, 0); |
||||
ctx.globalCompositeOperation = 'source-over'; |
||||
ctx.drawImage(image, 0, 0, scaledWidth, scaledHeight); |
||||
ctx.restore(); |
||||
|
||||
return imageCanvas; |
||||
} |
||||
}, |
||||
|
||||
drawInPerspective: function(direction, frameSize){ |
||||
var canvas = this.element; |
||||
var image = this.canvas; |
||||
var angle = Math.ceil(this.angle); |
||||
var ctx; |
||||
var originalWidth = image.width; |
||||
var originalHeight = image.height; |
||||
var destinationWidth = destinationWidth || originalWidth; // for future use
|
||||
var destinationHeight = destinationHeight || originalHeight; // for future use
|
||||
|
||||
var perspectiveCanvas = document.createElement('canvas'); |
||||
perspectiveCanvas.height = destinationHeight; |
||||
perspectiveCanvas.width = destinationWidth; |
||||
var perspectiveCtx = perspectiveCanvas.getContext('2d'); |
||||
|
||||
var alpha = angle * Math.PI/180; // Math uses radian
|
||||
|
||||
if(alpha > 0){ // if we have an angle greater than 0 then apply the perspective
|
||||
var right = (direction == CoverFlow.RIGHT); |
||||
|
||||
var initialX=0, finalX=0, initialY=0, finalY=0; |
||||
|
||||
frameSize = frameSize || 1; |
||||
var xDes, yDes; |
||||
var heightDes, widthDes; |
||||
var perspectiveWidht = destinationWidth; |
||||
|
||||
var frameFactor = frameSize / originalWidth; |
||||
var frames = Math.floor(originalWidth / frameSize); |
||||
|
||||
var widthSrc = frameSize ; |
||||
var heightSrc = originalHeight; |
||||
|
||||
for(var i=0; i < frames; i++){ |
||||
var xSrc = (i) * frameSize; |
||||
var ySrc = 0; |
||||
var betaTan = 0; |
||||
width = destinationWidth * (i) * frameFactor; |
||||
horizon = destinationHeight / 2; |
||||
|
||||
if(right){ |
||||
betaTan = horizon/((Math.tan(alpha)*horizon) + width); |
||||
xDes = (betaTan*width)/(Math.tan(alpha) + betaTan); |
||||
yDes = Math.tan(alpha) * xDes; |
||||
|
||||
if(i == frames -1){ |
||||
finalX=xDes; |
||||
finalY=yDes; |
||||
} |
||||
}else{ |
||||
betaTan = horizon/((Math.tan(alpha)*horizon) +(destinationWidth-width)); |
||||
xDes = (Math.tan(alpha)*(destinationWidth) + (betaTan * width))/(Math.tan(alpha) + betaTan); |
||||
yDes = -Math.tan(alpha)*xDes + (Math.tan(alpha)*(destinationWidth)); |
||||
|
||||
if(i == 0){ |
||||
initialX = xDes; |
||||
initialY = yDes; |
||||
finalX = destinationWidth; |
||||
finalY = 0; |
||||
} |
||||
} |
||||
|
||||
heightDes = destinationHeight - (2*yDes); |
||||
widthDes = heightDes / destinationHeight * destinationWidth; |
||||
|
||||
perspectiveCtx.drawImage(image, xSrc, ySrc, widthSrc, heightSrc, xDes, yDes, widthDes, heightDes); |
||||
|
||||
} |
||||
|
||||
perspectiveWidth = finalX - initialX; |
||||
originalCanvasWidth = destinationWidth; |
||||
canvas.width = perspectiveWidth; |
||||
|
||||
ctx = canvas.getContext('2d'); |
||||
|
||||
//remove exceeded pixels
|
||||
ctx.beginPath(); |
||||
if(right){ |
||||
ctx.moveTo(0, 0); |
||||
ctx.lineTo(finalX, finalY); |
||||
ctx.lineTo(finalX, finalY + (destinationHeight - 2*finalY)); |
||||
ctx.lineTo(0, destinationHeight); |
||||
ctx.lineTo(0,0); |
||||
}else{ |
||||
var initialX1 = initialX - (originalCanvasWidth - perspectiveWidth); |
||||
var finalX1 = finalX - (originalCanvasWidth - perspectiveWidth); |
||||
ctx.moveTo(0, initialY); |
||||
ctx.lineTo(finalX1, finalY); |
||||
ctx.lineTo(finalX1, destinationHeight); |
||||
ctx.lineTo(initialX1, initialY + (destinationHeight - 2*initialY)); |
||||
ctx.lineTo(0, initialY); |
||||
} |
||||
ctx.closePath(); |
||||
ctx.clip(); |
||||
|
||||
ctx.drawImage(perspectiveCanvas, initialX, 0, perspectiveWidth, destinationHeight, 0, 0, perspectiveWidth, destinationHeight); |
||||
|
||||
}else{ |
||||
|
||||
canvas.width = perspectiveCanvas.width; |
||||
canvas.height = perspectiveCanvas.height; |
||||
perspectiveCtx.drawImage(image, 0, 0, originalWidth, originalHeight, 0, 0, destinationWidth, destinationHeight); |
||||
ctx = canvas.getContext('2d'); |
||||
ctx.clearRect(0, 0, canvas.width, canvas.height); |
||||
ctx.drawImage(perspectiveCanvas, 0, 0); |
||||
} |
||||
} |
||||
|
||||
}; |
||||
|
||||
/** |
||||
* @class CoverFlowAnimation |
||||
* @requires YAHOO.util.AnimMgr |
||||
*/ |
||||
CoverFlowAnimation = function(config, animationItems, duration){ |
||||
this.init(config, animationItems, duration); |
||||
};
|
||||
|
||||
CoverFlowAnimation.prototype = { |
||||
direction: null, |
||||
|
||||
center: null, |
||||
|
||||
startLeftPos: null, |
||||
|
||||
startRightPos: null, |
||||
|
||||
animationItems: null, |
||||
|
||||
method : YAHOO.util.Easing.easeNone, |
||||
|
||||
animated: false, |
||||
|
||||
startTime: null, |
||||
|
||||
actualFrames : 0,
|
||||
|
||||
useSeconds : true, // default to seconds
|
||||
|
||||
currentFrame : 0, |
||||
|
||||
totalFrames : YAHOO.util.AnimMgr.fps, |
||||
|
||||
init: function(config, animationItems, duration){ |
||||
this.direction = config.direction; |
||||
this.center = config.center; |
||||
this.startLeftPos = config.startLeftPos; |
||||
this.startRightPos = config.startRightPos; |
||||
this.animationItems = animationItems; |
||||
this.duration = duration || 1; |
||||
this.registerEvents(); |
||||
}, |
||||
|
||||
registerEvents: function(){ |
||||
/** |
||||
* Custom event that fires after onStart, useful in subclassing |
||||
* @private |
||||
*/ |
||||
this._onStart = new YAHOO.util.CustomEvent('_start', this, true); |
||||
|
||||
/** |
||||
* Custom event that fires when animation begins |
||||
* Listen via subscribe method (e.g. myAnim.onStart.subscribe(someFunction) |
||||
* @event onStart |
||||
*/ |
||||
this.onStart = new YAHOO.util.CustomEvent('start', this); |
||||
|
||||
/** |
||||
* Custom event that fires between each frame |
||||
* Listen via subscribe method (e.g. myAnim.onTween.subscribe(someFunction) |
||||
* @event onTween |
||||
*/ |
||||
this.onTween = new YAHOO.util.CustomEvent('tween', this); |
||||
|
||||
/** |
||||
* Custom event that fires after onTween |
||||
* @private |
||||
*/ |
||||
this._onTween = new YAHOO.util.CustomEvent('_tween', this, true); |
||||
|
||||
/** |
||||
* Custom event that fires when animation ends |
||||
* Listen via subscribe method (e.g. myAnim.onComplete.subscribe(someFunction) |
||||
* @event onComplete |
||||
*/ |
||||
this.onComplete = new YAHOO.util.CustomEvent('complete', this); |
||||
/** |
||||
* Custom event that fires after onComplete |
||||
* @private |
||||
*/ |
||||
this._onComplete = new YAHOO.util.CustomEvent('_complete', this, true); |
||||
|
||||
this._onStart.subscribe(this.doOnStart); |
||||
this._onTween.subscribe(this.doOnTween); |
||||
this._onComplete.subscribe(this.doOnComplete);
|
||||
|
||||
}, |
||||
|
||||
isAnimated : function() { |
||||
return this.animated; |
||||
}, |
||||
|
||||
getStartTime : function() { |
||||
return this.startTime; |
||||
},
|
||||
|
||||
doMethod: function(start, end) { |
||||
return this.method(this.currentFrame, start, end - start, this.totalFrames); |
||||
},
|
||||
|
||||
animate : function() { |
||||
if ( this.isAnimated() ) { |
||||
return false; |
||||
} |
||||
|
||||
this.currentFrame = 0; |
||||
|
||||
this.totalFrames = ( this.useSeconds ) ? Math.ceil(YAHOO.util.AnimMgr.fps * this.duration) : this.duration; |
||||
|
||||
if (this.duration === 0 && this.useSeconds) { // jump to last frame if zero second duration
|
||||
this.totalFrames = 1;
|
||||
} |
||||
YAHOO.util.AnimMgr.registerElement(this); |
||||
return true; |
||||
}, |
||||
|
||||
stop : function(finish) { |
||||
if (!this.isAnimated()) { // nothing to stop
|
||||
return false; |
||||
} |
||||
|
||||
if (finish) { |
||||
this.currentFrame = this.totalFrames; |
||||
this._onTween.fire(); |
||||
} |
||||
YAHOO.util.AnimMgr.stop(this); |
||||
}, |
||||
|
||||
doOnStart : function() {
|
||||
this.onStart.fire(); |
||||
|
||||
this.runtimeItems = []; |
||||
for (var i=0; i<this.animationItems.length; i++) { |
||||
this.setRuntimeItem(this.animationItems[i]); |
||||
} |
||||
|
||||
this.animated = true; |
||||
this.actualFrames = 0; |
||||
this.startTime = new Date();
|
||||
}, |
||||
|
||||
doOnTween : function() { |
||||
var data = { |
||||
duration: new Date() - this.getStartTime(), |
||||
currentFrame: this.currentFrame |
||||
}; |
||||
|
||||
data.toString = function() { |
||||
return ( |
||||
'duration: ' + data.duration + |
||||
', currentFrame: ' + data.currentFrame |
||||
); |
||||
}; |
||||
|
||||
this.onTween.fire(data); |
||||
|
||||
this.actualFrames += 1; |
||||
|
||||
var runtimeItems = this.runtimeItems; |
||||
|
||||
for (var i=0; i < runtimeItems.length; i++) { |
||||
this.setItemAttributes(runtimeItems[i]);
|
||||
} |
||||
|
||||
}, |
||||
|
||||
doOnComplete : function() { |
||||
var actual_duration = (new Date() - this.getStartTime()) / 1000 ; |
||||
|
||||
var data = { |
||||
duration: actual_duration, |
||||
frames: this.actualFrames, |
||||
fps: this.actualFrames / actual_duration |
||||
}; |
||||
|
||||
data.toString = function() { |
||||
return ( |
||||
'duration: ' + data.duration + |
||||
', frames: ' + data.frames + |
||||
', fps: ' + data.fps |
||||
); |
||||
}; |
||||
|
||||
this.animated = false; |
||||
this.actualFrames = 0; |
||||
this.onComplete.fire(data); |
||||
}, |
||||
|
||||
setRuntimeItem: function(item){ |
||||
var runtimeItem = {}; |
||||
runtimeItem.item = item.item; |
||||
runtimeItem.attribute = {}; |
||||
for(var attr in item.attribute){ |
||||
runtimeItem.attribute[attr] = item.attribute[attr]; |
||||
if(attr == 'angle'){ |
||||
if(item.attribute[attr].start - item.attribute[attr].end > 0){ |
||||
runtimeItem.attribute[attr].perspectiveDirection = this.direction; |
||||
runtimeItem.attribute[attr].center = true; |
||||
}else{ |
||||
runtimeItem.attribute[attr].perspectiveDirection = this.direction == CoverFlow.RIGHT ? CoverFlow.LEFT : CoverFlow.RIGHT; |
||||
runtimeItem.attribute[attr].center = false; |
||||
} |
||||
} |
||||
} |
||||
this.runtimeItems.push(runtimeItem); |
||||
}, |
||||
|
||||
setItemAttributes: function(item){ |
||||
|
||||
for(var attr in item.attribute){ |
||||
|
||||
var value = Math.ceil(this.doMethod(item.attribute[attr].start, item.attribute[attr].end)); |
||||
|
||||
if(attr == 'angle'){ |
||||
item.item.setAngle(value); |
||||
var frameSize = Math.ceil(this.doMethod(3, 1)); |
||||
item.item.drawInPerspective(item.attribute[attr].perspectiveDirection, frameSize); |
||||
var left; |
||||
if(item.attribute[attr].center){ |
||||
left = this.doMethod(item.item.getLeft(), this.center - item.item.element.width/2); |
||||
}else{ |
||||
if(this.direction == CoverFlow.LEFT) |
||||
left = this.doMethod(item.item.getLeft(), this.startLeftPos - item.item.element.width); |
||||
else |
||||
left = this.doMethod(item.item.getLeft(), this.startRightPos); |
||||
} |
||||
item.item.setLeft(Math.ceil(left)); |
||||
|
||||
}else{ |
||||
item.item.setLeft(value); |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
|
||||
//});
|
@ -0,0 +1,37 @@
|
||||
|
||||
|
||||
|
||||
YAHOO.util.Event.onDOMReady(function(){ |
||||
|
||||
var images = [ |
||||
{src: 'images/ardillitaMac.jpg', label: 'Ardileta!', onclick: function(){alert('image1');}}, |
||||
{src: 'http://farm2.static.flickr.com/1380/1426855399_b4b8eccbdb.jpg?v=0'}, |
||||
{src: 'http://farm1.static.flickr.com/69/213130158_0d1aa23576_d.jpg'}, |
||||
{src: 'http://farm1.static.flickr.com/69/213130158_0d1aa23576_d.jpg'}, |
||||
{src: 'images/msn2.jpg', label: 'My Mac'}, |
||||
{src: 'images/msn2.jpg', label: 'My Mac again...'} |
||||
|
||||
]; |
||||
var myCoverFlow = new YAHOO.ext.CoverFlow('coverFlowTest', {height: 200, width: 600, images: images}); |
||||
|
||||
function moveLeft(e, coverFlow){ |
||||
coverFlow.selectNext(); |
||||
} |
||||
function moveRight(e, coverFlow){ |
||||
coverFlow.selectPrevious(); |
||||
} |
||||
var myMoveLeftBtn = new YAHOO.widget.Button('moveLeftButton', {onclick: {fn: moveLeft, obj: myCoverFlow}}); |
||||
var myMoveRightBtn = new YAHOO.widget.Button('moveRightButton', {onclick: {fn: moveRight, obj: myCoverFlow}}); |
||||
|
||||
|
||||
var otherImages = [ |
||||
{src: 'images/ardillitaMac.jpg', label: 'Ardileta!', onclick: function(){alert('image1');}}, |
||||
{src: 'images/msn2.jpg', label: 'My Mac'}, |
||||
{src: 'images/msn2.jpg', label: 'My Mac again...'} |
||||
|
||||
];
|
||||
var anotherCoverFlow = new YAHOO.ext.CoverFlow('anotherCoverFlowTest', {height: 150, width: 500, images: otherImages, bgColor: '#C0C0C0'}); |
||||
|
||||
|
||||
|
||||
}); |
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<buildpath> |
||||
<buildpathentry kind="src" path=""/> |
||||
<buildpathentry kind="con" path="org.eclipse.php.core.LANGUAGE"/> |
||||
</buildpath> |
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<projectDescription> |
||||
<name>Islandora Content Modeler</name> |
||||
<comment></comment> |
||||
<projects> |
||||
</projects> |
||||
<buildSpec> |
||||
<buildCommand> |
||||
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name> |
||||
<arguments> |
||||
</arguments> |
||||
</buildCommand> |
||||
<buildCommand> |
||||
<name>org.eclipse.wst.validation.validationbuilder</name> |
||||
<arguments> |
||||
</arguments> |
||||
</buildCommand> |
||||
<buildCommand> |
||||
<name>org.eclipse.dltk.core.scriptbuilder</name> |
||||
<arguments> |
||||
</arguments> |
||||
</buildCommand> |
||||
</buildSpec> |
||||
<natures> |
||||
<nature>org.eclipse.php.core.PHPNature</nature> |
||||
<nature>org.eclipse.wst.jsdt.core.jsNature</nature> |
||||
</natures> |
||||
</projectDescription> |
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<classpath> |
||||
<classpathentry kind="src" path=""/> |
||||
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/> |
||||
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject"> |
||||
<attributes> |
||||
<attribute name="hide" value="true"/> |
||||
</attributes> |
||||
</classpathentry> |
||||
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/> |
||||
<classpathentry kind="output" path=""/> |
||||
</classpath> |
@ -0,0 +1,3 @@
|
||||
#Mon May 17 18:04:49 CDT 2010 |
||||
eclipse.preferences.version=1 |
||||
include_path=0;/islandora_content_modeler |
@ -0,0 +1 @@
|
||||
org.eclipse.wst.jsdt.launching.baseBrowserLibrary |
@ -0,0 +1 @@
|
||||
Window |
@ -0,0 +1,33 @@
|
||||
.contentModeller .collection |
||||
{ |
||||
width: 400px; |
||||
float: left; |
||||
} |
||||
|
||||
.contentModeller .model |
||||
{ |
||||
width: 475px; |
||||
float: right; |
||||
} |
||||
|
||||
.contentModeller img |
||||
{ |
||||
width: 16px; |
||||
padding: 0px; |
||||
vertical-align: middle; |
||||
cursor: hand; |
||||
} |
||||
|
||||
.contentModeller .ajaxForm |
||||
{ |
||||
margin-top: 25px; |
||||
padding: 10px; |
||||
width:300px; |
||||
border: 1px dashed black; |
||||
display: none; |
||||
} |
||||
|
||||
.contentModeller #ajaxBusy |
||||
{ |
||||
display: none; |
||||
} |
@ -0,0 +1,16 @@
|
||||
.jnotify-item |
||||
{ |
||||
height: auto; |
||||
padding: 4px 4px 4px 4px; |
||||
margin: 0 0 5px 0; |
||||
display: block; |
||||
position: relative; |
||||
} |
||||
|
||||
.jnotify-item-close |
||||
{ |
||||
float: right; |
||||
margin-left: 2px; |
||||
} |
||||
|
||||
|
@ -0,0 +1,68 @@
|
||||
.treeview, .treeview ul { |
||||
padding: 0; |
||||
margin: 0; |
||||
list-style: none; |
||||
} |
||||
|
||||
.treeview ul { |
||||
|
||||
margin-top: 4px; |
||||
} |
||||
|
||||
.treeview .hitarea { |
||||
background: url(../images/treeview-default.gif) -64px -25px no-repeat; |
||||
height: 16px; |
||||
width: 16px; |
||||
margin-left: -16px; |
||||
float: left; |
||||
cursor: pointer; |
||||
} |
||||
/* fix for IE6 */ |
||||
* html .hitarea { |
||||
display: inline; |
||||
float:none; |
||||
} |
||||
|
||||
.treeview li { |
||||
margin: 0; |
||||
padding: 3px 0pt 3px 16px; |
||||
} |
||||
|
||||
.treeview a.selected { |
||||
background-color: #eee; |
||||
} |
||||
|
||||
#treecontrol { margin: 1em 0; display: none; } |
||||
|
||||
.treeview .hover { color: red; cursor: pointer; } |
||||
|
||||
.treeview li { background: url(../images/treeview-default-line.gif) 0 0 no-repeat; } |
||||
.treeview li.collapsable, .treeview li.expandable { background-position: 0 -176px; } |
||||
|
||||
.treeview .expandable-hitarea { background-position: -80px -3px; } |
||||
|
||||
.treeview li.last { background-position: 0 -1766px } |
||||
.treeview li.lastCollapsable, .treeview li.lastExpandable { background-image: url(../images/treeview-default.gif); } |
||||
.treeview li.lastCollapsable { background-position: 0 -111px } |
||||
.treeview li.lastExpandable { background-position: -32px -67px } |
||||
|
||||
.treeview div.lastCollapsable-hitarea, .treeview div.lastExpandable-hitarea { background-position: 0; } |
||||
|
||||
.treeview-red li { background-image: url(../images/treeview-red-line.gif); } |
||||
.treeview-red .hitarea, .treeview-red li.lastCollapsable, .treeview-red li.lastExpandable { background-image: url(../images/treeview-red.gif); } |
||||
|
||||
.treeview-black li { background-image: url(../images/treeview-black-line.gif); } |
||||
.treeview-black .hitarea, .treeview-black li.lastCollapsable, .treeview-black li.lastExpandable { background-image: url(../images/treeview-black.gif); } |
||||
|
||||
.treeview-gray li { background-image: url(../images/treeview-gray-line.gif); } |
||||
.treeview-gray .hitarea, .treeview-gray li.lastCollapsable, .treeview-gray li.lastExpandable { background-image: url(../images/treeview-gray.gif); } |
||||
|
||||
.treeview-famfamfam li { background-image: url(../images/treeview-famfamfam-line.gif); } |
||||
.treeview-famfamfam .hitarea, .treeview-famfamfam li.lastCollapsable, .treeview-famfamfam li.lastExpandable { background-image: url(../images/treeview-famfamfam.gif); } |
||||
|
||||
|
||||
.filetree li { padding: 3px 0 2px 16px; } |
||||
.filetree span.folder, .filetree span.file { padding: 1px 0 1px 20px; } |
||||
.filetree span.folder { background: url(../images/folder.gif) 0 0 no-repeat; } |
||||
.filetree li.expandable span.folder { background: url(../images/folder-closed.gif) 0 0 no-repeat; } |
||||
.filetree span.file { background: url(../images/file.gif) 0 0 no-repeat; } |
After Width: | Height: | Size: 180 B |
After Width: | Height: | Size: 178 B |
After Width: | Height: | Size: 120 B |
After Width: | Height: | Size: 105 B |
After Width: | Height: | Size: 111 B |
After Width: | Height: | Size: 110 B |
After Width: | Height: | Size: 119 B |
After Width: | Height: | Size: 101 B |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 4.3 KiB |
@ -0,0 +1,486 @@
|
||||
/* |
||||
* jQuery UI CSS Framework |
||||
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) |
||||
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. |
||||
*/ |
||||
|
||||
/* Layout helpers |
||||
----------------------------------*/ |
||||
.ui-helper-hidden { display: none; } |
||||
.ui-helper-hidden-accessible { position: absolute; left: -99999999px; } |
||||
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } |
||||
.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } |
||||
.ui-helper-clearfix { display: inline-block; } |
||||
/* required comment for clearfix to work in Opera \*/ |
||||
* html .ui-helper-clearfix { height:1%; } |
||||
.ui-helper-clearfix { display:block; } |
||||
/* end clearfix */ |
||||
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } |
||||
|
||||
|
||||
/* Interaction Cues |
||||
----------------------------------*/ |
||||
.ui-state-disabled { cursor: default !important; } |
||||
|
||||
|
||||
/* Icons |
||||
----------------------------------*/ |
||||
|
||||
/* states and images */ |
||||
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } |
||||
|
||||
|
||||
/* Misc visuals |
||||
----------------------------------*/ |
||||
|
||||
/* Overlays */ |
||||
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } |
||||
|
||||
|
||||
/* |
||||
* jQuery UI CSS Framework |
||||
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) |
||||
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. |
||||
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px |
||||
*/ |
||||
|
||||
|
||||
/* Component containers |
||||
----------------------------------*/ |
||||
.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; } |
||||
.ui-widget .ui-widget { font-size: 1em; } |
||||
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; } |
||||
.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; } |
||||
.ui-widget-content a { color: #222222; } |
||||
.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } |
||||
.ui-widget-header a { color: #222222; } |
||||
|
||||
/* Interaction states |
||||
----------------------------------*/ |
||||
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; } |
||||
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; } |
||||
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } |
||||
.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; } |
||||
.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } |
||||
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; } |
||||
.ui-widget :active { outline: none; } |
||||
|
||||
/* Interaction Cues |
||||
----------------------------------*/ |
||||
.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } |
||||
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } |
||||
.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } |
||||
.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } |
||||
.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } |
||||
.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } |
||||
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } |
||||
.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } |
||||
|
||||
/* Icons |
||||
----------------------------------*/ |
||||
|
||||
/* states and images */ |
||||
.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } |
||||
.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } |
||||
.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } |
||||
.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); } |
||||
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } |
||||
.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } |
||||
.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } |
||||
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } |
||||
|
||||
/* positioning */ |
||||
.ui-icon-carat-1-n { background-position: 0 0; } |
||||
.ui-icon-carat-1-ne { background-position: -16px 0; } |
||||
.ui-icon-carat-1-e { background-position: -32px 0; } |
||||
.ui-icon-carat-1-se { background-position: -48px 0; } |
||||
.ui-icon-carat-1-s { background-position: -64px 0; } |
||||
.ui-icon-carat-1-sw { background-position: -80px 0; } |
||||
.ui-icon-carat-1-w { background-position: -96px 0; } |
||||
.ui-icon-carat-1-nw { background-position: -112px 0; } |
||||
.ui-icon-carat-2-n-s { background-position: -128px 0; } |
||||
.ui-icon-carat-2-e-w { background-position: -144px 0; } |
||||
.ui-icon-triangle-1-n { background-position: 0 -16px; } |
||||
.ui-icon-triangle-1-ne { background-position: -16px -16px; } |
||||
.ui-icon-triangle-1-e { background-position: -32px -16px; } |
||||
.ui-icon-triangle-1-se { background-position: -48px -16px; } |
||||
.ui-icon-triangle-1-s { background-position: -64px -16px; } |
||||
.ui-icon-triangle-1-sw { background-position: -80px -16px; } |
||||
.ui-icon-triangle-1-w { background-position: -96px -16px; } |
||||
.ui-icon-triangle-1-nw { background-position: -112px -16px; } |
||||
.ui-icon-triangle-2-n-s { background-position: -128px -16px; } |
||||
.ui-icon-triangle-2-e-w { background-position: -144px -16px; } |
||||
.ui-icon-arrow-1-n { background-position: 0 -32px; } |
||||
.ui-icon-arrow-1-ne { background-position: -16px -32px; } |
||||
.ui-icon-arrow-1-e { background-position: -32px -32px; } |
||||
.ui-icon-arrow-1-se { background-position: -48px -32px; } |
||||
.ui-icon-arrow-1-s { background-position: -64px -32px; } |
||||
.ui-icon-arrow-1-sw { background-position: -80px -32px; } |
||||
.ui-icon-arrow-1-w { background-position: -96px -32px; } |
||||
.ui-icon-arrow-1-nw { background-position: -112px -32px; } |
||||
.ui-icon-arrow-2-n-s { background-position: -128px -32px; } |
||||
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } |
||||
.ui-icon-arrow-2-e-w { background-position: -160px -32px; } |
||||
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } |
||||
.ui-icon-arrowstop-1-n { background-position: -192px -32px; } |
||||
.ui-icon-arrowstop-1-e { background-position: -208px -32px; } |
||||
.ui-icon-arrowstop-1-s { background-position: -224px -32px; } |
||||
.ui-icon-arrowstop-1-w { background-position: -240px -32px; } |
||||
.ui-icon-arrowthick-1-n { background-position: 0 -48px; } |
||||
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } |
||||
.ui-icon-arrowthick-1-e { background-position: -32px -48px; } |
||||
.ui-icon-arrowthick-1-se { background-position: -48px -48px; } |
||||
.ui-icon-arrowthick-1-s { background-position: -64px -48px; } |
||||
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } |
||||
.ui-icon-arrowthick-1-w { background-position: -96px -48px; } |
||||
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } |
||||
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } |
||||
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } |
||||
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } |
||||
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } |
||||
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } |
||||
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } |
||||
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } |
||||
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } |
||||
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } |
||||
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } |
||||
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } |
||||
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } |
||||
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } |
||||
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } |
||||
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } |
||||
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } |
||||
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } |
||||
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } |
||||
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } |
||||
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } |
||||
.ui-icon-arrow-4 { background-position: 0 -80px; } |
||||
.ui-icon-arrow-4-diag { background-position: -16px -80px; } |
||||
.ui-icon-extlink { background-position: -32px -80px; } |
||||
.ui-icon-newwin { background-position: -48px -80px; } |
||||
.ui-icon-refresh { background-position: -64px -80px; } |
||||
.ui-icon-shuffle { background-position: -80px -80px; } |
||||
.ui-icon-transfer-e-w { background-position: -96px -80px; } |
||||
.ui-icon-transferthick-e-w { background-position: -112px -80px; } |
||||
.ui-icon-folder-collapsed { background-position: 0 -96px; } |
||||
.ui-icon-folder-open { background-position: -16px -96px; } |
||||
.ui-icon-document { background-position: -32px -96px; } |
||||
.ui-icon-document-b { background-position: -48px -96px; } |
||||
.ui-icon-note { background-position: -64px -96px; } |
||||
.ui-icon-mail-closed { background-position: -80px -96px; } |
||||
.ui-icon-mail-open { background-position: -96px -96px; } |
||||
.ui-icon-suitcase { background-position: -112px -96px; } |
||||
.ui-icon-comment { background-position: -128px -96px; } |
||||
.ui-icon-person { background-position: -144px -96px; } |
||||
.ui-icon-print { background-position: -160px -96px; } |
||||
.ui-icon-trash { background-position: -176px -96px; } |
||||
.ui-icon-locked { background-position: -192px -96px; } |
||||
.ui-icon-unlocked { background-position: -208px -96px; } |
||||
.ui-icon-bookmark { background-position: -224px -96px; } |
||||
.ui-icon-tag { background-position: -240px -96px; } |
||||
.ui-icon-home { background-position: 0 -112px; } |
||||
.ui-icon-flag { background-position: -16px -112px; } |
||||
.ui-icon-calendar { background-position: -32px -112px; } |
||||
.ui-icon-cart { background-position: -48px -112px; } |
||||
.ui-icon-pencil { background-position: -64px -112px; } |
||||
.ui-icon-clock { background-position: -80px -112px; } |
||||
.ui-icon-disk { background-position: -96px -112px; } |
||||
.ui-icon-calculator { background-position: -112px -112px; } |
||||
.ui-icon-zoomin { background-position: -128px -112px; } |
||||
.ui-icon-zoomout { background-position: -144px -112px; } |
||||
.ui-icon-search { background-position: -160px -112px; } |
||||
.ui-icon-wrench { background-position: -176px -112px; } |
||||
.ui-icon-gear { background-position: -192px -112px; } |
||||
.ui-icon-heart { background-position: -208px -112px; } |
||||
.ui-icon-star { background-position: -224px -112px; } |
||||
.ui-icon-link { background-position: -240px -112px; } |
||||
.ui-icon-cancel { background-position: 0 -128px; } |
||||
.ui-icon-plus { background-position: -16px -128px; } |
||||
.ui-icon-plusthick { background-position: -32px -128px; } |
||||
.ui-icon-minus { background-position: -48px -128px; } |
||||
.ui-icon-minusthick { background-position: -64px -128px; } |
||||
.ui-icon-close { background-position: -80px -128px; } |
||||
.ui-icon-closethick { background-position: -96px -128px; } |
||||
.ui-icon-key { background-position: -112px -128px; } |
||||
.ui-icon-lightbulb { background-position: -128px -128px; } |
||||
.ui-icon-scissors { background-position: -144px -128px; } |
||||
.ui-icon-clipboard { background-position: -160px -128px; } |
||||
.ui-icon-copy { background-position: -176px -128px; } |
||||
.ui-icon-contact { background-position: -192px -128px; } |
||||
.ui-icon-image { background-position: -208px -128px; } |
||||
.ui-icon-video { background-position: -224px -128px; } |
||||
.ui-icon-script { background-position: -240px -128px; } |
||||
.ui-icon-alert { background-position: 0 -144px; } |
||||
.ui-icon-info { background-position: -16px -144px; } |
||||
.ui-icon-notice { background-position: -32px -144px; } |
||||
.ui-icon-help { background-position: -48px -144px; } |
||||
.ui-icon-check { background-position: -64px -144px; } |
||||
.ui-icon-bullet { background-position: -80px -144px; } |
||||
.ui-icon-radio-off { background-position: -96px -144px; } |
||||
.ui-icon-radio-on { background-position: -112px -144px; } |
||||
.ui-icon-pin-w { background-position: -128px -144px; } |
||||
.ui-icon-pin-s { background-position: -144px -144px; } |
||||
.ui-icon-play { background-position: 0 -160px; } |
||||
.ui-icon-pause { background-position: -16px -160px; } |
||||
.ui-icon-seek-next { background-position: -32px -160px; } |
||||
.ui-icon-seek-prev { background-position: -48px -160px; } |
||||
.ui-icon-seek-end { background-position: -64px -160px; } |
||||
.ui-icon-seek-start { background-position: -80px -160px; } |
||||
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ |
||||
.ui-icon-seek-first { background-position: -80px -160px; } |
||||
.ui-icon-stop { background-position: -96px -160px; } |
||||
.ui-icon-eject { background-position: -112px -160px; } |
||||
.ui-icon-volume-off { background-position: -128px -160px; } |
||||
.ui-icon-volume-on { background-position: -144px -160px; } |
||||
.ui-icon-power { background-position: 0 -176px; } |
||||
.ui-icon-signal-diag { background-position: -16px -176px; } |
||||
.ui-icon-signal { background-position: -32px -176px; } |
||||
.ui-icon-battery-0 { background-position: -48px -176px; } |
||||
.ui-icon-battery-1 { background-position: -64px -176px; } |
||||
.ui-icon-battery-2 { background-position: -80px -176px; } |
||||
.ui-icon-battery-3 { background-position: -96px -176px; } |
||||
.ui-icon-circle-plus { background-position: 0 -192px; } |
||||
.ui-icon-circle-minus { background-position: -16px -192px; } |
||||
.ui-icon-circle-close { background-position: -32px -192px; } |
||||
.ui-icon-circle-triangle-e { background-position: -48px -192px; } |
||||
.ui-icon-circle-triangle-s { background-position: -64px -192px; } |
||||
.ui-icon-circle-triangle-w { background-position: -80px -192px; } |
||||
.ui-icon-circle-triangle-n { background-position: -96px -192px; } |
||||
.ui-icon-circle-arrow-e { background-position: -112px -192px; } |
||||
.ui-icon-circle-arrow-s { background-position: -128px -192px; } |
||||
.ui-icon-circle-arrow-w { background-position: -144px -192px; } |
||||
.ui-icon-circle-arrow-n { background-position: -160px -192px; } |
||||
.ui-icon-circle-zoomin { background-position: -176px -192px; } |
||||
.ui-icon-circle-zoomout { background-position: -192px -192px; } |
||||
.ui-icon-circle-check { background-position: -208px -192px; } |
||||
.ui-icon-circlesmall-plus { background-position: 0 -208px; } |
||||
.ui-icon-circlesmall-minus { background-position: -16px -208px; } |
||||
.ui-icon-circlesmall-close { background-position: -32px -208px; } |
||||
.ui-icon-squaresmall-plus { background-position: -48px -208px; } |
||||
.ui-icon-squaresmall-minus { background-position: -64px -208px; } |
||||
.ui-icon-squaresmall-close { background-position: -80px -208px; } |
||||
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } |
||||
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } |
||||
.ui-icon-grip-solid-vertical { background-position: -32px -224px; } |
||||
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } |
||||
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } |
||||
.ui-icon-grip-diagonal-se { background-position: -80px -224px; } |
||||
|
||||
|
||||
/* Misc visuals |
||||
----------------------------------*/ |
||||
|
||||
/* Corner radius */ |
||||
.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; } |
||||
.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } |
||||
.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } |
||||
.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } |
||||
.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } |
||||
.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } |
||||
.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } |
||||
.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } |
||||
.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } |
||||
|
||||
/* Overlays */ |
||||
.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } |
||||
.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* Resizable |
||||
----------------------------------*/ |
||||
.ui-resizable { position: relative;} |
||||
.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;} |
||||
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } |
||||
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } |
||||
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } |
||||
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } |
||||
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } |
||||
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } |
||||
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } |
||||
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } |
||||
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Accordion |
||||
----------------------------------*/ |
||||
.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } |
||||
.ui-accordion .ui-accordion-li-fix { display: inline; } |
||||
.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } |
||||
.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } |
||||
/* IE7-/Win - Fix extra vertical space in lists */ |
||||
.ui-accordion a { zoom: 1; } |
||||
.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } |
||||
.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } |
||||
.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } |
||||
.ui-accordion .ui-accordion-content-active { display: block; }/* Autocomplete |
||||
----------------------------------*/ |
||||
.ui-autocomplete { position: absolute; cursor: default; } |
||||
.ui-autocomplete-loading { background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; } |
||||
|
||||
/* workarounds */ |
||||
* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ |
||||
|
||||
/* Menu |
||||
----------------------------------*/ |
||||
.ui-menu { |
||||
list-style:none; |
||||
padding: 2px; |
||||
margin: 0; |
||||
display:block; |
||||
} |
||||
.ui-menu .ui-menu { |
||||
margin-top: -3px; |
||||
} |
||||
.ui-menu .ui-menu-item { |
||||
margin:0; |
||||
padding: 0; |
||||
zoom: 1; |
||||
float: left; |
||||
clear: left; |
||||
width: 100%; |
||||
} |
||||
.ui-menu .ui-menu-item a { |
||||
text-decoration:none; |
||||
display:block; |
||||
padding:.2em .4em; |
||||
line-height:1.5; |
||||
zoom:1; |
||||
} |
||||
.ui-menu .ui-menu-item a.ui-state-hover, |
||||
.ui-menu .ui-menu-item a.ui-state-active { |
||||
font-weight: normal; |
||||
margin: -1px; |
||||
} |
||||
/* Button |
||||
----------------------------------*/ |
||||
|
||||
.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ |
||||
.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ |
||||
button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ |
||||
.ui-button-icons-only { width: 3.4em; } |
||||
button.ui-button-icons-only { width: 3.7em; } |
||||
|
||||
/*button text element */ |
||||
.ui-button .ui-button-text { display: block; line-height: 1.4; } |
||||
.ui-button-text-only .ui-button-text { padding: .4em 1em; } |
||||
.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } |
||||
.ui-button-text-icon .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } |
||||
.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } |
||||
/* no icon support for input elements, provide padding by default */ |
||||
input.ui-button { padding: .4em 1em; } |
||||
|
||||
/*button icon element(s) */ |
||||
.ui-button-icon-only .ui-icon, .ui-button-text-icon .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } |
||||
.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } |
||||
.ui-button-text-icon .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } |
||||
.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } |
||||
|
||||
/*button sets*/ |
||||
.ui-buttonset { margin-right: 7px; } |
||||
.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } |
||||
|
||||
/* workarounds */ |
||||
button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Dialog |
||||
----------------------------------*/ |
||||
.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } |
||||
.ui-dialog .ui-dialog-titlebar { padding: .5em 1em .3em; position: relative; } |
||||
.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; } |
||||
.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } |
||||
.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } |
||||
.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } |
||||
.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } |
||||
.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } |
||||
.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; } |
||||
.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } |
||||
.ui-draggable .ui-dialog-titlebar { cursor: move; } |
||||
/* Slider |
||||
----------------------------------*/ |
||||
.ui-slider { position: relative; text-align: left; } |
||||
.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } |
||||
.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } |
||||
|
||||
.ui-slider-horizontal { height: .8em; } |
||||
.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } |
||||
.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } |
||||
.ui-slider-horizontal .ui-slider-range-min { left: 0; } |
||||
.ui-slider-horizontal .ui-slider-range-max { right: 0; } |
||||
|
||||
.ui-slider-vertical { width: .8em; height: 100px; } |
||||
.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } |
||||
.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } |
||||
.ui-slider-vertical .ui-slider-range-min { bottom: 0; } |
||||
.ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs |
||||
----------------------------------*/ |
||||
.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ |
||||
.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } |
||||
.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } |
||||
.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } |
||||
.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } |
||||
.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } |
||||
.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ |
||||
.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } |
||||
.ui-tabs .ui-tabs-hide { display: none !important; } |
||||
/* Datepicker |
||||
----------------------------------*/ |
||||
.ui-datepicker { width: 17em; padding: .2em .2em 0; } |
||||
.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } |
||||
.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } |
||||
.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } |
||||
.ui-datepicker .ui-datepicker-prev { left:2px; } |
||||
.ui-datepicker .ui-datepicker-next { right:2px; } |
||||
.ui-datepicker .ui-datepicker-prev-hover { left:1px; } |
||||
.ui-datepicker .ui-datepicker-next-hover { right:1px; } |
||||
.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } |
||||
.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } |
||||
.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } |
||||
.ui-datepicker select.ui-datepicker-month-year {width: 100%;} |
||||
.ui-datepicker select.ui-datepicker-month, |
||||
.ui-datepicker select.ui-datepicker-year { width: 49%;} |
||||
.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } |
||||
.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } |
||||
.ui-datepicker td { border: 0; padding: 1px; } |
||||
.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } |
||||
.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } |
||||
.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } |
||||
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } |
||||
|
||||
/* with multiple calendars */ |
||||
.ui-datepicker.ui-datepicker-multi { width:auto; } |
||||
.ui-datepicker-multi .ui-datepicker-group { float:left; } |
||||
.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } |
||||
.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } |
||||
.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } |
||||
.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } |
||||
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } |
||||
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } |
||||
.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } |
||||
.ui-datepicker-row-break { clear:both; width:100%; } |
||||
|
||||
/* RTL support */ |
||||
.ui-datepicker-rtl { direction: rtl; } |
||||
.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } |
||||
.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } |
||||
.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } |
||||
.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } |
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } |
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } |
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } |
||||
.ui-datepicker-rtl .ui-datepicker-group { float:right; } |
||||
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } |
||||
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } |
||||
|
||||
/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ |
||||
.ui-datepicker-cover { |
||||
display: none; /*sorry for IE5*/ |
||||
display/**/: block; /*sorry for IE5*/ |
||||
position: absolute; /*must have*/ |
||||
z-index: -1; /*must have*/ |
||||
filter: mask(); /*must have*/ |
||||
top: -4px; /*must have*/ |
||||
left: -4px; /*must have*/ |
||||
width: 200px; /*must have*/ |
||||
height: 200px; /*must have*/ |
||||
}/* Progressbar |
||||
----------------------------------*/ |
||||
.ui-progressbar { height:2em; text-align: left; } |
||||
.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } |
After Width: | Height: | Size: 386 B |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 364 B |
After Width: | Height: | Size: 110 B |
After Width: | Height: | Size: 105 B |
After Width: | Height: | Size: 106 B |
After Width: | Height: | Size: 837 B |
After Width: | Height: | Size: 841 B |
After Width: | Height: | Size: 622 B |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 745 B |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 807 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 362 B |
@ -0,0 +1,7 @@
|
||||
; $Id$ |
||||
name = Islandora Content Modeller |
||||
dependencies[] = fedora_repository |
||||
description = Allows you to manage and build content models for Islandora/Fedora. |
||||
package = Fedora Repository |
||||
version = 6.1dev |
||||
core = 6.x |
@ -0,0 +1,271 @@
|
||||
var collection = new Array('Root'); |
||||
var model = false; |
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
$(document).ajaxStart(function(){
|
||||
$('#ajaxBusy').show();
|
||||
}).ajaxStop(function(){
|
||||
$('#ajaxBusy').hide(); |
||||
});
|
||||
|
||||
$('#Notification').jnotifyInizialize({ |
||||
oneAtTime: false, |
||||
appendType: 'append' |
||||
}) |
||||
.css({ |
||||
'marginTop': '20px', |
||||
'left': '20px', |
||||
'width': '500px', |
||||
'z-index': '9999' |
||||
}); |
||||
|
||||
updateCollectionTree(); |
||||
updateModelList(); |
||||
|
||||
$('.refresh').click(function () {
|
||||
$('#Notification').jnotifyAddMessage({text: 'Refreshed collection '+collection[collection.length-1]+' and model '+(model==false?'list':model)+'.', permanent: false}); |
||||
updateCollectionTree(); |
||||
if (model == false) |
||||
updateModelList(); |
||||
else |
||||
updateModelTree(); |
||||
return false; |
||||
}); |
||||
|
||||
$('.list').click(function () {
|
||||
$('#Notification').jnotifyAddMessage({text: 'Refreshed model list.', permanent: false}); |
||||
model = false; |
||||
updateModelList(); |
||||
return false; |
||||
}); |
||||
|
||||
|
||||
function updateBreadcrumbs() |
||||
{ |
||||
var content = ''; |
||||
for (var i = 0; i < collection.length; i++) |
||||
{ |
||||
content += '<a href="#" class="collection_crumb" id="'+i+'">'+collection[i]+'</a> /'; |
||||
} |
||||
$('#collection_crumbs').html(content); |
||||
} |
||||
|
||||
function handleForm() |
||||
{ |
||||
$('#edit-form-module').change(function () { |
||||
$.get('modeller/ajax/getFiles/', { module: $('#edit-form-module').val() }, function (data) { |
||||
$('#edit-form-filename-select').html(data); |
||||
}); |
||||
$('#edit-form-class-select, #edit-form-method-select, #edit-form-handler-select').html(''); |
||||
}); |
||||
|
||||
$('.form-item #edit-form-filename').hide(); |
||||
$('.form-item #edit-form-filename').before('<select id="edit-form-filename-select"></select>'); |
||||
$('#edit-form-filename-select').change(function () { |
||||
$('#edit-form-filename').val($('#edit-form-filename-select').val());
|
||||
$.get('modeller/ajax/getClasses/', { module: $('#edit-form-module').val(),
|
||||
file: $('#edit-form-filename').val(),
|
||||
className: $('#edit-form-class').val() },
|
||||
function (data) { $('#edit-form-class-select').html(data); });
|
||||
}); |
||||
|
||||
|
||||
$('.form-item #edit-form-class').hide(); |
||||
$('.form-item #edit-form-class').before('<select id="edit-form-class-select"></select>'); |
||||
$('#edit-form-class-select').change(function () { |
||||
$('#edit-form-class').val($('#edit-form-class-select').val());
|
||||
$.get('modeller/ajax/getMethods/', { module: $('#edit-form-module').val(), |
||||
file: $('#edit-form-filename').val(),
|
||||
className: $('#edit-form-class').val() },
|
||||
function (data) { |
||||
$('#edit-form-method-select').html(data); |
||||
$('#edit-form-handler-select').html(data); |
||||
});
|
||||
}); |
||||
|
||||
if ($('#edit-form-file').val() || $('#edit-form-class').val() || $('#edit-form-filename').val()) |
||||
{ |
||||
$.get('modeller/ajax/getFiles/', { module: $('#edit-form-module').val(), file: $('#edit-form-filename').val() }, function (data) {
|
||||
$('#edit-form-filename-select').html(data); |
||||
}); |
||||
$.get('modeller/ajax/getClasses/', { module: $('#edit-form-module').val(), file: $('#edit-form-filename').val(), className: $('#edit-form-class').val() }, function (data) { |
||||
$('#edit-form-class-select').html(data); |
||||
}); |
||||
}
|
||||
|
||||
$('.form-item #edit-form-method, .form-item #edit-form-handler').hide(); |
||||
$('.form-item #edit-form-method').before('<select id="edit-form-method-select"></select>'); |
||||
$('.form-item #edit-form-handler').before('<select id="edit-form-handler-select"></select>'); |
||||
$('#edit-form-method-select').change(function () { |
||||
$('#edit-form-method').val($('#edit-form-method-select').val());
|
||||
}); |
||||
$('#edit-form-handler-select').change(function () { |
||||
$('#edit-form-handler').val($('#edit-form-handler-select').val());
|
||||
}); |
||||
|
||||
|
||||
if ( $('#edit-form-class').val()) |
||||
{ |
||||
$.get('modeller/ajax/getMethods/', { module: $('#edit-form-module').val(), file: $('#edit-form-filename').val(), className: $('#edit-form-class').val(), method: $('#edit-form-method').val() }, function (data) { |
||||
$('#edit-form-method-select').html(data); |
||||
}); |
||||
$.get('modeller/ajax/getMethods/', { module: $('#edit-form-module').val(), file: $('#edit-form-filename').val(), className: $('#edit-form-class').val(), method: $('#edit-form-handler').val() }, function (data) { |
||||
$('#edit-form-handler-select').html(data); |
||||
});
|
||||
}
|
||||
|
||||
$('#ajaxForm #cancel').click(function (d) { |
||||
$('#ajaxForm').fadeOut(); |
||||
return false; |
||||
}); |
||||
|
||||
$('#ajaxForm form').submit(function (d) { |
||||
$.post(d.target.action, |
||||
$('#'+d.target.id).serialize()+'&op=Save',
|
||||
function (data) |
||||
{ |
||||
lines = data.split(':'); |
||||
if (lines.shift() == 'success') |
||||
{ |
||||
$('#Notification').jnotifyAddMessage({text: lines.join(':'), permanent: false}); |
||||
$('#ajaxForm').fadeOut(); |
||||
if (model == false) |
||||
updateModelList(); |
||||
else |
||||
updateModelTree(); |
||||
updateCollectionTree();
|
||||
} else |
||||
{ |
||||
$('#ajaxForm').html(data); |
||||
handleForm(); |
||||
} |
||||
}); |
||||
return false; |
||||
}); |
||||
} |
||||
|
||||
function buttonIcons() |
||||
{ |
||||
$('.ajaxButtonIcon').unbind(); |
||||
$('.ajaxButtonIcon').click(function () { |
||||
$.get('modeller/ajax/button', { formReq: this.id}, function (data) { |
||||
lines = data.split(':'); |
||||
if (lines.shift() == 'success') |
||||
{ |
||||
$('#Notification').jnotifyAddMessage({text: lines.join(':'), permanent: false}); |
||||
if (model == false) |
||||
updateModelList(); |
||||
else |
||||
updateModelTree(); |
||||
updateCollectionTree();
|
||||
} else |
||||
{ |
||||
$('#Notification').jnotifyAddMessage({text: data, permanent: false, type: 'error'}); |
||||
} |
||||
}); |
||||
|
||||
}); |
||||
} |
||||
|
||||
function formIcons() |
||||
{ |
||||
$('.ajaxFormIcon').unbind(); |
||||
$('.ajaxFormIcon').click(function () { |
||||
var params=this.id.split(' '); |
||||
var formName=params.shift(); |
||||
$.get('modeller/ajax/processForm/'+formName, { formReq: params.join(' ')}, function (data) { |
||||
if (data == '') |
||||
{ |
||||
$('#Notification').jnotifyAddMessage({text: 'Error: Unable to load requested form <b>\''+formName+'\'</b>.', permanent: false, type: 'error'});
|
||||
} else |
||||
{ |
||||
$('#ajaxForm').html(data).fadeIn();
|
||||
handleForm(); |
||||
} |
||||
}); |
||||
|
||||
return false; |
||||
}); |
||||
} |
||||
|
||||
function updateModelList() { |
||||
$.get('modeller/ajax/listModels' , function (j) {
|
||||
$('#model_tree').html(j); |
||||
$('#model_tree ul').treeview({ animated: "fast", |
||||
collapsed: true, |
||||
unique: false, |
||||
persist: "cookie", |
||||
cookieId: "modelTree"}); |
||||
|
||||
$(".list_model").click( function () {
|
||||
model = this.id; |
||||
updateModelTree(); |
||||
$('#Notification').jnotifyAddMessage({text: 'Displayed model '+this.id, permanent: false}); |
||||
return false;
|
||||
}); |
||||
|
||||
buttonIcons(); |
||||
formIcons();
|
||||
|
||||
}); |
||||
}
|
||||
|
||||
function updateModelTree() { |
||||
$.get('modeller/ajax/model', { model_pid: model} , function (j) {
|
||||
$('#model_tree').html(j); |
||||
$('#model_tree ul').treeview({ animated: "fast", |
||||
collapsed: true, |
||||
unique: false, |
||||
persist: "cookie", |
||||
cookieId: "modelTree"}); |
||||
|
||||
buttonIcons(); |
||||
formIcons();
|
||||
|
||||
}); |
||||
} |
||||
|
||||
function updateCollectionTree() { |
||||
collection_pid = collection[collection.length-1]; |
||||
if (collection_pid == 'Root') |
||||
collection_pid = false; |
||||
|
||||
$.get('modeller/ajax/collection', { collection_pid: collection_pid} , function (j) {
|
||||
updateBreadcrumbs();
|
||||
|
||||
$('#collection_tree').html(j); |
||||
$('#collection_tree ul').treeview({ animated: "fast", |
||||
collapsed: true, |
||||
unique: false, |
||||
persist: "cookie", |
||||
cookieId: "collectionTree" }); |
||||
|
||||
buttonIcons(); |
||||
formIcons(); |
||||
|
||||
$(".collection_model").click( function () {
|
||||
model = this.id; |
||||
updateModelTree(); |
||||
$('#Notification').jnotifyAddMessage({text: 'Displayed model '+this.id, permanent: false}); |
||||
return false;
|
||||
}); |
||||
|
||||
$(".collection_child").click( function () {
|
||||
collection.push(this.id); |
||||
updateCollectionTree(); |
||||
$('#Notification').jnotifyAddMessage({text: 'Switched to collection '+this.id, permanent: false}); |
||||
return false; |
||||
}); |
||||
|
||||
$(".collection_crumb").click( function () {
|
||||
var pop_no = collection.length-this.id-1; |
||||
for (var i =0; i < pop_no; i++) |
||||
collection.pop(); |
||||
updateCollectionTree(); |
||||
$('#Notification').jnotifyAddMessage({text: 'Switched to collection '+collection[collection.length-1], permanent: false}); |
||||
return false; |
||||
}); |
||||
}); |
||||
} |
||||
}); |
@ -0,0 +1,92 @@
|
||||
/** |
||||
* Cookie plugin |
||||
* |
||||
* Copyright (c) 2006 Klaus Hartl (stilbuero.de) |
||||
* Dual licensed under the MIT and GPL licenses: |
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
* |
||||
*/ |
||||
|
||||
/** |
||||
* Create a cookie with the given name and value and other optional parameters. |
||||
* |
||||
* @example $.cookie('the_cookie', 'the_value'); |
||||
* @desc Set the value of a cookie. |
||||
* @example $.cookie('the_cookie', 'the_value', {expires: 7, path: '/', domain: 'jquery.com', secure: true}); |
||||
* @desc Create a cookie with all available options. |
||||
* @example $.cookie('the_cookie', 'the_value'); |
||||
* @desc Create a session cookie. |
||||
* @example $.cookie('the_cookie', null); |
||||
* @desc Delete a cookie by passing null as value. |
||||
* |
||||
* @param String name The name of the cookie. |
||||
* @param String value The value of the cookie. |
||||
* @param Object options An object literal containing key/value pairs to provide optional cookie attributes. |
||||
* @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object. |
||||
* If a negative value is specified (e.g. a date in the past), the cookie will be deleted. |
||||
* If set to null or omitted, the cookie will be a session cookie and will not be retained |
||||
* when the the browser exits. |
||||
* @option String path The value of the path atribute of the cookie (default: path of page that created the cookie). |
||||
* @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie). |
||||
* @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will |
||||
* require a secure protocol (like HTTPS). |
||||
* @type undefined |
||||
* |
||||
* @name $.cookie |
||||
* @cat Plugins/Cookie |
||||
* @author Klaus Hartl/klaus.hartl@stilbuero.de |
||||
*/ |
||||
|
||||
/** |
||||
* Get the value of a cookie with the given name. |
||||
* |
||||
* @example $.cookie('the_cookie'); |
||||
* @desc Get the value of a cookie. |
||||
* |
||||
* @param String name The name of the cookie. |
||||
* @return The value of the cookie. |
||||
* @type String |
||||
* |
||||
* @name $.cookie |
||||
* @cat Plugins/Cookie |
||||
* @author Klaus Hartl/klaus.hartl@stilbuero.de |
||||
*/ |
||||
jQuery.cookie = function(name, value, options) { |
||||
if (typeof value != 'undefined') { // name and value given, set cookie
|
||||
options = options || {}; |
||||
if (value === null) { |
||||
value = ''; |
||||
options.expires = -1; |
||||
} |
||||
var expires = ''; |
||||
if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { |
||||
var date; |
||||
if (typeof options.expires == 'number') { |
||||
date = new Date(); |
||||
date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); |
||||
} else { |
||||
date = options.expires; |
||||
} |
||||
expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
|
||||
} |
||||
var path = options.path ? '; path=' + options.path : ''; |
||||
var domain = options.domain ? '; domain=' + options.domain : ''; |
||||
var secure = options.secure ? '; secure' : ''; |
||||
document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); |
||||
} else { // only name given, get cookie
|
||||
var cookieValue = null; |
||||
if (document.cookie && document.cookie != '') { |
||||
var cookies = document.cookie.split(';'); |
||||
for (var i = 0; i < cookies.length; i++) { |
||||
var cookie = jQuery.trim(cookies[i]); |
||||
// Does this cookie string begin with the name we want?
|
||||
if (cookie.substring(0, name.length + 1) == (name + '=')) { |
||||
cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
return cookieValue; |
||||
} |
||||
}; |
@ -0,0 +1,143 @@
|
||||
/** |
||||
* jQuery.jNotify |
||||
* jQuery Notification Engine |
||||
*
|
||||
* Copyright (c) 2010 Fabio Franzini |
||||
* |
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
* of this software and associated documentation files (the "Software"), to deal |
||||
* in the Software without restriction, including without limitation the rights |
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
* copies of the Software, and to permit persons to whom the Software is |
||||
* furnished to do so, subject to the following conditions: |
||||
* |
||||
* The above copyright notify and this permission notify shall be included in |
||||
* all copies or substantial portions of the Software. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
* THE SOFTWARE. |
||||
*
|
||||
* @author Fabio Franzini |
||||
* @copyright 2010 www.fabiofranzini.com |
||||
* @version 1 |
||||
**/ |
||||
|
||||
(function(jQuery) { |
||||
jQuery.fn.jnotifyInizialize = function(options) { |
||||
var element = this; |
||||
|
||||
var defaults = { |
||||
oneAtTime: false, |
||||
appendType: 'append' |
||||
}; |
||||
|
||||
var options = jQuery.extend({}, defaults, options); |
||||
|
||||
this.addClass('notify-wrapper'); |
||||
|
||||
if (options.oneAtTime) |
||||
this.addClass('notify-wrapper-oneattime'); |
||||
|
||||
if (options.appendType == 'prepend' && options.oneAtTime == false) |
||||
this.addClass('notify-wrapper-prepend'); |
||||
|
||||
return this; |
||||
}; |
||||
jQuery.fn.jnotifyAddMessage = function(options) { |
||||
|
||||
var notifyWrapper = this; |
||||
|
||||
if (notifyWrapper.hasClass('notify-wrapper')) { |
||||
|
||||
var defaults = { |
||||
text: '', |
||||
type: 'message', |
||||
showIcon: true, |
||||
permanent: false, |
||||
disappearTime: 3000 |
||||
}; |
||||
|
||||
var options = jQuery.extend({}, defaults, options); |
||||
var styleClass; |
||||
var iconClass; |
||||
|
||||
switch (options.type) { |
||||
case 'message': |
||||
{ |
||||
styleClass = 'ui-state-highlight'; |
||||
iconClass = 'ui-icon-info'; |
||||
} |
||||
break; |
||||
case 'error': |
||||
{ |
||||
styleClass = 'ui-state-error'; |
||||
iconClass = 'ui-icon-alert'; |
||||
} |
||||
break; |
||||
default: |
||||
{ |
||||
styleClass = 'ui-state-highlight'; |
||||
iconClass = 'ui-icon-info'; |
||||
} |
||||
break; |
||||
} |
||||
|
||||
if (notifyWrapper.hasClass('notify-wrapper-oneattime')) { |
||||
this.children().remove(); |
||||
} |
||||
|
||||
var notifyItemWrapper = jQuery('<div class="jnotify-item-wrapper"></div>'); |
||||
var notifyItem = jQuery('<div class="ui-corner-all jnotify-item"></div>') |
||||
.addClass(styleClass); |
||||
|
||||
if (notifyWrapper.hasClass('notify-wrapper-prepend')) |
||||
notifyItem.prependTo(notifyWrapper); |
||||
else |
||||
notifyItem.appendTo(notifyWrapper); |
||||
|
||||
notifyItem.wrap(notifyItemWrapper); |
||||
|
||||
if (options.showIcon) |
||||
jQuery('<span class="ui-icon" style="float:left; margin-right: .3em;" />') |
||||
.addClass(iconClass) |
||||
.appendTo(notifyItem); |
||||
|
||||
jQuery('<span></span>').html(options.text).appendTo(notifyItem); |
||||
jQuery('<div class="jnotify-item-close"><span class="ui-icon ui-icon-circle-close"/></div>') |
||||
.prependTo(notifyItem) |
||||
.click(function() { remove(notifyItem) }); |
||||
|
||||
// IEsucks
|
||||
if (navigator.userAgent.match(/MSIE (\d+\.\d+);/)) { |
||||
notifyWrapper.css({ top: document.documentElement.scrollTop }); |
||||
//http://groups.google.com/group/jquery-dev/browse_thread/thread/ba38e6474e3e9a41
|
||||
notifyWrapper.removeClass('IEsucks'); |
||||
} |
||||
// ------
|
||||
|
||||
if (!options.permanent) { |
||||
setTimeout(function() { remove(notifyItem); }, options.disappearTime); |
||||
} |
||||
} |
||||
|
||||
function remove(obj) { |
||||
obj.animate({ opacity: '0' }, 600, function() { |
||||
obj.parent().animate({ height: '0px' }, 300, |
||||
function() { |
||||
obj.parent().remove(); |
||||
// IEsucks
|
||||
if (navigator.userAgent.match(/MSIE (\d+\.\d+);/)) { |
||||
//http://groups.google.com/group/jquery-dev/browse_thread/thread/ba38e6474e3e9a41
|
||||
obj.parent().parent().removeClass('IEsucks'); |
||||
} |
||||
// -------
|
||||
}); |
||||
}); |
||||
} |
||||
}; |
||||
})(jQuery); |
@ -0,0 +1,254 @@
|
||||
/* |
||||
* Treeview 1.4 - jQuery plugin to hide and show branches of a tree |
||||
*
|
||||
* http://bassistance.de/jquery-plugins/jquery-plugin-treeview/
|
||||
* http://docs.jquery.com/Plugins/Treeview
|
||||
* |
||||
* Copyright (c) 2007 Jörn Zaefferer |
||||
* |
||||
* Dual licensed under the MIT and GPL licenses: |
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
* |
||||
* Revision: $Id: jquery.treeview.js 4684 2008-02-07 19:08:06Z joern.zaefferer $ |
||||
* |
||||
*/ |
||||
|
||||
;(function($) { |
||||
|
||||
$.extend($.fn, { |
||||
swapClass: function(c1, c2) { |
||||
var c1Elements = this.filter('.' + c1); |
||||
this.filter('.' + c2).removeClass(c2).addClass(c1); |
||||
c1Elements.removeClass(c1).addClass(c2); |
||||
return this; |
||||
}, |
||||
replaceClass: function(c1, c2) { |
||||
return this.filter('.' + c1).removeClass(c1).addClass(c2).end(); |
||||
}, |
||||
hoverClass: function(className) { |
||||
className = className || "hover"; |
||||
return this.hover(function() { |
||||
$(this).addClass(className); |
||||
}, function() { |
||||
$(this).removeClass(className); |
||||
}); |
||||
}, |
||||
heightToggle: function(animated, callback) { |
||||
animated ? |
||||
this.animate({ height: "toggle" }, animated, callback) : |
||||
this.each(function(){ |
||||
jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ](); |
||||
if(callback) |
||||
callback.apply(this, arguments); |
||||
}); |
||||
}, |
||||
heightHide: function(animated, callback) { |
||||
if (animated) { |
||||
this.animate({ height: "hide" }, animated, callback); |
||||
} else { |
||||
this.hide(); |
||||
if (callback) |
||||
this.each(callback);
|
||||
} |
||||
}, |
||||
prepareBranches: function(settings) { |
||||
if (!settings.prerendered) { |
||||
// mark last tree items
|
||||
this.filter(":last-child:not(ul)").addClass(CLASSES.last); |
||||
// collapse whole tree, or only those marked as closed, anyway except those marked as open
|
||||
this.filter((settings.collapsed ? "" : "." + CLASSES.closed) + ":not(." + CLASSES.open + ")").find(">ul").hide(); |
||||
} |
||||
// return all items with sublists
|
||||
return this.filter(":has(>ul)"); |
||||
}, |
||||
applyClasses: function(settings, toggler) { |
||||
|
||||
this.filter(":has(>ul):not(:has(>a))").find(">span").click(function(event) { |
||||
toggler.apply($(this).next()); |
||||
}).add( $("a", this) ).hoverClass(); |
||||
|
||||
if (!settings.prerendered) { |
||||
// handle closed ones first
|
||||
this.filter(":has(>ul:hidden)") |
||||
.addClass(CLASSES.expandable) |
||||
.replaceClass(CLASSES.last, CLASSES.lastExpandable); |
||||
|
||||
// handle open ones
|
||||
this.not(":has(>ul:hidden)") |
||||
.addClass(CLASSES.collapsable) |
||||
.replaceClass(CLASSES.last, CLASSES.lastCollapsable); |
||||
|
||||
// create hitarea
|
||||
this.prepend("<div class=\"" + CLASSES.hitarea + "\"/>").find("div." + CLASSES.hitarea).each(function() { |
||||
var classes = ""; |
||||
$.each($(this).parent().attr("class").split(" "), function() { |
||||
classes += this + "-hitarea "; |
||||
}); |
||||
$(this).addClass( classes ); |
||||
}); |
||||
} |
||||
|
||||
// apply event to hitarea
|
||||
this.find("div." + CLASSES.hitarea).click( toggler ); |
||||
}, |
||||
treeview: function(settings) { |
||||
|
||||
if (!settings.cookieId) { |
||||
settings = $.extend({ |
||||
cookieId: "treeview" |
||||
}, settings); |
||||
} |
||||
|
||||
if (settings.add) { |
||||
return this.trigger("add", [settings.add]); |
||||
} |
||||
|
||||
if ( settings.toggle ) { |
||||
var callback = settings.toggle; |
||||
settings.toggle = function() { |
||||
return callback.apply($(this).parent()[0], arguments); |
||||
}; |
||||
} |
||||
|
||||
// factory for treecontroller
|
||||
function treeController(tree, control) { |
||||
// factory for click handlers
|
||||
function handler(filter) { |
||||
return function() { |
||||
// reuse toggle event handler, applying the elements to toggle
|
||||
// start searching for all hitareas
|
||||
toggler.apply( $("div." + CLASSES.hitarea, tree).filter(function() { |
||||
// for plain toggle, no filter is provided, otherwise we need to check the parent element
|
||||
return filter ? $(this).parent("." + filter).length : true; |
||||
}) ); |
||||
return false; |
||||
}; |
||||
} |
||||
// click on first element to collapse tree
|
||||
$("a:eq(0)", control).click( handler(CLASSES.collapsable) ); |
||||
// click on second to expand tree
|
||||
$("a:eq(1)", control).click( handler(CLASSES.expandable) ); |
||||
// click on third to toggle tree
|
||||
$("a:eq(2)", control).click( handler() );
|
||||
} |
||||
|
||||
// handle toggle event
|
||||
function toggler() { |
||||
$(this) |
||||
.parent() |
||||
// swap classes for hitarea
|
||||
.find(">.hitarea") |
||||
.swapClass( CLASSES.collapsableHitarea, CLASSES.expandableHitarea ) |
||||
.swapClass( CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea ) |
||||
.end() |
||||
// swap classes for parent li
|
||||
.swapClass( CLASSES.collapsable, CLASSES.expandable ) |
||||
.swapClass( CLASSES.lastCollapsable, CLASSES.lastExpandable ) |
||||
// find child lists
|
||||
.find( ">ul" ) |
||||
// toggle them
|
||||
.heightToggle( settings.animated, settings.toggle ); |
||||
if ( settings.unique ) { |
||||
$(this).parent() |
||||
.siblings() |
||||
// swap classes for hitarea
|
||||
.find(">.hitarea") |
||||
.replaceClass( CLASSES.collapsableHitarea, CLASSES.expandableHitarea ) |
||||
.replaceClass( CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea ) |
||||
.end() |
||||
.replaceClass( CLASSES.collapsable, CLASSES.expandable ) |
||||
.replaceClass( CLASSES.lastCollapsable, CLASSES.lastExpandable ) |
||||
.find( ">ul" ) |
||||
.heightHide( settings.animated, settings.toggle ); |
||||
} |
||||
} |
||||
|
||||
function serialize() { |
||||
function binary(arg) { |
||||
return arg ? 1 : 0; |
||||
} |
||||
var data = []; |
||||
branches.each(function(i, e) { |
||||
data[i] = $(e).is(":has(>ul:visible)") ? 1 : 0; |
||||
}); |
||||
$.cookie(settings.cookieId, data.join("") ); |
||||
} |
||||
|
||||
function deserialize() { |
||||
var stored = $.cookie(settings.cookieId); |
||||
if ( stored ) { |
||||
var data = stored.split(""); |
||||
branches.each(function(i, e) { |
||||
$(e).find(">ul")[ parseInt(data[i]) ? "show" : "hide" ](); |
||||
}); |
||||
} |
||||
} |
||||
|
||||
// add treeview class to activate styles
|
||||
this.addClass("treeview"); |
||||
|
||||
// prepare branches and find all tree items with child lists
|
||||
var branches = this.find("li").prepareBranches(settings); |
||||
|
||||
switch(settings.persist) { |
||||
case "cookie": |
||||
var toggleCallback = settings.toggle; |
||||
settings.toggle = function() { |
||||
serialize(); |
||||
if (toggleCallback) { |
||||
toggleCallback.apply(this, arguments); |
||||
} |
||||
}; |
||||
deserialize(); |
||||
break; |
||||
case "location": |
||||
var current = this.find("a").filter(function() { return this.href.toLowerCase() == location.href.toLowerCase(); }); |
||||
if ( current.length ) { |
||||
current.addClass("selected").parents("ul, li").add( current.next() ).show(); |
||||
} |
||||
break; |
||||
} |
||||
|
||||
branches.applyClasses(settings, toggler); |
||||
|
||||
// if control option is set, create the treecontroller and show it
|
||||
if ( settings.control ) { |
||||
treeController(this, settings.control); |
||||
$(settings.control).show(); |
||||
} |
||||
|
||||
return this.bind("add", function(event, branches) { |
||||
$(branches).prev() |
||||
.removeClass(CLASSES.last) |
||||
.removeClass(CLASSES.lastCollapsable) |
||||
.removeClass(CLASSES.lastExpandable) |
||||
.find(">.hitarea") |
||||
.removeClass(CLASSES.lastCollapsableHitarea) |
||||
.removeClass(CLASSES.lastExpandableHitarea); |
||||
$(branches).find("li").andSelf().prepareBranches(settings).applyClasses(settings, toggler); |
||||
}); |
||||
} |
||||
}); |
||||
|
||||
// classes used by the plugin
|
||||
// need to be styled via external stylesheet, see first example
|
||||
var CLASSES = $.fn.treeview.classes = { |
||||
open: "open", |
||||
closed: "closed", |
||||
expandable: "expandable", |
||||
expandableHitarea: "expandable-hitarea", |
||||
lastExpandableHitarea: "lastExpandable-hitarea", |
||||
collapsable: "collapsable", |
||||
collapsableHitarea: "collapsable-hitarea", |
||||
lastCollapsableHitarea: "lastCollapsable-hitarea", |
||||
lastCollapsable: "lastCollapsable", |
||||
lastExpandable: "lastExpandable", |
||||
last: "last", |
||||
hitarea: "hitarea" |
||||
}; |
||||
|
||||
// provide backwards compability
|
||||
$.fn.Treeview = $.fn.treeview; |
||||
|
||||
})(jQuery); |
@ -0,0 +1,56 @@
|
||||
<?php |
||||
|
||||
// $Id$ |
||||
|
||||
class treeview { |
||||
private $type; |
||||
private $content = ''; |
||||
private $icons = ''; |
||||
private $id = NULL; |
||||
private $children = array(); |
||||
|
||||
function __construct($content, $type = NULL, $icons = NULL, $id = NULL) { |
||||
$this->type = $type; |
||||
$this->content = $content; |
||||
$this->id = $id; |
||||
$this->icons = $icons; |
||||
} |
||||
|
||||
function buildTree($class = NULL, $includeul = TRUE) { |
||||
$ret = ''; |
||||
if ($includeul) |
||||
$ret .= '<ul ' . ($this->id != NULL ? 'id="'. $this->id .'"' : '') . ($class != NULL ? 'class="'. $class .'"' : '') .'>'; |
||||
$ret .= '<li>'; |
||||
if ($this->type != NULL) { |
||||
$ret .='<span class="'. $this->type .'">'; |
||||
} |
||||
$ret .= $this->content; |
||||
if ($this->type != NULL) { |
||||
$ret .= '</span>'; |
||||
} |
||||
|
||||
$ret .= $this->icons; |
||||
|
||||
if (count($this->children) > 0) { |
||||
if ($includeul) |
||||
$ret .= '<ul>'; |
||||
else |
||||
$ret .= '<ul '. ($this->id != NULL ? 'id="' . $this->id .'"' : '') .'>'; |
||||
foreach ($this->children as $tree) { |
||||
$ret .= $tree->buildTree(NULL, FALSE); |
||||
} |
||||
$ret .= '</ul>'; |
||||
} |
||||
$ret .= '</li>'; |
||||
if ($includeul) |
||||
$ret .= '</ul>'; |
||||
|
||||
return $ret; |
||||
} |
||||
|
||||
function addChild($content, $type = 'file', $icons = NULL, $id = NULL) { |
||||
$tree = (is_object($content) && get_class($content) == 'treeview') ? $content : new treeview($content, $type, $icons, $id); |
||||
$this->children[] = $tree; |
||||
return $tree; |
||||
} |
||||
} |
@ -0,0 +1,29 @@
|
||||
1.4 |
||||
--- |
||||
|
||||
* Added changelog (this file) |
||||
* Fixed tree control to search only for anchors, allowing images or other elements inside the controls, while keeping the control usable with the keyboard |
||||
* Restructured folder layout: root contains plugin resources, lib contains script dependencies, demo contains demos and related files |
||||
* Added prerendered option: If set to true, assumes all hitarea divs and classes already rendered, speeding up initialization for big trees, but more obtrusive |
||||
* Added jquery.treeview.async.js for ajax-lazy-loading trees, see async.html demo |
||||
* Exposed $.fn.treeview.classes for custom classes if necessary |
||||
* Show treecontrol only when JavaScript is enabled |
||||
* Completely reworked themeing via CSS sprites, resulting in only two files per theme |
||||
* updated dotted, black, gray and red theme |
||||
* added famfamfam theme (no lines) |
||||
* Improved cookie persistence to allow multiple persisted trees per page via cookieId option |
||||
* Improved location persistence by making it case-insensitive |
||||
* Improved swapClass and replaceClass plugin implementations |
||||
* Added folder-closed.gif to filetree example |
||||
|
||||
1.3 |
||||
--- |
||||
|
||||
* Fixes for all outstanding bugs |
||||
* Added persistence features |
||||
* location based: click on a link in the treeview and reopen that link after the page loaded |
||||
* cookie based: save the state of the tree in a cookie on each click and load that on reload |
||||
* smoothed animations, fixing flickering in both IE and Opera |
||||
* Tested in Firefox 2, IE 6 & 7, Opera 9, Safari 3 |
||||
* Moved documentation to jQuery wiki |
||||
* Requires jQuery 1.2+ |
After Width: | Height: | Size: 386 B |