Browse Source

Merge commit 'bc7a51f545ad' into 6.x-release

pull/147/head
jonathangreen 14 years ago
parent
commit
42ddb89099
  1. 225
      ContentModel.inc
  2. 2
      ObjectHelper.inc
  3. 21
      api/fedora_utils.inc
  4. 2
      fedora_repository.module
  5. 230
      islandoracm.xsd
  6. 2
      plugins/map_viewer.inc
  7. 223
      plugins/nmlt/cck/scorm_fedora_type.txt
  8. 22
      plugins/nmlt/collection_policies/nmlt_collection_policy.xml
  9. 23
      plugins/nmlt/collection_policies/nmlt_collection_view.xslt
  10. 5
      plugins/nmlt/collection_policies/query.txt
  11. 20
      plugins/nmlt/content_models/islandora_SCORMCModel.xml
  12. 9
      plugins/nmlt/fedora_nmlt.info
  13. 48
      plugins/nmlt/fedora_nmlt.install
  14. 12
      plugins/nmlt/fedora_nmlt.module
  15. 369
      plugins/nmlt/scorm.inc

225
ContentModel.inc

@ -11,6 +11,7 @@ class ContentModel extends XMLDatastream {
private $mimes = NULL;
public $pid_namespace;
public $name;
private $xpath;
/**
* Gets the default DSID to use for ContentModel datastreams.
@ -223,8 +224,9 @@ class ContentModel extends XMLDatastream {
public function __construct($xmlStr, $pid = NULL, $dsid = NULL, $pid_namespace = NULL, $name = NULL) {
parent::__construct($xmlStr, $pid, $dsid);
$this->pid_namespace = $pid_namespace;
$this->name = ($name == NULL)?'Islandora Content Model':$name;
$this->xpath = new DOMXPath($this->xml);
$this->xpath->registerNamespace('cm', 'http://www.islandora.ca');
}
/**
@ -2013,4 +2015,225 @@ class ContentModel extends XMLDatastream {
}
return $ret;
}
/**
* Find the form element with name $name.
*
* @param string $name
* The name of the form element to find.
* @return DOMElement
* The form element $name, if found FALSE otherwise.
*/
public function getForm($name) {
$result = $this->xpath->query("//cm:form[@name='$name']");
return $result->length == 1 ? $result->item(0) : FALSE;
}
/**
*
* @return array
* An array of form names that exist in this content model.
*/
public function getFormNames() {
if (!$this->validate()) {
return FALSE;
}
$names = FALSE;
$result = $this->xpath->query('//cm:forms/cm:form/@name'); // Select the name attribute of all forms.
for($i = 0; $i < $result->length; $i++) {
$attribute = $result->item($i);
$name = $attribute->value;
$names[$name] = $name;
}
return $names;
}
/**
*
* @return array
* An array of form names that exist in this content model.
*/
public function getIngestFormNames() {
if (!$this->validate()) {
return FALSE;
}
$result = $this->xpath->query('//cm:forms/cm:form[@ingest_class and @ingest_file and @ingest_module]/@name'); // Select the name attribute of all forms.
for($i = 0; $i < $result->length; $i++) {
$attribute = $result->item($i);
$name = $attribute->value;
$names[$name] = $name;
}
return $names;
}
/**
*
* @return array
* An array of form names that exist in this content model.
*/
public function getEditFormNames() {
if (!$this->validate()) {
return FALSE;
}
$result = $this->xpath->query('//cm:forms/cm:form[@edit_class and @edit_file and @edit_module]/@name'); // Select the name attribute of all forms.
for($i = 0; $i < $result->length; $i++) {
$attribute = $result->item($i);
$name = $attribute->value;
$names[$name] = $name;
}
return $names;
}
/**
* Removes the named form.
*
* @param string $name
* Name of the form to remove.
*
* @return boolean
* TRUE on success, FALSE otherwise.
*/
public function removeForm($name) {
$result = $this->xpath->query("//cm:form[@name='$name']");
if ($result->length == 1) {
$form = $result->item(0);
$form->parentNode->removeChild($form);
return TRUE;
}
return FALSE;
}
/**
* Adds the named form.
*
* @param string $element
* Name of the form to add.
*
* @return boolean
* TRUE on success, FALSE otherwise.
*/
public function addForm($element) {
$result = $this->xpath->query("//cm:forms");
if ($result->length == 0) { // Forms doesn't exist
$forms = $this->xml->createElement('forms');
$element = $this->xml->importNode($element);
$forms->appendChild($element);
$result = $this->xpath->query("//cm:content_model");
$result->item(0)->appendChild($forms);
return TRUE;
}
else if ($result->length == 1) {
$element = $this->xml->importNode($element);
$result->item(0)->appendChild($element);
return TRUE;
}
return FALSE;
}
/**
* Edits a form element with attribute name='$name' from the 'forms' element.
*
* @param String $name
*/
public function editForm($name, $element) {
if (!$this->validate()) {
return FALSE;
}
$result = $this->xpath->query("//cm:form[@name='$name']");
if($result->length == 1) {
$form = $result->item(0);
$result = $this->xpath->query("child::node()", $form);
$element = $this->xml->importNode($element);
for($i = 0; $i < $result->length; $i++) {
$child = $result->item($i);
$element->appendChild($child);
}
$form->parentNode->replaceChild($element, $form);
return TRUE;
}
return FALSE;
}
/**
*
* @param <type> $element_definition
* @param <type> $parent_element
* @return <type>
*/
public function addElementToForm($element, $parent_element) {
$element = $this->xml->importNode($element, TRUE);
$parent_element->appendChild($element);
return TRUE;
}
/**
*
* @param <type> $element_definition
* @param <type> $parent_element
*/
public function editFormElement($new_element, $edit_element) {
$new_element = $this->xml->importNode($new_element, TRUE);
$name = $new_element->tagName;
$result = $new_element->getElementsByTagName('content');
if($result->length == 1) {
$new_content = $result->item(0);
$result = $this->xpath->query("child::cm:content/child::node()", $edit_element);
for($i = 0; $i < $result->length; $i++) {
$child = $result->item($i);
$new_content->appendChild($child);
}
}
$edit_element->parentNode->replaceChild($new_element, $edit_element);
return TRUE;
}
/**
*
* @param <type> $new_element
* @param <type> $element
*/
private function insertElementInPlace($new_element, $element) {
$next = $element->nextSibling;
if ($next) {
$element->parentNode->insertBefore($new_element, $next);
}
else {
$element->parentNode->appendChild($new_element);
}
}
/**
*
* @param <type> $form_element
* @return <type>
*/
public function incFormElement($form_element) {
$prev = $form_element;
$name = $prev->getAttribute('name');
while ($prev = $prev->previousSibling) {
if (get_class($prev) == 'DOMElement') {
$form_element->parentNode->insertBefore($form_element, $prev);
break;
}
}
return TRUE;
}
/**
*
* @param <type> $form_element
* @return <type>
*/
public function decFormElement($form_element) {
$next = $form_element;
while ($next = $next->nextSibling) {
if (get_class($next) == 'DOMElement') {
$this->insertElementInPlace($form_element, $next);
break;
}
}
return TRUE;
}
}

2
ObjectHelper.inc

@ -345,7 +345,7 @@ class ObjectHelper {
}
$xsl = $proc->importStylesheet($xsl);
$newdom = $proc->transformToDoc($input);
$output = $newdom->saveXML();
$output = $newdom->saveHTML();
return $output;
}

21
api/fedora_utils.inc

@ -105,3 +105,24 @@ function fix_encoding($in_str) {
return $valid;
}
function fixDsid($dsid) {
$new_dsid = trim($dsid);
$find = '/[^a-zA-Z0-9\.\_\-]/';
$replace = '';
$new_dsid = preg_replace($find, $replace, $new_dsid);
if( strlen($new_dsid) > 63 )
$new_dsid = substr($new_dsid, -63);
if( preg_match('/^[^a-zA-Z]/', $dsid ) )
$new_dsid = 'x' . $new_dsid;
if( strlen($new_dsid) == 0 )
$new_dsid = 'item' . rand(1, 100);
return $new_dsid;
}

2
fedora_repository.module

@ -815,7 +815,7 @@ function fedora_repository_get_items($pid = NULL, $dsId = NULL, $collection = NU
//the below is for islandlives we should be able to do this in the xslt though
//$css=$path.'/stylesheets/container-large.css';
//drupal_add_css($css);
return tabs_render($cmodels_tabs) . '</div>';
return tabs_render($cmodels_tabs);
}
function fedora_repository_urlencode_string($str) {

230
islandoracm.xsd

@ -1,4 +1,5 @@
<xsd:schema xmlns="http://www.islandora.ca" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.islandora.ca" elementFormDefault="qualified" >
<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 Content Model Schema
@ -15,6 +16,14 @@
<xsd:element name="ingest_rules" type="ingest_rulesType"/>
<xsd:element name="edit_metadata_method" type="edit_metadata_methodType" minOccurs="0"/>
<xsd:element name="forms">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="1" name="form" type="formType"
/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:all>
<xsd:attribute name="name" type="xsd:normalizedString" use="required"/>
</xsd:complexType>
@ -90,14 +99,16 @@
<xsd:complexType name="ruleType">
<xsd:sequence>
<xsd:element name="applies_to" type="xsd:normalizedString" minOccurs="1" maxOccurs="unbounded"/>
<xsd:element name="applies_to" type="xsd:normalizedString" minOccurs="1"
maxOccurs="unbounded"/>
<xsd:element name="ingest_methods" type="ingest_methodsType" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ingest_methodsType">
<xsd:sequence>
<xsd:element name="ingest_method" type="ingest_methodType" minOccurs="1" maxOccurs="unbounded"/>
<xsd:element name="ingest_method" type="ingest_methodType" minOccurs="1"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ingest_methodType">
@ -115,14 +126,17 @@
<xsd:complexType name="datastreamsType">
<xsd:sequence>
<xsd:element name="datastream" type="datastreamType" minOccurs="1" maxOccurs="unbounded"/>
<xsd:element name="datastream" type="datastreamType" minOccurs="1" maxOccurs="unbounded"
/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="datastreamType">
<xsd:sequence>
<xsd:element name="display_method" type="display_methodType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="add_datastream_method" type="add_datastream_methodType" minOccurs="0" maxOccurs="1"/>
<xsd:element name="display_method" type="display_methodType" minOccurs="0"
maxOccurs="unbounded"/>
<xsd:element name="add_datastream_method" type="add_datastream_methodType" minOccurs="0"
maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="dsid" type="xsd:normalizedString" use="required"/>
@ -164,4 +178,208 @@
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="formType">
<xsd:complexContent>
<xsd:extension base="formElementType">
<xsd:attribute name="name" type="xsd:normalizedString" use="required"/>
<xsd:attribute name="dsid" type="xsd:normalizedString" use="required"/>
<xsd:attribute name="ingest_module" type="xsd:normalizedString"/>
<xsd:attribute name="ingest_file" type="xsd:normalizedString"/>
<xsd:attribute name="ingest_class" type="xsd:normalizedString"/>
<xsd:attribute name="edit_module" type="xsd:normalizedString" use="optional"/>
<xsd:attribute name="edit_file" type="xsd:normalizedString" use="optional"/>
<xsd:attribute name="edit_class" type="xsd:normalizedString" use="optional"/>
<xsd:attribute name="document_module" type="xsd:normalizedString" use="required"/>
<xsd:attribute name="document_file" type="xsd:normalizedString" use="required"/>
<xsd:attribute name="document_class" type="xsd:normalizedString" use="required"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="formElementType">
<xsd:choice maxOccurs="unbounded" minOccurs="0">
<xsd:element maxOccurs="1" minOccurs="1" name="fieldset">
<xsd:complexType>
<xsd:all maxOccurs="1" minOccurs="1">
<xsd:element name="title" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="description" type="xsd:normalizedString"/>
<xsd:element default="true" minOccurs="0" name="collapsible"
type="xsd:boolean"/>
<xsd:element default="false" minOccurs="0" name="collapsed"
type="xsd:boolean"/>
<xsd:element name="content" type="formElementType"/>
<xsd:element minOccurs="0" name="form_builder" type="formBuilderControlType"
/>
</xsd:all>
</xsd:complexType>
</xsd:element>
<xsd:element name="textfield">
<xsd:complexType>
<xsd:all maxOccurs="1" minOccurs="1">
<xsd:element name="title" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="description" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="required" type="xsd:boolean"/>
<xsd:element minOccurs="0" name="default_value" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="autocomplete_path"
type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="form_builder" type="formBuilderControlType"
/>
</xsd:all>
</xsd:complexType>
</xsd:element>
<xsd:element minOccurs="1" name="textarea">
<xsd:complexType>
<xsd:all maxOccurs="1" minOccurs="1">
<xsd:element name="title" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="description" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="required" type="xsd:boolean"/>
<xsd:element minOccurs="0" name="default_value" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="form_builder" type="formBuilderControlType"
/>
</xsd:all>
</xsd:complexType>
</xsd:element>
<xsd:element maxOccurs="1" minOccurs="1" name="select">
<xsd:complexType>
<xsd:all maxOccurs="1" minOccurs="1">
<xsd:element name="title" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="description" type="xsd:normalizedString"/>
<xsd:element name="options" type="formControlOptionsType"/>
<xsd:element minOccurs="0" name="required" type="xsd:boolean"/>
<xsd:element minOccurs="0" name="default_value" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="form_builder" type="formBuilderControlType"
/>
</xsd:all>
</xsd:complexType>
</xsd:element>
<xsd:element minOccurs="1" name="set">
<xsd:complexType>
<xsd:all maxOccurs="1" minOccurs="1">
<xsd:element name="title" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="description" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="required" type="xsd:boolean"/>
<xsd:element minOccurs="0" name="default_value" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="autocomplete_path"
type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="form_builder" type="formBuilderControlType"
/>
</xsd:all>
</xsd:complexType>
</xsd:element>
<xsd:element minOccurs="1" name="filechooser">
<xsd:complexType>
<xsd:all maxOccurs="1" minOccurs="1">
<xsd:element name="title" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="description" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="required" type="xsd:boolean"/>
<xsd:element minOccurs="0" name="default_value" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="form_builder" type="formBuilderControlType"
/>
</xsd:all>
</xsd:complexType>
</xsd:element>
<xsd:element minOccurs="1" name="datepicker">
<xsd:complexType>
<xsd:all maxOccurs="1" minOccurs="1">
<xsd:element name="title" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="description" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="required" type="xsd:boolean"/>
<xsd:element minOccurs="0" name="default_value" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="form_builder" type="formBuilderControlType"
/>
</xsd:all>
</xsd:complexType>
</xsd:element>
<xsd:element maxOccurs="1" minOccurs="1" name="tabpanel">
<xsd:complexType>
<xsd:all maxOccurs="1" minOccurs="1">
<xsd:element name="title" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="description" type="xsd:normalizedString"/>
<xsd:element default="true" minOccurs="0" name="collapsible"
type="xsd:boolean"/>
<xsd:element default="false" minOccurs="0" name="collapsed"
type="xsd:boolean"/>
<xsd:element name="content" type="formElementType"/>
<xsd:element minOccurs="0" name="form_builder" type="formBuilderControlType"
/>
</xsd:all>
</xsd:complexType>
</xsd:element>
<xsd:element name="checkbox">
<xsd:complexType>
<xsd:all maxOccurs="1" minOccurs="1">
<xsd:element name="title" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="description" type="xsd:normalizedString"/>
<xsd:element name="return_value" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="form_builder" type="formBuilderControlType"
/>
</xsd:all>
</xsd:complexType>
</xsd:element>
<xsd:element minOccurs="1" name="hidden">
<xsd:complexType>
<xsd:all>
<xsd:element minOccurs="1" name="value" type="xsd:normalizedString"/>
<xsd:element minOccurs="0" name="form_builder" type="formBuilderControlType"/>
<xsd:element minOccurs="0" name="content" type="formElementType"/>
</xsd:all>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="formControlXPathType">
<xsd:simpleContent>
<xsd:extension base="xsd:normalizedString">
<xsd:attribute name="full_path" type="xsd:boolean"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="formControlElementValidateType">
<xsd:complexContent>
<xsd:extension base="array"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="array">
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="item" type="xsd:normalizedString"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="formControlOptionsType">
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="option" type="xsd:normalizedString"/>
</xsd:sequence>
<xsd:attribute name="ignoreFirstOption" type="xsd:boolean" use="required"/>
</xsd:complexType>
<xsd:complexType name="formBuilderControlType">
<xsd:sequence>
<xsd:element name="xpath">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="path">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:normalizedString">
<xsd:attribute name="full" type="xsd:boolean" use="required"
/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="parent_path" minOccurs="0">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:normalizedString"> </xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
<xsd:choice>
<xsd:element name="xml" type="xsd:normalizedString"/>
<xsd:element name="element" type="xsd:normalizedString"/>
<xsd:element name="attribute" type="xsd:normalizedString"/>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="require_value" type="xsd:boolean"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

2
plugins/map_viewer.inc

@ -46,7 +46,7 @@ class ShowMapStreamsInFieldSets {
'#type' => 'tabpage',
'#title' => t('Description'),
'#content' => $item->get_dissemination('islandora:mods2htmlSdef', 'mods2html')
. $objectHelper->getFormattedDatastreamList($this->pid, NULL, $item),
. $objectHelper->get_formatted_datastream_list($this->pid, NULL, $item),
);
// Render the tabset.
return tabs_render($tabset);

223
plugins/nmlt/cck/scorm_fedora_type.txt

@ -1,223 +0,0 @@
$content['type'] = array (
'name' => 'SCORM Repository Item',
'type' => 'repository_item',
'description' => 'Contains a reference to an item in the Fedora repository. The item will be fully rendered when a user views the node. Comments and other node-attached content can then be added to the node page.',
'title_label' => 'Title',
'body_label' => 'Body',
'min_word_count' => '0',
'help' => '',
'node_options' =>
array (
'status' => true,
'promote' => true,
'sticky' => false,
'revision' => false,
),
'upload' => '1',
'old_type' => 'repository_item',
'orig_type' => '',
'module' => 'node',
'custom' => '1',
'modified' => '1',
'locked' => '0',
'comment' => '2',
'comment_default_mode' => '4',
'comment_default_order' => '1',
'comment_default_per_page' => '50',
'comment_controls' => '3',
'comment_anonymous' => 0,
'comment_subject_field' => '1',
'comment_preview' => '1',
'comment_form_location' => '0',
'fivestar' => 1,
'fivestar_stars' => '5',
'fivestar_labels_enable' => 1,
'fivestar_label_0' => 'Cancel rating',
'fivestar_label_1' => 'Poor',
'fivestar_label_2' => 'Okay',
'fivestar_label_3' => 'Good',
'fivestar_label_4' => 'Great',
'fivestar_label_5' => 'Awesome',
'fivestar_label_6' => 'Give it @star/@count',
'fivestar_label_7' => 'Give it @star/@count',
'fivestar_label_8' => 'Give it @star/@count',
'fivestar_label_9' => 'Give it @star/@count',
'fivestar_label_10' => 'Give it @star/@count',
'fivestar_style' => 'average',
'fivestar_text' => 'dual',
'fivestar_title' => 1,
'fivestar_feedback' => 1,
'fivestar_unvote' => 1,
'fivestar_position_teaser' => 'hidden',
'fivestar_position' => 'below',
);
$content['fields'] = array (
0 =>
array (
'label' => 'SCORM Object',
'field_name' => 'field_scorm_obj',
'type' => 'filefield',
'widget_type' => 'SCORM_widget',
'change' => 'Change basic information',
'weight' => '-3',
'file_extensions' => 'zip',
'progress_indicator' => 'bar',
'file_path' => '',
'max_filesize_per_file' => '',
'max_filesize_per_node' => '',
'description' => 'Embed a SCORM object into this node.',
'required' => 0,
'multiple' => '0',
'list_field' => '0',
'list_default' => 1,
'description_field' => '0',
'op' => 'Save field settings',
'module' => 'filefield',
'widget_module' => 'SCORM',
'columns' =>
array (
'fid' =>
array (
'type' => 'int',
'not null' => false,
'views' => true,
),
'list' =>
array (
'type' => 'int',
'size' => 'tiny',
'not null' => false,
'views' => true,
),
'data' =>
array (
'type' => 'text',
'serialize' => true,
'views' => true,
),
),
'display_settings' =>
array (
'label' =>
array (
'format' => 'above',
'exclude' => 0,
),
'teaser' =>
array (
'format' => 'SCORM_embedded',
'exclude' => 0,
),
'full' =>
array (
'format' => 'SCORM_embedded',
'exclude' => 0,
),
4 =>
array (
'format' => 'SCORM_embedded',
'exclude' => 0,
),
2 =>
array (
'format' => 'SCORM_embedded',
'exclude' => 0,
),
3 =>
array (
'format' => 'SCORM_embedded',
'exclude' => 0,
),
),
),
1 =>
array (
'label' => 'Fedora Object Reference',
'field_name' => 'field_fedora_pid_reference',
'type' => 'pidfield',
'widget_type' => 'pidfield_widget',
'change' => 'Change basic information',
'weight' => '-2',
'size' => '60',
'description' => 'A Fedora object PID that this node references.',
'default_value' =>
array (
0 =>
array (
'value' => '',
'_error_element' => 'value',
),
),
'default_value_php' => '',
'default_value_widget' =>
array (
'field_fedora_pid_reference' =>
array (
0 =>
array (
'value' => '',
'_error_element' => 'value',
),
),
),
'required' => 0,
'multiple' => '0',
'max_length' => '64',
'op' => 'Save field settings',
'module' => 'pidfield',
'widget_module' => 'pidfield',
'columns' =>
array (
'value' =>
array (
'type' => 'varchar',
'length' => '64',
'not null' => false,
'sortable' => true,
'views' => true,
),
),
'display_settings' =>
array (
'label' =>
array (
'format' => 'above',
'exclude' => 0,
),
'teaser' =>
array (
'format' => 'default',
'exclude' => 0,
),
'full' =>
array (
'format' => 'default',
'exclude' => 0,
),
4 =>
array (
'format' => 'default',
'exclude' => 0,
),
2 =>
array (
'format' => 'default',
'exclude' => 0,
),
3 =>
array (
'format' => 'default',
'exclude' => 0,
),
),
),
);
$content['extra'] = array (
'title' => '-5',
'body_field' => '-1',
'revision_information' => '0',
'comment_settings' => '3',
'menu' => '-4',
'path' => '1',
'attachments' => '2',
);

22
plugins/nmlt/collection_policies/nmlt_collection_policy.xml

@ -1,22 +0,0 @@
<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_model dsid="ISLANDORACM" name="SCORM Learning Object" namespace="nmlt:" pid="islandora:SCORMCModel"/>
</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>

23
plugins/nmlt/collection_policies/nmlt_collection_view.xslt

@ -1,23 +0,0 @@
<xsl:stylesheet xmlns:s="http://www.w3.org/2001/sw/DataAccess/rf1/result" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:variable name="BASEURL">
<xsl:value-of select="$baseUrl"></xsl:value-of>
</xsl:variable>
<ul>
<xsl:for-each select="/s:sparql/s:results/s:result">
<xsl:variable name="pid" select="substring-after(s:object/@uri, &apos;/&apos;)"></xsl:variable>
<li>
<a>
<xsl:attribute name="href">
<xsl:value-of select="$BASEURL"></xsl:value-of>
<xsl:text>/fedora/repository/</xsl:text>
<xsl:value-of select="$pid"></xsl:value-of>/-/<xsl:value-of select="s:title"></xsl:value-of>
</xsl:attribute>
<xsl:value-of select="s:title"></xsl:value-of>
</a>
</li>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>

5
plugins/nmlt/collection_policies/query.txt

@ -1,5 +0,0 @@
select $object $title from <#ri>
where ($object <dc:title> $title
and ($object <fedora-model:hasModel> <info:fedora/islandora:SCORMCModel>)
and $object <fedora-model:state> <info:fedora/fedora-system:def/model#Active>)
order by $title

20
plugins/nmlt/content_models/islandora_SCORMCModel.xml

@ -1,20 +0,0 @@
<content_model name="SCORM_Object" xmlns="http://www.islandora.ca" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.islandora.ca http://localhost/islandoracm.xsd">
<mimetypes>
<type>application/zip</type>
</mimetypes>
<ingest_rules>
<rule>
<applies_to>application/zip</applies_to>
</rule>
</ingest_rules>
<ingest_form dsid="QDC" page="2">
<form_builder_method class="SCORMObject" file="scorm.inc" handler="handleIngestForm" method="buildIngestForm" module="fedora_nmlt"/>
</ingest_form>
<datastreams>
<datastream dsid="TN">
<display_method class="SCORMObject" file="scorm.inc" method="showFieldSets" module="fedora_nmlt"/>
</datastream>
<datastream dsid="INDEX"/>
</datastreams>
<edit_metadata_method class="" dsid="" file="" handler="" method="" module=""/>
</content_model>

9
plugins/nmlt/fedora_nmlt.info

@ -1,9 +0,0 @@
; $Id$
name = Islandora NMLT
description = Provides SCORM learning object support for Islandora
package = Fedora Repository
dependencies[] = fedora_repository
dependencies[] = content_copy
dependencies[] = SCORM
version = 6.1dev
core = 6.x

48
plugins/nmlt/fedora_nmlt.install

@ -1,48 +0,0 @@
<?php
function fedora_nmlt_install() {
$file = drupal_get_path('module', 'fedora_nmlt').'/cck/scorm_fedora_type.txt';
fedora_nmlt_import_content_type('<create>', '', $file);
}
function fedora_nmlt_enable() {
// Set the module weight so it can override other modules.
db_query("UPDATE {system} SET weight = 50 WHERE name = 'fedora_nmlt'");
}
/**
* Programmatically create CCK fields and types using the content copy module
* @param $type string
* content type to create, defaults to new type, if type exists, only fields will be added
* @param $macro array
* exported array from content types -&gt; export. If file is not specified, macro will be used
* @param $file string
* path to file containing content copy exported macro data structure. no escaping needed.
*/
function fedora_nmlt_import_content_type($type = '<create>', $macro = '', $file = '') {
if(!module_exists("content_copy")){
drupal_set_message('Programmatically creating CCK fields requires the Content Copy module. Exiting.');
return;
}
include_once( $_SERVER['DOCUMENT_ROOT'].'/'. drupal_get_path('module', 'content') .'/includes/content.admin.inc');
include_once( $_SERVER['DOCUMENT_ROOT'].'/'. drupal_get_path('module', 'node') .'/content_types.inc');
$values = array();
$values['type_name'] = $type;
if($file){
if(file_exists($file)){
$values['macro'] = file_get_contents($file);
}else{
drupal_set_message('Unable to read input file for import. Exiting.');
return;
}
}elseif($macro){
$values['macro'] = $macro;
}
$form_state = array();
$form_state['values'] = $values;
//drupal_set_message('<pre>DEBUG: '.print_r($values['macro'],1).'</pre>');
drupal_execute("content_copy_import_form", $form_state);
content_clear_type_cache();
}

12
plugins/nmlt/fedora_nmlt.module

@ -1,12 +0,0 @@
<?php
function fedora_nmlt_menu_alter(&$items) {
$items["node/%node/result"] = array(
'title' => 'Results',
'page callback' => 'scorm_show_results',
'page arguments' => array(1),
'access callback' => user_access('use scorm'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}

369
plugins/nmlt/scorm.inc

@ -1,369 +0,0 @@
<?php
// $Id$
class SCORMObject {
function __construct($pid = '') {
module_load_include('inc', 'fedora_repository', 'api/fedora_item');
if (!empty($pid)) {
$this->pid = $pid;
$this->item = new Fedora_Item($pid);
}
}
public function buildIngestForm($form = array(), $form_state = array()) {
$form['bulk_ingest_location'] = array(
'#title' => 'Bulk ingest location',
'#type' => 'textfield',
'#size' => 60,
'#description' => "Server location from which to upload SCORM objects. Leave this blank if you are uploading a single file.",
);
return $form;
}
public function buildEditMetadataForm($form = array()) {
$form['submit'] = array(
'#type' => 'submit',
'#weight' => 10,
'#value' => 'Update'
);
$form['pid'] = array(
'#type' => 'hidden',
'#value' => $this->pid,
);
$form['dsid'] = array(
'#type' => 'hidden',
'#value' => "DARWIN_CORE",
);
return $this->buildDrupalForm($form);
}
public function handleEditMetadataForm($form_id, $form_values) {
/*
* Process the metadata form
* Update the datastreams
*/
module_load_include('inc', 'fedora_repository', 'api/fedora_item');
module_load_include('inc', 'fedora_repository', 'plugins/DarwinCore');
module_load_include('inc', 'fedora_repository', 'MimeClass');
global $user;
$mimetype = new MimeClass();
$dwc = new DarwinCore($this->item);
$dwc->handleForm($form_values);
$this->item->purge_datastream('DARWIN_CORE');
$this->item->add_datastream_from_string($dwc->darwinCoreXML, 'DARWIN_CORE',
'Darwin Core Metadata', 'text/xml', 'X');
return TRUE;
}
/**
* process the metadata form
* Create fedora object
* Add the datastreams
*/
public function handleIngestForm($form_values) {
module_load_include('inc', 'fedora_repository', 'MimeClass');
module_load_include('inc', 'fedora_repository', 'api/fedora_item');
global $user;
$mimetype = new MimeClass();
$file_list = array();
if (!empty($form_values['bulk_ingest_location'])) {
if ($scorm_dir = opendir($form_values['bulk_ingest_location'])) {
while (FALSE !== ($file_name = readdir($scorm_dir))) {
$ext = strrchr($file_name, '.');
if ($ext == '.zip') {
array_push($file_list, $form_values['bulk_ingest_location'] .'/'. $file_name);
}
}
closedir($scorm_dir);
sort($file_list);
}
}
else {
array_push($file_list, $form_values['ingest-file-location']);
}
scorm_create_scorm_objects($form_values['collection_pid'], $file_list, $form_values['content_model_pid'], $form_values['relationship'] );
}
public function showFieldSets() {
global $base_url;
// Try and get a node that references this object.
//$result = db_query("SELECT * FROM {content_node_field} nf INNER JOIN {content_node_field_instance} ni ON nf.field_name = ni.field_name WHERE nf.type='field_fedora_pid_reference'");
fedora_pidfield_redirect_to_node($this);
$tabset['my_tabset']['first_tab'] = array(
'#type' => 'tabpage',
'#title' => t('Description'),
);
if (module_load_include('module', 'SCORM', 'SCORM')) {
$dest_array = explode('/', urldecode(drupal_get_destination()));
$nid = $dest_array[count($dest_array) - 1];
$node = node_load($nid);
$tabset = array();
$tabset['my_tabset'] = array(
'#type' => 'tabset',
);
$tabset['my_tabset']['second_tab'] = array(
'#type' => 'tabpage',
'#title' => t('Results'),
'#content' => scorm_show_results($node),
);
}
module_load_include('inc', 'fedora_repository', 'ObjectHelper');
$obj = new ObjectHelper();
$tabset['my_tabset']['first_tab']['tabset'] = array(
'#type' => 'tabset',
);
$tabset['my_tabset']['first_tab']['tabset']['view'] = array(
'#type' => 'tabpage',
'#title' => t('View'),
'#content' => $obj->getQDC($this->pid),
);
if (fedora_repository_access(OBJECTHELPER :: $EDIT_FEDORA_METADATA, $this->pid, $user)) {
$editform = drupal_get_form('fedora_repository_edit_qdc_form', $this->pid, 'DC');
$tabset['my_tabset']['first_tab']['tabset']['edit'] = array(
'#type' => 'tabpage',
'#title' => t('Edit'),
'#content' => $editform,
);
}
return tabs_render($tabset);
}
public function extractFile($filename) {
// Get a file from the zip and put it in a temporary location.
$tmpdir = sys_get_temp_dir();
exec("unzip $this->file $filename -d $tmpdir", $output);
if (file_exists($tmpdir.'/'.$filename)) {
return $tmpdir.'/'.$filename;
}
else {
return FALSE;
}
}
private function _cleanUpHTML($html) {
$tmp = substr($html, strpos($html, '<body>'));
return _filter_html($tmp, FILTER_HTML_STRIP);
}
public function _createSCORMObjectNode($scorm_file, $item) {
module_load_include('inc', 'node', 'node.pages'); // required\
module_load_include('inc', 'fedora_repository', 'api/dublin_core');
global $user;
$node = array('type' => 'repository_item');
$form_state = array();
$dc = new Dublin_Core($item);
$title = $dc->dc['dc:title'][0];
if (empty($title)) {
$title = $pid;
}
$form_state['values']['title'] = $title; // node's title
// Prepare the file field.
$mime = 'application/zip';
$file = new stdClass();
$file->filename = basename($scorm_file);
$file->filepath = $scorm_file;
$file->filemime = $mime;
$file->filesize = filesize($scorm_file);
$file->uid = $user->uid;
$file->status = 0;
$file->timestamp = time();
drupal_write_record('files', $file);
$file->fid = db_result(db_query("SELECT fid FROM {files} WHERE filepath = '%s'", $file->filepath));
// Create a drupal node that includes a SCORM object and reference to this Fedora PID.
// Drupal Content Type is SCORM Fedora Object. Fields are
// field_scorm_obj-0-value
// field_fedora_pid_reference-0-value
$form_state['values']['field_fedora_pid_reference'][0]['value'] = $item->pid;
/*$form_state['values']['field_scorm_obj'] = array (
array(
'fid' => $file->fid,
'title' => basename($file->filename),
'filename' => $file->filename,
'filepath' => $file->filepath,
'filesize' => $file->filesize,
'mimetype' => $mime,
'description' => basename($file->filename),
'list' => 1,
),
);*/
$form_state['values']['op'] = t('Save'); // required value
drupal_execute('repository_item_node_form', $form_state, (object)$node);
// you can probably configure the node-author in $form_state or $node,
// but i'm doing it this way to demonstrate the use of $form_state['nid'].
// the following lines aren't required, but otherwise the node-author will be "Anonymous" in this case.
$node = node_load($form_state['nid']); // nid from the node that gets created is set in $form_state['nid'] after drupal_execute()
$node->uid = $user->uid; // set author to the current user
$field = content_fields('field_scorm_obj', 'repository_item');
// Load up the appropriate validators
//$validators = array_merge(filefield_widget_upload_validators($field), SCORM_widget_upload_validators($field));
$validators = SCORM_widget_upload_validators($field);
// Where do we store the files?
$files_path = filefield_widget_file_path($field);
// Create the file object
$file = field_file_save_file($scorm_file, $validators, $files_path);
// Apply the file to the field
$file['data']['width'] = 640;
$file['data']['height'] = 480;
$node->field_scorm_obj = array(0 => $file);
$this->_processSCORMObject($file);
node_save($node);
return $node;
}
private function _processSCORMObject($field) {
$packagedata=scorm_validate_file($field['filepath']);
$scorm->pkgtype = $packagedata->pkgtype;
$scorm->datadir = $packagedata->datadir;
$scorm->launch = $packagedata->launch;
$scorm->parse = 1;
$scorm->timemodified = time();
/* if (!scorm_external_link($scorm->reference)) {
$scorm->md5hash = md5_file($CFG->dataroot.'/'.$scorm->course.'/'.$scorm->reference);
} else {
$scorm->dir = $CFG->dataroot.'/'.$scorm->course.'/moddata/scorm';
$scorm->md5hash = md5_file($scorm->dir.$scorm->datadir.'/'.basename($scorm->reference));
}*/
$scorm = scorm_option2text($scorm);
//TODO: Implement form for user to set height and width for SCORM package
$scorm->width = '640';
$scorm->height = '480';
if (!isset($scorm->whatgrade)) {
$scorm->whatgrade = 0;
}
$scorm->grademethod = ($scorm->whatgrade * 10) + $scorm->grademethod;
//TODO: Do we need this fields:
$scorm->name="SCORM";
$scorm->summary="SCORM 2004.";
$scorm->grademethod='';
$scorm->maxgrade=100;
$scorm->maxattempt=0;
$scorm->updatefreq=0;
$scorm->course=1;
//At this point it is still empty
$scorm->version='';
$scorm->skipview=0;
$scorm->hidebrowse=0;
$scorm->hidetoc=0;
$scorm->hidenav=0;
$scorm->auto=0;
$scorm->popup=0;
//TODO: Do we still need it?
//$scorm->reference=$field->filepath;
//TODO: Remove MD5 field, we dont use it.
//$id = insert_record('scorm', $scorm);
$result = db_query("INSERT INTO {scorm}
(course,name,nodereference,reference,summary,version,maxgrade,grademethod,whatgrade,maxattempt,updatefreq,md5hash,launch,
skipview,hidebrowse,hidetoc,hidenav,auto,popup,options,width,height,timemodified)
VALUES (%d,'%s',%d,'%s','%s','%s',%d,%d,%d,%d,%d,'%s',%d,%d,%d,%d,%d,%d,%d,'%s',%d,%d,%d)", $scorm->course, $scorm->name, NULL, NULL, $scorm->summary, $scorm->version,
$scorm->maxgrade, $scorm->grademethod, $scorm->whatgrade, $scorm->maxattempt, $scorm->updatefreq, NULL, $scorm->launch, $scorm->skipview, $scorm->hidebrowse,
$scorm->hidetoc, $scorm->hidenav, $scorm->auto, $scorm->popup, $scorm->options, $scorm->width, $scorm->height, $scorm->timemodified );
$id = db_last_insert_id('scorm', 'id'); //$id=mysql_insert_id();
//TODO: Test it on Linux
// Move SCORM from temp dir to scorm dir
$storedir=file_directory_path() .'/SCORM';
$path=$storedir .'/'. $id;
if (!file_exists($storedir)) {
mkdir($storedir);
}
$res=mkdir($path);
if ($res==TRUE) {
full_copy($packagedata->tempdir, $path);
//rmdirr($packagedata->tempdir);
scorm_delete_files($packagedata->tempdir);
//Replace reference field with node field.
db_query("UPDATE {scorm} SET reference = '%s' WHERE id = %d", $field['fid'], $id);
}
else
return FALSE;
$scorm->id = $id;
//Parse SCORM manifest
$scorm->launch=scorm_parse_scorm($path, $scorm->id);
//Save SCORM launch instance
db_query("UPDATE {scorm} SET launch = '%s' WHERE id = %d", $scorm->launch, $scorm->id);
}
}
function scorm_create_scorm_objects($collection_pid, $file_list = array(), $content_model_pid = 'islandora:SCORMCModel', $relationship = 'isMemberOfCollection') {
module_load_include('inc', 'fedora_repository', 'api/fedora_item');
$batch = array(
'title' => 'Ingesting SCORM objects',
'operations' => array(),
'file' => drupal_get_path('module', 'fedora_nmlt') .'/scorm.inc',
);
foreach ($file_list as $file_path) {
$batch['operations'][] = array('_create_single_SCORM_object', array($file_path, $collection_pid, $content_model_pid, $relationship));
}
batch_set($batch);
}
function _create_single_SCORM_object($file, $collection_pid, $content_model_pid, $relationship = 'isMemberOfCollection') {
module_load_include('inc', 'fedora_repository', 'api/fedora_item');
$url = parse_url(variable_get('fedora_base_url', 'http://localhost:8080/fedora'));
$fedora_host = ("{$url['scheme']}://{$url['host']}" . (!empty($url['port']) ? ":{$url['port']}/" : '/'));
$scorm2fedora_url = $fedora_host . 'scorm2fedora';
$ch = curl_init($scorm2fedora_url);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('scormfile' => "@{$file}"));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$post_result = curl_exec($ch);
curl_close($ch);
$scorm2fedora_result = json_decode($post_result);
$scorm_object_pid = $scorm2fedora_result->pid;
if (!empty($scorm_object_pid)) {
$scorm_object = new Fedora_Item($scorm_object_pid);
$scorm_object->add_relationship('hasModel', $content_model_pid, FEDORA_MODEL_URI);
$scorm_object->add_relationship($relationship, $collection_pid);
$scorm = new SCORMObject($scorm_object_pid);
$scorm->_createSCORMObjectNode($file, $scorm_object);
}
}
Loading…
Cancel
Save