diff --git a/backup/backup.class.php b/backup/backup.class.php index 51c0ec6c60f..441ed10e47c 100644 --- a/backup/backup.class.php +++ b/backup/backup.class.php @@ -41,7 +41,8 @@ abstract class backup implements checksumable { // Backup format const FORMAT_MOODLE = 'moodle2'; const FORMAT_MOODLE1 = 'moodle1'; - const FORMAT_IMSCC = 'imscc'; + const FORMAT_IMSCC1 = 'imscc1'; + const FORMAT_IMSCC11 = 'imscc11'; const FORMAT_UNKNOWN = 'unknown'; // Interactive diff --git a/backup/cc/cc112moodle.php b/backup/cc/cc112moodle.php new file mode 100644 index 00000000000..d9c03e21600 --- /dev/null +++ b/backup/cc/cc112moodle.php @@ -0,0 +1,205 @@ +. +/** + * @package moodlecore + * @subpackage backup-imscc + * @copyright 2011 Darko Miletic (dmiletic@moodlerooms.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.'); + +require_once($CFG->dirroot . '/backup/cc/cc2moodle.php'); +require_once($CFG->dirroot . '/backup/cc/entities11.class.php'); +require_once($CFG->dirroot . '/backup/cc/entity11.resource.class.php'); +require_once($CFG->dirroot . '/backup/cc/entity11.forum.class.php'); +require_once($CFG->dirroot . '/backup/cc/entity11.quiz.class.php'); +require_once($CFG->dirroot . '/backup/cc/entity11.lti.class.php'); + +class cc112moodle extends cc2moodle { + const CC_TYPE_FORUM = 'imsdt_xmlv1p1'; + const CC_TYPE_QUIZ = 'imsqti_xmlv1p2/imscc_xmlv1p1/assessment'; + const CC_TYPE_QUESTION_BANK = 'imsqti_xmlv1p2/imscc_xmlv1p1/question-bank'; + const CC_TYPE_WEBLINK = 'imswl_xmlv1p1'; + const CC_TYPE_ASSOCIATED_CONTENT = 'associatedcontent/imscc_xmlv1p1/learning-application-resource'; + const CC_TYPE_BASICLTI = 'imsbasiclti_xmlv1p0'; + + public static $namespaces = array('imscc' => 'http://www.imsglobal.org/xsd/imsccv1p1/imscp_v1p1', + 'lomimscc' => 'http://ltsc.ieee.org/xsd/imsccv1p1/LOM/manifest', + 'lom' => 'http://ltsc.ieee.org/xsd/imsccv1p1/LOM/resource', + 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'cc' => 'http://www.imsglobal.org/xsd/imsccv1p1/imsccauth_v1p1'); + + public static $restypes = array('associatedcontent/imscc_xmlv1p1/learning-application-resource', 'webcontent'); + public static $forumns = array('dt' => 'http://www.imsglobal.org/xsd/imsccv1p1/imsdt_v1p1'); + public static $quizns = array('xmlns' => 'http://www.imsglobal.org/xsd/ims_qtiasiv1p2'); + public static $resourcens = array('wl' => 'http://www.imsglobal.org/xsd/imsccv1p1/imswl_v1p1'); + public static $basicltins = array( + 'xmlns' => 'http://www.imsglobal.org/xsd/imslticc_v1p0', + 'blti' => 'http://www.imsglobal.org/xsd/imsbasiclti_v1p0', + 'lticm' => 'http://www.imsglobal.org/xsd/imslticm_v1p0', + 'lticp' => 'http://www.imsglobal.org/xsd/imslticp_v1p0' + ); + + + public function __construct($path_to_manifest) { + parent::__construct($path_to_manifest); + } + + public function generate_moodle_xml () { + + global $CFG; + + mkdir(static::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'course_files'); + + $sheet_base = static::loadsheet(SHEET_BASE); + + // MOODLE_BACKUP / INFO / DETAILS / MOD + $node_info_details_mod = $this->create_code_info_details_mod(); + + // MOODLE_BACKUP / BLOCKS / BLOCK + $node_course_blocks_block = $this->create_node_course_blocks_block(); + + // MOODLE_BACKUP / COURSES / SECTIONS / SECTION + $node_course_sections_section = $this->create_node_course_sections_section(); + + // MOODLE_BACKUP / COURSES / QUESTION_CATEGORIES + $node_course_question_categories = $this->create_node_question_categories(); + + // MOODLE_BACKUP / COURSES / MODULES / MOD + $node_course_modules_mod = $this->create_node_course_modules_mod(); + + // MOODLE_BACKUP / COURSE / HEADER + $node_course_header = $this->create_node_course_header(); + + // GENERAL INFO + $filename = optional_param('file', 'not_available.zip', PARAM_RAW); + $filename = basename($filename); + + $www_root = $CFG->wwwroot; + + $find_tags = array('[#zip_filename#]', + '[#www_root#]', + '[#node_course_header#]', + '[#node_info_details_mod#]', + '[#node_course_blocks_block#]', + '[#node_course_sections_section#]', + '[#node_course_question_categories#]', + '[#node_course_modules#]'); + + $replace_values = array($filename, + $www_root, + $node_course_header, + $node_info_details_mod, + $node_course_blocks_block, + $node_course_sections_section, + $node_course_question_categories, + $node_course_modules_mod); + + $result_xml = str_replace($find_tags, $replace_values, $sheet_base); + + // COPY RESOURSE FILES + $entities = new entities11(); + + $entities->move_all_files(); + + if (array_key_exists("index", self::$instances)) { + + if (!file_put_contents(static::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'moodle.xml', $result_xml)) { + static::log_action('Cannot save the moodle manifest file: ' . static::$path_to_tmp_folder . DIRECTORY_SEPARATOR . 'moodle.xml', true); + } else { + $status = true; + } + + } else { + $status = false; + static::log_action('The course is empty', false); + } + + return $status; + + } + + public function convert_to_moodle_type ($cc_type) { + $type = parent::convert_to_moodle_type($cc_type); + + if ($type == TYPE_UNKNOWN) { + if ($cc_type == static::CC_TYPE_BASICLTI) { + $type = MOODLE_TYPE_LTI; + } + } + + return $type; + } + + protected function create_node_question_categories () { + + $quiz = new cc11_quiz(); + + static::log_action('Creating node: QUESTION_CATEGORIES'); + + $node_course_question_categories = $quiz->generate_node_question_categories(); + + return $node_course_question_categories; + } + + protected function create_code_info_details_mod () { + $result = parent::create_code_info_details_mod(); + + $count_blti = $this->count_instances(MOODLE_TYPE_LTI); + + $sheet_info_details_mod_instances_instance = static::loadsheet(SHEET_INFO_DETAILS_MOD_INSTANCE); + + $blti_mod = ''; + + if ($count_blti > 0) { + $blti_instance = $this->create_mod_info_details_mod_instances_instance($sheet_info_details_mod_instances_instance, $count_blti, static::$instances['instances'][MOODLE_TYPE_LTI]); + $blti_mod = $blti_instance ? $this->create_mod_info_details_mod(MOODLE_TYPE_LTI, $blti_instance) : ''; + } + + return $result . $blti_mod; + } + + protected function create_node_course_modules_mod () { + $resources = new cc11_resource(); + $forums = new cc11_forum(); + $quiz = new cc11_quiz(); + $basiclti = new cc11_lti(); + + static::log_action('Creating node: COURSE/MODULES/MOD'); + + // RESOURCES (WEB CONTENT AND WEB LINK) + $node_course_modules_mod_resource = $resources->generate_node(); + + // FORUMS + $node_course_modules_mod_forum = $forums->generate_node(); + + // QUIZ + $node_course_modules_mod_quiz = $quiz->generate_node_course_modules_mod(); + + //BasicLTI + $node_course_modules_mod_basiclti = $basiclti->generate_node(); + + $node_course_modules = $node_course_modules_mod_resource . + $node_course_modules_mod_forum . + $node_course_modules_mod_quiz . + $node_course_modules_mod_basiclti; + + return $node_course_modules; + } + +} \ No newline at end of file diff --git a/backup/cc/cc2moodle.php b/backup/cc/cc2moodle.php index 1d562b8e67a..43d31346a1d 100644 --- a/backup/cc/cc2moodle.php +++ b/backup/cc/cc2moodle.php @@ -30,34 +30,91 @@ require_once($CFG->dirroot . '/backup/cc/entity.quiz.class.php'); class cc2moodle { + const CC_TYPE_FORUM = 'imsdt_xmlv1p0'; + const CC_TYPE_QUIZ = 'imsqti_xmlv1p2/imscc_xmlv1p0/assessment'; + const CC_TYPE_QUESTION_BANK = 'imsqti_xmlv1p2/imscc_xmlv1p0/question-bank'; + const CC_TYPE_WEBLINK = 'imswl_xmlv1p0'; + const CC_TYPE_WEBCONTENT = 'webcontent'; + const CC_TYPE_ASSOCIATED_CONTENT = 'associatedcontent/imscc_xmlv1p0/learning-application-resource'; + const CC_TYPE_EMPTY = ''; + + public static $restypes = array('associatedcontent/imscc_xmlv1p0/learning-application-resource', 'webcontent'); + public static $forumns = array('dt' => 'http://www.imsglobal.org/xsd/imsdt_v1p0'); + public static $quizns = array('xmlns' => 'http://www.imsglobal.org/xsd/ims_qtiasiv1p2'); + public static $resourcens = array('wl' => 'http://www.imsglobal.org/xsd/imswl_v1p0'); + /** + * + * @return array + */ + public static function getquizns() { + return static::$quizns; + } + + /** + * + * @return array + */ + public static function getforumns() { + return static::$forumns; + } + + /** + * + * @return array + */ + public static function getresourcens() { + return static::$resourcens; + } + + public static function get_manifest($folder) { + if (!is_dir($folder)) { + return false; + } + + $result = false; + try { + $dirIter = new RecursiveDirectoryIterator($folder, RecursiveDirectoryIterator::KEY_AS_PATHNAME); + $recIter = new RecursiveIteratorIterator($dirIter, RecursiveIteratorIterator::CHILD_FIRST); + foreach ($recIter as $info) { + if ($info->isFile() && ($info->getFilename() == 'imsmanifest.xml')) { + $result = $info->getPathname(); + break; + } + } + } catch (Exception $e) {} + + return $result; + } + public static $instances = array(); public static $manifest; public static $path_to_manifest_folder; - public static $namespaces = array('imscc' => 'http://www.imsglobal.org/xsd/imscc/imscp_v1p1', + public static $namespaces = array('imscc' => 'http://www.imsglobal.org/xsd/imscc/imscp_v1p1', 'lomimscc' => 'http://ltsc.ieee.org/xsd/imscc/LOM', - 'lom' => 'http://ltsc.ieee.org/xsd/LOM', - 'voc' => 'http://ltsc.ieee.org/xsd/LOM/vocab', - 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', - 'cc' => 'http://www.imsglobal.org/xsd/imsccauth_v1p0'); + 'lom' => 'http://ltsc.ieee.org/xsd/LOM', + 'voc' => 'http://ltsc.ieee.org/xsd/LOM/vocab', + 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'cc' => 'http://www.imsglobal.org/xsd/imsccauth_v1p0'); function __construct ($path_to_manifest) { - self::$manifest = new DOMDocument(); + static::$manifest = new DOMDocument(); + static::$manifest->validateOnParse = false; - self::$path_to_manifest_folder = dirname($path_to_manifest); + static::$path_to_manifest_folder = dirname($path_to_manifest); - self::log_action('Proccess start'); - self::log_action('Load the manifest file: ' . $path_to_manifest); + static::log_action('Proccess start'); + static::log_action('Load the manifest file: ' . $path_to_manifest); - if (!self::$manifest->load($path_to_manifest)) { - self::log_action('Cannot load the manifest file: ' . $path_to_manifest, true); + if (!static::$manifest->load($path_to_manifest, LIBXML_NONET)) { + static::log_action('Cannot load the manifest file: ' . $path_to_manifest, true); } } public function is_auth () { - $xpath = self::newx_path(self::$manifest, self::$namespaces); + $xpath = static::newx_path(static::$manifest, static::$namespaces); $count_auth = $xpath->evaluate('count(/imscc:manifest/cc:authorizations)'); @@ -70,9 +127,9 @@ class cc2moodle { return $response; } - private function get_metadata ($section, $key) { + protected function get_metadata ($section, $key) { - $xpath = self::newx_path(self::$manifest, self::$namespaces); + $xpath = static::newx_path(static::$manifest, static::$namespaces); $metadata = $xpath->query('/imscc:manifest/imscc:metadata/lomimscc:lom/lomimscc:' . $section . '/lomimscc:' . $key . '/lomimscc:string'); $value = !empty($metadata->item(0)->nodeValue) ? $metadata->item(0)->nodeValue : ''; @@ -84,9 +141,9 @@ class cc2moodle { global $CFG; - mkdir(self::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'course_files'); + mkdir(static::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'course_files'); - $sheet_base = self::loadsheet(SHEET_BASE); + $sheet_base = static::loadsheet(SHEET_BASE); // MOODLE_BACKUP / INFO / DETAILS / MOD $node_info_details_mod = $this->create_code_info_details_mod(); @@ -107,7 +164,7 @@ class cc2moodle { $node_course_header = $this->create_node_course_header(); // GENERAL INFO - $filename = optional_param('file', 'not_available.zip'); + $filename = optional_param('file', 'not_available.zip', PARAM_RAW); $filename = basename($filename); $www_root = $CFG->wwwroot; @@ -139,8 +196,8 @@ class cc2moodle { if (array_key_exists("index", self::$instances)) { - if (!file_put_contents(self::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'moodle.xml', $result_xml)) { - self::log_action('Cannot save the moodle manifest file: ' . self::$path_to_tmp_folder . DIRECTORY_SEPARATOR . 'moodle.xml', true); + if (!file_put_contents(static::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'moodle.xml', $result_xml)) { + static::log_action('Cannot save the moodle manifest file: ' . static::$path_to_tmp_folder . DIRECTORY_SEPARATOR . 'moodle.xml', true); } else { $status = true; } @@ -148,14 +205,14 @@ class cc2moodle { } else { $status = false; notify('The course is empty'); - self::log_action('The course is empty', false); + static::log_action('The course is empty', false); } return $status; } - private function get_sections_numbers ($instances) { + protected function get_sections_numbers ($instances) { $count = 0; @@ -170,13 +227,15 @@ class cc2moodle { return $count; } - private function create_node_course_header () { + protected function create_node_course_header () { $node_course_header = ''; - $sheet_course_header = self::loadsheet(SHEET_COURSE_HEADER); + $sheet_course_header = static::loadsheet(SHEET_COURSE_HEADER); - $course_title = $this->get_metadata('general', 'title'); - $section_count = $this->get_sections_numbers(self::$instances) - 1; + $course_title = trim($this->get_metadata('general', 'title')); + $course_title = empty($course_title) ? 'Untitled Course' : $course_title; + $course_description = $this->get_metadata('general', 'description'); + $section_count = $this->get_sections_numbers(static::$instances) - 1; if ($section_count == -1) { $section_count = 0; @@ -190,11 +249,13 @@ class cc2moodle { $find_tags = array('[#course_name#]', '[#course_short_name#]', + '[#course_description#]', '[#date_now#]', '[#section_count#]'); - $replace_values = array($course_title, - $course_short_name, + $replace_values = array(htmlentities($course_title), + htmlentities($course_short_name), + htmlentities($course_description), time(), $section_count); @@ -203,25 +264,25 @@ class cc2moodle { return $node_course_header; } - private function create_node_question_categories () { + protected function create_node_question_categories () { - $quiz = new quiz(); + $quiz = new cc_quiz(); - self::log_action('Creating node: QUESTION_CATEGORIES'); + static::log_action('Creating node: QUESTION_CATEGORIES'); $node_course_question_categories = $quiz->generate_node_question_categories(); return $node_course_question_categories; } - private function create_node_course_modules_mod () { + protected function create_node_course_modules_mod () { - $labels = new label(); - $resources = new resource(); - $forums = new forum(); - $quiz = new quiz(); + $labels = new cc_label(); + $resources = new cc_resource(); + $forums = new cc_forum(); + $quiz = new cc_quiz(); - self::log_action('Creating node: COURSE/MODULES/MOD'); + static::log_action('Creating node: COURSE/MODULES/MOD'); // LABELS $node_course_modules_mod_label = $labels->generate_node(); @@ -234,18 +295,18 @@ class cc2moodle { // QUIZ $node_course_modules_mod_quiz = $quiz->generate_node_course_modules_mod(); - $node_course_modules = $node_course_modules_mod_label . $node_course_modules_mod_resource . $node_course_modules_mod_forum . $node_course_modules_mod_quiz; + $node_course_modules = /*$node_course_modules_mod_label .*/ $node_course_modules_mod_resource . $node_course_modules_mod_forum . $node_course_modules_mod_quiz; return $node_course_modules; } - private function create_node_course_sections_section () { + protected function create_node_course_sections_section () { - self::log_action('Creating node: COURSE/SECTIONS/SECTION'); + static::log_action('Creating node: COURSE/SECTIONS/SECTION'); $node_course_sections_section = ''; - $sheet_course_sections_section = self::loadsheet(SHEET_COURSE_SECTIONS_SECTION); + $sheet_course_sections_section = static::loadsheet(SHEET_COURSE_SECTIONS_SECTION); $topics = $this->get_nodes_by_criteria('deep', ROOT_DEEP); @@ -292,13 +353,13 @@ class cc2moodle { return $node_course_sections_section; } - private function create_node_course_blocks_block () { + protected function create_node_course_blocks_block () { global $CFG; - self::log_action('Creating node: COURSE/BLOCKS/BLOCK'); + static::log_action('Creating node: COURSE/BLOCKS/BLOCK'); - $sheet_course_blocks_block = self::loadsheet(SHEET_COURSE_BLOCKS_BLOCK); + $sheet_course_blocks_block = static::loadsheet(SHEET_COURSE_BLOCKS_BLOCK); $node_course_blocks_block = ''; $format_config = $CFG->dirroot . '/course/format/weeks/config.php'; @@ -360,9 +421,9 @@ class cc2moodle { } - private function create_node_course_sections_section_mods_mod ($root_parent) { + protected function create_node_course_sections_section_mods_mod ($root_parent) { - $sheet_course_sections_section_mods_mod = self::loadsheet(SHEET_COURSE_SECTIONS_SECTION_MODS_MOD); + $sheet_course_sections_section_mods_mod = static::loadsheet(SHEET_COURSE_SECTIONS_SECTION_MODS_MOD); $childs = $this->get_nodes_by_criteria('root_parent', $root_parent); if ($childs) { @@ -419,8 +480,8 @@ class cc2moodle { $response = array(); - if (array_key_exists('index', self::$instances)) { - foreach (self::$instances['index'] as $item) { + if (array_key_exists('index', static::$instances)) { + foreach (static::$instances['index'] as $item) { if ($item[$key] == $value) { $response[] = $item; } @@ -430,13 +491,14 @@ class cc2moodle { return $response; } - private function create_code_info_details_mod () { + //Modified here + protected function create_code_info_details_mod () { - self::log_action('Creating node: INFO/DETAILS/MOD'); + static::log_action('Creating node: INFO/DETAILS/MOD'); - $xpath = self::newx_path(self::$manifest, self::$namespaces); + $xpath = static::newx_path(static::$manifest, static::$namespaces); - $items = $xpath->query('/imscc:manifest/imscc:organizations/imscc:organization/imscc:item | /imscc:manifest/imscc:resources/imscc:resource[@type="' . CC_TYPE_QUESTION_BANK . '"]'); + $items = $xpath->query('/imscc:manifest/imscc:organizations/imscc:organization/imscc:item | /imscc:manifest/imscc:resources/imscc:resource[@type="' . static::CC_TYPE_QUESTION_BANK . '"]'); $this->create_instances($items); @@ -445,19 +507,19 @@ class cc2moodle { $count_resource = $this->count_instances(MOODLE_TYPE_RESOURCE); $count_label = $this->count_instances(MOODLE_TYPE_LABEL); - $sheet_info_details_mod_instances_instance = self::loadsheet(SHEET_INFO_DETAILS_MOD_INSTANCE); + $sheet_info_details_mod_instances_instance = static::loadsheet(SHEET_INFO_DETAILS_MOD_INSTANCE); if ($count_resource > 0) { - $resource_instance = $this->create_mod_info_details_mod_instances_instance($sheet_info_details_mod_instances_instance, $count_resource, self::$instances['instances'][MOODLE_TYPE_RESOURCE]); + $resource_instance = $this->create_mod_info_details_mod_instances_instance($sheet_info_details_mod_instances_instance, $count_resource, static::$instances['instances'][MOODLE_TYPE_RESOURCE]); } if ($count_quiz > 0) { - $quiz_instance = $this->create_mod_info_details_mod_instances_instance($sheet_info_details_mod_instances_instance, $count_quiz, self::$instances['instances'][MOODLE_TYPE_QUIZ]); + $quiz_instance = $this->create_mod_info_details_mod_instances_instance($sheet_info_details_mod_instances_instance, $count_quiz, static::$instances['instances'][MOODLE_TYPE_QUIZ]); } if ($count_forum > 0) { - $forum_instance = $this->create_mod_info_details_mod_instances_instance($sheet_info_details_mod_instances_instance, $count_forum, self::$instances['instances'][MOODLE_TYPE_FORUM]); + $forum_instance = $this->create_mod_info_details_mod_instances_instance($sheet_info_details_mod_instances_instance, $count_forum, static::$instances['instances'][MOODLE_TYPE_FORUM]); } if ($count_label > 0) { - $label_instance = $this->create_mod_info_details_mod_instances_instance($sheet_info_details_mod_instances_instance, $count_label, self::$instances['instances'][MOODLE_TYPE_LABEL]); + $label_instance = $this->create_mod_info_details_mod_instances_instance($sheet_info_details_mod_instances_instance, $count_label, static::$instances['instances'][MOODLE_TYPE_LABEL]); } $resource_mod = $count_resource ? $this->create_mod_info_details_mod(MOODLE_TYPE_RESOURCE, $resource_instance) : ''; @@ -465,13 +527,13 @@ class cc2moodle { $forum_mod = $count_forum ? $this->create_mod_info_details_mod(MOODLE_TYPE_FORUM, $forum_instance) : ''; $label_mod = $count_label ? $this->create_mod_info_details_mod(MOODLE_TYPE_LABEL, $label_instance) : ''; - return $label_mod . $resource_mod . $quiz_mod . $forum_mod; + return /*$label_mod .*/ $resource_mod . $quiz_mod . $forum_mod; } - private function create_mod_info_details_mod ($mod_type, $node_info_details_mod_instances_instance) { + protected function create_mod_info_details_mod ($mod_type, $node_info_details_mod_instances_instance) { - $sheet_info_details_mod = self::loadsheet(SHEET_INFO_DETAILS_MOD); + $sheet_info_details_mod = static::loadsheet(SHEET_INFO_DETAILS_MOD); $find_tags = array('[#mod_type#]' ,'[#node_info_details_mod_instances_instance#]'); $replace_values = array($mod_type , $node_info_details_mod_instances_instance); @@ -479,7 +541,7 @@ class cc2moodle { return str_replace($find_tags, $replace_values, $sheet_info_details_mod); } - private function create_mod_info_details_mod_instances_instance ($sheet, $instances_quantity, $instances) { + protected function create_mod_info_details_mod_instances_instance ($sheet, $instances_quantity, $instances) { $instance = ''; @@ -489,10 +551,10 @@ class cc2moodle { for ($i = 1; $i <= $instances_quantity; $i++) { - $user_info = ($instances[$i - 1]['common_cartriedge_type'] == CC_TYPE_FORUM) ? 'true' : 'false'; + $user_info = ($instances[$i - 1]['common_cartriedge_type'] == static::CC_TYPE_FORUM) ? 'true' : 'false'; $replace_values = array($instances[$i - 1]['instance'], - $instances[$i - 1]['title'], + htmlentities($instances[$i - 1]['title']), $user_info); $instance .= str_replace($find_tags, $replace_values, $sheet); @@ -502,14 +564,14 @@ class cc2moodle { } - private function create_instances ($items, $level = 0, &$array_index = 0, $index_root = 0) { + protected function create_instances ($items, $level = 0, &$array_index = 0, $index_root = 0) { $level++; $i = 1; if ($items) { - $xpath = self::newx_path(self::$manifest, self::$namespaces); + $xpath = self::newx_path(static::$manifest, static::$namespaces); foreach ($items as $item) { @@ -543,17 +605,17 @@ class cc2moodle { $index_root = $array_index; } - self::$instances['index'][$array_index]['common_cartriedge_type'] = $cc_type; - self::$instances['index'][$array_index]['moodle_type'] = $moodle_type; - self::$instances['index'][$array_index]['title'] = $title ? $title : ''; - self::$instances['index'][$array_index]['root_parent'] = $index_root; - self::$instances['index'][$array_index]['index'] = $array_index; - self::$instances['index'][$array_index]['deep'] = $level; - self::$instances['index'][$array_index]['instance'] = $this->count_instances($moodle_type); - self::$instances['index'][$array_index]['resource_indentifier'] = $identifierref; + static::$instances['index'][$array_index]['common_cartriedge_type'] = $cc_type; + static::$instances['index'][$array_index]['moodle_type'] = $moodle_type; + static::$instances['index'][$array_index]['title'] = $title ? $title : ''; + static::$instances['index'][$array_index]['root_parent'] = $index_root; + static::$instances['index'][$array_index]['index'] = $array_index; + static::$instances['index'][$array_index]['deep'] = $level; + static::$instances['index'][$array_index]['instance'] = $this->count_instances($moodle_type); + static::$instances['index'][$array_index]['resource_indentifier'] = $identifierref; - self::$instances['instances'][$moodle_type][] = array('title' => $title, - 'instance' => self::$instances['index'][$array_index]['instance'], + static::$instances['instances'][$moodle_type][] = array('title' => $title, + 'instance' => static::$instances['index'][$array_index]['instance'], 'common_cartriedge_type' => $cc_type , 'resource_indentifier' => $identifierref); $more_items = $xpath->query('imscc:item', $item); @@ -572,10 +634,10 @@ class cc2moodle { $quantity = 0; - if (array_key_exists('index', self::$instances)) { - if (self::$instances['index'] && $type) { + if (array_key_exists('index', static::$instances)) { + if (static::$instances['index'] && $type) { - foreach (self::$instances['index'] as $instance) { + foreach (static::$instances['index'] as $instance) { if (!empty($instance['moodle_type'])) { $types[] = $instance['moodle_type']; } @@ -590,37 +652,41 @@ class cc2moodle { } public function convert_to_moodle_type ($cc_type) { + $type = TYPE_UNKNOWN; - if ($cc_type == CC_TYPE_FORUM) { + if ($cc_type == static::CC_TYPE_FORUM) { $type = MOODLE_TYPE_FORUM; } - if ($cc_type == CC_TYPE_QUIZ) { + + if ($cc_type == static::CC_TYPE_QUIZ) { $type = MOODLE_TYPE_QUIZ; } - if ($cc_type == CC_TYPE_WEBLINK) { + + if ($cc_type == static::CC_TYPE_WEBLINK) { $type = MOODLE_TYPE_RESOURCE; } - if ($cc_type == CC_TYPE_WEBCONTENT) { - $type = MOODLE_TYPE_RESOURCE; - } - if ($cc_type == CC_TYPE_ASSOCIATED_CONTENT) { - $type = MOODLE_TYPE_RESOURCE; - } - if ($cc_type == CC_TYPE_QUESTION_BANK) { - $type = MOODLE_TYPE_QUESTION_BANK; - } - if ($cc_type == CC_TYPE_EMPTY) { - $type = MOODLE_TYPE_LABEL; - } - $type = empty($type) ? TYPE_UNKNOWN : $type; + if ($cc_type == static::CC_TYPE_WEBCONTENT) { + $type = MOODLE_TYPE_RESOURCE; + } + + if ($cc_type == static::CC_TYPE_ASSOCIATED_CONTENT) { + $type = MOODLE_TYPE_RESOURCE; + } + + if ($cc_type == static::CC_TYPE_QUESTION_BANK) { + $type = MOODLE_TYPE_QUESTION_BANK; + } + /*if ($cc_type == static::CC_TYPE_EMPTY) { + $type = MOODLE_TYPE_LABEL; + }*/ return $type; } public function get_item_cc_type ($identifier) { - $xpath = self::newx_path(self::$manifest, self::$namespaces); + $xpath = static::newx_path(static::$manifest, static::$namespaces); $nodes = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="' . $identifier . '"]/@type'); @@ -638,7 +704,7 @@ class cc2moodle { if (!empty($namespaces)) { foreach ($namespaces as $prefix => $ns) { if (!$xpath->registerNamespace($prefix, $ns)) { - self::log_action('Cannot register the namespace: ' . $prefix . ':' . $ns, true); + static::log_action('Cannot register the namespace: ' . $prefix . ':' . $ns, true); } } } @@ -650,32 +716,35 @@ class cc2moodle { $content = (is_readable($file) && ($content = file_get_contents($file))) ? $content : false; - self::log_action('Loading sheet: ' . $file); + static::log_action('Loading sheet: ' . $file); if (!$content) { - self::log_action('Cannot load the xml sheet: ' . $file, true); + static::log_action('Cannot load the xml sheet: ' . $file, true); } - self::log_action('Load OK!'); + static::log_action('Load OK!'); return $content; } + public static function log_file() { + return static::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'cc2moodle.log'; + } + public static function log_action ($text, $critical_error = false) { - $filename = cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'cc2moodle.log'; $full_message = strtoupper(date("j/n/Y g:i:s a")) . " - " . $text . "\r"; - file_put_contents($filename, $full_message, FILE_APPEND); + file_put_contents(static::log_file(), $full_message, FILE_APPEND); if ($critical_error) { - self::critical_error($text); + static::critical_error($text); } } - private function critical_error ($text) { + protected function critical_error ($text) { - $path_to_log = cc2moodle::$path_to_manifest_folder . '/cc2moodle.log'; + $path_to_log = static::log_file(); echo ' @@ -698,16 +767,10 @@ class cc2moodle { die(); } - private function create_course_code ($title) { - - $code = ''; - $words = explode(' ', $title); - - foreach ($words as $word) { - $code .= $word[0]; - } - - $code = strtoupper($code . '-1'); + protected function create_course_code ($title) { + //Making sure that text of the short name does not go over the DB limit. + //and leaving the space to add additional characters by the platform + $code = substr(strtoupper(str_replace(' ', '', trim($title))),0,94); return $code; } } diff --git a/backup/cc/cc_includes.php b/backup/cc/cc_includes.php new file mode 100644 index 00000000000..263172cf778 --- /dev/null +++ b/backup/cc/cc_includes.php @@ -0,0 +1,40 @@ +. +/** +* Main include for IMS Common Cartridge export classes +* +* @package backup-convert +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once($CFG->dirroot .'/backup/cc/cc_lib/xmlbase.php'); +require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_resources.php'); +require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_builder_creator.php'); +require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_manifest.php'); +require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_metadata.php'); +require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_metadata_resource.php'); +require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_metadata_file.php'); +require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_version11.php'); +require_once($CFG->dirroot .'/backup/cc/cc_lib/gral_lib/pathutils.php'); +require_once($CFG->dirroot .'/backup/cc/cc_lib/gral_lib/functions.php'); +require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_organization.php'); +require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_converter_basiclti.php'); +require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_converter_lti.php'); +require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_converter_forum.php'); +require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_converter_url.php'); +require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_converter_resource.php'); +require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_convert_moodle2.php'); diff --git a/backup/cc/cc_lib/cc_asssesment.php b/backup/cc/cc_lib/cc_asssesment.php new file mode 100644 index 00000000000..b15f5401d82 --- /dev/null +++ b/backup/cc/cc_lib/cc_asssesment.php @@ -0,0 +1,64 @@ +. +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + + +require_once 'cc_general.php'; + +class assesment1_resurce_file extends general_cc_file { + const deafultname = 'assesment.xml'; + + protected $rootns = 'xmlns'; + protected $rootname = 'questestinterop'; + protected $ccnamespaces = array('xmlns' => 'http://www.imsglobal.org/xsd/ims_qtiasiv1p2', + 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance'); + protected $ccnsnames = array('xmlns' => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/domainProfile_4/ims_qtiasiv1p2_localised.xsd'); + + protected $assesment_title = null; + protected $assesment_ident = null; + protected $qtimetadata = array(); + + protected function on_save() { + $rns = $this->ccnamespaces[$this->rootns]; + //add some root stuff + $assesment = $this->append_new_element_ns($this->root, $rns, 'assesment'); + $this->append_new_attribute_ns($assesment, $rns, 'ident', $this->assesment_ident); + $this->append_new_attribute_ns($assesment, $rns, 'title', $this->assesment_title); + + if (!empty($this->qtimetadata)) { + $qtimetadata = $this->append_new_element_ns($assesment, $rns, 'qtimetadata'); + foreach ($this->qtimetadata as $label => $entry) { + $this->append_new_element_ns($qtimetadata, $rns, 'fieldlabel', $label); + $this->append_new_element_ns($qtimetadata, $rns, 'fieldentry', $entry); + } + } + + //TODO: implement section processing (looks quite complicated for implementing) + + //TODO: finish this! + return false; + } +} + + +class assesment11_resurce_file extends assesment1_resurce_file { + protected $ccnsnames = array('xmlns' => 'http://www.imsglobal.org/profile/cc/ccv1p1/ccv1p1_qtiasiv1p2p1_v1p0.xsd'); +} diff --git a/backup/cc/cc_lib/cc_basiclti.php b/backup/cc/cc_lib/cc_basiclti.php new file mode 100644 index 00000000000..f0c7263d9fa --- /dev/null +++ b/backup/cc/cc_lib/cc_basiclti.php @@ -0,0 +1,181 @@ +. +/** +* @package backup-convert +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once 'cc_general.php'; + +class basicltil1_resurce_file extends general_cc_file { + const deafultname = 'basiclti.xml'; + + protected $rootns = 'xmlns'; + protected $rootname = 'cartridge_basiclti_link'; + protected $ccnamespaces = array('xmlns' => 'http://www.imsglobal.org/xsd/imslticc_v1p0', + 'blti' => 'http://www.imsglobal.org/xsd/imsbasiclti_v1p0', + 'lticm' => 'http://www.imsglobal.org/xsd/imslticm_v1p0', + 'lticp' => 'http://www.imsglobal.org/xsd/imslticp_v1p0', + 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance'); + protected $ccnsnames = array('xmlns' => 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticc_v1p0.xsd', + 'blti' => 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0p1.xsd', + 'lticm' => 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd', + 'lticp' => 'http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd'); + + protected $title = 'Untitled'; + protected $description = 'description'; + protected $custom_properties = array(); + protected $extension_properties = array(); + protected $extension_platform = null; + protected $launch_url = null; + protected $secure_launch_url = null; + protected $icon = null; + protected $secure_icon = null; + protected $vendor = false; + protected $vendor_code = 'I'; + protected $vendor_name = null; + protected $vendor_description = null; + protected $vendor_url = null; + protected $vendor_contact = null; + protected $cartridge_bundle = null; + protected $cartridge_icon = null; + + public function set_title($title) { + $this->title = $title; + } + public function set_description($description) { + $this->description = $description; + } + public function set_launch_url ($url) { + $this->launch_url = $url; + } + public function set_secure_launch_url ($url) { + $this->secure_launch_url = $url; + } + public function set_launch_icon ($icon) { + $this->icon = $icon; + } + public function set_secure_launch_icon ($icon) { + $this->secure_icon = $icon; + } + public function set_vendor_code ($code) { + $this->vendor_code = $code; + $this->vendor = true; + } + public function set_vendor_name ($name) { + $this->vendor_name = $name; + $this->vendor = true; + } + public function set_vendor_description ($desc) { + $this->vendor_description = $desc; + $this->vendor = true; + } + public function set_vendor_url ($url) { + $this->vendor_url = $url; + $this->vendor = true; + } + public function set_vendor_contact ($email) { + $this->vendor_contact = array('email' => $email); + $this->vendor = true; + } + public function add_custom_property ($property, $value) { + $this->custom_properties[$property] = $value; + } + public function add_extension ($extension, $value) { + $this->extension_properties[$extension] = $value; + } + public function set_extension_platform ($value) { + $this->extension_platform = $value; + } + + public function set_cartridge_bundle($value) { + $this->cartridge_bundle = $value; + } + + public function set_cartridge_icon($value) { + $this->cartridge_icon = $value; + } + + protected function on_save() { + //this has to be done like this since order of apearance of the tags is also mandatory + //and specified in basiclti schema files + + //main items + $rns = $this->ccnamespaces['blti']; + $this->append_new_element_ns($this->root, $rns, 'title' , $this->title ); + $this->append_new_element_ns($this->root, $rns, 'description', $this->description); + + //custom properties + if (!empty($this->custom_properties)) { + $custom = $this->append_new_element_ns($this->root, $rns, 'custom'); + foreach ($this->custom_properties as $property => $value) { + $node = $this->append_new_element_ns($custom, $this->ccnamespaces['lticm'], 'property' , $value); + $this->append_new_attribute_ns($node, $this->ccnamespaces['xmlns'],'name', $property); + } + } + + //extension properties + if (!empty($this->extension_properties)) { + $extension = $this->append_new_element_ns($this->root, $rns, 'extensions'); + if (!empty($this->extension_platform)) { + $this->append_new_attribute_ns($extension, $this->ccnamespaces['xmlns'], 'platform', $this->extension_platform); + } + foreach ($this->extension_properties as $property => $value) { + $node = $this->append_new_element_ns($extension, $this->ccnamespaces['lticm'], 'property' , $value); + $this->append_new_attribute_ns($node, $this->ccnamespaces['xmlns'], 'name', $property); + } + } + + $this->append_new_element_ns($this->root, $rns, 'launch_url' , $this->launch_url ); + if (!empty($this->secure_launch_url)) { + $this->append_new_element_ns($this->root, $rns, 'secure_launch_url' , $this->secure_launch_url); + } + $this->append_new_element_ns($this->root, $rns, 'icon' , $this->icon ); + if (!empty($this->secure_icon)) { + $this->append_new_element_ns($this->root, $rns, 'secure_icon' , $this->secure_icon); + } + + //vendor info + $vendor = $this->append_new_element_ns($this->root, $rns, 'vendor'); + $vcode = empty($this->vendor_code) ? 'I' : $this->vendor_code; + $this->append_new_element_ns($vendor, $this->ccnamespaces['lticp'], 'code', $vcode); + $this->append_new_element_ns($vendor, $this->ccnamespaces['lticp'], 'name', $this->vendor_name); + if (!empty($this->vendor_description)) { + $this->append_new_element_ns($vendor, $this->ccnamespaces['lticp'], 'description', $this->vendor_description); + } + if (!empty($this->vendor_url)) { + $this->append_new_element_ns($vendor, $this->ccnamespaces['lticp'], 'url', $this->vendor_url); + } + if (!empty($this->vendor_contact)) { + $vcontact = $this->append_new_element_ns($vendor, $this->ccnamespaces['lticp'], 'contact'); + $this->append_new_element_ns($vcontact, $this->ccnamespaces['lticp'], 'email', $this->vendor_contact['email']); + } + + //cartridge bundle and icon + if (!empty($this->cartridge_bundle)) { + $cbundle = $this->append_new_element_ns($this->root, $this->ccnamespaces['xmlns'], 'cartridge_bundle'); + $this->append_new_attribute_ns($cbundle, $this->ccnamespaces['xmlns'], 'identifierref', $this->cartridge_bundle); + } + if (!empty($this->cartridge_icon)) { + $cicon = $this->append_new_element_ns($this->root, $this->ccnamespaces['xmlns'], 'cartridge_icon'); + $this->append_new_attribute_ns($cicon, $this->ccnamespaces['xmlns'], 'identifierref', $this->cartridge_icon); + } + + return true; + } + +} diff --git a/backup/cc/cc_lib/cc_builder_creator.php b/backup/cc/cc_lib/cc_builder_creator.php new file mode 100644 index 00000000000..e9932069672 --- /dev/null +++ b/backup/cc/cc_lib/cc_builder_creator.php @@ -0,0 +1,41 @@ +. +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +/** + * Factory pattern class + * Create the version class to use + * + */ +class cc_builder_creator { + + public static function factory($version){ + if (is_null($version)) { + throw new Exception("Version is null!"); + } + if (include_once 'cc_version' . $version . '.php') { + $classname = 'cc_version' . $version; + return new $classname; + } else { + throw new Exception ("Dont find cc version class!"); + } + } +} \ No newline at end of file diff --git a/backup/cc/cc_lib/cc_convert_moodle2.php b/backup/cc/cc_lib/cc_convert_moodle2.php new file mode 100644 index 00000000000..e672f1ef42d --- /dev/null +++ b/backup/cc/cc_lib/cc_convert_moodle2.php @@ -0,0 +1,194 @@ +. +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +if (!extension_loaded('fileinfo')) { + die('You must install fileinfo extension!'); +} + +abstract class cc_convert_moodle2 { + + /** + * + * Enter description here ... + * @param unknown_type $packagedir + * @param unknown_type $outdir + * @throws DOMException + * @throws InvalidArgumentException + */ + public static function convert($packagedir, $outdir) { + $dir = realpath($packagedir); + if (empty($dir)) { + throw new InvalidArgumentException('Directory does not exist!'); + } + $odir = realpath($outdir); + if (empty($odir)) { + throw new InvalidArgumentException('Directory does not exist!'); + } + $coursefile = $dir.DIRECTORY_SEPARATOR.'course'.DIRECTORY_SEPARATOR.'course.xml'; + $doc = new XMLGenericDocument(); + if ($doc->load($coursefile)) { + $course_name = $doc->nodeValue('/course/fullname'); + $course_desc = $doc->nodeValue('/course/summary'); + $course_language = $doc->nodeValue('/course/lang'); + $course_language = empty($course_language) ? 'en' : $course_language; + $course_category = $doc->nodeValue('/course/category/name'); + + //Initialize the manifest metadata class + $meta = new cc_metadata_manifest(); + + //Package metadata + $metageneral = new cc_metadata_general(); + $metageneral->set_language($course_language); + $metageneral->set_title($course_name, $course_language); + $metageneral->set_description($course_desc, $course_language); + $metageneral->set_catalog('category'); + $metageneral->set_entry($course_category); + $meta->add_metadata_general($metageneral); + + // Create the manifest + $manifest = new cc_manifest(cc_version::v11); + + $manifest->add_metadata_manifest($meta); + + $organization = null; + + //Package structure - default organization and resources + //Get the course structure - this will be transformed into organization + //Step 1 - Get the list and order of sections/topics + $moodle_backup = $dir . DIRECTORY_SEPARATOR . 'moodle_backup.xml'; + $secp = new XMLGenericDocument(); + $docp = new XMLGenericDocument(); + if ($docp->load($moodle_backup)) { + //sections + $sections = array(); + $section_list = $docp->nodeList('/moodle_backup/information/contents/sections/section'); + if (!empty($section_list)) { + foreach ($section_list as $node) { + $sectionid = $docp->nodeValue('sectionid', $node); + $sectiontitle = $docp->nodeValue('title' , $node); + $sectionpath = $docp->nodeValue('directory', $node); + $sequence = array(); + //Get section stuff + $section_file = $dir . + DIRECTORY_SEPARATOR . + $sectionpath . + DIRECTORY_SEPARATOR . + 'section.xml'; + if ($secp->load($section_file)) { + $rawvalue = $secp->nodeValue('/section/sequence'); + if ($rawvalue != '$@NULL@$') { + $sequence = explode(',', $rawvalue); + } + } + $sections[$sectionid] = array($sectiontitle, $sequence); + } + } + //organization title + $organization = new cc_organization(); + //Add section/topic items + foreach ($sections as $sectionid => $values) { + $item = new cc_item(); + $item->title = $values[0]; + self::process_sequence($item, $manifest, $values[1], $dir, $odir); + $organization->add_item($item); + } + $manifest->put_nodes(); + } + + if (!empty($organization)) { + $manifest->add_new_organization($organization); + } + + $manifestpath = $outdir.DIRECTORY_SEPARATOR.'imsmanifest.xml'; + $manifest->saveTo($manifestpath); + } + + } + + /** + * + * Process the activites and create item structure + * @param cc_i_item $item + * @param array $sequence + * @param string $packageroot - directory path + * @throws DOMException + */ + protected static function process_sequence(cc_i_item &$item, cc_i_manifest &$manifest, array $sequence, $packageroot, $outdir) { + $moodle_backup = $packageroot . DIRECTORY_SEPARATOR . 'moodle_backup.xml'; + $doc = new XMLGenericDocument(); + if(!$doc->load($moodle_backup)) { + return; + } + $activities = $doc->nodeList('/moodle_backup/information/contents/activities/activity'); + if (!empty($activities)) { + $dpp = new XMLGenericDocument(); + foreach ($activities as $activity) { + $moduleid = $doc->nodeValue('moduleid', $activity); + if (in_array($moduleid, $sequence)) { + //detect activity type + $directory = $doc->nodeValue('directory', $activity); + $path = $packageroot . DIRECTORY_SEPARATOR . $directory; + $module_file = $path . DIRECTORY_SEPARATOR . 'module.xml'; + if ($dpp->load($module_file)) { + $activity_type = $dpp->nodeValue('/module/modulename'); + $activity_indentation = $dpp->nodeValue('/module/indent'); + $aitem = self::item_indenter($item, $activity_indentation); + $caller = "cc_converter_{$activity_type}"; + if (class_exists($caller)) { + $obj = new $caller($aitem, $manifest, $packageroot, $path); + if ( !$obj->convert($outdir) ) { + echo "failed to convert {$activity_type}".PHP_EOL; + } + } else { + echo "skipped {$activity_type}".PHP_EOL; + } + } + } + } + } + } + + protected static function item_indenter(cc_i_item &$item, $level = 0) { + $indent = (int)$level; + $indent = ($indent) <= 0 ? 0 : $indent; + $nprev = null; + $nfirst = null; + for ($pos = 0, $size = $indent; $pos < $size; $pos++) { + $nitem = new cc_item(); + $nitem->title = ''; + if (empty($nfirst)) { + $nfirst = $nitem; + } + if (!empty($nprev)) { + $nprev->add_child_item($nitem); + } + $nprev = $nitem; + } + $result = $item; + if (!empty($nfirst)) { + $item->add_child_item($nfirst); + $result = $nprev; + } + return $result; + } + +} \ No newline at end of file diff --git a/backup/cc/cc_lib/cc_converter_basiclti.php b/backup/cc/cc_lib/cc_converter_basiclti.php new file mode 100644 index 00000000000..49299c03768 --- /dev/null +++ b/backup/cc/cc_lib/cc_converter_basiclti.php @@ -0,0 +1,49 @@ +. +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once 'cc_converters.php'; +require_once 'cc_general.php'; +require_once 'cc_basiclti.php'; + +class cc_converter_basiclti extends cc_converter { + + public function __construct(cc_i_item &$item, cc_i_manifest &$manifest, $rootpath, $path){ + $this->cc_type = cc_version11::basiclti; + $this->defaultfile = 'basiclti.xml'; + $this->defaultname = basicltil1_resurce_file::deafultname; + parent::__construct($item, $manifest, $rootpath, $path); + } + + public function convert($outdir) { + $rt = new basicltil1_resurce_file(); + $title = $this->doc->nodeValue('/activity/basiclti/name'); + $rt->set_title($title); + $rt->set_launch_url($this->doc->nodeValue('/activity/basiclti/toolurl')); + $rt->set_launch_icon(''); + $rt->set_vendor_code($this->doc->nodeValue('/activity/basiclti/organizationid')); + $rt->set_vendor_description($this->doc->nodeValue('/activity/basiclti/organizationdescr')); + $rt->set_vendor_url($this->doc->nodeValue('/activity/basiclti/organizationurl')); + $this->store($rt, $outdir, $title); + return true; + } + +} diff --git a/backup/cc/cc_lib/cc_converter_forum.php b/backup/cc/cc_lib/cc_converter_forum.php new file mode 100644 index 00000000000..98337567b87 --- /dev/null +++ b/backup/cc/cc_lib/cc_converter_forum.php @@ -0,0 +1,61 @@ +. +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once 'cc_converters.php'; +require_once 'cc_general.php'; +require_once 'cc_forum.php'; + +class cc_converter_forum extends cc_converter { + + public function __construct(cc_i_item &$item, cc_i_manifest &$manifest, $rootpath, $path){ + $this->cc_type = cc_version11::discussiontopic; + $this->defaultfile = 'forum.xml'; + $this->defaultname = 'discussion.xml'; + parent::__construct($item, $manifest, $rootpath, $path); + } + + public function convert($outdir) { + $rt = new forum11_resurce_file(); + $title = $this->doc->nodeValue('/activity/forum/name'); + $rt->set_title($title); + $text = $this->doc->nodeValue('/activity/forum/intro'); + $deps = null; + if (!empty($text)) { + $textformat = intval($this->doc->nodeValue('/activity/forum/introformat')); + $contextid = $this->doc->nodeValue('/activity/@contextid'); + $result = cc_helpers::process_linked_files($text, + $this->manifest, + $this->rootpath, + $contextid, + $outdir); + + $textformat = ($textformat == 1) ? 'text/html' : 'text/plain'; + $rt->set_text($result[0], $textformat); + $deps = $result[1]; + } + + $this->store($rt, $outdir, $title, $deps); + return true; + } + +} + diff --git a/backup/cc/cc_lib/cc_converter_lti.php b/backup/cc/cc_lib/cc_converter_lti.php new file mode 100644 index 00000000000..1a2b681204e --- /dev/null +++ b/backup/cc/cc_lib/cc_converter_lti.php @@ -0,0 +1,46 @@ +. +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once 'cc_converters.php'; +require_once 'cc_general.php'; +require_once 'cc_basiclti.php'; + +class cc_converter_lti extends cc_converter { + + public function __construct(cc_i_item &$item, cc_i_manifest &$manifest, $rootpath, $path){ + $this->cc_type = cc_version11::basiclti; + $this->defaultfile = 'lti.xml'; + $this->defaultname = basicltil1_resurce_file::deafultname; + parent::__construct($item, $manifest, $rootpath, $path); + } + + public function convert($outdir) { + $rt = new basicltil1_resurce_file(); + $title = $this->doc->nodeValue('/activity/lti/name'); + $rt->set_title($title); + $rt->set_description($this->doc->nodeValue('/activity/lti/intro')); + $rt->set_launch_url($this->doc->nodeValue('/activity/lti/toolurl')); + $rt->set_launch_icon(''); + $this->store($rt, $outdir, $title); + return true; + } +} diff --git a/backup/cc/cc_lib/cc_converter_resource.php b/backup/cc/cc_lib/cc_converter_resource.php new file mode 100644 index 00000000000..6293c953b44 --- /dev/null +++ b/backup/cc/cc_lib/cc_converter_resource.php @@ -0,0 +1,59 @@ +. +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once 'cc_converters.php'; +require_once 'cc_general.php'; + +class cc_converter_resource extends cc_converter { + + public function __construct(cc_i_item &$item, cc_i_manifest &$manifest, $rootpath, $path){ + $this->cc_type = cc_version11::webcontent; + $this->defaultfile = 'resource.xml'; + parent::__construct($item, $manifest, $rootpath, $path); + } + + public function convert($outdir) { + $title = $this->doc->nodeValue('/activity/resource/name'); + $contextid = $this->doc->nodeValue('/activity/@contextid'); + $files = cc_helpers::handle_resource_content($this->manifest, + $this->rootpath, + $contextid, + $outdir); + $deps = null; + $resvalue = null; + foreach ($files as $vfile => $values) { + if ($values[2]) { + $resvalue = $values[0]; + break; + } + } + + $resitem = new cc_item(); + $resitem->identifierref = $resvalue; + $resitem->title = $title; + $this->item->add_child_item($resitem); + + return true; + } + +} + diff --git a/backup/cc/cc_lib/cc_converter_url.php b/backup/cc/cc_lib/cc_converter_url.php new file mode 100644 index 00000000000..53b1eab98ab --- /dev/null +++ b/backup/cc/cc_lib/cc_converter_url.php @@ -0,0 +1,62 @@ +. +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once 'cc_converters.php'; +require_once 'cc_general.php'; +require_once 'cc_weblink.php'; + +class cc_converter_url extends cc_converter { + + public function __construct(cc_i_item &$item, cc_i_manifest &$manifest, $rootpath, $path){ + $this->cc_type = cc_version11::weblink; + $this->defaultfile = 'url.xml'; + $this->defaultname = 'weblink.xml'; + parent::__construct($item, $manifest, $rootpath, $path); + } + + public function convert($outdir) { + $rt = new url11_resurce_file(); + $title = $this->doc->nodeValue('/activity/url/name'); + $rt->set_title($title); + $url = $this->doc->nodeValue('/activity/url/externalurl'); + if (!empty($url)) { + /** + * + * Display value choices + * 0 - automatic (system chooses what to do) (usualy defaults to the open) + * 1 - embed - display within a frame + * 5 - open - just open it full in the same frame + * 6 - in popup - popup - new frame + */ + $display = intval($this->doc->nodeValue('/activity/forum/display')); + $target = ($display == 6) ? '_blank' : '_self'; + //TODO: Moodle also supports custom parameters + //this should be transformed somehow into url where possible + $rt->set_url($url, $target); + } + + $this->store($rt, $outdir, $title); + return true; + } + +} + diff --git a/backup/cc/cc_lib/cc_converters.php b/backup/cc/cc_lib/cc_converters.php new file mode 100644 index 00000000000..d531964756c --- /dev/null +++ b/backup/cc/cc_lib/cc_converters.php @@ -0,0 +1,129 @@ +. +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once 'cc_interfaces.php'; + +abstract class cc_converter { + /** + * + * Enter description here ... + * @var cc_item + */ + protected $item = null; + /** + * + * Enter description here ... + * @var cc_manifest + */ + protected $manifest = null; + /** + * + * Enter description here ... + * @var string + */ + protected $rootpath = null; + /** + * + * Enter description here ... + * @var string + */ + protected $path = null; + /** + * + * Enter description here ... + * @var string + */ + protected $defaultfile = null; + /** + * + * Enter description here ... + * @var string + */ + protected $defaultname = null; + /** + * + * Enter description here ... + * @var string + */ + protected $cc_type = null; + /** + * + * Document + * @var XMLGenericDocument + */ + protected $doc = null; + + /** + * + * ctor + * @param cc_i_item $item + * @param cc_i_manifest $manifest + * @param string $rootpath + * @param string $path + * @throws InvalidArgumentException + */ + public function __construct(cc_i_item &$item, cc_i_manifest &$manifest, $rootpath, $path){ + $rpath = realpath($rootpath); + if (empty($rpath)) { + throw new InvalidArgumentException('Invalid path!'); + } + $rpath2 = realpath($path); + if (empty($rpath)) { + throw new InvalidArgumentException('Invalid path!'); + } + $doc = new XMLGenericDocument(); + if (!$doc->load($path . DIRECTORY_SEPARATOR . $this->defaultfile)) { + throw new RuntimeException('File does not exist!'); + } + + $this->doc = $doc; + $this->item = $item; + $this->manifest = $manifest; + $this->rootpath = $rpath; + $this->path = $rpath2; + } + + /** + * + * performs conversion + * @param string $outdir - root directory of common cartridge + * @return boolean + */ + abstract public function convert($outdir); + + /** + * + * Stores any files that need to be stored + */ + protected function store(general_cc_file $doc, $outdir, $title, $deps = null) { + $rdir = new cc_resource_location($outdir); + $rtp = $rdir->fullpath(true).$this->defaultname; + $doc->saveTo($rtp); + $resource = new cc_resource($rdir->rootdir(), $this->defaultname, $rdir->dirname(true)); + $resource->dependency = empty($deps) ? array() : $deps; + $res = $this->manifest->add_resource($resource, null, $this->cc_type); + $resitem = new cc_item(); + $resitem->attach_resource($res[0]); + $resitem->title = $title; + $this->item->add_child_item($resitem); + } +} diff --git a/backup/cc/cc_lib/cc_forum.php b/backup/cc/cc_lib/cc_forum.php new file mode 100644 index 00000000000..27ec08eefa4 --- /dev/null +++ b/backup/cc/cc_lib/cc_forum.php @@ -0,0 +1,93 @@ +. +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once 'cc_general.php'; + +class forum1_resurce_file extends general_cc_file { + const deafultname = 'discussion.xml'; + + protected $rootns = 'dt'; + protected $rootname = 'dt:topic'; + protected $ccnamespaces = array('dt' => 'http://www.imsglobal.org/xsd/imsdt_v1p0', + 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance'); + protected $ccnsnames = array('dt' => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/domainProfile_6/imsdt_v1p0_localised.xsd'); + + protected $title = null; + protected $text_type = 'text/plain'; + protected $text = null; + protected $attachments = array(); + + public function set_title($title) { + $this->title = $title; + } + + public function set_text($text, $type='text/plain') { + $this->text = $text; + $this->text_type = $type; + } + + public function set_attachments(array $attachments) { + $this->attachments = $attachments; + } + + protected function on_save() { + $this->append_new_element($this->root, 'title', $this->title); + $text = $this->append_new_element($this->root, 'text', $this->text); + $this->append_new_attribute($text, 'texttype', $this->text_type); + if (!empty($this->attachments)) { + $attachments = $this->append_new_element($this->root, 'attachments'); + foreach ($this->attachments as $value) { + $att = $this->append_new_element($attachments, 'attachment'); + $this->append_new_attribute($att, 'href', $value); + } + } + return true; + } + +} + +class forum11_resurce_file extends forum1_resurce_file { + protected $rootns = 'dt'; + protected $rootname = 'topic'; + protected $ccnamespaces = array('dt' => 'http://www.imsglobal.org/xsd/imsccv1p1/imsdt_v1p1', + 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance'); + protected $ccnsnames = array('dt' => 'http://www.imsglobal.org/profile/cc/ccv1p1/ccv1p1_imsdt_v1p1.xsd'); + + protected function on_save() { + $rns = $this->ccnamespaces[$this->rootns]; + $this->append_new_element_ns($this->root, $rns, 'title', $this->title); + $text = $this->append_new_element_ns($this->root, $rns, 'text', $this->text); + $this->append_new_attribute_ns($text, $rns, 'texttype', $this->text_type); + if (!empty($this->attachments)) { + $attachments = $this->append_new_element_ns($this->root, $rns, 'attachments'); + foreach ($this->attachments as $value) { + $att = $this->append_new_element_ns($attachments, $rns, 'attachment'); + $this->append_new_attribute_ns($att, $rns, 'href', $value); + } + } + return true; + } + +} + + + diff --git a/backup/cc/cc_lib/cc_general.php b/backup/cc/cc_lib/cc_general.php new file mode 100644 index 00000000000..23ffd434c52 --- /dev/null +++ b/backup/cc/cc_lib/cc_general.php @@ -0,0 +1,71 @@ +. +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once 'gral_lib/cssparser.php'; +require_once 'xmlbase.php'; + +class general_cc_file extends XMLGenericDocument { + /** + * + * Root element + * @var DOMElement + */ + protected $root = null; + protected $rootns = null; + protected $rootname = null; + protected $ccnamespaces = array(); + protected $ccnsnames = array(); + + public function __construct() { + parent::__construct(); + + foreach ($this->ccnamespaces as $key => $value){ + $this->registerNS($key,$value); + } + } + + + protected function on_create() { + $rootel = $this->append_new_element_ns($this->doc, + $this->ccnamespaces[$this->rootns], + $this->rootname); + //add all namespaces + foreach ($this->ccnamespaces as $key => $value) { + $dummy_attr = "{$key}:dummy"; + $this->doc->createAttributeNS($value,$dummy_attr); + } + + // add location of schemas + $schemaLocation=''; + foreach ($this->ccnsnames as $key => $value) { + $vt = empty($schemaLocation) ? '' : ' '; + $schemaLocation .= $vt.$this->ccnamespaces[$key].' '.$value; + } + $this->append_new_attribute_ns($rootel, + $this->ccnamespaces['xsi'], + 'xsi:schemaLocation', + $schemaLocation); + + $this->root = $rootel; + } + +} diff --git a/backup/cc/cc_lib/cc_interfaces.php b/backup/cc/cc_lib/cc_interfaces.php new file mode 100644 index 00000000000..81feabdafd3 --- /dev/null +++ b/backup/cc/cc_lib/cc_interfaces.php @@ -0,0 +1,116 @@ +. +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +/** + * CC Manifest Interface + */ +interface cc_i_manifest { + + public function on_create (); + public function on_load (); + public function on_save (); + public function add_new_organization (cc_i_organization &$org); + public function get_resources (); + public function get_resource_list (); + public function add_resource (cc_i_resource $res, $identifier=null, $type='webcontent'); + public function add_metadata_manifest(cc_i_metadata_manifest $met); + public function add_metadata_resource (cc_i_metadata_resource $met,$identifier); + public function add_metadata_file (cc_i_metadata_file $met,$identifier,$filename); + public function put_nodes (); + +} + + + +/** + * CC Organization Interface + */ +interface cc_i_organization { + + public function add_item (cc_i_item &$item); + public function has_items (); + public function attr_value (&$nod, $name, $ns=null); + public function process_organization (&$node,&$doc); + +} + + + +/** + * CC Item Interface + */ +interface cc_i_item { + + public function add_child_item (cc_i_item &$item); + public function attach_resource ($res); // can be object or value + public function has_child_items (); + public function attr_value (&$nod, $name, $ns=null); + public function process_item (&$node,&$doc); + +} + + +/** + * CC Resource Interface + */ +interface cc_i_resource { + + public function get_attr_value (&$nod, $name, $ns=null); + public function add_resource ($fname, $location=''); + public function import_resource (DOMElement &$node, cc_i_manifest &$doc); + public function process_resource ($manifestroot, &$fname,$folder); + +} + + + +/** + * CC Metadata Manifest Interface + */ +interface cc_i_metadata_manifest { + + public function add_metadata_general($obj); + public function add_metadata_technical($obj); + public function add_metadata_rights($obj); + public function add_metadata_lifecycle($obj); + +} + + +/** + * CC Metadata Resource Interface + */ +interface cc_i_metadata_resource { + + public function add_metadata_resource_educational($obj); + +} + +/** + * CC Metadata File Interface + */ +interface cc_i_metadata_file { + + public function add_metadata_file_educational($obj); + +} + diff --git a/backup/cc/cc_lib/cc_manifest.php b/backup/cc/cc_lib/cc_manifest.php new file mode 100644 index 00000000000..01dbb1f1bd8 --- /dev/null +++ b/backup/cc/cc_lib/cc_manifest.php @@ -0,0 +1,377 @@ +. +/** +* Manifest management +* +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + + +require_once 'cc_utils.php'; +require_once 'xmlbase.php'; +require_once 'cc_resources.php'; +require_once 'cc_version_base.php'; +require_once 'gral_lib/pathutils.php'; + + +/** + * Manifest Class + * + */ +class cc_manifest extends XMLGenericDocument implements cc_i_manifest { + private $ccversion = null; + private $ccobj = null; + private $rootmanifest = null; + private $activemanifest = null; + private $parentmanifest = null; + private $parentparentmanifest = null; + private $ares = array(); + private $mainidentifier = null; + + public function __construct($ccver = cc_version::v1,$activemanifest=null, + $parentmanifest=null,$parentparentmanifest=null) { + + if (is_int($ccver)){ + $this->ccversion=$ccver; + $classname = "cc_version{$ccver}"; + $this->ccobj = new $classname; + parent::__construct('UTF-8',true); + } else + if (is_object($ccver) && (get_class($ccver)=='cc_manifest')){ + $this->doc = $ccver->doc; + $this->rootmanifest = $ccver->rootmanifest; + $this->activemanifest = $activemanifest; + $this->parentmanifest = $parentmanifest; + $this->parentparentmanifest = $parentparentmanifest; + $this->ccversion = $ccver->ccversion; + $this->ccobj = $ccver; + $this->register_namespaces_for_xpath(); + } + } + + public function __destruct() { + parent::__destruct(); + } + + + /** + * Register Namespace for use XPATH + * + */ + public function register_namespaces_for_xpath(){ + $scnam = $this->activemanifest->get_cc_namespaces(); + foreach ($scnam as $key => $value){ + $this->registerNS($key,$value); + } + } + + /** + * TODO - implement this method - critical + * Enter description here ... + */ + private function fill_manifest() { + + } + + /** + * Add Metadata For Manifest + * + * @param cc_i_metadata_manifest $met + */ + public function add_metadata_manifest (cc_i_metadata_manifest $met){ + $metanode = $this->node("//imscc:manifest[@identifier='". + $this->activemanifest->manifestID(). + "']/imscc:metadata"); + $nmeta = $this->activemanifest->create_metadata_node($met,$this->doc,$metanode); + $metanode->appendChild($nmeta); + } + + + /** + * Add Metadata For Resource + * + * @param cc_i_metadata_resource $met + * @param string $identifier + */ + public function add_metadata_resource (cc_i_metadata_resource $met,$identifier){ + $metanode = $this->node("//imscc:resource". + "[@identifier='". + $identifier. + "']"); + $metanode2 = $this->node("//imscc:resource". + "[@identifier='". + $identifier. + "']/imscc:file"); + $dnode = $this->doc->createElementNS($this->ccnamespaces['imscc'], "metadata"); + + $metanode->insertBefore($dnode,$metanode2); + + $this->activemanifest->create_metadata_resource_node($met,$this->doc,$dnode); + } + + + /** + * Add Metadata For File + * + * @param cc_i_metadata_file $met + * @param string $identifier + * @param string $filename + */ + public function add_metadata_file (cc_i_metadata_file $met,$identifier,$filename){ + + if (empty($met) || empty($identifier) || empty($filename)){ + throw new Exception('Try to add a metadata file with nulls values given!'); + } + + $metanode = $this->node("//imscc:resource". + "[@identifier='". + $identifier. + "']/imscc:file". + "[@href='". + $filename. + "']"); + + $dnode = $this->doc->createElementNS($this->ccnamespaces['imscc'], "metadata"); + + $metanode->appendChild($dnode); + + $this->activemanifest->create_metadata_file_node($met,$this->doc,$dnode); + } + + + public function on_create (){ + $this->activemanifest = cc_builder_creator::factory($this->ccversion); + $this->rootmanifest = $this->activemanifest; + $result = $this->activemanifest->create_manifest($this->doc); + $this->register_namespaces_for_xpath(); + return $result; + + } + + + public function get_relative_base_path() {return $this->activemanifest->base();} + public function parent_manifest () {return new cc_manifest($this,$this->parentmanifest,$this->parentparentmanifest);} + public function root_manifest () {return new cc_manifest($this,$this->rootmanifest);} + public function manifestID () {return $this->activemanifest->manifestID();} + public function get_manifest_namespaces() {return $this->rootmanifest->get_cc_namespaces(); } + + + + /** + * Add a new organization + * + * @param cc_i_organization $org + */ + public function add_new_organization(cc_i_organization &$org) { + $norg = $this->activemanifest->create_organization_node($org,$this->doc); + $orgnode = $this->node("//imscc:manifest[@identifier='". + $this->activemanifest->manifestID(). + "']/imscc:organizations"); + $orgnode->appendChild($norg); + } + + + + public function get_resources($searchspecific='') { + $reslist = $this->get_resource_list($searchspecific); + $resourcelist = array(); + foreach ($reslist as $resourceitem) { + $resourcelist[]=new cc_resource($this, $resourceitem); + } + return $resourcelist; + } + + + + public function get_cc_namespace_path($nsname) { + if (is_string($nsname) && (!empty($nsname))){ + $scnam = $this->activemanifest->get_cc_namespaces(); + return $scnam[$nsname]; + } + return null; + } + + + public function get_resource_list($searchspecific=''){ + return $this->nodeList("//imscc:manifest[@identifier='". + $this->activemanifest->manifestID(). + "']/imscc:resources/imscc:resource".$searchspecific); + } + + + public function on_load (){ + $this->register_namespaces_for_xpath(); + $this->fill_manifest(); + return true; + } + + public function on_save (){ + return true; + } + + + /** + * Add a resource to the manifest + * + * @param cc_i_resource $res + * @param string $identifier + * @param string $type + * @return array + */ + public function add_resource (cc_i_resource $res, $identifier=null, $type='webcontent'){ + + if (!$this->ccobj->valid($type)){ + throw new Exception("Type invalid..."); + } + + if (is_null($res)){ + throw new Exception('Invalid Resource or dont give it'); + } + $rst = null; + + if (is_string($res)){ + $rst = new cc_resource($this->filePath(), $res); + if (is_string($identifier)){ + $rst->identifier = $identifier; + } + } else { + $rst = $res; + } + + //TODO: This has to be reviewed since it does not handle properly mutiple file + // dependencies + if (is_object($identifier)) { + $this->activemanifest->create_resource_node($rst,$this->doc,$identifier); + } else { + $nresnode = null; + + $rst->type = $type; + if (!cc_helpers::is_html($rst->filename)) { + $rst->href = null; + } + $this->activemanifest->create_resource_node($rst,$this->doc,$nresnode); + + + for ($i = 1 ; $i < count ($rst->files); $i++){ + $ident = $this->get_identifier_by_filename($rst->files[$i]); + if(empty($ident)){ + $newres = new cc_resource($rst->manifestroot,$rst->files[$i],false); + if (!empty($newres)) { + if (!cc_helpers::is_html($rst->files[$i])) { + $newres->href = null; + } + $newres->type = 'webcontent'; + $this->activemanifest->create_resource_node($newres,$this->doc,$nresnode); + } + } + + } + foreach ($this->activemanifest->resources as $k => $v){ + ($k); + $depen = $this->check_if_exist_in_other($v->files[0]); + if (!empty($depen)){ + $this->replace_file_x_dependency($depen,$v->files[0]); + // coloca aca como type = webcontent porque son archivos dependientes + // quizas aqui habria q ver de que type es el que vino y segun eso, ponerlo + // en associatedcontent o en webcontent + $v->type = 'webcontent'; + } + } + } + + $tmparray = array($rst->identifier,$rst->files[0]); + return $tmparray; + } + + + + private function check_if_exist_in_other($name){ + $status = array(); + foreach ($this->activemanifest->resources as $key => $value){ + ($key); + for ($i=1; $i< count($value->files); $i++){ + if ($name == $value->files[$i]){ + array_push($status,$value->identifier); + } + } + } + return $status; + } + + + private function replace_file_x_dependency($depen,$name){ + foreach ($depen as $key => $value){ + ($key); + $ident = $this->get_identifier_by_filename($name); + $this->activemanifest->resources[$value]->files = + $this->array_remove_by_value($this->activemanifest->resources[$value]->files,$name); + if (!in_array($ident,$this->activemanifest->resources[$value]->dependency)){ + array_push($this->activemanifest->resources[$value]->dependency,$ident); + } + + } + return true; + } + + + private function get_identifier_by_filename($name){ + $result = null; + foreach ($this->activemanifest->resources as $key => $value) { + if ($name == $value->files[0]){ + $result = $key; + break; + } + } + return $result; + } + + + + private function array_remove_by_value($arr,$value) { + return array_values(array_diff($arr,array($value))); + + } + + private function array_remove_by_key($arr,$key) { + return array_values(array_diff_key($arr,array($key))); + + } + + + /** + * Append the resources nodes in the Manifest + * + * @return DOMNode + */ + public function put_nodes (){ + + $resnodestr = "//imscc:manifest[@identifier='".$this->activemanifest->manifestID(). + "']/imscc:resources"; + $resnode = $this->node($resnodestr); + + foreach ($this->activemanifest->resources as $key => $node) { + ($key); + $resnode->appendChild($this->activemanifest->create_resource_node($node,$this->doc,null)); + } + return $resnode; + + } +} + + diff --git a/backup/cc/cc_lib/cc_metadata.php b/backup/cc/cc_lib/cc_metadata.php new file mode 100644 index 00000000000..6020b9055c3 --- /dev/null +++ b/backup/cc/cc_lib/cc_metadata.php @@ -0,0 +1,236 @@ +. + +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + + + + /** + Defined as specified in CC 1.1 + */ +class intended_user_role { + const LEARNER = 'Learner'; + const INSTRUCTOR = 'Instructor'; + const MENTOR = 'Mentor'; +} + +class technical_role { + const AUTHOR = 'author'; + const PUBLISHER = 'publisher'; + const UNKNOWN = 'unknown'; + const INITIATOR = 'initiator'; + const TERMINATOR = 'terminator'; + const VALIDATOR = 'validator'; + const EDITOR = 'editor'; + const GRAPHICAL_DESIGNER = 'graphical designer'; + const TECHNICAL_IMPLEMENTER = 'technical implementer'; + const CONTENT_PROVIDER = 'content provider'; + const TECHNICAL_VALIDATOR = 'technical validator'; + const EDUCATION_VALIDATOR = 'educational validator'; + const SCRIPT_WRITER = 'script writer'; + const INSTRUCTIONAL_DESIGNER= 'instructional designer'; + const SUBJET_MATTER_EXPERT = 'subject matter expert'; +} + + +class rights_copyright { + const YES = 'yes'; + const NO = 'no'; +} + + +class rights_cost { + const YES = 'yes'; + const NO = 'no'; +} + + +// Language identifier (as defined in ISO 639-1, ISO 639-2, and ISO 3166-1) +class language_lom { + const US_ENGLISH = 'en-US'; + const GB_ENGLISH = 'en-GB'; + const AR_SPANISH = 'es-AR'; + const GR_GREEK = 'el-GR'; + +} + + + +/** + * Metadata Manifest + * + */ +class cc_metadata_manifest implements cc_i_metadata_manifest { + + + public $arraygeneral = array(); + public $arraytech = array(); + public $arrayrights = array(); + public $arraylifecycle = array(); + + + public function add_metadata_general($obj){ + if (empty($obj)){ + throw new Exception('Medatada Object given is invalid or null!'); + } + !is_null($obj->title)? $this->arraygeneral['title']=$obj->title:null; + !is_null($obj->language)? $this->arraygeneral['language']=$obj->language:null; + !is_null($obj->description)? $this->arraygeneral['description']=$obj->description:null; + !is_null($obj->keyword)? $this->arraygeneral['keyword']=$obj->keyword:null; + !is_null($obj->coverage)? $this->arraygeneral['coverage']=$obj->coverage:null; + !is_null($obj->catalog)? $this->arraygeneral['catalog']=$obj->catalog:null; + !is_null($obj->entry)? $this->arraygeneral['entry']=$obj->entry:null; + } + + public function add_metadata_technical($obj){ + if (empty($obj)){ + throw new Exception('Medatada Object given is invalid or null!'); + } + !is_null($obj->format)? $this->arraytech['format']=$obj->format:null; + } + + + public function add_metadata_rights($obj){ + if (empty($obj)){ + throw new Exception('Medatada Object given is invalid or null!'); + } + !is_null($obj->copyright)? $this->arrayrights['copyrightAndOtherRestrictions']=$obj->copyright:null; + !is_null($obj->description)? $this->arrayrights['description']=$obj->description:null; + !is_null($obj->cost)? $this->arrayrights['cost']=$obj->cost:null; + + } + + + public function add_metadata_lifecycle($obj){ + if (empty($obj)){ + throw new Exception('Medatada Object given is invalid or null!'); + } + !is_null($obj->role)? $this->arraylifecycle['role']=$obj->role:null; + !is_null($obj->entity)? $this->arraylifecycle['entity']=$obj->entity:null; + !is_null($obj->date)? $this->arraylifecycle['date']=$obj->date:null; + + } + +} + + +/** + * Metadata Lifecycle Type + * + */ +class cc_metadata_lifecycle{ + + public $role = array(); + public $entity = array(); + public $date = array(); + + public function set_role($role){ + $this->role[] = array($role); + } + public function set_entity($entity){ + $this->entity[] = array($entity); + } + public function set_date($date){ + $this->date[] = array($date); + } + + +} + +/** + * Metadata Rights Type + * + */ +class cc_metadata_rights { + + public $copyright = array(); + public $description = array(); + public $cost = array(); + + public function set_copyright($copy){ + $this->copyright[] = array($copy); + } + public function set_description ($des,$language){ + $this->description[] = array($language,$des); + } + public function set_cost($cost){ + $this->cost[] = array($cost); + } + +} + + +/** + * Metadata Technical Type + * + */ +class cc_metadata_technical { + + public $format = array(); + + + public function set_format($format){ + $this->format[] = array($format); + } + +} + + +/** + * Metadata General Type + * + */ +class cc_metadata_general { + + public $title = array(); + public $language = array(); + public $description = array(); + public $keyword = array(); + public $coverage = array(); + public $catalog = array(); + public $entry = array(); + + + + public function set_coverage ($coverage,$language){ + $this->coverage[] = array($language,$coverage); + } + public function set_description ($description,$language){ + $this->description[] = array($language,$description); + } + public function set_keyword ($keyword,$language){ + $this->keyword[] = array($language,$keyword); + } + public function set_language ($language){ + $this->language[] = array($language); + } + public function set_title ($title,$language){ + $this->title[] = array($language,$title); + } + public function set_catalog ($cat){ + $this->catalog[] = array($cat); + } + public function set_entry ($entry){ + $this->entry[] = array($entry); + } + + +} \ No newline at end of file diff --git a/backup/cc/cc_lib/cc_metadata_file.php b/backup/cc/cc_lib/cc_metadata_file.php new file mode 100644 index 00000000000..525a32bb9ca --- /dev/null +++ b/backup/cc/cc_lib/cc_metadata_file.php @@ -0,0 +1,58 @@ +. + +/** +* Metadata management +* +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + + +/** + * Metadata File Education Type + * + */ +class cc_metadata_file_educational{ + + public $value = array(); + + public function set_value ($value){ + $arr = array($value); + $this->value[] = $arr; + } + +} + +/** + * Metadata File + * + */ +class cc_metadata_file implements cc_i_metadata_file { + + public $arrayeducational = array(); + + public function add_metadata_file_educational($obj){ + if (empty($obj)){ + throw new Exception('Medatada Object given is invalid or null!'); + } + !is_null($obj->value)? $this->arrayeducational['value']=$obj->value:null; + } + + +} \ No newline at end of file diff --git a/backup/cc/cc_lib/cc_metadata_resource.php b/backup/cc/cc_lib/cc_metadata_resource.php new file mode 100644 index 00000000000..b575beffef1 --- /dev/null +++ b/backup/cc/cc_lib/cc_metadata_resource.php @@ -0,0 +1,60 @@ +. + +/** +* Metadata managing +* +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + + + +/** + * Metadata Resource Educational Type + * + */ +class cc_metadata_resouce_educational{ + + public $value = array(); + + + public function set_value ($value){ + $arr = array($value); + $this->value[] = $arr; + } + +} + +/** + * Metadata Resource + * + */ +class cc_metadata_resouce implements cc_i_metadata_resource { + + public $arrayeducational = array(); + + public function add_metadata_resource_educational($obj){ + if (empty($obj)){ + throw new Exception('Medatada Object given is invalid or null!'); + } + !is_null($obj->value)? $this->arrayeducational['value']=$obj->value:null; + } + + +} \ No newline at end of file diff --git a/backup/cc/cc_lib/cc_organization.php b/backup/cc/cc_lib/cc_organization.php new file mode 100644 index 00000000000..3720f014184 --- /dev/null +++ b/backup/cc/cc_lib/cc_organization.php @@ -0,0 +1,278 @@ +. + +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once 'cc_utils.php'; +require_once 'cc_version_base.php'; +require_once 'cc_resources.php'; +require_once 'cc_manifest.php'; + + +/** + * Organization Class + * + */ + +class cc_organization implements cc_i_organization { + + + public $title = null; + public $identifier = null; + public $structure = null; + public $itemlist = null; + private $metadata = null; + private $sequencing = null; + + + + public function __construct($node=null, $doc=null) { + if (is_object($node) && is_object($doc)) { + $this->process_organization($node,$doc); + } else { + $this->init_new(); + } + } + + /** + * Add one Item into the Organization + * + * @param cc_i_item $item + */ + public function add_item(cc_i_item &$item) { + if (is_null($this->itemlist)) { + $this->itemlist = array(); + } + $this->itemlist[$item->identifier] = $item; + } + + /** + * Add new Item into the Organization + * + * @param string $title + * @return cc_i_item + */ + public function add_new_item($title='') { + $nitem = new cc_item(); + $nitem->title = $title; + $this->add_item($nitem); + return $nitem; + } + + + public function has_items() { + return is_array($this->itemlist) && (count($this->itemlist) > 0); + } + + public function attr_value(&$nod, $name, $ns=null) { + return is_null($ns) ? + ($nod->hasAttribute($name) ? $nod->getAttribute($name) : null) : + ($nod->hasAttributeNS($ns, $name) ? $nod->getAttributeNS($ns, $name) : null); + } + + + public function process_organization(&$node,&$doc) { + $this->identifier = $this->attr_value($node,"identifier"); + $this->structure = $this->attr_value($node,"structure"); + $this->title = ''; + $nlist = $node->getElementsByTagName('title'); + if (is_object($nlist) && ($nlist->length > 0) ) { + $this->title = $nlist->item(0)->nodeValue; + } + $nlist = $doc->nodeList("//imscc:organization[@identifier='".$this->identifier."']/imscc:item"); + $this->itemlist=array(); + foreach ($nlist as $item) { + $this->itemlist[$item->getAttribute("identifier")] = new cc_item($item,$doc); + } + $this->isempty=false; + } + + public function init_new() { + $this->title = null; + $this->identifier = cc_helpers::uuidgen('O_'); + $this->structure = 'rooted-hierarchy'; + $this->itemlist = null; + $this->metadata = null; + $this->sequencing = null; + + } + + public function uuidgen() { + $uuid = sprintf('%04x%04x', mt_rand(0, 65535), mt_rand(0, 65535)); + return strtoupper(trim($uuid)); + } + + +} + + +/** + * Item Class + * + */ +class cc_item implements cc_i_item { + + + public $identifier = null; + public $identifierref = null; + public $isvisible = null; + public $title = null; + public $parameters = null; + public $childitems = null; + private $parentItem = null; + private $isempty = true; + + + + public function __construct($node=null,$doc=null) { + if (is_object($node)) { + $clname = get_class($node); + if ($clname =='cc_resource') { + $this->init_new_item(); + $this->identifierref = $node->identifier; + $this->title = is_string($doc) && (!empty($doc)) ? $doc : 'item'; + } else if ($clname =='cc_manifest') { + $this->init_new_item(); + $this->identifierref = $node->manifestID(); + $this->title = is_string($doc) && (!empty($doc)) ? $doc : 'item'; + } else if ( is_object($doc)){ + $this->process_item($node,$doc); + } else { + $this->init_new_item(); + } + } else { + $this->init_new_item(); + } + } + + + + public function attr_value(&$nod, $name, $ns=null) { + return is_null($ns) ? + ($nod->hasAttribute($name) ? $nod->getAttribute($name) : null) : + ($nod->hasAttributeNS($ns, $name) ? $nod->getAttributeNS($ns, $name) : null); + } + + + public function process_item(&$node,&$doc) { + $this->identifier = $this->attr_value($node,"identifier"); + $this->structure = $this->attr_value($node,"structure"); + $this->identifierref = $this->attr_value($node,"identifierref"); + $atr = $this->attr_value($node,"isvisible"); + $this->isvisible = is_null($atr) ? true : $atr; + $nlist = $node->getElementsByTagName('title'); + if (is_object($nlist) && ($nlist->length > 0) ) { + $this->title = $nlist->item(0)->nodeValue; + } + $nlist = $doc->nodeList("//imscc:item[@identifier='".$this->identifier."']/imscc:item"); + if ($nlist->length > 0) { + $this->childitems=array(); + foreach ($nlist as $item) { + $key=$this->attr_value($item,"identifier"); + $this->childitems[$key] = new cc_item($item,$doc); + } + } + $this->isempty = false; + } + + /** + * Add one Child Item + * + * @param cc_i_item $item + */ + public function add_child_item(cc_i_item &$item) { + if (is_null($this->childitems)) { + $this->childitems = array(); + } + $this->childitems[$item->identifier] = $item; + } + + + /** + * Add new child Item + * + * @param string $title + * @return cc_i_item + */ + public function add_new_child_item($title='') { + $sc = new cc_item(); + $sc->title = $title; + $this->add_child_item($sc); + return $sc; + } + + + + public function attach_resource($resource) { + + if ($this->has_child_items()) { + throw new Exception("Can not attach resource to item that contains other items!"); + } + $resident = null; + if (is_string($resource)) { + $resident = $resource; + } else if (is_object($resource)) { + $clname = get_class($resource); + if ($clname == 'cc_resource') { + $resident = $resource->identifier; + } else + if ($clname == 'cc_manifest') { + $resident = $resource->manifestID(); + } else { + throw new Exception("Unable to attach resource. Invalid object."); + } + } + if (is_null($resident) || (empty($resident))) { + throw new Exception("Resource must have valid identifier!"); + } + $this->identifierref = $resident; + } + + public function has_child_items() { + return is_array($this->childitems) && (count($this->childitems) > 0); + } + + public function child_item($identifier) { + return $this->has_child_items() ? $this->childitems[$identifier] : null; + } + + + public function init_clean() { + $this->identifier = null; + $this->isvisible = null; + $this->title = null; + $this->parameters = null; + $this->childitems = null; + $this->parentItem = null; + $this->isempty = true; + } + + public function init_new_item() { + $this->identifier = cc_helpers::uuidgen('I_'); + $this->isvisible = true; //default is true + $this->title = null; + $this->parameters = null; + $this->childitems = null; + $this->parentItem = null; + $this->isempty = false; + } + +} \ No newline at end of file diff --git a/backup/cc/cc_lib/cc_resources.php b/backup/cc/cc_lib/cc_resources.php new file mode 100644 index 00000000000..43b9ac65d91 --- /dev/null +++ b/backup/cc/cc_lib/cc_resources.php @@ -0,0 +1,244 @@ +. + +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once 'cc_interfaces.php'; +require_once 'xmlbase.php'; +require_once 'gral_lib/pathutils.php'; +require_once 'gral_lib/ccdependencyparser.php'; +require_once 'cc_version_base.php'; +require_once 'cc_version1.php'; +require_once 'cc_manifest.php'; + +/** + * Common Cartridge Version + * + */ +class cc_version{ + const v1 = 1; + const v11 = 11; +} + + +class cc1_resource_type { + const webcontent = 'webcontent'; + const questionbank = 'imsqti_xmlv1p2/imscc_xmlv1p0/question-bank'; + const assessment = 'imsqti_xmlv1p2/imscc_xmlv1p0/assessment'; + const associatedcontent = 'associatedcontent/imscc_xmlv1p0/learning-application-resource'; + const discussiontopic = 'imsdt_xmlv1p0'; + const weblink = 'imswl_xmlv1p0'; + + public static $checker = array(self::webcontent, + self::assessment, + self::associatedcontent, + self::discussiontopic, + self::questionbank, + self::weblink); + +} + +class cc11_resource_type { + const webcontent = 'webcontent'; + const questionbank = 'imsqti_xmlv1p2/imscc_xmlv1p1/question-bank'; + const assessment = 'imsqti_xmlv1p2/imscc_xmlv1p1/assessment'; + const associatedcontent = 'associatedcontent/imscc_xmlv1p1/learning-application-resource'; + const discussiontopic = 'imsdt_xmlv1p1'; + const weblink = 'imswl_xmlv1p1'; + const basiclti = 'imsbasiclti_xmlv1p0'; + + public static $checker = array(self::webcontent, + self::assessment, + self::associatedcontent, + self::discussiontopic, + self::questionbank, + self::weblink, + self::basiclti); + +} + + +/** + * Resource Class + * + */ +class cc_resource implements cc_i_resource { + + public $identifier = null; + public $type = null; + public $dependency = array(); + public $identifierref = null; + public $href = null; + public $base = null; + public $persiststate = null; + public $filename = null; + public $files = array(); + public $isempty = null; + public $manifestroot = null; + public $folder = null; + + private $throwonerror = true; + + public function __construct($manifest, $file, $folder='', $throwonerror = true) { + $this->throwonerror = $throwonerror; + if (is_string($manifest)) { + $this->folder = $folder; + $this->process_resource($manifest, $file,$folder); + $this->manifestroot = $manifest; + } else if (is_object($manifest)) { + $this->import_resource($file,$manifest.$folder); + } + } + + /** + * Add resource + * + * @param string $fname + * @param string $location + */ + public function add_resource ($fname, $location =''){ + $this->process_resource($fname,$location); + + } + + + /** + * Import a resource + * + * @param DOMElement $node + * @param cc_i_manifest $doc + */ + public function import_resource(DOMElement &$node, cc_i_manifest &$doc) { + + $searchstr = "//imscc:manifest[@identifier='".$doc->manifestID(). + "']/imscc:resources/imscc:resource"; + $this->identifier = $this->get_attr_value($node,"identifier"); + $this->type = $this->get_attr_value($node,"type"); + $this->href = $this->get_attr_value($node,"href"); + $this->base = $this->get_attr_value($node,"base"); + $this->persiststate = null; + $nodo = $doc->nodeList($searchstr."[@identifier='". + $this->identifier."']/metadata/@href"); + $this->metadata = $nodo->nodeValue; + $this->filename = $this->href; + $nlist = $doc->nodeList($searchstr."[@identifier='". + $this->identifier."']/imscc:file/@href"); + $this->files = array(); + foreach ($nlist as $file) { + $this->files[] = $file->nodeValue; + } + $nlist = $doc->nodeList($searchstr."[@identifier='". + $this->identifier."']/imscc:dependency/@identifierref"); + $this->dependency = array(); + foreach ($nlist as $dependency) { + $this->dependency[] = $dependency->nodeValue; + } + $this->isempty = false; + } + + + /** + * Get a attribute value + * + * @param DOMElement $nod + * @param string $name + * @param string $ns + * @return string + */ + public function get_attr_value(&$nod, $name, $ns=null) { + return is_null($ns) ? + ($nod->hasAttribute($name) ? $nod->getAttribute($name) : null) : + ($nod->hasAttributeNS($ns, $name) ? $nod->getAttributeNS($ns, $name) : null); + } + + + /** + * Process a resource + * + * @param string $manifestroot + * @param string $fname + * @param string $folder + */ + public function process_resource($manifestroot, &$fname, $folder) { + $file = empty($folder) ? $manifestroot.'/'.$fname : $manifestroot.'/'.$folder.'/'.$fname; + if (!file_exists($file) && $this->throwonerror){ + throw new Exception('The file doesnt exist!'); + } + + //TODO: ver el tema de fpatch con el tema de unix y windows + //$fpathtocheck = $this->adjust_path($manifestroot,$fname); + //!empty($fpathtocheck) && + if (GetDepFiles($manifestroot, $fname, $this->folder, $this->files)) { + array_unshift($this->files,$folder.$fname); + $this->init_empty_new(); + $this->href = $folder.$fname; + $this->identifierref = $folder.$fname; + $this->filename = $fname; + $this->isempty = false; + $this->folder = $folder; + } else { + $this->init_clean(); + } + } + + public function adjust_path($mroot, $fname) { + $result = null; + if (file_exists($fname->filename)) { + $result = pathDiff($fname->filename,$mroot); + + } else if (file_exists($mroot.$fname->filename) || file_exists($mroot.DIRECTORY_SEPARATOR.$fname->filename)) { + $result = trim(toUrlPath($fname->filename),"/"); + } + return $result; + } + + + + public function init_clean() { + $this->identifier = null; + $this->type = null; + $this->href = null; + $this->base = null; + $this->metadata = array(); + $this->dependency = array(); + $this->identifierref = null; + $this->persiststate = null; + $this->filename = ''; + $this->files = array(); + $this->isempty = true; + } + + + public function init_empty_new() { + $this->identifier = cc_helpers::uuidgen('I_', '_R'); + $this->type = null; + $this->href = null; + $this->persiststate = null; + $this->filename = null; + $this->isempty = false; + $this->identifierref = null; + } + + public function get_manifestroot(){ + return $this->manifestroot; + } + +} \ No newline at end of file diff --git a/backup/cc/cc_lib/cc_utils.php b/backup/cc/cc_lib/cc_utils.php new file mode 100644 index 00000000000..40fda062cbc --- /dev/null +++ b/backup/cc/cc_lib/cc_utils.php @@ -0,0 +1,383 @@ +. + +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once 'xmlbase.php'; + +/** + * + * Various helper utils + * @author Darko Miletic dmiletic@moodlerooms.com + * + */ +abstract class cc_helpers { + + /** + * + * Checks extension of the supplied filename + * @param string $filename + */ + public static function is_html($filename) { + $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); + return in_array($extension, array('htm', 'html')); + } + + /** + * + * Generates unique identifier + * @param string $prefix + * @param string $suffix + * @return string + */ + public static function uuidgen($prefix = '', $suffix = '', $uppercase = true) { + $uuid = trim(sprintf('%s%04x%04x%s', $prefix, mt_rand(0, 65535), mt_rand(0, 65535), $suffix)); + $result = $uppercase ? strtoupper($uuid) : strtolower($uuid) ; + return $result; + } + + /** + * + * Creates new folder with random name + * @param string $where + * @param string $prefix + * @param string $suffix + * @return mixed - directory short name or false in case of faliure + */ + public static function randomdir($where, $prefix = '', $suffix = '') { + $dirname = false; + $randomname = self::uuidgen($prefix, $suffix, false); + $newdirname = $where.DIRECTORY_SEPARATOR.$randomname; + if (mkdir($newdirname)) { + chmod($newdirname, 0755); + $dirname = $randomname; + } + return $dirname; + } + + /** + * + * Get list of embedded files + * @param string $html + * @return multitype:mixed + */ + public static function embedded_files($html) { + $result = array(); + $doc = new XMLGenericDocument(); + if ($doc->loadHTML($html)) { + $list = $doc->nodeList("//img[starts-with(@src,'@@PLUGINFILE@@')]/@src"); + foreach ($list as $filelink) { + $result[] = str_replace('@@PLUGINFILE@@', '', $filelink->nodeValue); + } + } + return $result; + } + + public static function embedded_mapping($packageroot, $contextid = null) { + $main_file = $packageroot . DIRECTORY_SEPARATOR . 'files.xml'; + $mfile = new XMLGenericDocument(); + if (!$mfile->load($main_file)) { + return false; + } + $query = "/files/file[filename!='.']"; + if (!empty($contextid)) { + $query .= "[contextid='{$contextid}']"; + } + $files = $mfile->nodeList($query); + $depfiles = array(); + foreach ($files as $node) { + $mainfile = intval($mfile->nodeValue('sortorder', $node)); + $filename = $mfile->nodeValue('filename', $node); + $filepath = $mfile->nodeValue('filepath', $node); + $source = $mfile->nodeValue('source', $node); + $author = $mfile->nodeValue('author', $node); + $license = $mfile->nodeValue('license', $node); + $hashedname = $mfile->nodeValue('contenthash', $node); + $hashpart = substr($hashedname, 0, 2); + $location = 'files'.DIRECTORY_SEPARATOR.$hashpart.DIRECTORY_SEPARATOR.$hashedname; + $type = $mfile->nodeValue('mimetype', $node); + $depfiles[$filepath.$filename] = array( $location, + ($mainfile == 1), + strtolower(str_replace(' ', '_',$filename)), + $type, + $source, + $author, + $license, + strtolower(str_replace(' ', '_',$filepath))); + } + + return $depfiles; + } + + public static function add_files(cc_i_manifest &$manifest, $packageroot, $outdir, $allinone = true) { + if (pkg_static_resources::instance()->finished) { + return; + } + $files = cc_helpers::embedded_mapping($packageroot); + $rdir = $allinone ? new cc_resource_location($outdir) : null; + foreach ($files as $virtual => $values) { + $clean_filename = $values[2]; + if (!$allinone) { + $rdir = new cc_resource_location($outdir); + } + $rtp = $rdir->fullpath(true).$clean_filename; + //Are there any relative virtual directories? + //let us try to recreate them + $justdir = $rdir->fullpath(true).$values[7]; + if (!file_exists($justdir)) { + if (!mkdir($justdir, 0777, true)) { + throw new RuntimeException('Unable to create directories!'); + } + } + + $source = $packageroot.DIRECTORY_SEPARATOR.$values[0]; + if (!copy($source, $rtp)) { + throw new RuntimeException('Unable to copy files!'); + } + $resource = new cc_resource($rdir->rootdir(), $clean_filename, $rdir->dirname(true)); + $res = $manifest->add_resource($resource, null, cc_version11::webcontent); + pkg_static_resources::instance()->add($virtual, $res[0], $rdir->dirname(true).$clean_filename, $values[1], $resource); + } + + pkg_static_resources::instance()->finished = true; + } + + /** + * + * Excerpt from IMS CC 1.1 overview : + * No spaces in filenames, directory and file references should + * employ all lowercase or all uppercase - no mixed case + * + * @param cc_i_manifest $manifest + * @param string $packageroot + * @param integer $contextid + * @param string $outdir + * @param boolean $allinone + * @throws RuntimeException + */ + public static function handle_static_content(cc_i_manifest &$manifest, $packageroot, $contextid, $outdir, $allinone = true){ + cc_helpers::add_files($manifest, $packageroot, $outdir, $allinone); + return pkg_static_resources::instance()->get_values(); + } + + public static function handle_resource_content(cc_i_manifest &$manifest, $packageroot, $contextid, $outdir, $allinone = true){ + $result = array(); + cc_helpers::add_files($manifest, $packageroot, $outdir, $allinone); + $files = cc_helpers::embedded_mapping($packageroot, $contextid); + //$rdir = $allinone ? new cc_resource_location($outdir) : null; + $rootnode = null; + $rootvals = null; + $depfiles = array(); + $depres = array(); + $flocation = null; + foreach ($files as $virtual => $values) { + $clean_filename = $values[2]; + $vals = pkg_static_resources::instance()->get_identifier($virtual); + $resource = $vals[3]; + $identifier = $resource->identifier; + $flocation = $vals[1]; + if ($values[1]) { + $rootnode = $resource; + $rootvals = $flocation; + continue; + } + + $depres[] = $identifier; + $depfiles[] = $vals[1]; + $result[$virtual] = array($identifier, $flocation, false); + } + + if (!empty($rootnode)) { + $rootnode->files = array_merge($rootnode->files, $depfiles); + $result[$virtual] = array($rootnode->identifier, $rootvals, true); + } + + return $result; + } + + public static function process_linked_files($content, cc_i_manifest &$manifest, $packageroot, $contextid, $outdir) { + /** + - detect all embedded files + - locate their physical counterparts in moodle 2 backup + - copy all files in the cc package stripping any spaces and using inly lowercase letters + - add those files as resources of the type webcontent to the manifest + - replace the links to the resourcse using $IMS-CC-FILEBASE$ and their new locations + - cc_resource has array of files and array of dependencies + - most likely we would need to add all files as independent resources and than + attach them all as dependencies to the forum tag + */ + $lfiles = self::embedded_files($content); + $text = $content; + $deps = null; + if (!empty($lfiles)) { + $files = self::handle_static_content($manifest, + $packageroot, + $contextid, + $outdir); + foreach ($lfiles as $lfile) { + if (array_key_exists($lfile, $files)) { + $text = str_replace('@@PLUGINFILE@@'.$lfile, + '$IMS-CC-FILEBASE$../'.$files[$lfile][1], + $text); + $deps[] = $files[$lfile][0]; + } + } + } + return array($text, $deps); + } + + public static function relative_location($originpath, $linkingpath) { + return false; + } + +} + + +final class cc_resource_location { + /** + * + * Root directory + * @var string + */ + private $rootdir = null; + /** + * + * new directory + * @var string + */ + private $dir = null; + /** + * + * Full precalculated path + * @var string + */ + private $fullpath = null; + + /** + * + * ctor + * @param string $rootdir - path to the containing directory + * @throws InvalidArgumentException + * @throws RuntimeException + */ + public function __construct($rootdir) { + $rdir = realpath($rootdir); + if (empty($rdir)) { + throw new InvalidArgumentException('Invalid path!'); + } + $dir = cc_helpers::randomdir($rdir, 'i_'); + if ($dir === false) { + throw new RuntimeException('Unable to create directory!'); + } + $this->rootdir = $rdir; + $this->dir = $dir; + $this->fullpath = $rdir.DIRECTORY_SEPARATOR.$dir; + } + + /** + * + * Newly created directory + * @return string + */ + public function dirname($endseparator=false) { + return $this->dir.($endseparator ? '/' : ''); + } + + /** + * + * Full path to the new directory + * @return string + */ + public function fullpath($endseparator=false) { + return $this->fullpath.($endseparator ? DIRECTORY_SEPARATOR : ''); + } + + /** + * Returns containing dir + * @return string + */ + public function rootdir($endseparator=false) { + return $this->rootdir.($endseparator ? DIRECTORY_SEPARATOR : ''); + } +} + +class pkg_static_resources { + + /** + * @var array + */ + private $values = array(); + + /** + * @var boolean + */ + public $finished = false; + + /** + * @var pkg_static_resources + */ + private static $instance = null; + + private function __clone() {} + private function __construct() {} + + /** + * @return pkg_static_resources + */ + public static function instance() { + if (empty(self::$instance)) { + $c = __CLASS__; + self::$instance = new $c(); + } + return self::$instance; + } + + /** + * + * add new element + * @param string $identifier + * @param string $file + * @param boolean $main + */ + public function add($key, $identifier, $file, $main, $node = null) { + $this->values[$key] = array($identifier, $file, $main, $node); + } + + /** + * @return array + */ + public function get_values() { + return $this->values; + } + + public function get_identifier($location) { + $result = false; + if (array_key_exists($location, $this->values)) { + $result = $this->values[$location]; + } + return $result; + } + + public function reset() { + $this->values = array(); + $this->finished = false ; + } +} diff --git a/backup/cc/cc_lib/cc_version1.php b/backup/cc/cc_lib/cc_version1.php new file mode 100644 index 00000000000..30f382a8479 --- /dev/null +++ b/backup/cc/cc_lib/cc_version1.php @@ -0,0 +1,566 @@ +. + +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once 'cc_utils.php'; +require_once 'cc_version_base.php'; +require_once 'cc_organization.php'; + + +/** + * Version 1 class of Common Cartridge + * + */ +class cc_version1 extends cc_version_base { + const webcontent = 'webcontent'; + const questionbank = 'imsqti_xmlv1p2/imscc_xmlv1p0/question-bank'; + const assessment = 'imsqti_xmlv1p2/imscc_xmlv1p0/assessment'; + const associatedcontent = 'associatedcontent/imscc_xmlv1p0/learning-application-resource'; + const discussiontopic = 'imsdt_xmlv1p0'; + const weblink = 'imswl_xmlv1p0'; + + public static $checker = array(self::webcontent, + self::assessment, + self::associatedcontent, + self::discussiontopic, + self::questionbank, + self::weblink); + + /** + * Validate if the type are valid or not + * + * @param string $type + * @return bool + */ + public function valid($type) { + return in_array($type, self::$checker); + } + + public function __construct() { + $this->ccnamespaces = array('imscc' => 'http://www.imsglobal.org/xsd/imscc/imscp_v1p1', + 'lomimscc' => 'http://ltsc.ieee.org/xsd/imscc/LOM', + 'lom' => 'http://ltsc.ieee.org/xsd/LOM', + 'voc' => 'http://ltsc.ieee.org/xsd/LOM/vocab', + 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance' + ); + + $this->ccnsnames = array('imscc' => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/imscp_v1p2_localised.xsd' , + 'lom' => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/domainProfile_2/lomLoose_localised.xsd' , + 'lomimscc' => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/domainProfile_1/lomLoose_localised.xsd', + 'voc' => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/domainProfile_2/vocab/loose.xsd' + ); + + $this->ccversion = '1.0.0'; + $this->camversion = '1.0.0'; + $this->_generator = 'Moodle 2 Common Cartridge generator'; + } + + protected function on_create(DOMDocument &$doc, $rootmanifestnode=null,$nmanifestID=null) { + $doc->formatOutput = true; + $doc->preserveWhiteSpace = true; + + + $this->manifestID = is_null($nmanifestID) ? cc_helpers::uuidgen('M_') : $nmanifestID; + $mUUID = $doc->createAttribute('identifier'); + $mUUID->nodeValue = $this->manifestID; + + + if (is_null($rootmanifestnode)) { + if (!empty($this->_generator)) { + $comment = $doc->createComment($this->_generator); + $doc->appendChild($comment); + } + + $rootel = $doc->createElementNS($this->ccnamespaces['imscc'],'manifest'); + $rootel->appendChild($mUUID); + $doc->appendChild($rootel); + + //add all namespaces + foreach ($this->ccnamespaces as $key => $value) { + if ($key != 'lom' ){ + $dummy_attr = $key.":dummy"; + $doc->createAttributeNS($value,$dummy_attr); + } + } + + // add location of schemas + $schemaLocation=''; + foreach ($this->ccnsnames as $key => $value) { + $vt = empty($schemaLocation) ? '' : ' '; + $schemaLocation .= $vt.$this->ccnamespaces[$key].' '.$value; + } + $aSchemaLoc = $doc->createAttributeNS($this->ccnamespaces['xsi'],'xsi:schemaLocation'); + $aSchemaLoc->nodeValue=$schemaLocation; + $rootel->appendChild($aSchemaLoc); + + } else { + $rootel = $doc->createElementNS($this->ccnamespaces['imscc'],'imscc:manifest'); + $rootel->appendChild($mUUID); + } + + $metadata = $doc->createElementNS($this->ccnamespaces['imscc'],'metadata'); + $schema = $doc->createElementNS($this->ccnamespaces['imscc'],'schema','IMS Common Cartridge'); + $schemaversion = $doc->createElementNS($this->ccnamespaces['imscc'],'schemaversion',$this->ccversion); + + $metadata->appendChild($schema); + $metadata->appendChild($schemaversion); + $rootel->appendChild($metadata); + + if (!is_null($rootmanifestnode)) { + $rootmanifestnode->appendChild($rootel); + } + + $organizations = $doc->createElementNS($this->ccnamespaces['imscc'],'organizations'); + $rootel->appendChild($organizations); + $resources = $doc->createElementNS($this->ccnamespaces['imscc'],'resources'); + $rootel->appendChild($resources); + + return true; + } + + + protected function update_attribute(DOMDocument &$doc, $attrname, $attrvalue, DOMElement &$node) { + $busenew = (is_object($node) && $node->hasAttribute($attrname)); + $nResult = null; + if (!$busenew && is_null($attrvalue)) { + $node->removeAttribute($attrname); + } else { + $nResult = $busenew ? $node->getAttributeNode($attrname) : $doc->createAttribute($attrname); + $nResult->nodeValue = $attrvalue; + if (!$busenew) { + $node->appendChild($nResult); + } + } + return $nResult; + } + + + protected function update_attribute_ns(DOMDocument &$doc, $attrname, $attrnamespace,$attrvalue, DOMElement &$node) { + $busenew = (is_object($node) && $node->hasAttributeNS($attrnamespace, $attrname)); + $nResult = null; + if (!$busenew && is_null($attrvalue)) { + $node->removeAttributeNS($attrnamespace, $attrname); + } else { + $nResult = $busenew ? $node->getAttributeNodeNS($attrnamespace, $attrname) : $doc->createAttributeNS($attrnamespace, $attrname); + $nResult->nodeValue = $attrvalue; + if (!$busenew) { + $node->appendChild($nResult); + } + } + return $nResult; + } + + + protected function get_child_node(DOMDocument &$doc, $itemname, DOMElement &$node) { + $nlist = $node->getElementsByTagName($itemname); + $item = is_object($nlist) && ($nlist->length > 0) ? $nlist->item(0) : null; + return $item; + } + + + protected function update_child_item(DOMDocument &$doc, $itemname, $itemvalue, DOMElement &$node, $attrtostore=null) { + $tnode = $this->get_child_node($doc,'title',$node); + $usenew = is_null($tnode); + $tnode = $usenew ? $doc->createElementNS($this->ccnamespaces['imscc'], $itemname) : $tnode; + if (!is_null($attrtostore)) { + foreach ($attrtostore as $key => $value) { + $this->update_attribute($doc,$key,$value,$tnode); + } + } + $tnode->nodeValue = $itemvalue; + if ($usenew) { + $node->appendChild($tnode); + } + } + + + protected function update_items($items, DOMDocument &$doc, DOMElement &$xmlnode) { + foreach ($items as $key => $item) { + $itemnode = $doc->createElementNS($this->ccnamespaces['imscc'], 'item'); + $this->update_attribute($doc, 'identifier' , $key , $itemnode); + $this->update_attribute($doc, 'identifierref', $item->identifierref, $itemnode); + $this->update_attribute($doc, 'parameters' , $item->parameters , $itemnode); + if (!empty($item->title)) { + $titlenode = $doc->createElementNS($this->ccnamespaces['imscc'], + 'title', + $item->title); + $itemnode->appendChild($titlenode); + } + if ($item->has_child_items()) { + $this->update_items($item->childitems, $doc, $itemnode); + } + $xmlnode->appendChild($itemnode); + } + } + + + /** + * Create a Resource (How to) + * + * @param cc_i_resource $res + * @param DOMDocument $doc + * @param object $xmlnode + * @return DOMNode + */ + protected function create_resource(cc_i_resource &$res, DOMDocument &$doc, $xmlnode=null) { + $usenew = is_object($xmlnode); + $dnode = $usenew ? $xmlnode : $doc->createElementNS($this->ccnamespaces['imscc'], "resource"); + $this->update_attribute($doc,'identifier',$res->identifier,$dnode); + $this->update_attribute($doc,'type' ,$res->type ,$dnode); + !is_null($res->href) ? $this->update_attribute($doc,'href',$res->href,$dnode): null; + $this->update_attribute($doc,'base' ,$res->base ,$dnode); + + foreach ($res->files as $file) { + $nd = $doc->createElementNS($this->ccnamespaces['imscc'],'file'); + $ndatt = $doc->createAttribute('href'); + $ndatt->nodeValue = $file; + $nd->appendChild($ndatt); + $dnode->appendChild($nd); + } + $this->resources[$res->identifier] = $res; + + foreach ($res->dependency as $dependency){ + $nd = $doc->createElementNS($this->ccnamespaces['imscc'],'dependency'); + $ndatt = $doc->createAttribute('identifierref'); + $ndatt->nodeValue = $dependency; + $nd->appendChild($ndatt); + $dnode->appendChild($nd); + } + + return $dnode; + } + + + + /** + * Create an Item Folder (How To) + * + * @param cc_i_organization $org + * @param DOMDocument $doc + * @param DOMElement $xmlnode + */ + protected function create_item_folder (cc_i_organization &$org, DOMDocument &$doc, DOMElement &$xmlnode=null){ + + $itemfoldernode = $doc->createElementNS($this->ccnamespaces['imscc'],'item'); + $this->update_attribute($doc,'identifier', "root", $itemfoldernode); + + if ($org->has_items()) { + $this->update_items($org->itemlist, $doc, $itemfoldernode); + } + if (is_null($this->organizations)) { + $this->organizations = array(); + } + $this->organizations[$org->identifier] = $org; + + $xmlnode->appendChild($itemfoldernode); + } + + + + + /** + * Create an Organization (How To) + * + * @param cc_i_organization $org + * @param DOMDocument $doc + * @param object $xmlnode + * @return DOMNode + */ + protected function create_organization (cc_i_organization &$org, DOMDocument &$doc, $xmlnode=null){ + + $usenew = is_object($xmlnode); + $dnode = $usenew ? $xmlnode : $doc->createElementNS($this->ccnamespaces['imscc'], "organization"); + $this->update_attribute($doc,'identifier' ,$org->identifier,$dnode); + $this->update_attribute($doc,'structure' ,$org->structure ,$dnode); + + $this->create_item_folder($org,$doc,$dnode); + + return $dnode; + } + + + + + /** + * Create Metadata For Manifest (How To) + * + * @param cc_i_metadata_manifest $met + * @param DOMDocument $doc + * @param object $xmlnode + * @return DOMNode + */ + protected function create_metadata_manifest (cc_i_metadata_manifest $met,DOMDocument &$doc,$xmlnode=null) { + + $dnode = $doc->createElementNS($this->ccnamespaces['lomimscc'], "lom"); + if (!empty($xmlnode)) { + $xmlnode->appendChild($dnode); + } + $dnodegeneral = empty($met->arraygeneral ) ? null : $this->create_metadata_general ($met, $doc, $xmlnode); + $dnodetechnical = empty($met->arraytech ) ? null : $this->create_metadata_technical($met, $doc, $xmlnode); + $dnoderights = empty($met->arrayrights ) ? null : $this->create_metadata_rights ($met, $doc, $xmlnode); + $dnodelifecycle = empty($met->arraylifecycle) ? null : $this->create_metadata_lifecycle($met, $doc, $xmlnode); + + !is_null($dnodegeneral)?$dnode->appendChild($dnodegeneral):null; + !is_null($dnodetechnical)?$dnode->appendChild($dnodetechnical):null; + !is_null($dnoderights)?$dnode->appendChild($dnoderights):null; + !is_null($dnodelifecycle)?$dnode->appendChild($dnodelifecycle):null; + + return $dnode; + + } + + + + /** + * Create Metadata For Resource (How To) + * + * @param cc_i_metadata_resource $met + * @param DOMDocument $doc + * @param object $xmlnode + * @return DOMNode + */ + protected function create_metadata_resource (cc_i_metadata_resource $met,DOMDocument &$doc,$xmlnode=null) { + + $dnode = $doc->createElementNS($this->ccnamespaces['lom'], "lom"); + + !empty($xmlnode)? $xmlnode->appendChild($dnode):null; + !empty($met->arrayeducational) ? $this->create_metadata_educational($met,$doc,$dnode):null; + + return $dnode; + } + + + + + /** + * Create Metadata For File (How To) + * + * @param cc_i_metadata_file $met + * @param DOMDocument $doc + * @param Object $xmlnode + * @return DOMNode + */ + protected function create_metadata_file (cc_i_metadata_file $met,DOMDocument &$doc,$xmlnode=null) { + + $dnode = $doc->createElementNS($this->ccnamespaces['lom'], "lom"); + + !empty($xmlnode)? $xmlnode->appendChild($dnode):null; + !empty($met->arrayeducational) ? $this->create_metadata_educational($met,$doc,$dnode):null; + + return $dnode; + } + + + + + /** + * Create General Metadata (How To) + * + * @param object $met + * @param DOMDocument $doc + * @param object $xmlnode + * @return DOMNode + */ + protected function create_metadata_general($met,DOMDocument &$doc,$xmlnode){ + ($xmlnode); + $nd = $doc->createElementNS($this->ccnamespaces['lomimscc'],'general'); + + foreach ($met->arraygeneral as $name => $value) { + !is_array($value)?$value =array($value):null; + foreach ($value as $k => $v){ + ($k); + if ($name != 'language' && $name != 'catalog' && $name != 'entry'){ + $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'],$name); + $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'],'string',$v[1]); + $ndatt = $doc->createAttribute('language'); + $ndatt->nodeValue = $v[0]; + $nd3->appendChild($ndatt); + $nd2->appendChild($nd3); + $nd->appendChild($nd2); + }else{ + if ($name == 'language'){ + $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'],$name,$v[0]); + $nd->appendChild($nd2); + } + } + } + } + if (!empty($met->arraygeneral['catalog']) || !empty($met->arraygeneral['entry'])){ + $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'],'identifier'); + $nd->appendChild($nd2); + if (!empty($met->arraygeneral['catalog'])){ + $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'],'catalog',$met->arraygeneral['catalog'][0][0]); + $nd2->appendChild($nd3); + } + if (!empty($met->arraygeneral['entry'])){ + $nd4 = $doc->createElementNS($this->ccnamespaces['lomimscc'],'entry',$met->arraygeneral['entry'][0][0]); + $nd2->appendChild($nd4); + } + } + return $nd; + } + + + + + /** + * Create Technical Metadata (How To) + * + * @param object $met + * @param DOMDocument $doc + * @param object $xmlnode + * @return DOMNode + */ + protected function create_metadata_technical($met,DOMDocument &$doc,$xmlnode){ + ($xmlnode); + $nd = $doc->createElementNS($this->ccnamespaces['lomimscc'],'technical'); + $xmlnode->appendChild($nd); + + foreach ($met->arraytech as $name => $value) { + ($name); + !is_array($value)?$value =array($value):null; + foreach ($value as $k => $v){ + ($k); + $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'],$name,$v[0]); + $nd->appendChild($nd2); + } + } + return $nd; + } + + + + + /** + * Create Rights Metadata (How To) + * + * @param object $met + * @param DOMDocument $doc + * @param object $xmlnode + * @return DOMNode + */ + protected function create_metadata_rights($met,DOMDocument &$doc,$xmlnode){ + ($xmlnode); + + $nd = $doc->createElementNS($this->ccnamespaces['lomimscc'],'rights'); + + foreach ($met->arrayrights as $name => $value) { + !is_array($value)?$value =array($value):null; + foreach ($value as $k => $v){ + ($k); + if ($name == 'description'){ + $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'],$name); + $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'],'string',$v[1]); + $ndatt = $doc->createAttribute('language'); + $ndatt->nodeValue = $v[0]; + $nd3->appendChild($ndatt); + $nd2->appendChild($nd3); + $nd->appendChild($nd2); + }elseif ($name == 'copyrightAndOtherRestrictions' || $name == 'cost'){ + $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'],$name); + $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'],'value',$v[0]); + $nd2->appendChild($nd3); + $nd->appendChild($nd2); + } + } + } + return $nd; + } + + + + + /** + * Create LifeCyle Metadata (How To) + * + * @param object $met + * @param DOMDocument $doc + * @param object $xmlnode + * @return DOMNode + */ + protected function create_metadata_lifecycle($met,DOMDocument &$doc,$xmlnode){ + ($xmlnode); + + $nd = $doc->createElementNS($this->ccnamespaces['lomimscc'],'lifeCycle'); + $nd2= $doc->createElementNS($this->ccnamespaces['lomimscc'],'contribute'); + + + $nd->appendChild ($nd2); + $xmlnode->appendChild ($nd); + + foreach ($met->arraylifecycle as $name => $value) { + !is_array($value)?$value =array($value):null; + foreach ($value as $k => $v){ + ($k); + if ($name == 'role'){ + $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'],$name); + $nd2->appendChild($nd3); + $nd4 = $doc->createElementNS($this->ccnamespaces['lomimscc'],'value',$v[0]); + $nd3->appendChild($nd4); + }else{ + if ($name == 'date'){ + $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'],$name); + $nd2->appendChild($nd3); + $nd4 = $doc->createElementNS($this->ccnamespaces['lomimscc'],'dateTime',$v[0]); + $nd3->appendChild($nd4); + }else{ + $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'],$name,$v[0]); + $nd2->appendChild($nd3); + } + } + } + } + return $nd; + } + + + + + /** + * Create Education Metadata (How To) + * + * @param object $met + * @param DOMDocument $doc + * @param object $xmlnode + * @return DOMNode + */ + protected function create_metadata_educational ($met,DOMDocument &$doc, $xmlnode){ + $nd = $doc->createElementNS($this->ccnamespaces['lom'],'educational'); + $nd2 = $doc->createElementNS($this->ccnamespaces['lom'],'intendedEndUserRole'); + $nd3 = $doc->createElementNS($this->ccnamespaces['voc'],'vocabulary'); + + $xmlnode->appendChild($nd); + $nd->appendChild($nd2); + $nd2->appendChild($nd3); + + foreach ($met->arrayeducational as $name => $value) { + !is_array($value)?$value =array($value):null; + foreach ($value as $k => $v){ + ($k); + $nd4 = $doc->createElementNS($this->ccnamespaces['voc'],$name,$v[0]); + $nd3->appendChild($nd4); + } + } + return $nd; + } + +} \ No newline at end of file diff --git a/backup/cc/cc_lib/cc_version11.php b/backup/cc/cc_lib/cc_version11.php new file mode 100644 index 00000000000..6df8ab715bd --- /dev/null +++ b/backup/cc/cc_lib/cc_version11.php @@ -0,0 +1,93 @@ +. + +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once 'cc_version1.php'; + + +/** + * Version 1.1 class of Common Cartridge + * + */ +class cc_version11 extends cc_version1 { + const webcontent = 'webcontent'; + const questionbank = 'imsqti_xmlv1p2/imscc_xmlv1p1/question-bank'; + const assessment = 'imsqti_xmlv1p2/imscc_xmlv1p1/assessment'; + const associatedcontent = 'associatedcontent/imscc_xmlv1p1/learning-application-resource'; + const discussiontopic = 'imsdt_xmlv1p1'; + const weblink = 'imswl_xmlv1p1'; + const basiclti = 'imsbasiclti_xmlv1p0'; + + public static $checker = array(self::webcontent, + self::assessment, + self::associatedcontent, + self::discussiontopic, + self::questionbank, + self::weblink, + self::basiclti); + + /** + * Validate if the type are valid or not + * + * @param string $type + * @return bool + */ + public function valid($type) { + return in_array($type, self::$checker); + } + + public function __construct() { + $this->ccnamespaces = array('imscc' => 'http://www.imsglobal.org/xsd/imsccv1p1/imscp_v1p1', + 'lomimscc' => 'http://ltsc.ieee.org/xsd/imsccv1p1/LOM/manifest' , + 'lom' => 'http://ltsc.ieee.org/xsd/imsccv1p1/LOM/resource' , + 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance' + ); + + $this->ccnsnames = array('imscc' => 'http://www.imsglobal.org/profile/cc/ccv1p1/ccv1p1_imscp_v1p2_v1p0.xsd' , + 'lomimscc' => 'http://www.imsglobal.org/profile/cc/ccv1p1/LOM/ccv1p1_lommanifest_v1p0.xsd', + 'lom' => 'http://www.imsglobal.org/profile/cc/ccv1p1/LOM/ccv1p1_lomresource_v1p0.xsd' + ); + + $this->ccversion = '1.1.0'; + $this->camversion = '1.1.0'; + $this->_generator = 'Moodle 2 Common Cartridge generator'; + } + + protected function update_items($items, DOMDocument &$doc, DOMElement &$xmlnode) { + foreach ($items as $key => $item) { + $itemnode = $doc->createElementNS($this->ccnamespaces['imscc'], 'item'); + $this->update_attribute($doc, 'identifier' , $key , $itemnode); + $this->update_attribute($doc, 'identifierref', $item->identifierref, $itemnode); + if (!is_null($item->title)) { + $titlenode = $doc->createElementNS($this->ccnamespaces['imscc'], + 'title', + $item->title); + $itemnode->appendChild($titlenode); + } + if ($item->has_child_items()) { + $this->update_items($item->childitems, $doc, $itemnode); + } + $xmlnode->appendChild($itemnode); + } + } + +} diff --git a/backup/cc/cc_lib/cc_version_base.php b/backup/cc/cc_lib/cc_version_base.php new file mode 100644 index 00000000000..9fc230e9d64 --- /dev/null +++ b/backup/cc/cc_lib/cc_version_base.php @@ -0,0 +1,131 @@ +. + +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once 'cc_organization.php'; + + +/** + * Abstract Version Base class + * + */ +abstract class cc_version_base { + protected $_generator = null; + protected $ccnamespaces = array(); + protected $isrootmanifest = false; + protected $manifestID = null; + protected $organizationid = null; + public $resources = null; + protected $metadata = null; + public $organizations = null; + protected $base = null; + public $ccversion = null; + public $camversion = null; + + + abstract protected function on_create(DOMDocument &$doc,$rootmanifestnode=null,$nmanifestID=null); + + abstract protected function create_metadata_manifest (cc_i_metadata_manifest $met,DOMDocument &$doc,$xmlnode=null); + + abstract protected function create_metadata_resource (cc_i_metadata_resource $met,DOMDocument &$doc,$xmlnode=null); + + abstract protected function create_metadata_file (cc_i_metadata_file $met,DOMDocument &$doc,$xmlnode=null); + + abstract protected function create_resource(cc_i_resource &$res, DOMDocument &$doc, $xmlnode=null); + + abstract protected function create_organization(cc_i_organization &$org, DOMDocument &$doc, $xmlnode=null); + + public function get_cc_namespaces(){ + return $this->ccnamespaces; + } + + public function create_manifest(DOMDocument &$doc,$rootmanifestnode=null){ + return $this->on_create($doc,$rootmanifestnode); + } + + public function create_resource_node(cc_i_resource &$res, DOMDocument &$doc, $xmlnode = null) { + return $this->create_resource($res,$doc,$xmlnode); + } + + + public function create_metadata_node (&$met, DOMDocument &$doc, $xmlnode = null){ + return $this->create_metadata_manifest($met,$doc,$xmlnode); + } + + public function create_metadata_resource_node (&$met, DOMDocument &$doc, $xmlnode = null){ + return $this->create_metadata_resource($met,$doc,$xmlnode); + } + + public function create_metadata_file_node (&$met, DOMDocument &$doc, $xmlnode = null){ + return $this->create_metadata_file($met,$doc,$xmlnode); + } + + public function create_organization_node(cc_i_organization &$org, DOMDocument &$doc, $xmlnode = null) { + return $this->create_organization($org,$doc,$xmlnode); + } + + public function manifestID(){ + return $this->manifestID; + } + + public function set_manifestID($id){ + $this->manifestID = $id; + } + + public function get_base(){ + return $this->base; + } + + public function set_base($baseval){ + $this->base = $baseval; + } + + public function import_resources(DOMElement &$node, cc_i_manifest &$doc) { + if (is_null($this->resources)){ + $this->resources = array(); + } + $nlist = $node->getElementsByTagNameNS($this->ccnamespaces['imscc'],'resource'); + if (is_object($nlist)) { + foreach ($nlist as $nd) { + $sc = new cc_resource($doc,$nd); + $this->resources[$sc->identifier]=$sc; + } + } + } + + public function import_organization_items(DOMElement &$node, cc_i_manifest &$doc) { + if (is_null($this->organizations)) { + $this->organizations = array(); + } + $nlist = $node->getElementsByTagNameNS($this->ccnamespaces['imscc'],'organization'); + if (is_object($nlist)) { + foreach ($nlist as $nd) { + $sc = new cc_organization($nd,$doc); + $this->organizations[$sc->identifier]=$sc; + } + } + } + + public function set_generator($value) { + $this->_generator = $value; + } +} \ No newline at end of file diff --git a/backup/cc/cc_lib/cc_weblink.php b/backup/cc/cc_lib/cc_weblink.php new file mode 100644 index 00000000000..db68fa2dd82 --- /dev/null +++ b/backup/cc/cc_lib/cc_weblink.php @@ -0,0 +1,99 @@ +. + +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once 'cc_general.php'; + +class url1_resurce_file extends general_cc_file { + const deafultname = 'weblink.xml'; + + protected $rootns = 'wl'; + protected $rootname = 'wl:webLink'; + protected $ccnamespaces = array('wl' => 'http://www.imsglobal.org/xsd/imswl_v1p0', + 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance'); + protected $ccnsnames = array('wl' => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/domainProfile_5/imswl_v1p0_localised.xsd'); + + protected $url = null; + protected $title = null; + protected $href = null; + protected $target = '_self'; + protected $window_features = null; + + /** + * + * Set the url title + * @param string $title + */ + public function set_title($title) { + $this->title = htmlentities($title); + } + + /** + * + * Set the url specifics + * @param string $url + * @param string $target + * @param string $window_features + */ + public function set_url($url, $target='_self', $window_features=null) { + $this->url = $url; + $this->target = $target; + $this->window_features = $window_features; + } + + protected function on_save() { + $this->append_new_element($this->root, 'title', $this->title); + $url = $this->append_new_element($this->root, 'url'); + $this->append_new_attribute($url, 'href', $this->url); + if (!empty($this->target)) { + $this->append_new_attribute($url, 'target', $this->target); + } + if (!empty($this->window_features)) { + $this->append_new_attribute($url, 'windowFeatures', $this->window_features); + } + return true; + } + +} + +class url11_resurce_file extends url1_resurce_file { + protected $rootname = 'webLink'; + + protected $ccnamespaces = array('wl' => 'http://www.imsglobal.org/xsd/imsccv1p1/imswl_v1p1', + 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance'); + protected $ccnsnames = array('wl' => 'http://www.imsglobal.org/profile/cc/ccv1p1/ccv1p1_imswl_v1p1.xsd'); + + protected function on_save() { + $rns = $this->ccnamespaces[$this->rootns]; + $this->append_new_element_ns($this->root, $rns, 'title', $this->title); + $url = $this->append_new_element_ns($this->root, $rns, 'url'); + $this->append_new_attribute_ns($url, $rns, 'href', $this->url); + if (!empty($this->target)) { + $this->append_new_attribute_ns($url, $rns, 'target', $this->target); + } + if (!empty($this->window_features)) { + $this->append_new_attribute_ns($url, $rns, 'windowFeatures', $this->window_features); + } + return true; + } +} + diff --git a/backup/cc/cc_lib/gral_lib/ccdependencyparser.php b/backup/cc/cc_lib/gral_lib/ccdependencyparser.php new file mode 100644 index 00000000000..5992b8e635e --- /dev/null +++ b/backup/cc/cc_lib/gral_lib/ccdependencyparser.php @@ -0,0 +1,168 @@ +. + +require_once $CFG->dirroot .'/backup/cc/cc_lib/xmlbase.php'; +require_once 'cssparser.php'; +require_once 'pathutils.php'; + + + +/** + * + * Older version better suited for PHP < 5.2 + * @deprecated + * @param unknown_type $url + * @return boolean + */ +function is_url_deprecated($url) { + if ( + !preg_match('#^http\\:\\/\\/[a-z0-9\-]+\.([a-z0-9\-]+\.)?[a-z]+#i', $url) && + !preg_match('#^https\\:\\/\\/[a-z0-9\-]+\.([a-z0-9\-]+\.)?[a-z]+#i', $url) && + !preg_match('#^ftp\\:\\/\\/[a-z0-9\-]+\.([a-z0-9\-]+\.)?[a-z]+#i', $url) + ) { + $status = false; + } else { + $status = true; + } + return $status; +} + +/** + * + * validates URL + * @param string $url + * @return boolean + */ +function is_url($url) { + $result = filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED) !== false; + return $result; +} + +function GetDepFiles($manifestroot, $fname,$folder,&$filenames) { + $extension = pathinfo($fname, PATHINFO_EXTENSION); + $filenames = array(); + $dcx = new XMLGenericDocument(); + $result = true; + + switch ($extension){ + case 'xml': + $result = @$dcx->loadXMLFile($manifestroot.$folder.$fname); + if (!$result) { + $result = @$dcx->loadXMLFile($manifestroot.DIRECTORY_SEPARATOR.$folder.DIRECTORY_SEPARATOR.$fname); + } + GetDepFilesXML($manifestroot, $fname,$filenames,$dcx, $folder); + break; + case 'html': + case 'htm': + $result = @$dcx->loadHTMLFile($manifestroot.$folder.$fname); + if (!$result) { + $result = @$dcx->loadHTMLFile($manifestroot.DIRECTORY_SEPARATOR.$folder.DIRECTORY_SEPARATOR.$fname); + } + GetDepFilesHTML($manifestroot, $fname,$filenames,$dcx, $folder); + break; + } + return $result; +} + + + +function GetDepFilesXML ($manifestroot, $fname,&$filenames,&$dcx, $folder){ + $nlist = $dcx->nodeList("//img/@src | //attachments/attachment/@href | //link/@href | //script/@src"); + $css_obj_array = array(); + foreach ($nlist as $nl) { + $item = $folder.$nl->nodeValue; + $path_parts = pathinfo($item); + $fname = $path_parts['basename']; + $ext = array_key_exists('extension',$path_parts) ? $path_parts['extension'] : ''; + if (!is_url($nl->nodeValue)) { + //$file = $folder.$nl->nodeValue; // DEPENDERA SI SE QUIERE Q SEA RELATIVO O ABSOLUTO + $file = $nl->nodeValue; + toNativePath($file); + $filenames[]=$file; + } + } + $dcx->registerNS('qti','http://www.imsglobal.org/xsd/imscc/ims_qtiasiv1p2.xsd'); + $dcx->resetXpath(); + $nlist = $dcx->nodeList("//qti:mattext | //text"); + $dcx2 = new XMLGenericDocument(); + foreach ($nlist as $nl) { + if ($dcx2->loadString($nl->nodeValue)){ + GetDepFilesHTML($manifestroot,$fname,$filenames,$dcx2,$folder); + } + } +} + + + +function GetDepFilesHTML ($manifestroot, $fname, &$filenames, &$dcx, $folder){ + $dcx->resetXpath(); + $nlist = $dcx->nodeList("//img/@src | //link/@href | //script/@src | //a[not(starts-with(@href,'#'))]/@href"); + $css_obj_array=array(); + foreach ($nlist as $nl) { + $item = $folder.$nl->nodeValue; + $path_parts = pathinfo($item); + $fname = $path_parts['basename']; + $ext = array_key_exists('extension',$path_parts) ? $path_parts['extension'] : ''; + if (!is_url($folder.$nl->nodeValue) && !is_url($nl->nodeValue)) { + $path = $folder.$nl->nodeValue; + $file = fullPath($path,"/"); + toNativePath($file); + if (file_exists($manifestroot.DIRECTORY_SEPARATOR.$file)) { + $filenames[]= $file; + } + } + if ($ext == 'css') { + $css = new cssparser(); + $css->Parse($dcx->filePath().$nl->nodeValue); + $css_obj_array[$item]=$css; + } + } + $nlist = $dcx->nodeList("//*/@class"); + foreach ($nlist as $nl) { + $item = $folder.$nl->nodeValue; + foreach ($css_obj_array as $csskey => $cssobj) { + $bimg = $cssobj->Get($item,"background-image"); + $limg = $cssobj->Get($item,"list-style-image"); + $npath = pathinfo($csskey); + if ((!empty($bimg))&& ($bimg != 'none')) { + $filenames[] = stripUrl($bimg,$npath['dirname'].'/'); + } else + if ((!empty($limg))&& ($limg != 'none')) { + $filenames[] = stripUrl($limg,$npath['dirname'].'/'); + } + } + } + $elems_to_check = array("body","p","ul","h4","a","th"); + $do_we_have_it = array(); + foreach ($elems_to_check as $elem) { + $do_we_have_it[$elem]=($dcx->nodeList("//".$elem)->length > 0); + } + foreach ($elems_to_check as $elem) { + if ($do_we_have_it[$elem]) { + foreach ($css_obj_array as $csskey => $cssobj) { + $sb = $cssobj->Get($elem, "background-image"); + $sbl = $cssobj->Get($elem,"list-style-image"); + $npath = pathinfo($csskey); + if ((!empty($sb)) && ($sb != 'none')) { + $filenames[] = stripUrl($sb,$npath['dirname'].'/'); + } else + if ((!empty($sbl)) && ($sbl != 'none')) { + $filenames[] = stripUrl($sbl,$npath['dirname'].'/'); + } + } + } + } +} \ No newline at end of file diff --git a/backup/cc/cc_lib/gral_lib/cssparser.php b/backup/cc/cc_lib/gral_lib/cssparser.php new file mode 100644 index 00000000000..1dcbee8858d --- /dev/null +++ b/backup/cc/cc_lib/gral_lib/cssparser.php @@ -0,0 +1,261 @@ +. + +class cssparser { + private $css; + private $html; + + function cssparser($html = true) { + // Register "destructor" + register_shutdown_function(array(&$this, "finalize")); + $this->html = ($html != false); + $this->Clear(); + } + + function finalize() { + unset($this->css); + } + + function Clear() { + unset($this->css); + $this->css = array(); + if($this->html) { + $this->Add("ADDRESS", ""); + $this->Add("APPLET", ""); + $this->Add("AREA", ""); + $this->Add("A", "text-decoration : underline; color : Blue;"); + $this->Add("A:visited", "color : Purple;"); + $this->Add("BASE", ""); + $this->Add("BASEFONT", ""); + $this->Add("BIG", ""); + $this->Add("BLOCKQUOTE", ""); + $this->Add("BODY", ""); + $this->Add("BR", ""); + $this->Add("B", "font-weight: bold;"); + $this->Add("CAPTION", ""); + $this->Add("CENTER", ""); + $this->Add("CITE", ""); + $this->Add("CODE", ""); + $this->Add("DD", ""); + $this->Add("DFN", ""); + $this->Add("DIR", ""); + $this->Add("DIV", ""); + $this->Add("DL", ""); + $this->Add("DT", ""); + $this->Add("EM", ""); + $this->Add("FONT", ""); + $this->Add("FORM", ""); + $this->Add("H1", ""); + $this->Add("H2", ""); + $this->Add("H3", ""); + $this->Add("H4", ""); + $this->Add("H5", ""); + $this->Add("H6", ""); + $this->Add("HEAD", ""); + $this->Add("HR", ""); + $this->Add("HTML", ""); + $this->Add("IMG", ""); + $this->Add("INPUT", ""); + $this->Add("ISINDEX", ""); + $this->Add("I", "font-style: italic;"); + $this->Add("KBD", ""); + $this->Add("LINK", ""); + $this->Add("LI", ""); + $this->Add("MAP", ""); + $this->Add("MENU", ""); + $this->Add("META", ""); + $this->Add("OL", ""); + $this->Add("OPTION", ""); + $this->Add("PARAM", ""); + $this->Add("PRE", ""); + $this->Add("P", ""); + $this->Add("SAMP", ""); + $this->Add("SCRIPT", ""); + $this->Add("SELECT", ""); + $this->Add("SMALL", ""); + $this->Add("STRIKE", ""); + $this->Add("STRONG", ""); + $this->Add("STYLE", ""); + $this->Add("SUB", ""); + $this->Add("SUP", ""); + $this->Add("TABLE", ""); + $this->Add("TD", ""); + $this->Add("TEXTAREA", ""); + $this->Add("TH", ""); + $this->Add("TITLE", ""); + $this->Add("TR", ""); + $this->Add("TT", ""); + $this->Add("UL", ""); + $this->Add("U", "text-decoration : underline;"); + $this->Add("VAR", ""); + } + } + + function SetHTML($html) { + $this->html = ($html != false); + } + + function Add($key, $codestr) { + $key = strtolower($key); + $codestr = strtolower($codestr); + if(!isset($this->css[$key])) { + $this->css[$key] = array(); + } + $codes = explode(";",$codestr); + if(count($codes) > 0) { + $codekey=''; $codevalue=''; + foreach($codes as $code) { + $code = trim($code); + $this->assignValues(explode(":",$code),$codekey,$codevalue); + if(strlen($codekey) > 0) { + $this->css[$key][trim($codekey)] = trim($codevalue); + } + } + } + } + + private function assignValues($arr,&$val1,&$val2) { + $n = count($arr); + if ($n > 0) { + $val1=$arr[0]; + $val2=($n > 1) ? $arr[1] : ''; + } + } + function Get($key, $property) { + $key = strtolower($key); + $property = strtolower($property); + $tag='';$subtag='';$class='';$id=''; + $this->assignValues(explode(":",$key),$tag,$subtag); + $this->assignValues(explode(".",$tag),$tag,$class); + $this->assignValues(explode("#",$tag),$tag,$id); + $result = ""; + $_subtag=''; $_class=''; $_id=''; + foreach($this->css as $_tag => $value) { + $this->assignValues(explode(":",$_tag),$_tag,$_subtag); + $this->assignValues(explode(".",$_tag),$_tag,$_class); + $this->assignValues(explode("#",$_tag),$_tag,$_id); + + $tagmatch = (strcmp($tag, $_tag) == 0) | (strlen($_tag) == 0); + $subtagmatch = (strcmp($subtag, $_subtag) == 0) | (strlen($_subtag) == 0); + $classmatch = (strcmp($class, $_class) == 0) | (strlen($_class) == 0); + $idmatch = (strcmp($id, $_id) == 0); + + if($tagmatch & $subtagmatch & $classmatch & $idmatch) { + $temp = $_tag; + if((strlen($temp) > 0) & (strlen($_class) > 0)) { + $temp .= ".".$_class; + } elseif(strlen($temp) == 0) { + $temp = ".".$_class; + } + if((strlen($temp) > 0) & (strlen($_subtag) > 0)) { + $temp .= ":".$_subtag; + } elseif(strlen($temp) == 0) { + $temp = ":".$_subtag; + } + if(isset($this->css[$temp][$property])) { + $result = $this->css[$temp][$property]; + } + } + } + return $result; + } + + function GetSection($key) { + $key = strtolower($key); + $tag='';$subtag='';$class='';$id=''; + $_subtag=''; $_class=''; $_id=''; + + $this->assignValues(explode(":",$key),$tag,$subtag); + $this->assignValues(explode(".",$tag),$tag,$class); + $this->assignValues(explode("#",$tag),$tag,$id); + $result = array(); + foreach($this->css as $_tag => $value) { + $this->assignValues(explode(":",$_tag),$_tag,$_subtag); + $this->assignValues(explode(".",$_tag),$_tag,$_class); + $this->assignValues(explode("#",$_tag),$_tag,$_id); + + $tagmatch = (strcmp($tag, $_tag) == 0) | (strlen($_tag) == 0); + $subtagmatch = (strcmp($subtag, $_subtag) == 0) | (strlen($_subtag) == 0); + $classmatch = (strcmp($class, $_class) == 0) | (strlen($_class) == 0); + $idmatch = (strcmp($id, $_id) == 0); + + if($tagmatch & $subtagmatch & $classmatch & $idmatch) { + $temp = $_tag; + if((strlen($temp) > 0) & (strlen($_class) > 0)) { + $temp .= ".".$_class; + } elseif(strlen($temp) == 0) { + $temp = ".".$_class; + } + if((strlen($temp) > 0) & (strlen($_subtag) > 0)) { + $temp .= ":".$_subtag; + } elseif(strlen($temp) == 0) { + $temp = ":".$_subtag; + } + foreach($this->css[$temp] as $property => $value) { + $result[$property] = $value; + } + } + } + return $result; + } + + function ParseStr($str) { + $this->Clear(); + // Remove comments + $str = preg_replace("/\/\*(.*)?\*\//Usi", "", $str); + // Parse this damn csscode + $parts = explode("}",$str); + if(count($parts) > 0) { + foreach($parts as $part) { + $keystr='';$codestr=''; + $this->assignValues(explode("{",$part),$keystr,$codestr); + $keys = explode(",",trim($keystr)); + if(count($keys) > 0) { + foreach($keys as $key) { + if(strlen($key) > 0) { + $key = str_replace("\n", "", $key); + $key = str_replace("\\", "", $key); + $this->Add($key, trim($codestr)); + } + } + } + } + } + // + return (count($this->css) > 0); + } + + function Parse($filename) { + $this->Clear(); + if(file_exists($filename)) { + return $this->ParseStr(file_get_contents($filename)); + } else { + return false; + } + } + + function GetCSS() { + $result = ""; + foreach($this->css as $key => $values) { + $result .= $key." {\n"; + foreach($values as $key => $value) { + $result .= " $key: $value;\n"; + } + $result .= "}\n\n"; + } + return $result; + } +} \ No newline at end of file diff --git a/backup/cc/cc_lib/gral_lib/functions.php b/backup/cc/cc_lib/gral_lib/functions.php new file mode 100644 index 00000000000..fcacf81dc1e --- /dev/null +++ b/backup/cc/cc_lib/gral_lib/functions.php @@ -0,0 +1,131 @@ +. + +/** + * Librería de funciones básicas V1.0 (June, 16th 2009) + * + * + * @author Daniel Mühlrad + * @link daniel.muhlrad@uvcms.com + * @version 1.0 + * @copyright 2009 + * + */ + + + + +/** + * Make a Handler error with an exception msg error + * + * @param integer $errno + * @param string $errstr + * @param string $errfile + * @param string $errline + */ +function errorHandler($errno, $errstr, $errfile, $errline) { + // si deseas podes guardarlos en un archivo + ($errfile);($errline); + throw new Exception($errstr, $errno); +} + + + +/** + * Return de mime-type of a file + * + * @param string $file + * @param string $default_type + * + */ +function file_mime_type ($file, $default_type = 'application/octet-stream'){ + $ftype = $default_type; + $magic_path = dirname(__FILE__) + . DIRECTORY_SEPARATOR + . '..' + . DIRECTORY_SEPARATOR + . 'magic' + . DIRECTORY_SEPARATOR + . 'magic'; + $finfo = @finfo_open(FILEINFO_MIME , $magic_path); + if ($finfo !== false) { + + $fres = @finfo_file($finfo, $file); + + if ( is_string($fres) && !empty($fres) ) { + $ftype = $fres; + } + @finfo_close($finfo); + } + return $ftype; +} + + + + +function array_remove_by_value($arr,$value) { + return array_values(array_diff($arr,array($value))); + +} + + +function array_remove_by_key($arr,$key) { + return array_values(array_diff_key($arr,array($key))); + +} + + +function cc_print_object($object) { + echo '
' . htmlspecialchars(print_r($object,true)) . '
'; +} + + + +/** + * IndexOf - first version of find an element in the Array given + * returns the index of the *first* occurance + * @param mixed $needle + * @param array $haystack + * @return mixed The element or false if the function didnt find it + */ + +function indexOf($needle, $haystack) { + for ($i = 0; $i < count($haystack) ; $i++) { + if ($haystack[$i] == $needle) { + return $i; + } + } + return false; +} + + +/** + * IndexOf2 - second version of find an element in the Array given + * + * @param mixed $needle + * @param array $haystack + * @return mixed The index of the element or false if the function didnt find it + */ + +function indexOf2($needle, $haystack) { + for($i = 0,$z = count($haystack); $i < $z; $i++){ + if ($haystack[$i] == $needle) { //finds the needle + return $i; + } + } + return false; +} + diff --git a/backup/cc/cc_lib/gral_lib/parser.php b/backup/cc/cc_lib/gral_lib/parser.php new file mode 100644 index 00000000000..00e0dc33788 --- /dev/null +++ b/backup/cc/cc_lib/gral_lib/parser.php @@ -0,0 +1,149 @@ +. + +require_once $CFG->dirroot .'/backup/cc/cc_lib/xmlbase.php'; +require_once 'cssparser.php'; +require_once 'pathutils.php'; + + + +function is_url($url) { + if ( + !preg_match('#^http\\:\\/\\/[a-z0-9\-]+\.([a-z0-9\-]+\.)?[a-z]+#i', $url) && + !preg_match('#^https\\:\\/\\/[a-z0-9\-]+\.([a-z0-9\-]+\.)?[a-z]+#i', $url) && + !preg_match('#^ftp\\:\\/\\/[a-z0-9\-]+\.([a-z0-9\-]+\.)?[a-z]+#i', $url) + ) { + $status = false; + } else { + $status = true; + } + return $status; +} + +function GetDepFiles($manifestroot, $fname,$folder,&$filenames) { + + $extension = end(explode('.',$fname)); + $filenames = array(); + $dcx = new XMLGenericDocument(); + $result = true; + + switch ($extension){ + case 'xml': + $result = @$dcx->loadXMLFile($manifestroot.$folder.$fname); + if (!$result) { + $result = @$dcx->loadXMLFile($manifestroot.DIRECTORY_SEPARATOR.$folder.DIRECTORY_SEPARATOR.$fname); + } + GetDepFilesXML($manifestroot, $fname,$filenames,$dcx, $folder); + break; + case 'html': + case 'htm': + $result = @$dcx->loadHTMLFile($manifestroot.$folder.$fname); + if (!$result) { + $result = @$dcx->loadHTMLFile($manifestroot.DIRECTORY_SEPARATOR.$folder.DIRECTORY_SEPARATOR.$fname); + } + GetDepFilesHTML($manifestroot, $fname,$filenames,$dcx, $folder); + break; + } + return $result; +} + + + +function GetDepFilesXML ($manifestroot, $fname,&$filenames,&$dcx, $folder){ + $nlist = $dcx->nodeList("//img/@src | //attachments/attachment/@href | //link/@href | //script/@src"); + $css_obj_array = array(); + foreach ($nlist as $nl) { + $item = $nl->nodeValue; + $path_parts = pathinfo($item); + $fname = $path_parts['basename']; + $ext = array_key_exists('extension',$path_parts) ? $path_parts['extension'] : ''; + if (!is_url($nl->nodeValue)) { + //$file = $folder.$nl->nodeValue; // DEPENDERA SI SE QUIERE Q SEA RELATIVO O ABSOLUTO + $file = $nl->nodeValue; + toNativePath($file); + $filenames[]=$file; + } + } + $dcx->registerNS('qti','http://www.imsglobal.org/xsd/imscc/ims_qtiasiv1p2.xsd'); + $dcx->resetXpath(); + $nlist = $dcx->nodeList("//qti:mattext | //text"); + $dcx2 = new XMLGenericDocument(); + foreach ($nlist as $nl) { + if ($dcx2->loadString($nl->nodeValue)){ + GetDepFilesHTML($manifestroot,$fname,$filenames,$dcx2,$folder); + } + } +} + + + +function GetDepFilesHTML ($manifestroot, $fname,&$filenames,&$dcx, $folder){ + $dcx->resetXpath(); + $nlist = $dcx->nodeList("//img/@src | //link/@href | //script/@src | //a[not(starts-with(@href,'#'))]/@href"); + $css_obj_array=array(); + foreach ($nlist as $nl) { + $item = $nl->nodeValue; + $path_parts = pathinfo($item); + $fname = $path_parts['basename']; + $ext = array_key_exists('extension',$path_parts) ? $path_parts['extension'] : ''; + if (!is_url($folder.$nl->nodeValue) && !is_url($nl->nodeValue)) { + $path = $nl->nodeValue; + //$file = fullPath($path,"/"); + toNativePath($path); + $filenames[]= $path; + } + if ($ext == 'css') { + $css = new cssparser(); + $css->Parse($dcx->filePath().$nl->nodeValue); + $css_obj_array[$item]=$css; + } + } + $nlist = $dcx->nodeList("//*/@class"); + foreach ($nlist as $nl) { + $item = $nl->nodeValue; + foreach ($css_obj_array as $csskey => $cssobj) { + $bimg = $cssobj->Get($item,"background-image"); + $limg = $cssobj->Get($item,"list-style-image"); + $npath = pathinfo($csskey); + if ((!empty($bimg))&& ($bimg != 'none')) { + $filenames[] = stripUrl($bimg,$npath['dirname'].'/'); + } else + if ((!empty($limg))&& ($limg != 'none')) { + $filenames[] = stripUrl($limg,$npath['dirname'].'/'); + } + } + } + $elems_to_check = array("body","p","ul","h4","a","th"); + $do_we_have_it = array(); + foreach ($elems_to_check as $elem) { + $do_we_have_it[$elem]=($dcx->nodeList("//".$elem)->length > 0); + } + foreach ($elems_to_check as $elem) { + if ($do_we_have_it[$elem]) { + foreach ($css_obj_array as $csskey => $cssobj) { + $sb = $cssobj->Get($elem, "background-image"); + $sbl = $cssobj->Get($elem,"list-style-image"); + $npath = pathinfo($csskey); + if ((!empty($sb)) && ($sb != 'none')) { + $filenames[] = stripUrl($sb,$npath['dirname'].'/'); + } else + if ((!empty($sbl)) && ($sbl != 'none')) { + $filenames[] = stripUrl($sbl,$npath['dirname'].'/'); + } + } + } + } +} \ No newline at end of file diff --git a/backup/cc/cc_lib/gral_lib/pathutils.php b/backup/cc/cc_lib/gral_lib/pathutils.php new file mode 100644 index 00000000000..4e2bbb315c3 --- /dev/null +++ b/backup/cc/cc_lib/gral_lib/pathutils.php @@ -0,0 +1,419 @@ +. + +/** + * Function expands all relative parts of supplied path string thus + * removing things like ../../ or ./../. + * + * @param string $path + * @param string $dirsep Character that represents directory separator should be + * specified here. Default is DIRECTORY_SEPARATOR. + * @return string + */ +function fullPath($path,$dirsep=DIRECTORY_SEPARATOR) { + $token = '$IMS-CC-FILEBASE$'; + $path = str_replace($token,'',$path); + if ( is_string($path) && ($path != '') ) { + $sep = $dirsep; + $dotDir= '.'; + $upDir = '..'; + $length= strlen($path); + $rtemp= trim($path); + $start = strrpos($path, $sep); + $canContinue = ($start !== false); + $result= $canContinue ? '': $path; + $rcount=0; + while ($canContinue) { + $dirPart = ($start !== false) ? substr($rtemp,$start+1,$length-$start) : $rtemp; + $canContinue = ($dirPart !== false); + if ($canContinue) { + if ($dirPart != $dotDir) { + if ($dirPart == $upDir) { + $rcount++; + } else { + if ($rcount > 0) { + $rcount--; + } else { + $result = ($result == '') ? $dirPart : $dirPart.$sep.$result; + } + } + } + $rtemp = substr($path,0,$start); + $start = strrpos($rtemp, $sep); + $canContinue = (($start !== false) || (strlen($rtemp) > 0)); + } + } //end while + } + return $result; +} + + + +/** + * Function strips url part from css link + * + * @param string $path + * @param string $rootDir + * @return string + */ +function stripUrl($path, $rootDir='') { + $result = $path; + if ( is_string($path) && ($path != '') ) { + $start=strpos($path,'(')+1; + $length=strpos($path,')')-$start; + $rut = $rootDir.substr($path,$start,$length); + $result=fullPath($rut,'/'); + } + return $result; +} + +/** + * Converts direcotry separator in given path to / to validate in CC + * Value is passed byref hence variable itself is changed + * + * @param string $path + */ +function toNativePath(&$path) { + for ($count = 0 ; $count < strlen($path); ++$count) { + $chr = $path{$count}; + if (($chr == '\\') || ($chr == '/')) { + $path{$count} = '/'; + } + } +} + + +/** + * Converts direcotry separator in given path to the one on the server platform + * Value is passed byref hence variable itself is changed + * + * @param string $path + */ +function toNativePath2(&$path) { + for ($count = 0 ; $count < strlen($path); ++$count) { + $chr = $path{$count}; + if (($chr == '\\') || ($chr == '/')) { + $path{$count} = DIRECTORY_SEPARATOR; + } + } +} + +/** + * Converts \ Directory separator to the / more suitable for URL + * + * @param string $path + */ +function toUrlPath(&$path) { + for ($count = 0 ; $count < strlen($path); ++$count) { + $chr = $path{$count}; + if (($chr == '\\')) { + $path{$count} = '/'; + } + } +} + +/** + * Returns relative path from two directories with full path + * + * @param string $path1 + * @param string $path2 + * @return string + */ +function pathDiff($path1, $path2) { + toUrlPath($path1); + toUrlPath($path2); + $result = ""; + $bl2 = strlen($path2); + $a = strpos($path1,$path2); + if ($a !== false) { + $result = trim(substr($path1,$bl2+$a),'/'); + } + return $result; +} + + /** + * Copy a file, or recursively copy a folder and its contents + * + * @author Aidan Lister + * @version 1.0.1 + * @link http://aidanlister.com/repos/v/function.copyr.php + * @param string $source Source path + * @param string $dest Destination path + * @return bool Returns TRUE on success, FALSE on failure + */ + function copyr($source, $dest) + { + // Simple copy for a file + if (is_file($source)) { + return copy($source, $dest); + } + + // Make destination directory + if (!is_dir($dest)) { + mkdir($dest); + } + + // Loop through the folder + $dir = dir($source); + while (false !== $entry = $dir->read()) { + // Skip pointers + if ($entry == '.' || $entry == '..') { + continue; + } + + // Deep copy directories + if ($dest !== "$source/$entry") { + copyr("$source/$entry", "$dest/$entry"); + } + } + + // Clean up + $dir->close(); + return true; + } + +/** + * Function returns array with directories contained in folder (only first level) + * + * @param string $rootDir directory to look into + * @param string $contains which string to look for + * @param array $excludeitems array of names to be excluded + * @param bool $startswith should the $contains value be searched only from + * beginning + * @return array Returns array of sub-directories. In case $rootDir path is + * invalid it returns FALSE. + */ +function getDirectories($rootDir, $contains, $excludeitems = null, $startswith = true) { + $result = is_dir($rootDir); + if ($result) { + $dirlist = dir($rootDir); + $entry = null; + $result = array(); + while(false !== ($entry = $dirlist->read())) { + $currdir = $rootDir.$entry; + if (is_dir($currdir)) { + $bret = strpos($entry,$contains); + if (($bret !== false)) { + if (($startswith && ($bret == 0)) || !$startswith) { + if (!( is_array($excludeitems) && in_array($entry,$excludeitems) )) { + $result[] = $entry; + } + } + } + } + } + } + return $result; +} + +function getFilesOnly($rootDir, $contains, $excludeitems = null, $startswith = true,$extension=null) { + $result = is_dir($rootDir); + if ($result) { + $filelist = dir($rootDir); + $entry = null; + $result = array(); + while(false !== ($entry = $filelist->read())) { + $curritem = $rootDir.$entry; + $pinfo = pathinfo($entry); + $ext = array_key_exists('extension',$pinfo) ? $pinfo['extension'] : null; + if (is_file($curritem) && (is_null($extension) || ($ext == $extension) )) { + $bret = strpos($entry,$contains); + if (($bret !== false)) { + if (($startswith && ($bret == 0)) || !$startswith) { + if (!( is_array($excludeitems) && in_array($entry,$excludeitems) )) { + $result[] = $entry; + } + } + } + } + } + } + natcasesort($result); + return $result; +} + + + +/** + * Search an identifier in array + * + * @param array $array + * @param string $name + * + */ + +function search_ident_by_name($array,$name){ + if (empty($array)){ + throw new Exception('The array given is null'); + } + $ident = null; + foreach ($array as $k => $v){ + ($k); + if ($v[1] == $name){ + $ident = $v[0]; + break; + } + } + return $ident; +} + + + + + +/** + * Function returns files recursivly with appeneded relative path + * + * @param string $startDir + * @param string $rootDir + * @param array $excludedirs + * @param array $excludefileext + * @return array + */ +function getRawFiles($startDir, &$fhandle, $rootDir='', $excludedirs = null, $excludefileext = null) { + $result = is_dir($startDir); + if ($result) { + $dirlist = dir($startDir); + $entry = null; + while(false !== ($entry = $dirlist->read())) { + $curritem = $startDir.$entry; + if (($entry=='.') || ($entry =='..')) { + continue; + } + if (is_dir($curritem)) { + if (!( is_array($excludedirs) && in_array($entry,$excludedirs) )) { + getRawFiles($startDir.$entry."/",$fhandle,$rootDir.$entry."/",$excludedirs,$excludefileext); + } + continue; + } + if (is_file($curritem)){ + $pinfo = pathinfo($entry); + $ext = array_key_exists('extension',$pinfo) ? $pinfo['extension'] : ''; + if (!is_array($excludefileext) || + (is_array($excludefileext) && !in_array($ext,$excludefileext))) { + fwrite($fhandle,$rootDir.$entry."\n"); + } + } + } + } + return $result; +} + + +function getRawFiles2($startDir,&$arr, $rootDir='', $excludedirs = null, $excludefileext = null) { + + $result = is_dir($startDir); + if ($result) { + $dirlist = dir($startDir); + $entry = null; + while(false !== ($entry = $dirlist->read())) { + $curritem = $startDir.$entry; + if (($entry=='.') || ($entry =='..')) { + continue; + } + if (is_dir($curritem)) { + if (!( is_array($excludedirs) && in_array($entry,$excludedirs) )) { + getRawFiles2($startDir.$entry."/",$arr,$rootDir.$entry."/",$excludedirs,$excludefileext); + } + continue; + } + if (is_file($curritem)){ + $pinfo = pathinfo($entry); + $ext = array_key_exists('extension',$pinfo) ? $pinfo['extension'] : ''; + if (!is_array($excludefileext) || + (is_array($excludefileext) && !in_array($ext,$excludefileext))) { + array_push($arr,$rootDir.$entry); + // fwrite($fhandle,$rootDir.$entry."\n"); + } + } + } + } + return $result; +} + + +function GetFiles($startDir, $outfile, $rootDir='', $excludedirs = null, $excludefileext = null) { + $fh = @fopen($outfile,"w+"); + if ($fh !== FALSE) { + getRawFiles($startDir,$fh,$rootDir,$excludedirs,$excludefileext); + @fclose($fh); + @chmod($outfile,0777); + } +} + + +/** + * Function to get an array with all files in a directory and subdirectories + * + * @param string $startDir + * @param string $rootDir + * @param string $excludedirs + * @param string $excludefileext + * @return array + */ + +function GetFilesArray($startDir, $rootDir='', $excludedirs = null, $excludefileext = null) { + $arr = array(); + getRawFiles2($startDir,$arr,$rootDir,$excludedirs,$excludefileext); + return $arr; +} + + + +/** + * Function returns array with directories contained in folder (only first level) + * simmilar to getDirectories but returned items are naturally sorted. + * + * @param string $rootDir + * @param string $contains + * @param array $excludeitems + * @param bool $startswith + * @return array + */ +function getCourseDirs ($rootDir, $contains, $excludeitems=null, $startswith=true) { + $result = getDirectories($rootDir,$contains,$excludeitems,$startswith); + if ($result !== false) { + natcasesort($result); + $result = array_values($result); + } + return $result; +} + + +/** + * Delete a directory recursive with files inside + * + * @param string $dirname + * @return bool + */ +function rmdirr($dirname) +{ + if (!file_exists($dirname)) { + return false; + } + if (is_file($dirname) || is_link($dirname)) { + return unlink($dirname); + } + $dir = dir($dirname); + while (false !== $entry = $dir->read()) { + if ($entry == '.' || $entry == '..') { + continue; + } + rmdirr($dirname . DIRECTORY_SEPARATOR . $entry); + } + $dir->close(); + return rmdir($dirname); +} \ No newline at end of file diff --git a/backup/cc/cc_lib/xmlbase.php b/backup/cc/cc_lib/xmlbase.php new file mode 100644 index 00000000000..0edb9e7eb83 --- /dev/null +++ b/backup/cc/cc_lib/xmlbase.php @@ -0,0 +1,406 @@ +. + +/** +* @package backup-convert +* @subpackage cc-library +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once 'gral_lib/cssparser.php'; + +/** + * Base XML class + * + */ +class XMLGenericDocument { + + + private $charset; + /** + * + * Document + * @var DOMDocument + */ + public $doc = null; + /** + * + * Xpath + * @var DOMXPath + */ + protected $dxpath = null; + private $filename; + private $filepath; + private $isloaded = false; + private $arrayPrefixNS = array(); + private $is_html = false; + + + function __construct($ch = 'UTF-8',$validatenow=true){ + $this->charset = $ch; + $this->documentInit(); + $this->doc->validateOnParse = $validatenow; + } + + function __destruct(){ + $this->dxpath = null; + $this->doc = null; + } + + private function documentInit($withonCreate=true) { + $hg = false; + if ($this->isloaded){ + $guardstate = $this->doc->validateOnParse; + $hg = true; + unset($this->dxpath); + unset($this->doc); + $this->isloaded = false; + } + $this->doc = new DOMDocument("1.0",$this->charset); + $this->doc->strictErrorChecking = true; + if ($hg) { + $this->doc->validateOnParse = $guardstate; + } + $this->doc->formatOutput = true; + $this->doc->preserveWhiteSpace = true; + if($withonCreate) { + $this->on_create(); + } + } + + public function viewXML (){ + return $this->doc->saveXML; + } + + public function registerNS($prefix, $nsuri) { + $this->arrayPrefixNS[$prefix]=$nsuri; + } + + public function load($fname) { + // Sine xml will remain loaded should the repeated load fail we should recreate document to be empty. + $this->documentInit(false); + $this->isloaded = $this->doc->load($fname); + if ($this->isloaded){ + $this->filename = $fname; + $this->processPath(); + $this->is_html = false; + } + return $this->on_load(); + } + + public function loadUrl($url){ + $this->documentInit(); + $this->isloaded = true; + $this->doc->loadXML( file_get_contents($url) ); + $this->is_html = false; + return $this->on_load(); + } + + public function loadHTML ($content){ + $this->documentInit(); + $this->doc->validateOnParse = false; + $this->isloaded = true; + $this->doc->loadHTML($content); + $this->is_html = true; + return $this->on_load(); + } + + public function loadXML ($content){ + $this->documentInit(); + $this->doc->validateOnParse = false; + $this->isloaded = true; + $this->doc->load($content); + $this->is_html = true; + return $this->on_load(); + } + + public function loadHTMLFile($fname){ + //Sine xml will remain loaded should the repeated load fail + //we shoudl recreate document to be empty + $this->documentInit(); + $this->doc->validateOnParse = false; + $this->isloaded = $this->doc->loadHTMLFile($fname); + if ($this->isloaded) { + $this->filename = $fname; + $this->processPath(); + $this->is_html=true; + } + return $this->on_load(); + } + + public function loadXMLFile($fname){ + //Sine xml will remain loaded should the repeated load fail + //we shoudl recreate document to be empty + $this->documentInit(); + $this->doc->validateOnParse = false; + $this->isloaded = $this->doc->load($fname); + if ($this->isloaded) { + $this->filename = $fname; + $this->processPath(); + $this->is_html=true; + } + return $this->on_load(); + } + + + public function loadString($content){ + + $this->doc = new DOMDocument("1.0",$this->charset); + $content = ''.$content.''; + $this->doc->loadXML($content); + + return true; + + } + + public function save() { + $this->saveTo($this->filename); + } + + public function saveTo($fname) { + $status = false; + if ($this->on_save()) { + if ($this->is_html) { + $this->doc->saveHTMLFile($fname); + } else { + $this->doc->save($fname); + } + $this->filename = $fname; + $this->processPath(); + $status = true; + } + return $status; + } + + public function validate() { + return $this->doc->validate(); + } + + public function attributeValue($path,$attrname,$node=null) { + $this->chkxpath(); + $result = null; + $resultlist = null; + if (is_null($node)) { + $resultlist = $this->dxpath->query($path); + } else { + $resultlist = $this->dxpath->query($path,$node); + } + if ( is_object($resultlist) && + ($resultlist->length > 0) && + $resultlist->item(0)->hasAttribute($attrname)){ + $result = $resultlist->item(0)->getAttribute($attrname); + } + return $result; + } + +// public function nodeValue($path,$count = 1,$node=null){ +// $nd = $this->node($path,$count,$node); +// return $this->nodeTextValue($nd); +// } + + /** + * + * Get's text value of the node based on xpath query + * @param string $path + * @param DOMNode $node + * @param int $count + * @return string + */ + public function nodeValue($path, $node = null, $count = 1){ + $nd = $this->node($path,$count,$node); + return $this->nodeTextValue($nd); + } + + /** + * + * Get's text value of the node + * @param DOMNode $node + * @return string + */ + public function nodeTextValue($node){ + $result = ''; + if (is_object($node)) { + if ($node->hasChildNodes()) { + $chnodesList = $node->childNodes; + $types = array(XML_TEXT_NODE, XML_CDATA_SECTION_NODE); + foreach ($chnodesList as $chnode) { + if (in_array($chnode->nodeType, $types)){ + $result .= $chnode->wholeText; + } + } + } + } + return $result; + } + + /** + * + * Enter description here ... + * @param string $path + * @param int $count + * @param DOMNode $nd + * @return DOMNode + */ + public function node($path, $count = 1, $nd=null) { + $result = null; + $resultlist = $this->nodeList($path,$nd); + if ( is_object($resultlist) && + ($resultlist->length > 0) ){ + $result = $resultlist->item($count -1); + } + return $result; + } + + /** + * + * Enter description here ... + * @param string $path + * @param DOMNode $node + * @return DOMNodeList + */ + public function nodeList($path,$node=null){ + + $this->chkxpath(); + + $resultlist = null; + if (is_null($node)) { + $resultlist = $this->dxpath->query($path); + } else { + $resultlist = $this->dxpath->query($path,$node); + } + return $resultlist; + } + + /** + * + * Create new attribute + * @param string $namespace + * @param string $name + * @param string $value + * @return DOMAttr + */ + public function create_attribute_ns($namespace, $name, $value = null) { + $result = $this->doc->createAttributeNS($namespace, $name); + if (!empty($value)) { + $result->nodeValue = $value; + } + return $result; + } + + /** + * + * Create new attribute + * @param string $name + * @param string $value + * @return DOMAttr + */ + public function create_attribute($name, $value = null) { + $result = $this->doc->createAttribute($name); + if (!empty($value)) { + $result->nodeValue = $value; + } + return $result; + } + + /** + * + * Adds new node + * @param DOMNode $parentnode + * @param string $namespace + * @param string $name + * @param string $value + * @return DOMNode + */ + public function append_new_element_ns(DOMNode &$parentnode, $namespace, $name, $value = null) { + $newnode = null; + if (empty($value)) { + $newnode = $this->doc->createElementNS($namespace, $name); + } else { + $newnode = $this->doc->createElementNS($namespace, $name, $value); + } + return $parentnode->appendChild($newnode); + } + + /** + * + * Adds new node + * @param DOMNode $parentnode + * @param string $name + * @param string $value + * @return DOMNode + */ + public function append_new_element(DOMNode &$parentnode, $name, $value = null) { + $newnode = null; + if (empty($value)) { + $newnode = $this->doc->createElement($name); + } else { + $newnode = $this->doc->createElement($name, $value); + } + return $parentnode->appendChild($newnode); + } + + /** + * + * Adds new attribute + * @param DOMNode $node + * @param string $name + * @param string $value + * @return DOMNode + */ + public function append_new_attribute(DOMNode &$node, $name, $value = null) { + return $node->appendChild($this->create_attribute($name, $value)); + } + + /** + * + * Adds new attribute + * @param DOMNode $node + * @param string $namespace + * @param string $name + * @param string $value + * @return DOMNode + */ + public function append_new_attribute_ns(DOMNode &$node, $namespace, $name, $value = null) { + return $node->appendChild($this->create_attribute_ns($namespace, $name, $value)); + } + + public function fileName() {return $this->filename;} + public function filePath() {return $this->filepath;} + + protected function on_load() {return $this->isloaded;} + protected function on_save() {return true;} + protected function on_create() {return true;} + + public function resetXpath() { + $this->dxpath = null; + $this->chkxpath(); + } + + private function chkxpath() { + if (!isset($this->dxpath) || is_null($this->dxpath)){ + $this->dxpath = new DOMXPath($this->doc); + foreach ($this->arrayPrefixNS as $nskey => $nsuri) { + $this->dxpath->registerNamespace($nskey,$nsuri); + } + } + } + + private function processPath(){ + $path_parts = pathinfo($this->filename); + $this->filepath = array_key_exists('dirname',$path_parts) ? $path_parts['dirname']."/" : ''; + } +} diff --git a/backup/cc/entities.class.php b/backup/cc/entities.class.php index 165fcf5c457..9dfb396c2e4 100644 --- a/backup/cc/entities.class.php +++ b/backup/cc/entities.class.php @@ -17,6 +17,7 @@ * @package moodlecore * @subpackage backup-imscc * @copyright 2009 Mauro Rondinelli (mauro.rondinelli [AT] uvcms.com) + * @copyright 2011 Darko Miletic (dmiletic@moodlerooms.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -188,21 +189,17 @@ class entities { } } - private function get_all_files () { + protected function get_all_files () { $all_files = array(); $xpath = cc2moodle::newx_path(cc2moodle::$manifest, cc2moodle::$namespaces); - $types = array('associatedcontent/imscc_xmlv1p0/learning-application-resource', - 'webcontent', - ); - - foreach ($types as $type) { + foreach (cc2moodle::$restypes as $type) { $files = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@type="' . $type . '"]/imscc:file/@href'); - if (!empty($files)) { + if (!empty($files) && ($files->length > 0)) { foreach ($files as $file) { $all_files[] = $file; } diff --git a/backup/cc/entities11.class.php b/backup/cc/entities11.class.php new file mode 100644 index 00000000000..0c1cd34e85b --- /dev/null +++ b/backup/cc/entities11.class.php @@ -0,0 +1,58 @@ +. +/** + * @package moodlecore + * @subpackage backup-imscc + * @copyright 2011 Darko Miletic (dmiletic@moodlerooms.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.'); + +require_once($CFG->dirroot . '/backup/cc/entities.class.php'); + +class entities11 extends entities { + + public function get_external_xml($identifier) { + $xpath = cc2moodle::newx_path(cc112moodle::$manifest, cc112moodle::$namespaces); + $files = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="' . + $identifier . '"]/imscc:file/@href'); + $response = empty($files) || ($files->length == 0) ? '' : $files->item(0)->nodeValue; + return $response; + } + + protected function get_all_files () { + $all_files = array(); + $xpath = cc2moodle::newx_path(cc112moodle::$manifest, cc112moodle::$namespaces); + foreach (cc112moodle::$restypes as $type) { + $files = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@type="' . + $type . '"]/imscc:file/@href'); + if (empty($files) || ($files->length == 0)) { + continue; + } + foreach ($files as $file) { + $all_files[] = $file; + } + unset($files); + } + + $all_files = empty($all_files) ? '' : $all_files; + + return $all_files; + } + +} + diff --git a/backup/cc/entity.forum.class.php b/backup/cc/entity.forum.class.php index ab8ab51c208..143de304bd7 100644 --- a/backup/cc/entity.forum.class.php +++ b/backup/cc/entity.forum.class.php @@ -17,12 +17,56 @@ * @package moodlecore * @subpackage backup-imscc * @copyright 2009 Mauro Rondinelli (mauro.rondinelli [AT] uvcms.com) + * @copyright 2011 Darko Miletic (dmiletic@moodlerooms.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.'); -class forum extends entities { +class cc_forum extends entities { + + public function full_path ($path, $dir_sep = DIRECTORY_SEPARATOR) { + + $token = '$IMS-CC-FILEBASE$'; + $path = str_replace($token, '', $path); + + if (is_string($path) && ($path != '')) { + $dir_sep; + $dot_dir = '.'; + $up_dir = '..'; + $length = strlen($path); + $rtemp = trim($path); + $start = strrpos($path, $dir_sep); + $can_continue = ($start !== false); + $result = $can_continue ? '' : $path; + $rcount = 0; + + while ($can_continue) { + + $dir_part = ($start !== false) ? substr($rtemp, $start + 1, $length - $start) : $rtemp; + $can_continue = ($dir_part !== false); + + if ($can_continue) { + if ($dir_part != $dot_dir) { + if ($dir_part == $up_dir) { + $rcount++; + } else { + if ($rcount > 0) { + $rcount --; + } else { + $result = ($result == '') ? $dir_part : $dir_part . $dir_sep . $result; + } + } + } + $rtemp = substr($path, 0, $start); + $start = strrpos($rtemp, $dir_sep); + $can_continue = (($start !== false) || (strlen($rtemp) > 0)); + } + } + } + + return $result; + } public function generate_node () { @@ -45,6 +89,7 @@ class forum extends entities { $topic_data = $this->get_topic_data($instance); + $result = ''; if (!empty($topic_data)) { $find_tags = array('[#mod_instance#]', @@ -53,35 +98,36 @@ class forum extends entities { '[#date_now#]'); $replace_values = array($instance['instance'], - $instance['title'] . ' - ' . $topic_data['title'], - $topic_data['description'], + //To be more true to the actual forum name we use only forum title + htmlentities($topic_data['title']), + htmlentities($topic_data['description']), time()); - return str_replace($find_tags, $replace_values, $sheet_mod_forum); + $result = str_replace($find_tags, $replace_values, $sheet_mod_forum); - } else { - return ''; } + + return $result; } public function get_topic_data ($instance) { $topic_data = ''; - $namespaces = array('dt' => 'http://www.imsglobal.org/xsd/imsdt_v1p0'); - $topic_file = $this->get_external_xml($instance['resource_indentifier']); if (!empty($topic_file)) { - $topic = $this->load_xml_resource(cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . $topic_file); + $topic_file_path = cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . $topic_file; + $topic_file_dir = dirname($topic_file_path); + $topic = $this->load_xml_resource($topic_file_path); if (!empty($topic)) { - $xpath = cc2moodle::newx_path($topic, $namespaces); + $xpath = cc2moodle::newx_path($topic, cc2moodle::getforumns()); $topic_title = $xpath->query('/dt:topic/title'); - $topic_title = !empty($topic_title->item(0)->nodeValue) ? $topic_title->item(0)->nodeValue : ''; + $topic_title = !empty($topic_title->item(0)->nodeValue) ? $topic_title->item(0)->nodeValue : 'Untitled Topic'; $topic_text = $xpath->query('/dt:topic/text'); $topic_text = !empty($topic_text->item(0)->nodeValue) ? $this->update_sources($topic_text->item(0)->nodeValue, dirname($topic_file)) : ''; @@ -100,7 +146,7 @@ class forum extends entities { $attachment_html = ''; foreach ($topic_attachments as $file) { - $attachment_html .= $this->generate_attachment_html($file->nodeValue); + $attachment_html .= $this->generate_attachment_html($this->full_path($file->nodeValue,'/')); } $topic_data['description'] = !empty($attachment_html) ? $topic_text . '

Attachments:

' . $attachment_html : $topic_text; diff --git a/backup/cc/entity.label.class.php b/backup/cc/entity.label.class.php index a9b611eeca1..ebb0416c7c0 100644 --- a/backup/cc/entity.label.class.php +++ b/backup/cc/entity.label.class.php @@ -22,7 +22,7 @@ defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.'); -class label extends entities { +class cc_label extends entities { public function generate_node () { @@ -47,10 +47,10 @@ class label extends entities { '[#mod_name#]', '[#mod_content#]', '[#date_now#]'); - + //$instance['title'] $replace_values = array($instance['instance'], - $instance['title'], - $instance['title'], + 'Untitled', + 'Untitled', time()); return str_replace($find_tags, $replace_values, $sheet_mod_label); diff --git a/backup/cc/entity.quiz.class.php b/backup/cc/entity.quiz.class.php index ec97d233acd..79ff905ffb0 100644 --- a/backup/cc/entity.quiz.class.php +++ b/backup/cc/entity.quiz.class.php @@ -17,14 +17,13 @@ * @package moodlecore * @subpackage backup-imscc * @copyright 2009 Mauro Rondinelli (mauro.rondinelli [AT] uvcms.com) + * @copyright 2011 Darko Miletic (dmiletic@moodlerooms.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.'); -class quiz extends entities { - - private $namespaces = array('xmlns' => 'http://www.imsglobal.org/xsd/ims_qtiasiv1p2'); +class cc_quiz extends entities { public function generate_node_question_categories () { @@ -141,15 +140,15 @@ class quiz extends entities { '[#node_questions_feedback#]'); $replace_values = array($instance['id'], - $instance['title'], - $instance['title'], - $quiz_stamp, - $questions_strings, + htmlentities($instance['title']), + htmlentities($instance['title']), + htmlentities($quiz_stamp), + htmlentities($questions_strings), time(), $instance['options']['max_attempts'], $instance['options']['timelimit'], $node_course_modules_quiz_question_instances, - $node_course_modules_quiz_feedback); + $node_course_modules_quiz_feedback); //this one has tags $node_question_mod = str_replace($find_tags, $replace_values, $sheet_question_mod); @@ -158,7 +157,7 @@ class quiz extends entities { private function get_global_config ($assessment, $option, $default_value, $replace_values = '') { - $xpath = cc2moodle::newx_path($assessment, $this->namespaces); + $xpath = cc2moodle::newx_path($assessment, cc2moodle::getquizns()); $metadata = $xpath->query('/xmlns:questestinterop/xmlns:assessment/xmlns:qtimetadata/xmlns:qtimetadatafield'); foreach ($metadata as $field) { @@ -257,7 +256,7 @@ class quiz extends entities { $quiz_stamp = 'localhost+' . time() . '+' . $this->generate_random_string(6); $replace_values = array($instance['id'], - $instance['title'], + htmlentities($instance['title']), $quiz_stamp, $node_course_question_categories_questions); @@ -305,10 +304,10 @@ class quiz extends entities { $question_type_node = ($question_moodle_type == MOODLE_QUIZ_SHORTANSWER) ? $this->create_node_course_question_categories_question_category_question_shortanswer($question) : $question_type_node; $replace_values = array($question['id'], - $this->truncate_text($question['title'], 255, true), - $question['title'], + htmlentities($this->truncate_text($question['title'], 255, true)), + htmlentities($question['title']), $question_moodle_type, - $question['feedback'], + htmlentities($question['feedback']), time(), $question_type_node, $quiz_stamp, @@ -328,7 +327,7 @@ class quiz extends entities { $questions = array(); - $xpath = cc2moodle::newx_path($assessment, $this->namespaces); + $xpath = cc2moodle::newx_path($assessment, cc2moodle::getquizns()); if (!$is_question_bank) { $questions_items = $xpath->query('/xmlns:questestinterop/xmlns:assessment/xmlns:section/xmlns:item'); @@ -398,7 +397,7 @@ class quiz extends entities { private function get_general_feedback ($assessment, $question_identifier) { - $xpath = cc2moodle::newx_path($assessment, $this->namespaces); + $xpath = cc2moodle::newx_path($assessment, cc2moodle::getquizns()); $respconditions = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:resprocessing/xmlns:respcondition'); @@ -443,7 +442,7 @@ class quiz extends entities { private function get_feedback ($assessment, $identifier, $item_identifier, $question_type) { - $xpath = cc2moodle::newx_path($assessment, $this->namespaces); + $xpath = cc2moodle::newx_path($assessment, cc2moodle::getquizns()); $resource_processing = $xpath->query('//xmlns:item[@ident="' . $item_identifier . '"]/xmlns:resprocessing/xmlns:respcondition'); @@ -488,7 +487,7 @@ class quiz extends entities { private function get_answers_fib ($question_identifier, $identifier, $assessment, &$last_answer_id) { - $xpath = cc2moodle::newx_path($assessment, $this->namespaces); + $xpath = cc2moodle::newx_path($assessment, cc2moodle::getquizns()); $answers_fib = array(); @@ -554,7 +553,7 @@ class quiz extends entities { private function get_answers_pattern_match ($question_identifier, $identifier, $assessment, &$last_answer_id) { - $xpath = cc2moodle::newx_path($assessment, $this->namespaces); + $xpath = cc2moodle::newx_path($assessment, cc2moodle::getquizns()); $answers_fib = array(); @@ -630,7 +629,7 @@ class quiz extends entities { private function get_answers ($identifier, $assessment, &$last_answer_id) { - $xpath = cc2moodle::newx_path($assessment, $this->namespaces); + $xpath = cc2moodle::newx_path($assessment, cc2moodle::getquizns()); $answers = array(); @@ -719,7 +718,7 @@ class quiz extends entities { private function get_score ($assessment, $identifier, $question_identifier) { - $xpath = cc2moodle::newx_path($assessment, $this->namespaces); + $xpath = cc2moodle::newx_path($assessment, cc2moodle::getquizns()); $resource_processing = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:resprocessing/xmlns:respcondition'); @@ -765,7 +764,7 @@ class quiz extends entities { '[#is_single#]'); $replace_values = array($node_course_question_categories_question_answer, - $answer_string, + htmlentities($answer_string), $is_single); $node_question_categories_question = str_replace($find_tags, $replace_values, $sheet_question_categories_question); @@ -820,8 +819,8 @@ class quiz extends entities { '[#use_case#]', '[#node_course_question_categories_question_category_question_answer#]'); - $replace_values = array($answers_string, - $use_case, + $replace_values = array(htmlentities($answers_string), + htmlentities($use_case), $node_course_question_categories_question_answer); @@ -867,7 +866,7 @@ class quiz extends entities { '[#false_answer_id#]'); $replace_values = array($node_course_question_categories_question_answer, - $true_answer_id, + htmlentities($true_answer_id), $false_answer_id); $node_question_categories_question = str_replace($find_tags, $replace_values, $sheet_question_categories_question); @@ -901,7 +900,7 @@ class quiz extends entities { '[#answer_feedback#]'); $replace_values = array($answer['id'], - $answer['title'], + htmlentities($answer['title']), $answer['score'], $answer['feedback']); @@ -912,7 +911,7 @@ class quiz extends entities { private function get_question_type ($identifier, $assessment) { - $xpath = cc2moodle::newx_path($assessment, $this->namespaces); + $xpath = cc2moodle::newx_path($assessment, cc2moodle::getquizns()); $metadata = $xpath->query('//xmlns:item[@ident="' . $identifier . '"]/xmlns:itemmetadata/xmlns:qtimetadata/xmlns:qtimetadatafield'); diff --git a/backup/cc/entity.resource.class.php b/backup/cc/entity.resource.class.php index 92408fbb8ff..788503e490f 100644 --- a/backup/cc/entity.resource.class.php +++ b/backup/cc/entity.resource.class.php @@ -17,14 +17,13 @@ * @package moodlecore * @subpackage backup-imscc * @copyright 2009 Mauro Rondinelli (mauro.rondinelli [AT] uvcms.com) + * @copyright 2011 Darko Miletic (dmiletic@moodlerooms.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.'); -class resource extends entities { - - private $namespaces = array('wl' => 'http://www.imsglobal.org/xsd/imswl_v1p0'); +class cc_resource extends entities { public function generate_node () { @@ -46,9 +45,9 @@ class resource extends entities { private function create_node_course_modules_mod_resource ($sheet_mod_resource, $instance) { $link = ''; - $xpath = cc2moodle::newx_path(CC2Moodle::$manifest, CC2Moodle::$namespaces); + $xpath = cc2moodle::newx_path(cc2moodle::$manifest, cc2moodle::$namespaces); - if ($instance['common_cartriedge_type'] == CC_TYPE_WEBCONTENT || $instance['common_cartriedge_type'] == CC_TYPE_ASSOCIATED_CONTENT) { + if ($instance['common_cartriedge_type'] == cc2moodle::CC_TYPE_WEBCONTENT || $instance['common_cartriedge_type'] == cc2moodle::CC_TYPE_ASSOCIATED_CONTENT) { $resource = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="' . $instance['resource_indentifier'] . '"]/@href'); $resource = !empty($resource->item(0)->nodeValue) ? $resource->item(0)->nodeValue : ''; @@ -66,7 +65,7 @@ class resource extends entities { } } - if ($instance['common_cartriedge_type'] == CC_TYPE_WEBLINK) { + if ($instance['common_cartriedge_type'] == cc2moodle::CC_TYPE_WEBLINK) { $external_resource = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="' . $instance['resource_indentifier'] . '"]/imscc:file/@href')->item(0)->nodeValue; @@ -75,9 +74,11 @@ class resource extends entities { $resource = $this->load_xml_resource(cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . $external_resource); if (!empty($resource)) { - $xpath = cc2moodle::newx_path($resource, $this->namespaces); - $resource = $xpath->query('/wl:webLink/url/@href'); - $link = $resource->item(0)->nodeValue; + $xpath = cc2moodle::newx_path($resource, cc2moodle::getresourcens()); + $resource = $xpath->query('/wl:webLink/wl:url/@href'); + if ($resource->length > 0) { + $link = $resource->item(0)->nodeValue; + } } } } @@ -91,9 +92,9 @@ class resource extends entities { '[#date_now#]'); $replace_values = array($instance['instance'], - $instance['title'], + htmlentities($instance['title']), 'file', - $link, + htmlentities($link), '', '', time()); diff --git a/backup/cc/entity11.basiclti.class.php b/backup/cc/entity11.basiclti.class.php new file mode 100644 index 00000000000..d15366bfc9b --- /dev/null +++ b/backup/cc/entity11.basiclti.class.php @@ -0,0 +1,119 @@ +. +/** + * @package moodlecore + * @subpackage backup-imscc + * @copyright 2011 Darko Miletic (dmiletic@moodlerooms.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.'); + +class cc11_basiclti extends entities11 { + + public function generate_node () { + + cc2moodle::log_action('Creating BasicLTI mods'); + + $response = ''; + + if (!empty(cc2moodle::$instances['instances'][MOODLE_TYPE_BASICLTI])) { + foreach (cc2moodle::$instances['instances'][MOODLE_TYPE_BASICLTI] as $instance) { + $response .= $this->create_node_course_modules_mod_basiclti($instance); + } + } + + return $response; + } + + private function create_node_course_modules_mod_basiclti ($instance) { + + $sheet_mod_basiclti = cc112moodle::loadsheet(SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_BASICLTI); + + $topic_data = $this->get_basiclti_data($instance); + + $result = ''; + if (!empty($topic_data)) { + + $find_tags = array('[#mod_instance#]' , + '[#mod_basiclti_name#]' , + '[#mod_basiclti_intro#]' , + '[#mod_basiclti_timec#]' , + '[#mod_basiclti_timem#]' , + '[#mod_basiclti_toolurl#]', + '[#mod_basiclti_orgid#]' , + '[#mod_basiclti_orgurl#]' , + '[#mod_basiclti_orgdesc#]' + ); + + $replace_values = array($instance['instance'], + $topic_data['title'], + $topic_data['description'], + time(),time(), + $topic_data['launchurl'], + $topic_data['orgid'], + $topic_data['orgurl'], + $topic_data['orgdesc'] + ); + + $result = str_replace($find_tags, $replace_values, $sheet_mod_basiclti); + + } + + return $result; + } + + protected function getValue($node, $default = '') { + $result = $default; + if (is_object($node) && ($node->length > 0) && !empty($node->item(0)->nodeValue)) { + $result = htmlentities(trim($node->item(0)->nodeValue)); + } + return $result; + } + + public function get_basiclti_data($instance) { + + $topic_data = ''; + + $basiclti_file = $this->get_external_xml($instance['resource_indentifier']); + + if (!empty($basiclti_file)) { + $basiclti_file_path = cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . $basiclti_file; + $basiclti_file_dir = dirname($basiclti_file_path); + $basiclti = $this->load_xml_resource($basiclti_file_path); + if (!empty($basiclti)) { + $xpath = cc2moodle::newx_path($basiclti, cc112moodle::$basicltins); + $topic_title = $this->getValue($xpath->query('/xmlns:cartridge_basiclti_link/blti:title'),'Untitled'); + $blti_description = $this->getValue($xpath->query('/xmlns:cartridge_basiclti_link/blti:description')); + $launch_url = $this->getValue($xpath->query('/xmlns:cartridge_basiclti_link/blti:launch_url')); + $tool_raw = $this->getValue($xpath->query('/xmlns:cartridge_basiclti_link/blti:vendor/lticp:code'),null); + $tool_url = $this->getValue($xpath->query('/xmlns:cartridge_basiclti_link/blti:vendor/lticp:url'),null); + $tool_desc = $this->getValue($xpath->query('/xmlns:cartridge_basiclti_link/blti:vendor/lticp:description'),null); + $topic_data['title' ] = $topic_title; + $topic_data['description'] = $blti_description; + $topic_data['launchurl' ] = $launch_url; + $topic_data['orgid' ] = $tool_raw; + $topic_data['orgurl' ] = $tool_url; + $topic_data['orgdesc' ] = $tool_desc; + } + } + + return $topic_data; + } + +} + diff --git a/backup/cc/entity11.forum.class.php b/backup/cc/entity11.forum.class.php new file mode 100644 index 00000000000..970fae1af16 --- /dev/null +++ b/backup/cc/entity11.forum.class.php @@ -0,0 +1,177 @@ +. +/** + * @package moodlecore + * @subpackage backup-imscc + * @copyright 2011 Darko Miletic (dmiletic@moodlerooms.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.'); + +class cc11_forum extends entities11 { + + public function full_path ($path, $dir_sep = DIRECTORY_SEPARATOR) { + + $token = '$IMS-CC-FILEBASE$'; + $path = str_replace($token, '', $path); + + if (is_string($path) && ($path != '')) { + $dir_sep; + $dot_dir = '.'; + $up_dir = '..'; + $length = strlen($path); + $rtemp = trim($path); + $start = strrpos($path, $dir_sep); + $can_continue = ($start !== false); + $result = $can_continue ? '' : $path; + $rcount = 0; + + while ($can_continue) { + + $dir_part = ($start !== false) ? substr($rtemp, $start + 1, $length - $start) : $rtemp; + $can_continue = ($dir_part !== false); + + if ($can_continue) { + if ($dir_part != $dot_dir) { + if ($dir_part == $up_dir) { + $rcount++; + } else { + if ($rcount > 0) { + $rcount --; + } else { + $result = ($result == '') ? $dir_part : $dir_part . $dir_sep . $result; + } + } + } + $rtemp = substr($path, 0, $start); + $start = strrpos($rtemp, $dir_sep); + $can_continue = (($start !== false) || (strlen($rtemp) > 0)); + } + } + } + + return $result; + } + + public function generate_node () { + + cc2moodle::log_action('Creating Forum mods'); + + $response = ''; + + if (!empty(cc2moodle::$instances['instances'][MOODLE_TYPE_FORUM])) { + foreach (cc2moodle::$instances['instances'][MOODLE_TYPE_FORUM] as $instance) { + $response .= $this->create_node_course_modules_mod_forum($instance); + } + } + + return $response; + } + + private function create_node_course_modules_mod_forum ($instance) { + + $sheet_mod_forum = cc112moodle::loadsheet(SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_FORUM); + + $topic_data = $this->get_topic_data($instance); + + $result = ''; + if (!empty($topic_data)) { + + $find_tags = array('[#mod_instance#]', + '[#mod_forum_title#]', + '[#mod_forum_intro#]', + '[#date_now#]'); + + $replace_values = array($instance['instance'], + //To be more true to the actual forum name we use only forum title + htmlentities($topic_data['title']), + htmlentities($topic_data['description']), + time()); + + $result = str_replace($find_tags, $replace_values, $sheet_mod_forum); + + } + + return $result; + } + + public function get_topic_data ($instance) { + + $topic_data = ''; + + $topic_file = $this->get_external_xml($instance['resource_indentifier']); + + if (!empty($topic_file)) { + + $topic_file_path = cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . $topic_file; + $topic_file_dir = dirname($topic_file_path); + $topic = $this->load_xml_resource($topic_file_path); + + if (!empty($topic)) { + + $xpath = cc2moodle::newx_path($topic, cc112moodle::$forumns); + + $topic_title = $xpath->query('/dt:topic/dt:title'); + if ($topic_title->length > 0 && !empty($topic_title->item(0)->nodeValue)) { + $topic_title = $topic_title->item(0)->nodeValue; + } else { + $topic_title = 'Untitled Topic'; + } + + $topic_text = $xpath->query('/dt:topic/dt:text'); + $topic_text = !empty($topic_text->item(0)->nodeValue) ? $this->update_sources($topic_text->item(0)->nodeValue, dirname($topic_file)) : ''; + $topic_text = !empty($topic_text) ? str_replace("%24", "\$", $this->include_titles($topic_text)) : ''; + + if (!empty($topic_title)) { + $topic_data['title'] = $topic_title; + $topic_data['description'] = $topic_text; + } + } + + $topic_attachments = $xpath->query('/dt:topic/dt:attachments/dt:attachment/@href'); + + if ($topic_attachments->length > 0) { + + $attachment_html = ''; + + foreach ($topic_attachments as $file) { + $attachment_html .= $this->generate_attachment_html($this->full_path($file->nodeValue,'/')); + } + + $topic_data['description'] = !empty($attachment_html) ? $topic_text . '

Attachments:

' . $attachment_html : $topic_text; + } + } + + return $topic_data; + } + + private function generate_attachment_html ($filename) { + + $images_extensions = array('gif' , 'jpeg' , 'jpg' , 'jif' , 'jfif' , 'png' , 'bmp'); + + $fileinfo = pathinfo($filename); + + if (in_array($fileinfo['extension'], $images_extensions)) { + return '' . $fileinfo['basename'] . '
'; + } else { + return '' . $fileinfo['basename'] . '
'; + } + + return ''; + } +} + diff --git a/backup/cc/entity11.lti.class.php b/backup/cc/entity11.lti.class.php new file mode 100644 index 00000000000..9e1654e5ef4 --- /dev/null +++ b/backup/cc/entity11.lti.class.php @@ -0,0 +1,112 @@ +. +/** + * @package moodlecore + * @subpackage backup-imscc + * @copyright 2011 Darko Miletic (dmiletic@moodlerooms.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.'); + +class cc11_lti extends entities11 { + + public function generate_node () { + + cc2moodle::log_action('Creating BasicLTI mods'); + + $response = ''; + + if (!empty(cc2moodle::$instances['instances'][MOODLE_TYPE_LTI])) { + foreach (cc2moodle::$instances['instances'][MOODLE_TYPE_LTI] as $instance) { + $response .= $this->create_node_course_modules_mod_basiclti($instance); + } + } + + return $response; + } + + private function create_node_course_modules_mod_basiclti ($instance) { + + $sheet_mod_basiclti = cc112moodle::loadsheet(SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_LTI); + + $topic_data = $this->get_basiclti_data($instance); + + $result = ''; + if (!empty($topic_data)) { + + $find_tags = array('[#mod_instance#]' , + '[#mod_basiclti_name#]' , + '[#mod_basiclti_intro#]' , + '[#mod_basiclti_timec#]' , + '[#mod_basiclti_timem#]' , + '[#mod_basiclti_toolurl#]' + ); + + $replace_values = array($instance['instance'], + $topic_data['title'], + $topic_data['description'], + time(),time(), + $topic_data['launchurl'] + ); + + $result = str_replace($find_tags, $replace_values, $sheet_mod_basiclti); + + } + + return $result; + } + + protected function getValue($node, $default = '') { + $result = $default; + if (is_object($node) && ($node->length > 0) && !empty($node->item(0)->nodeValue)) { + $result = htmlentities(trim($node->item(0)->nodeValue)); + } + return $result; + } + + public function get_basiclti_data($instance) { + + $topic_data = ''; + + $basiclti_file = $this->get_external_xml($instance['resource_indentifier']); + + if (!empty($basiclti_file)) { + $basiclti_file_path = cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . $basiclti_file; + $basiclti_file_dir = dirname($basiclti_file_path); + $basiclti = $this->load_xml_resource($basiclti_file_path); + if (!empty($basiclti)) { + $xpath = cc2moodle::newx_path($basiclti, cc112moodle::$basicltins); + $topic_title = $this->getValue($xpath->query('/xmlns:cartridge_basiclti_link/blti:title'),'Untitled'); + $blti_description = $this->getValue($xpath->query('/xmlns:cartridge_basiclti_link/blti:description')); + $launch_url = $this->getValue($xpath->query('/xmlns:cartridge_basiclti_link/blti:launch_url')); + $tool_raw = $this->getValue($xpath->query('/xmlns:cartridge_basiclti_link/blti:vendor/lticp:code'),null); + $tool_url = $this->getValue($xpath->query('/xmlns:cartridge_basiclti_link/blti:vendor/lticp:url'),null); + $tool_desc = $this->getValue($xpath->query('/xmlns:cartridge_basiclti_link/blti:vendor/lticp:description'),null); + $topic_data['title' ] = $topic_title; + $topic_data['description'] = $blti_description; + $topic_data['launchurl' ] = $launch_url; + $topic_data['orgid' ] = $tool_raw; + $topic_data['orgurl' ] = $tool_url; + $topic_data['orgdesc' ] = $tool_desc; + } + } + + return $topic_data; + } + +} + diff --git a/backup/cc/entity11.quiz.class.php b/backup/cc/entity11.quiz.class.php new file mode 100644 index 00000000000..a56fe2de31f --- /dev/null +++ b/backup/cc/entity11.quiz.class.php @@ -0,0 +1,956 @@ +. +/** + * @package moodlecore + * @subpackage backup-imscc + * @copyright 2009 Mauro Rondinelli (mauro.rondinelli [AT] uvcms.com) + * @copyright 2011 Darko Miletic + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.'); + +class cc11_quiz extends entities11 { + + public function generate_node_question_categories () { + + $instances = $this->generate_instances(); + + $node_course_question_categories = $this->create_node_course_question_categories($instances); + $node_course_question_categories = empty($node_course_question_categories) ? '' : $node_course_question_categories; + + return $node_course_question_categories; + + } + + public function generate_node_course_modules_mod () { + + cc112moodle::log_action('Creating Quiz mods'); + + $node_course_modules_mod = ''; + $instances = $this->generate_instances(); + + if (!empty($instances)) { + foreach ($instances as $instance) { + if ($instance['is_question_bank'] == 0) { + $node_course_modules_mod .= $this->create_node_course_modules_mod($instance); + } + } + } + + return $node_course_modules_mod; + + } + + private function create_node_course_modules_mod_quiz_feedback () { + + $sheet_question_mod_feedback = cc112moodle::loadsheet(SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_QUIZ_FEEDBACK); + + return $sheet_question_mod_feedback; + } + + private function generate_instances () { + + $last_instance_id = 0; + $last_question_id = 0; + $last_answer_id = 0; + + $instances = ''; + + $types = array(MOODLE_TYPE_QUIZ, MOODLE_TYPE_QUESTION_BANK); + + foreach ($types as $type) { + + if (!empty(cc112moodle::$instances['instances'][$type])) { + + foreach (cc112moodle::$instances['instances'][$type] as $instance) { + + if ($type == MOODLE_TYPE_QUIZ) { + $is_question_bank = 0; + } else { + $is_question_bank = 1; + } + + $assessment_file = $this->get_external_xml($instance['resource_indentifier']); + + if (!empty($assessment_file)) { + + $assessment = $this->load_xml_resource(cc112moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . $assessment_file); + + if (!empty($assessment)) { + + $replace_values = array('unlimited' => 0); + + $questions = $this->get_questions($assessment, $last_question_id, $last_answer_id, dirname($assessment_file), $is_question_bank); + $question_count = count($questions); + + if (!empty($question_count)) { + + $last_instance_id++; + + $instances[$instance['resource_indentifier']]['questions'] = $questions; + $instances[$instance['resource_indentifier']]['id'] = $last_instance_id; + $instances[$instance['resource_indentifier']]['title'] = $instance['title']; + $instances[$instance['resource_indentifier']]['is_question_bank'] = $is_question_bank; + $instances[$instance['resource_indentifier']]['options']['timelimit'] = $this->get_global_config($assessment, 'qmd_timelimit', 0); + $instances[$instance['resource_indentifier']]['options']['max_attempts'] = $this->get_global_config($assessment, 'cc_maxattempts', 0, $replace_values); + } + } + } + } + } + } + + return $instances; + } + + + private function create_node_course_modules_mod ($instance) { + + $sheet_question_mod = cc112moodle::loadsheet(SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_QUIZ); + + $node_course_modules_quiz_question_instances = $this->create_node_course_modules_mod_quiz_question_instances($instance); + $node_course_modules_quiz_feedback = $this->create_node_course_modules_mod_quiz_feedback($instance); + + $questions_strings = $this->get_questions_string($instance); + $quiz_stamp = 'localhost+' . time() . '+' . $this->generate_random_string(6); + + $find_tags = array('[#mod_id#]', + '[#mod_name#]', + '[#mod_intro#]', + '[#mod_stamp#]', + '[#question_string#]', + '[#date_now#]', + '[#mod_max_attempts#]', + '[#mod_timelimit#]', + '[#node_question_instance#]', + '[#node_questions_feedback#]'); + + $replace_values = array($instance['id'], + htmlentities($instance['title']), + htmlentities($instance['title']), + htmlentities($quiz_stamp), + htmlentities($questions_strings), + time(), + $instance['options']['max_attempts'], + $instance['options']['timelimit'], + $node_course_modules_quiz_question_instances, + $node_course_modules_quiz_feedback); //this one has tags + + $node_question_mod = str_replace($find_tags, $replace_values, $sheet_question_mod); + + return $node_question_mod; + } + + private function get_global_config ($assessment, $option, $default_value, $replace_values = '') { + + $xpath = cc112moodle::newx_path($assessment, cc112moodle::getquizns()); + $metadata = $xpath->query('/xmlns:questestinterop/xmlns:assessment/xmlns:qtimetadata/xmlns:qtimetadatafield'); + + foreach ($metadata as $field) { + $field_label = $xpath->query('xmlns:fieldlabel', $field); + $field_label = !empty($field_label->item(0)->nodeValue) ? $field_label->item(0)->nodeValue : ''; + + if (strtolower($field_label) == strtolower($option)) { + $field_entry = $xpath->query('xmlns:fieldentry', $field); + $response = !empty($field_entry->item(0)->nodeValue) ? $field_entry->item(0)->nodeValue : ''; + } + } + + $response = !empty($response) ? trim($response) : ''; + + if (!empty($replace_values)) { + foreach ($replace_values as $key => $value) { + $response = ($key == $response) ? $value : $response; + } + } + + $response = empty($response) ? $default_value : $response; + + return $response; + } + + private function create_node_course_modules_mod_quiz_question_instances ($instance) { + + $node_course_module_mod_quiz_questions_instances = ''; + $sheet_question_mod_instance = cc112moodle::loadsheet(SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_QUIZ_QUESTION_INSTANCE); + + $find_tags = array('[#question_id#]' , '[#instance_id#]'); + + if (!empty($instance['questions'])) { + + foreach ($instance['questions'] as $question) { + $replace_values = array($question['id'] , $question['id']); + $node_course_module_mod_quiz_questions_instances .= str_replace($find_tags, $replace_values, $sheet_question_mod_instance); + } + + $node_course_module_mod_quiz_questions_instances = str_replace($find_tags, $replace_values, $node_course_module_mod_quiz_questions_instances); + } + + return $node_course_module_mod_quiz_questions_instances; + } + + private function get_questions_string ($instance) { + + $questions_string = ''; + + if (!empty($instance['questions'])) { + foreach ($instance['questions'] as $question) { + $questions_string .= $question['id'] . ','; + } + } + + $questions_string = !empty($questions_string) ? substr($questions_string, 0, strlen($questions_string) - 1) : ''; + + return $questions_string; + } + + private function create_node_course_question_categories ($instances) { + + $sheet_question_categories = cc112moodle::loadsheet(SHEET_COURSE_QUESTION_CATEGORIES); + + if (!empty($instances)) { + + $node_course_question_categories_question_category = ''; + + foreach ($instances as $instance) { + $node_course_question_categories_question_category .= $this->create_node_course_question_categories_question_category($instance); + } + + $find_tags = array('[#node_course_question_categories_question_category#]'); + $replace_values = array($node_course_question_categories_question_category); + + $node_course_question_categories = str_replace($find_tags, $replace_values, $sheet_question_categories); + } + + $node_course_question_categories = empty($node_course_question_categories) ? '' : $node_course_question_categories; + + return $node_course_question_categories; + } + + private function create_node_course_question_categories_question_category ($instance) { + + $sheet_question_categories_quetion_category = cc112moodle::loadsheet(SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY); + + $find_tags = array('[#quiz_id#]', + '[#quiz_name#]', + '[#quiz_stamp#]', + '[#node_course_question_categories_question_category_questions#]'); + + $node_course_question_categories_questions = $this->create_node_course_question_categories_question_category_question($instance); + $node_course_question_categories_questions = empty($node_course_question_categories_questions) ? '' : $node_course_question_categories_questions; + + $quiz_stamp = 'localhost+' . time() . '+' . $this->generate_random_string(6); + + $replace_values = array($instance['id'], + htmlentities($instance['title']), + $quiz_stamp, + $node_course_question_categories_questions); + + $node_question_categories = str_replace($find_tags, $replace_values, $sheet_question_categories_quetion_category); + + return $node_question_categories; + } + + private function create_node_course_question_categories_question_category_question ($instance) { + + global $USER; + + $node_course_question_categories_question = ''; + + $find_tags = array('[#question_id#]', + '[#question_title#]', + '[#question_text#]', + '[#question_type#]', + '[#question_general_feedback#]', + '[#date_now#]', + '[#question_type_nodes#]', + '[#question_stamp#]', + '[#question_version#]', + '[#logged_user#]'); + + $sheet_question_categories_question = cc112moodle::loadsheet(SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION); + + $questions = $instance['questions']; + + if (!empty($questions)) { + + foreach ($questions as $question) { + + $quiz_stamp = 'localhost+' . time() . '+' . $this->generate_random_string(6); + $quiz_version = 'localhost+' . time() . '+' . $this->generate_random_string(6); + + $question_moodle_type = $question['moodle_type']; + $question_cc_type = $question['cc_type']; + + $question_type_node = ''; + + $question_type_node = ($question_moodle_type == MOODLE_QUIZ_MULTIPLE_CHOICE) ? $this->create_node_course_question_categories_question_category_question_multiple_choice($question) : $question_type_node; + $question_type_node = ($question_moodle_type == MOODLE_QUIZ_TRUE_FALSE) ? $this->create_node_course_question_categories_question_category_question_true_false($question) : $question_type_node; + $question_type_node = ($question_moodle_type == MOODLE_QUIZ_ESSAY) ? $this->create_node_course_question_categories_question_category_question_eesay($question) : $question_type_node; + $question_type_node = ($question_moodle_type == MOODLE_QUIZ_SHORTANSWER) ? $this->create_node_course_question_categories_question_category_question_shortanswer($question) : $question_type_node; + + $replace_values = array($question['id'], + htmlentities($this->truncate_text($question['title'], 255, true)), + htmlentities($question['title']), + $question_moodle_type, + htmlentities($question['feedback']), + time(), + $question_type_node, + $quiz_stamp, + $quiz_version, + $USER->id); + + $node_course_question_categories_question .= str_replace($find_tags, $replace_values, $sheet_question_categories_question); + } + } + + $node_course_question_categories_question = empty($node_course_question_categories_question) ? '' : $node_course_question_categories_question; + + return $node_course_question_categories_question; + } + + private function get_questions ($assessment, &$last_question_id, &$last_answer_id, $root_path, $is_question_bank) { + + $questions = array(); + + $xpath = cc112moodle::newx_path($assessment, cc112moodle::getquizns()); + + if (!$is_question_bank) { + $questions_items = $xpath->query('/xmlns:questestinterop/xmlns:assessment/xmlns:section/xmlns:item'); + } else { + $questions_items = $xpath->query('/xmlns:questestinterop/xmlns:objectbank/xmlns:item'); + } + + foreach ($questions_items as $question_item) { + + $count_questions = $xpath->evaluate('count(xmlns:presentation/xmlns:flow/xmlns:material/xmlns:mattext)', $question_item); + + if ($count_questions == 0) { + $question_title = $xpath->query('xmlns:presentation/xmlns:material/xmlns:mattext', $question_item); + } else { + $question_title = $xpath->query('xmlns:presentation/xmlns:flow/xmlns:material/xmlns:mattext', $question_item); + } + + $question_title = !empty($question_title->item(0)->nodeValue) ? $question_title->item(0)->nodeValue : ''; + + $question_identifier = $xpath->query('@ident', $question_item); + $question_identifier = !empty($question_identifier->item(0)->nodeValue) ? $question_identifier->item(0)->nodeValue : ''; + + if (!empty($question_identifier)) { + + $question_type = $this->get_question_type($question_identifier, $assessment); + + if (!empty($question_type['moodle'])) { + + $last_question_id++; + + $questions[$question_identifier]['id'] = $last_question_id; + + $question_title = $this->update_sources($question_title, $root_path); + $question_title = !empty($question_title) ? str_replace("%24", "\$", $this->include_titles($question_title)) : ''; + + $questions[$question_identifier]['title'] = $question_title; + $questions[$question_identifier]['identifier'] = $question_identifier; + $questions[$question_identifier]['moodle_type'] = $question_type['moodle']; + $questions[$question_identifier]['cc_type'] = $question_type['cc']; + $questions[$question_identifier]['feedback'] = $this->get_general_feedback($assessment, $question_identifier); + $questions[$question_identifier]['answers'] = $this->get_answers($question_identifier, $assessment, $last_answer_id); + + } + } + } + + $questions = !empty($questions) ? $questions : ''; + + return $questions; + } + + private function str_replace_once ($search, $replace, $subject) { + + $first_char = strpos($subject, $search); + + if ($first_char !== false) { + + $before_str = substr($subject, 0, $first_char); + $after_str = substr($subject, $first_char + strlen($search)); + + return $before_str . $replace . $after_str; + + } else { + return $subject; + } + } + + private function get_general_feedback ($assessment, $question_identifier) { + + $xpath = cc112moodle::newx_path($assessment, cc112moodle::getquizns()); + + $respconditions = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:resprocessing/xmlns:respcondition'); + + if (!empty($respconditions)) { + + foreach ($respconditions as $respcondition) { + + $continue = $respcondition->getAttributeNode('continue'); + $continue = !empty($continue->nodeValue) ? strtolower($continue->nodeValue) : ''; + + if ($continue == 'yes') { + + $display_feedback = $xpath->query('xmlns:displayfeedback', $respcondition); + + if (!empty($display_feedback)) { + foreach ($display_feedback as $feedback) { + + $feedback_identifier = $feedback->getAttributeNode('linkrefid'); + $feedback_identifier = !empty($feedback_identifier->nodeValue) ? $feedback_identifier->nodeValue : ''; + + if (!empty($feedback_identifier)) { + $feedbacks_identifiers[] = $feedback_identifier; + } + } + } + } + } + } + + $feedback = ''; + $feedbacks_identifiers = empty($feedbacks_identifiers) ? '' : $feedbacks_identifiers; + + if (!empty($feedbacks_identifiers)) { + foreach ($feedbacks_identifiers as $feedback_identifier) { + $feedbacks = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:itemfeedback[@ident="' . $feedback_identifier . '"]/xmlns:flow_mat/xmlns:material/xmlns:mattext'); + $feedback .= !empty($feedbacks->item(0)->nodeValue) ? $feedbacks->item(0)->nodeValue . ' ' : ''; + } + } + + return $feedback; + } + + private function get_feedback ($assessment, $identifier, $item_identifier, $question_type) { + + $xpath = cc112moodle::newx_path($assessment, cc112moodle::getquizns()); + + $resource_processing = $xpath->query('//xmlns:item[@ident="' . $item_identifier . '"]/xmlns:resprocessing/xmlns:respcondition'); + + if (!empty($resource_processing)) { + + foreach ($resource_processing as $response) { + + $varequal = $xpath->query('xmlns:conditionvar/xmlns:varequal', $response); + $varequal = !empty($varequal->item(0)->nodeValue) ? $varequal->item(0)->nodeValue : ''; + + if (strtolower($varequal) == strtolower($identifier) || ($question_type == CC_QUIZ_ESSAY)) { + + $display_feedback = $xpath->query('xmlns:displayfeedback', $response); + + if (!empty($display_feedback)) { + foreach ($display_feedback as $feedback) { + + $feedback_identifier = $feedback->getAttributeNode('linkrefid'); + $feedback_identifier = !empty($feedback_identifier->nodeValue) ? $feedback_identifier->nodeValue : ''; + + if (!empty($feedback_identifier)) { + $feedbacks_identifiers[] = $feedback_identifier; + } + } + } + } + } + } + + $feedback = ''; + $feedbacks_identifiers = empty($feedbacks_identifiers) ? '' : $feedbacks_identifiers; + + if (!empty($feedbacks_identifiers)) { + foreach ($feedbacks_identifiers as $feedback_identifier) { + $feedbacks = $xpath->query('//xmlns:item[@ident="' . $item_identifier . '"]/xmlns:itemfeedback[@ident="' . $feedback_identifier . '"]/xmlns:flow_mat/xmlns:material/xmlns:mattext'); + $feedback .= !empty($feedbacks->item(0)->nodeValue) ? $feedbacks->item(0)->nodeValue . ' ' : ''; + } + } + + return $feedback; + } + + private function get_answers_fib ($question_identifier, $identifier, $assessment, &$last_answer_id) { + + $xpath = cc112moodle::newx_path($assessment, cc112moodle::getquizns()); + + $answers_fib = array(); + + $response_items = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:resprocessing/xmlns:respcondition'); + + foreach ($response_items as $response_item) { + + $setvar = $xpath->query('xmlns:setvar', $response_item); + $setvar = is_object($setvar->item(0)) ? $setvar->item(0)->nodeValue : ''; + + if ($setvar != '') { + + $last_answer_id++; + + $answer_title = $xpath->query('xmlns:conditionvar/xmlns:varequal[@respident="' . $identifier . '"]', $response_item); + $answer_title = !empty($answer_title->item(0)->nodeValue) ? $answer_title->item(0)->nodeValue : ''; + + $case = $xpath->query('xmlns:conditionvar/xmlns:varequal/@case', $response_item); + $case = is_object($case->item(0)) ? $case->item(0)->nodeValue : 'no' + ; + $case = strtolower($case) == 'yes' ? 1 : + 0; + + $display_feedback = $xpath->query('xmlns:displayfeedback', $response_item); + + unset($feedbacks_identifiers); + + if (!empty($display_feedback)) { + + foreach ($display_feedback as $feedback) { + + $feedback_identifier = $feedback->getAttributeNode('linkrefid'); + $feedback_identifier = !empty($feedback_identifier->nodeValue) ? $feedback_identifier->nodeValue : ''; + + if (!empty($feedback_identifier)) { + $feedbacks_identifiers[] = $feedback_identifier; + } + } + } + + $feedback = ''; + $feedbacks_identifiers = empty($feedbacks_identifiers) ? '' : $feedbacks_identifiers; + + if (!empty($feedbacks_identifiers)) { + foreach ($feedbacks_identifiers as $feedback_identifier) { + $feedbacks = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:itemfeedback[@ident="' . $feedback_identifier . '"]/xmlns:flow_mat/xmlns:material/xmlns:mattext'); + $feedback .= !empty($feedbacks->item(0)->nodeValue) ? $feedbacks->item(0)->nodeValue . ' ' : ''; + } + } + + $answers_fib[] = array('id' => $last_answer_id, + 'title' => $answer_title, + 'score' => $setvar, + 'feedback' => $feedback, + 'case' => $case); + } + } + + $answers_fib = empty($answers_fib) ? '' : $answers_fib; + + return $answers_fib; + } + + private function get_answers_pattern_match ($question_identifier, $identifier, $assessment, &$last_answer_id) { + + $xpath = cc112moodle::newx_path($assessment, cc112moodle::getquizns()); + + $answers_fib = array(); + + $response_items = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:resprocessing/xmlns:respcondition'); + + foreach ($response_items as $response_item) { + + $setvar = $xpath->query('xmlns:setvar', $response_item); + $setvar = is_object($setvar->item(0)) ? $setvar->item(0)->nodeValue : ''; + + if ($setvar != '') { + + $last_answer_id++; + + $answer_title = $xpath->query('xmlns:conditionvar/xmlns:varequal[@respident="' . $identifier . '"]', $response_item); + $answer_title = !empty($answer_title->item(0)->nodeValue) ? $answer_title->item(0)->nodeValue : ''; + + if (empty($answer_title)) { + $answer_title = $xpath->query('xmlns:conditionvar/xmlns:varsubstring[@respident="' . $identifier . '"]', $response_item); + $answer_title = !empty($answer_title->item(0)->nodeValue) ? '*' . $answer_title->item(0)->nodeValue . '*' : ''; + } + + if (empty($answer_title)) { + $answer_title = '*'; + } + + $case = $xpath->query('xmlns:conditionvar/xmlns:varequal/@case', $response_item); + $case = is_object($case->item(0)) ? $case->item(0)->nodeValue : 'no' + ; + $case = strtolower($case) == 'yes' ? 1 : + 0; + + $display_feedback = $xpath->query('xmlns:displayfeedback', $response_item); + + unset($feedbacks_identifiers); + + if (!empty($display_feedback)) { + + foreach ($display_feedback as $feedback) { + + $feedback_identifier = $feedback->getAttributeNode('linkrefid'); + $feedback_identifier = !empty($feedback_identifier->nodeValue) ? $feedback_identifier->nodeValue : ''; + + if (!empty($feedback_identifier)) { + $feedbacks_identifiers[] = $feedback_identifier; + } + } + } + + $feedback = ''; + $feedbacks_identifiers = empty($feedbacks_identifiers) ? '' : $feedbacks_identifiers; + + if (!empty($feedbacks_identifiers)) { + foreach ($feedbacks_identifiers as $feedback_identifier) { + $feedbacks = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:itemfeedback[@ident="' . $feedback_identifier . '"]/xmlns:flow_mat/xmlns:material/xmlns:mattext'); + $feedback .= !empty($feedbacks->item(0)->nodeValue) ? $feedbacks->item(0)->nodeValue . ' ' : ''; + } + } + + $answers_fib[] = array('id' => $last_answer_id, + 'title' => $answer_title, + 'score' => $setvar, + 'feedback' => $feedback, + 'case' => $case); + } + } + + $answers_fib = empty($answers_fib) ? '' : $answers_fib; + + return $answers_fib; + } + + + private function get_answers ($identifier, $assessment, &$last_answer_id) { + + $xpath = cc112moodle::newx_path($assessment, cc112moodle::getquizns()); + + $answers = array(); + + $question_cc_type = $this->get_question_type($identifier, $assessment); + $question_cc_type = $question_cc_type['cc']; + + if ($question_cc_type == CC_QUIZ_MULTIPLE_CHOICE || $question_cc_type == CC_QUIZ_MULTIPLE_RESPONSE || $question_cc_type == CC_QUIZ_TRUE_FALSE) { + + $query_answers = '//xmlns:item[@ident="' . $identifier . '"]/xmlns:presentation/xmlns:response_lid/xmlns:render_choice/xmlns:response_label'; + $query_answers_with_flow = '//xmlns:item[@ident="' . $identifier . '"]/xmlns:presentation/xmlns:flow/xmlns:response_lid/xmlns:render_choice/xmlns:response_label'; + + $query_indentifer = '@ident'; + $query_title = 'xmlns:material/xmlns:mattext'; + } + + if ($question_cc_type == CC_QUIZ_ESSAY) { + + $query_answers = '//xmlns:item[@ident="' . $identifier . '"]/xmlns:presentation/xmlns:response_str'; + $query_answers_with_flow = '//xmlns:item[@ident="' . $identifier . '"]/xmlns:presentation/xmlns:flow/xmlns:response_str'; + + $query_indentifer = '@ident'; + $query_title = 'xmlns:render_fib'; + } + + if ($question_cc_type == CC_QUIZ_FIB || $question_cc_type == CC_QUIZ_PATTERN_MACHT) { + + $xpath_query = '//xmlns:item[@ident="' . $identifier . '"]/xmlns:presentation/xmlns:response_str/@ident'; + $xpath_query_with_flow = '//xmlns:item[@ident="' . $identifier . '"]/xmlns:presentation/xmlns:flow/xmlns:response_str/@ident'; + + $count_response = $xpath->evaluate('count(' . $xpath_query_with_flow . ')'); + + if ($count_response == 0) { + $answer_identifier = $xpath->query($xpath_query); + } else { + $answer_identifier = $xpath->query($xpath_query_with_flow); + } + + $answer_identifier = !empty($answer_identifier->item(0)->nodeValue) ? $answer_identifier->item(0)->nodeValue : ''; + + if ($question_cc_type == CC_QUIZ_FIB) { + $answers = $this->get_answers_fib ($identifier, $answer_identifier, $assessment, $last_answer_id); + } else { + $answers = $this->get_answers_pattern_match ($identifier, $answer_identifier, $assessment, $last_answer_id); + } + + } else { + + $count_response = $xpath->evaluate('count(' . $query_answers_with_flow . ')'); + + if ($count_response == 0) { + $response_items = $xpath->query($query_answers); + } else { + $response_items = $xpath->query($query_answers_with_flow); + } + + if (!empty($response_items)) { + + foreach ($response_items as $response_item) { + + $last_answer_id++; + + $answer_identifier = $xpath->query($query_indentifer, $response_item); + $answer_identifier = !empty($answer_identifier->item(0)->nodeValue) ? $answer_identifier->item(0)->nodeValue : ''; + + $answer_title = $xpath->query($query_title, $response_item); + $answer_title = !empty($answer_title->item(0)->nodeValue) ? $answer_title->item(0)->nodeValue : ''; + + $answer_feedback = $this->get_feedback($assessment, $answer_identifier, $identifier, $question_cc_type); + + $answer_score = $this->get_score($assessment, $answer_identifier, $identifier); + + $answers[] = array('id' => $last_answer_id, + 'title' => $answer_title, + 'score' => $answer_score, + 'identifier' => $answer_identifier, + 'feedback' => $answer_feedback); + } + } + } + + $answers = empty($answers) ? '' : $answers; + + return $answers; + + } + + private function get_score ($assessment, $identifier, $question_identifier) { + + $xpath = cc112moodle::newx_path($assessment, cc112moodle::getquizns()); + + $resource_processing = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:resprocessing/xmlns:respcondition'); + + if (!empty($resource_processing)) { + + foreach ($resource_processing as $response) { + + $question_cc_type = $this->get_question_type($question_identifier, $assessment); + $question_cc_type = $question_cc_type['cc']; + + $varequal = $xpath->query('xmlns:conditionvar/xmlns:varequal', $response); + $varequal = !empty($varequal->item(0)->nodeValue) ? $varequal->item(0)->nodeValue : ''; + + if (strtolower($varequal) == strtolower($identifier)) { + $score = $xpath->query('xmlns:setvar', $response); + $score = !empty($score->item(0)->nodeValue) ? $score->item(0)->nodeValue : ''; + } + } + } + + $score = empty($score) ? 0 : $score; + + return $score; + } + + private function create_node_course_question_categories_question_category_question_multiple_choice ($question) { + + $node_course_question_categories_question_answer = ''; + $sheet_question_categories_question = cc112moodle::loadsheet(SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_MULTIPLE_CHOICE); + + if (!empty($question['answers'])) { + foreach ($question['answers'] as $answer) { + $node_course_question_categories_question_answer .= $this->create_node_course_question_categories_question_category_question_answer($answer); + } + } + + $answer_string = $this->get_answers_string($question['answers']); + + $is_single = ($question['cc_type'] == CC_QUIZ_MULTIPLE_CHOICE) ? 1 : 0; + + $find_tags = array('[#node_course_question_categories_question_category_question_answer#]', + '[#answer_string#]', + '[#is_single#]'); + + $replace_values = array($node_course_question_categories_question_answer, + htmlentities($answer_string), + $is_single); + + $node_question_categories_question = str_replace($find_tags, $replace_values, $sheet_question_categories_question); + + return $node_question_categories_question; + } + + private function create_node_course_question_categories_question_category_question_eesay ($question) { + + $node_course_question_categories_question_answer = ''; + + $sheet_question_categories_question = cc112moodle::loadsheet(SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_EESAY); + + if (!empty($question['answers'])) { + foreach ($question['answers'] as $answer) { + $node_course_question_categories_question_answer .= $this->create_node_course_question_categories_question_category_question_answer($answer); + } + } + + $find_tags = array('[#node_course_question_categories_question_category_question_answer#]'); + $replace_values = array($node_course_question_categories_question_answer); + + $node_question_categories_question = str_replace($find_tags, $replace_values, $sheet_question_categories_question); + + return $node_question_categories_question; + } + + private function create_node_course_question_categories_question_category_question_shortanswer ($question) { //, &$fib_questions) { + + $sheet_question_categories_question = cc112moodle::loadsheet(SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_SHORTANSWER); + $node_course_question_categories_question_answer = ''; + + if (!empty($question['answers'])) { + foreach ($question['answers'] as $answer) { + $node_course_question_categories_question_answer .= $this->create_node_course_question_categories_question_category_question_answer($answer); + } + } + + $answers_string = $this->get_answers_string($question['answers']); + + $use_case = 0; + + foreach ($question['answers'] as $answer) { + + if ($answer['case'] == 1) { + $use_case = 1; + } + + } + + $find_tags = array('[#answers_string#]', + '[#use_case#]', + '[#node_course_question_categories_question_category_question_answer#]'); + + $replace_values = array(htmlentities($answers_string), + htmlentities($use_case), + $node_course_question_categories_question_answer); + + + + $node_question_categories_question = str_replace($find_tags, $replace_values, $sheet_question_categories_question); + + return $node_question_categories_question; + + } + + private function create_node_course_question_categories_question_category_question_true_false ($question) { + + $node_course_question_categories_question_answer = ''; + + $sheet_question_categories_question = cc112moodle::loadsheet(SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_TRUE_FALSE); + + $max_score = 0; + $true_answer_id = 0; + $false_answer_id = 0; + + if (!empty($question['answers'])) { + + foreach ($question['answers'] as $answer) { + if ($answer['score'] > $max_score) { + $max_score = $answer['score']; + $true_answer_id = $answer['id']; + } + + $node_course_question_categories_question_answer .= $this->create_node_course_question_categories_question_category_question_answer($answer); + } + + foreach ($question['answers'] as $answer) { + + if ($answer['id'] != $true_answer_id) { + $max_score = $answer['score']; + $false_answer_id = $answer['id']; + } + } + } + + $find_tags = array('[#node_course_question_categories_question_category_question_answer#]', + '[#true_answer_id#]', + '[#false_answer_id#]'); + + $replace_values = array($node_course_question_categories_question_answer, + htmlentities($true_answer_id), + $false_answer_id); + + $node_question_categories_question = str_replace($find_tags, $replace_values, $sheet_question_categories_question); + + return $node_question_categories_question; + } + + private function get_answers_string ($answers) { + + $answer_string = ''; + + if (!empty($answers)) { + foreach ($answers as $answer) { + $answer_string .= $answer['id'] . ','; + } + } + + $answer_string = !empty($answer_string) ? substr($answer_string, 0, strlen($answer_string) - 1) : ''; + + return $answer_string; + + } + + private function create_node_course_question_categories_question_category_question_answer ($answer) { + + $sheet_question_categories_question_answer = cc112moodle::loadsheet(SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_ANSWER); + + $find_tags = array('[#answer_id#]', + '[#answer_text#]', + '[#answer_score#]', + '[#answer_feedback#]'); + + $replace_values = array($answer['id'], + htmlentities($answer['title']), + $answer['score'], + $answer['feedback']); + + $node_question_categories_question_answer = str_replace($find_tags, $replace_values, $sheet_question_categories_question_answer); + + return $node_question_categories_question_answer; + } + + private function get_question_type ($identifier, $assessment) { + + $xpath = cc112moodle::newx_path($assessment, cc112moodle::getquizns()); + + $metadata = $xpath->query('//xmlns:item[@ident="' . $identifier . '"]/xmlns:itemmetadata/xmlns:qtimetadata/xmlns:qtimetadatafield'); + + foreach ($metadata as $field) { + + $field_label = $xpath->query('xmlns:fieldlabel', $field); + $field_label = !empty($field_label->item(0)->nodeValue) ? $field_label->item(0)->nodeValue : ''; + + if ($field_label == 'cc_profile') { + $field_entry = $xpath->query('xmlns:fieldentry', $field); + $type = !empty($field_entry->item(0)->nodeValue) ? $field_entry->item(0)->nodeValue : ''; + } + } + + $return_type = array(); + + $return_type['moodle'] = ''; + $return_type['cc'] = $type; + + if ($type == CC_QUIZ_MULTIPLE_CHOICE) { + $return_type['moodle'] = MOODLE_QUIZ_MULTIPLE_CHOICE; + } + if ($type == CC_QUIZ_MULTIPLE_RESPONSE) { + $return_type['moodle'] = MOODLE_QUIZ_MULTIPLE_CHOICE; + } + if ($type == CC_QUIZ_TRUE_FALSE) { + $return_type['moodle'] = MOODLE_QUIZ_TRUE_FALSE; + } + if ($type == CC_QUIZ_ESSAY) { + $return_type['moodle'] = MOODLE_QUIZ_ESSAY; + } + if ($type == CC_QUIZ_FIB) { + $return_type['moodle'] = MOODLE_QUIZ_SHORTANSWER; + } + if ($type == CC_QUIZ_PATTERN_MACHT) { + $return_type['moodle'] = MOODLE_QUIZ_SHORTANSWER; + } + + return $return_type; + + } +} diff --git a/backup/cc/entity11.resource.class.php b/backup/cc/entity11.resource.class.php new file mode 100644 index 00000000000..b06e6c93712 --- /dev/null +++ b/backup/cc/entity11.resource.class.php @@ -0,0 +1,112 @@ +. +/** + * @package moodlecore + * @subpackage backup-imscc + * @copyright 2009 Mauro Rondinelli (mauro.rondinelli [AT] uvcms.com) + * @copyright 2011 Darko Miletic (dmiletic@moodlerooms.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.'); + +class cc11_resource extends entities11 { + + public function generate_node () { + + cc112moodle::log_action('Creating Resource mods'); + + $response = ''; + $sheet_mod_resource = cc112moodle::loadsheet(SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_RESOURCE); + + if (!empty(cc112moodle::$instances['instances'][MOODLE_TYPE_RESOURCE])) { + foreach (cc112moodle::$instances['instances'][MOODLE_TYPE_RESOURCE] as $instance) { + $response .= $this->create_node_course_modules_mod_resource($sheet_mod_resource, $instance); + } + } + + return $response; + + } + + private function create_node_course_modules_mod_resource ($sheet_mod_resource, $instance) { + + $link = ''; + $xpath = cc112moodle::newx_path(cc112moodle::$manifest, cc112moodle::$namespaces); + + if ($instance['common_cartriedge_type'] == cc112moodle::CC_TYPE_WEBCONTENT || $instance['common_cartriedge_type'] == cc112moodle::CC_TYPE_ASSOCIATED_CONTENT) { + $resource = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="' . $instance['resource_indentifier'] . '"]/@href'); + if ($resource->length > 0) { + $resource = !empty($resource->item(0)->nodeValue) ? $resource->item(0)->nodeValue : ''; + } else { + $resource = ''; + } + + if (empty($resource)) { + + unset($resource); + + $resource = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="' . $instance['resource_indentifier'] . '"]/imscc:file/@href'); + if ($resource->length > 0) { + $resource = !empty($resource->item(0)->nodeValue) ? $resource->item(0)->nodeValue : ''; + } else { + $resource = ''; + } + + } + + if (!empty($resource)) { + $link = $resource; + } + } + + if ($instance['common_cartriedge_type'] == cc112moodle::CC_TYPE_WEBLINK) { + + $external_resource = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="' . $instance['resource_indentifier'] . '"]/imscc:file/@href')->item(0)->nodeValue; + + if ($external_resource) { + + $resource = $this->load_xml_resource(cc112moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . $external_resource); + + if (!empty($resource)) { + $xpath = cc112moodle::newx_path($resource, cc112moodle::$resourcens); + $resource = $xpath->query('/wl:webLink/wl:url/@href'); + if ($resource->length > 0) { + $link = $resource->item(0)->nodeValue; + } + } + } + } + + $find_tags = array('[#mod_instance#]', + '[#mod_name#]', + '[#mod_type#]', + '[#mod_reference#]', + '[#mod_summary#]', + '[#mod_alltext#]', + '[#date_now#]'); + + $replace_values = array($instance['instance'], + htmlentities($instance['title']), + 'file', + htmlentities($link), + '', + '', + time()); + + return str_replace($find_tags, $replace_values, $sheet_mod_resource); + } +} diff --git a/backup/cc/includes/constants.php b/backup/cc/includes/constants.php index 58925d10496..fb555f0cf3b 100644 --- a/backup/cc/includes/constants.php +++ b/backup/cc/includes/constants.php @@ -56,6 +56,8 @@ define('SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_TRUE_FALSE', define('SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_EESAY', 'cc/sheets/course_question_categories_question_category_question_eesay.xml'); define('SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_SHORTANSWER', 'cc/sheets/course_question_categories_question_category_question_shortanswer.xml'); define('SHEET_COURSE_QUESTION_CATEGORIES_QUESTION_CATEGORY_QUESTION_ANSWER', 'cc/sheets/course_question_categories_question_category_question_answer.xml'); +define('SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_BASICLTI', 'cc/sheets/course_modules_mod_basiclti.xml'); +define('SHEET_COURSE_SECTIONS_SECTION_MODS_MOD_LTI', 'cc/sheets/course_modules_mod_lti.xml'); // CC RESOURCES TYPE ************************************************************************************************** // define('CC_TYPE_FORUM', 'imsdt_xmlv1p0'); @@ -72,6 +74,8 @@ define('MOODLE_TYPE_QUIZ', 'quiz'); define('MOODLE_TYPE_QUESTION_BANK', 'question_bank'); define('MOODLE_TYPE_RESOURCE', 'resource'); define('MOODLE_TYPE_LABEL', 'label'); +define('MOODLE_TYPE_BASICLTI', 'basiclti'); +define('MOODLE_TYPE_LTI', 'lti'); // UNKNOWN TYPE ******************************************************************************************************* // define('TYPE_UNKNOWN', '[UNKNOWN]'); diff --git a/backup/cc/schemas/domainProfile_4/ims_qtiasiv1p2.xsd b/backup/cc/schemas/domainProfile_4/ims_qtiasiv1p2.xsd index bf8d2872b15..a9aa0a7af1d 100644 --- a/backup/cc/schemas/domainProfile_4/ims_qtiasiv1p2.xsd +++ b/backup/cc/schemas/domainProfile_4/ims_qtiasiv1p2.xsd @@ -35,7 +35,7 @@ - + diff --git a/backup/cc/schemas/domainProfile_4/ims_qtiasiv1p2_def_copy.xsd b/backup/cc/schemas/domainProfile_4/ims_qtiasiv1p2_def_copy.xsd index 806870948ca..f5d36eb96e1 100644 --- a/backup/cc/schemas/domainProfile_4/ims_qtiasiv1p2_def_copy.xsd +++ b/backup/cc/schemas/domainProfile_4/ims_qtiasiv1p2_def_copy.xsd @@ -49,7 +49,7 @@ - + diff --git a/backup/cc/schemas/domainProfile_4/ims_qtiasiv1p2_localised.xsd b/backup/cc/schemas/domainProfile_4/ims_qtiasiv1p2_localised.xsd index 1cbf78aae0b..671d84e1f7a 100644 --- a/backup/cc/schemas/domainProfile_4/ims_qtiasiv1p2_localised.xsd +++ b/backup/cc/schemas/domainProfile_4/ims_qtiasiv1p2_localised.xsd @@ -43,7 +43,7 @@ - + diff --git a/backup/cc/schemas/imscp_v1p2.xsd b/backup/cc/schemas/imscp_v1p2.xsd index a8092c975f5..f6a5d07c9e1 100644 --- a/backup/cc/schemas/imscp_v1p2.xsd +++ b/backup/cc/schemas/imscp_v1p2.xsd @@ -54,7 +54,7 @@ FROM THE USE OF THIS SPECIFICATION. --> - + XSD Data File Information diff --git a/backup/cc/schemas/imscp_v1p2_localised.xsd b/backup/cc/schemas/imscp_v1p2_localised.xsd index 8098895e2fb..5afe0b5555e 100644 --- a/backup/cc/schemas/imscp_v1p2_localised.xsd +++ b/backup/cc/schemas/imscp_v1p2_localised.xsd @@ -62,7 +62,7 @@ - + XSD Data File Information diff --git a/backup/cc/schemas11/cc11libxml2validator.xsd b/backup/cc/schemas11/cc11libxml2validator.xsd new file mode 100644 index 00000000000..f1dfa35db47 --- /dev/null +++ b/backup/cc/schemas11/cc11libxml2validator.xsd @@ -0,0 +1,19 @@ + + + + + + + + diff --git a/backup/cc/schemas11/ccv1p1_imsccauth_v1p1.xsd b/backup/cc/schemas11/ccv1p1_imsccauth_v1p1.xsd new file mode 100644 index 00000000000..0c78ba39f5d --- /dev/null +++ b/backup/cc/schemas11/ccv1p1_imsccauth_v1p1.xsd @@ -0,0 +1,203 @@ + + + + + XSD Data File Information + ------------------------- + Author: Colin Smythe + Date: 31st August, 2010 + Version: 1.1 + Status: Final + Description: This is the IMS GLC Authorization Data Model for the Common Cartridge. + + History: Version 1.0 - the first release of this data model; + Version 1.1 - updates made to the namespace. + + License: IPR, License and Distribution Notices + + This machine readable file is derived from IMS Global Learning Consortium (GLC) specification IMS Common Cartridge Version 1.1 + found at http://www.imsglobal.org/cc and the original IMS GLC schema binding or code base + http://www.imsglobal.org/cc. + + Recipients of this document are requested to submit, with their comments, notification of any + relevant patent claims or other intellectual property rights of which they may be aware that might be + infringed by the schema binding contained in this document. + + IMS GLC takes no position regarding the validity or scope of any intellectual property or other + rights that might be claimed to pertain to the implementation or use of the technology described in this + document or the extent to which any license under such rights might or might not be available; neither + does it represent that it has made any effort to identify any such rights. Information on IMS GLCs + procedures with respect to rights in IMS GLC specifications can be found at the IMS GLC Intellectual Property + Rights web page: http://www.imsglobal.org/ipr/imsipr_policyFinal.pdf. + + Copyright (c) IMS Global Learning Consortium 1999-2011. All Rights Reserved. + + License Notice for Users + + Users of products or services that include this document are hereby granted a worldwide, royalty-free, + non-exclusive license to use this document. + + Distribution Notice for Developers + + Developers of products or services that are not original incorporators of this document and + have not changed this document, that is, are distributing a software product that incorporates this + document as is from a third-party source other than IMS, are hereby granted permission to copy, + display and distribute the contents of this document in any medium for any purpose without fee or + royalty provided that you include this IPR, License and Distribution notice in its entirety on ALL + copies, or portions thereof. + + Developers of products or services that are original incorporators of this document and wish + to provide distribution of this document as is or with modifications and developers of products and + services that are not original incorporators of this document and have changed this document, are + required to register with the IMS GLC community on the IMS GLC website as described in the following two + paragraphs:- + + * If you wish to distribute this document as is, with no modifications, you are hereby granted + permission to copy, display and distribute the contents of this document in any medium for any + purpose without fee or royalty provided that you include this IPR, License and Distribution notice in + its entirety on ALL copies, or portions thereof, that you make and you complete a valid license + registration with IMS and receive an email from IMS granting the license. To register, follow the + instructions on the IMS website: http://www.imsglobal.org/specificationdownload.cfm. Once + registered you are granted permission to transfer unlimited distribution rights of this document for the + purposes of third-party or other distribution of your product or service that incorporates this + document as long as this IPR, License and Distribution notice remains in place in its entirety; + + * If you wish to create and distribute a derived work from this document, you are hereby + granted permission to copy, display and distribute the contents of the derived work in any medium for + any purpose without fee or royalty provided that you include this IPR, License and Distribution + notice in its entirety on ALL copies, or portions thereof, that you make and you complete a valid + profile registration with IMS GLC and receive an email from IMS GLC granting the license. To register, follow + the instructions on the IMS GLC website: http://www.imsglobal.org/profile/. Once registered you are + granted permission to transfer unlimited distribution rights of the derived work for the purposes of + third-party or other distribution of your product or service that incorporates the derived work as long + as this IPR, License and Distribution notice remains in place in its entirety. + + The limited permissions granted above are perpetual and will not be revoked by IMS GLC or its + successors or assigns. + + THIS SPECIFICATION IS BEING OFFERED WITHOUT ANY WARRANTY WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NONINFRINGEMENT IS + EXPRESSLY DISCLAIMED. ANY USE OF THIS SPECIFICATION SHALL BE MADE ENTIRELY AT THE IMPLEMENTERS OWN RISK, AND NEITHER THE CONSORTIUM + NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF + ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY, ARISING FROM THE USE OF THIS SPECIFICATION. + + Source UML File Information + --------------------------- + The source file information must be supplied as an XMI file (without diagram layout information). + The supported UML authoring tools are: + (a) Poseidon – v6 (and later) + + Source XSLT File Information + ---------------------------- + XSL Generator: UMLtoXSDTransformv0p9.xsl + XSLT Processor: Xalan + Release: 1.0 Beta 3 + Date: 31st May, 2009 + + IMS GLC Auto-generation Binding Tool-kit (I-BAT) + ------------------------------------------------ + This file was auto-generated using the IMS GLC Binding Auto-generation Tool-kit (I-BAT). While every + attempt has been made to ensure that this tool auto-generates the files correctly, users should be aware + that this is an experimental tool. Permission is given to make use of this tool. IMS GLC makes no + claim on the materials created by third party users of this tool. Details on how to use this tool + are contained in the IMS GLC "I-BAT" Documentation available at the IMS GLC web-site. + + Tool Copyright: 2005-2010 (c) IMS Global Learning Consortium Inc. All Rights Reserved. + + + + + + + + + + + + + + + Any namespaced element from any namespace may be included within an "any" element. + The namespace for the imported element must be defined in the instance, and the schema must be imported. + The extension has a definition of "strict" i.e. they must have their own namespace. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The set of authorizations for the associated object. + + + + + + + + + + + + + + + + + + + + + The authorization detail for the cartridge in terms of the web service. + + + + + + + + + + + + + + + + + + + + + diff --git a/backup/cc/schemas11/ccv1p1_imscp_v1p2_v1p0.xsd b/backup/cc/schemas11/ccv1p1_imscp_v1p2_v1p0.xsd new file mode 100644 index 00000000000..dbcd97fc2f9 --- /dev/null +++ b/backup/cc/schemas11/ccv1p1_imscp_v1p2_v1p0.xsd @@ -0,0 +1,827 @@ + + + + + + + + + XSD Data File Information + ------------------------- + Author: Colin Smythe + Date: 31st January, 2011 + Version: 1.1 + Status: Final Release + Description: This model forms a part of the IMS GLC Common Catrtridge specification. This model is the profile of the + IMS GLC Content Package Core specification (v1.2). The changes made to create the profile are: + + (a) The 'default' characteristic for the 'Organizations' class has been removed; + (b) The 'isvisible' characteristic for the Item class has been removed; + (c) The 'parameters' characteristic for the Item class has been removed; + (d) The 'structure' characteristic for the Organization class has been fixed to 'rooted-hierarchy'; + (e) The 'extension' and 'version' characteristics for the Manifest class have been removed; + (f) The 'extension' attribute and 'extension' characteristic have been removed the Organizations class; + (g) The 'extension' attribute and 'extension' characteristic have been removed the Organization class; + (h) The 'extension' attribute and 'extension' characteristic have been removed from the Resources class; + (i) The 'extension' attribute and the 'extension' characteristic have been removed from the Resource class; + (j) The 'extension' attribute and 'extension' characteristic have been removed from the Item class; + (k) The 'extension' attribute and the 'extension' characteristic have been removed from the File class; + (l) The 'extension' attribute and 'extension' characteristic have been removed from the Dependency class; + (m) The 'type' characteristic of the Resource class has a new enumerated list of 'PredfinedContentTypes'; + (n) The 'title' attribute for the Item class has its multiplicity changed to '1' except for the top-level item + attribute in the Orgaization class where it must not occur; + (o) Manifests are NO longer allowed to contain sub-manifests; + (p) The multiplicity of the Organization class in the Organizations class has been made '0..1'; + (q) Only the metadata in the Manifest class is permitted to have the 'schema' and 'schemaversion' attributes; + (r) The 'schema', 'schemaversion' and 'title' attributes are redefined directly as 'String' primitiveTypes; + (s) The multiplicity of the 'item' attribute in the Organization class has been made '1'; + (t) The value for the 'schema' attribute has been set as 'IMS Common Cartridge'; + (u) The value for the 'schemaversion' attribute has been set to '1.1.0'; + (v) The authorizations attribute has been added as an imported extension to the manifest; + (w) The protect attribute has been added as an imported extension to the resource; + (x) The IEEE LOM attribute has been added as an imported extension to the manifest metadata; + (y) The 'intendeduse' attribute has been added to the ResourceType complexType. + + History: This profile is taken from the formal representation in UML of the IMS CP v1.2 core specification. + This is the second version of the profile for the CCv1.1. The two changes are the addition of the + ResourceMetadata class and the vocabulary for the permitted resource types. + + License: IPR, License and Distribution Notices + + This machine readable file is derived from IMS Global Learning Consortium (GLC) specification IMS Common Cartridge Version 1.1 + found at http://www.imsglobal.org/cc and the original IMS GLC schema binding or code base + http://www.imsglobal.org/cc. + + Recipients of this document are requested to submit, with their comments, notification of any + relevant patent claims or other intellectual property rights of which they may be aware that might be + infringed by the schema binding contained in this document. + + IMS GLC takes no position regarding the validity or scope of any intellectual property or other + rights that might be claimed to pertain to the implementation or use of the technology described in this + document or the extent to which any license under such rights might or might not be available; neither + does it represent that it has made any effort to identify any such rights. Information on IMS GLCs + procedures with respect to rights in IMS GLC specifications can be found at the IMS GLC Intellectual Property + Rights web page: http://www.imsglobal.org/ipr/imsipr_policyFinal.pdf. + + Copyright (c) IMS Global Learning Consortium 1999-2011. All Rights Reserved. + + License Notice for Users + + Users of products or services that include this document are hereby granted a worldwide, royalty-free, + non-exclusive license to use this document. + + Distribution Notice for Developers + + Developers of products or services that are not original incorporators of this document and + have not changed this document, that is, are distributing a software product that incorporates this + document as is from a third-party source other than IMS, are hereby granted permission to copy, + display and distribute the contents of this document in any medium for any purpose without fee or + royalty provided that you include this IPR, License and Distribution notice in its entirety on ALL + copies, or portions thereof. + + Developers of products or services that are original incorporators of this document and wish + to provide distribution of this document as is or with modifications and developers of products and + services that are not original incorporators of this document and have changed this document, are + required to register with the IMS GLC community on the IMS GLC website as described in the following two + paragraphs:- + + * If you wish to distribute this document as is, with no modifications, you are hereby granted + permission to copy, display and distribute the contents of this document in any medium for any + purpose without fee or royalty provided that you include this IPR, License and Distribution notice in + its entirety on ALL copies, or portions thereof, that you make and you complete a valid license + registration with IMS and receive an email from IMS granting the license. To register, follow the + instructions on the IMS website: http://www.imsglobal.org/specificationdownload.cfm. Once + registered you are granted permission to transfer unlimited distribution rights of this document for the + purposes of third-party or other distribution of your product or service that incorporates this + document as long as this IPR, License and Distribution notice remains in place in its entirety; + + * If you wish to create and distribute a derived work from this document, you are hereby + granted permission to copy, display and distribute the contents of the derived work in any medium for + any purpose without fee or royalty provided that you include this IPR, License and Distribution + notice in its entirety on ALL copies, or portions thereof, that you make and you complete a valid + profile registration with IMS GLC and receive an email from IMS GLC granting the license. To register, follow + the instructions on the IMS GLC website: http://www.imsglobal.org/profile/. Once registered you are + granted permission to transfer unlimited distribution rights of the derived work for the purposes of + third-party or other distribution of your product or service that incorporates the derived work as long + as this IPR, License and Distribution notice remains in place in its entirety. + + The limited permissions granted above are perpetual and will not be revoked by IMS GLC or its + successors or assigns. + + THIS SPECIFICATION IS BEING OFFERED WITHOUT ANY WARRANTY WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NONINFRINGEMENT IS + EXPRESSLY DISCLAIMED. ANY USE OF THIS SPECIFICATION SHALL BE MADE ENTIRELY AT THE IMPLEMENTERS OWN RISK, AND NEITHER THE CONSORTIUM + NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF + ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY, ARISING FROM THE USE OF THIS SPECIFICATION. + + Source UML File Information + --------------------------- + The source file information must be supplied as an XMI file (without diagram layout information). + The supported UML authoring tools are: + (a) Poseidon – v6 (and later) + + Source XSLT File Information + ---------------------------- + XSL Generator: UMLtoXSDTransformv0p9.xsl + XSLT Processor: Xalan + Release: 1.0 Beta 3 + Date: 31st May, 2009 + + IMS GLC Auto-generation Binding Tool-kit (I-BAT) + ------------------------------------------------ + This file was auto-generated using the IMS GLC Binding Auto-generation Tool-kit (I-BAT). While every + attempt has been made to ensure that this tool auto-generates the files correctly, users should be aware + that this is an experimental tool. Permission is given to make use of this tool. IMS GLC makes no + claim on the materials created by third party users of this tool. Details on how to use this tool + are contained in the IMS GLC "I-BAT" Documentation available at the IMS GLC web-site. + + Tool Copyright: 2005-2011 (c) IMS Global Learning Consortium Inc. All Rights Reserved. + + + + + + Schematron Validation Rules Information + --------------------------------------- + Author: Colin Smythe + Date: 29th November, 2010 + Version: 1.1 + Status: Final Release + + Description: This set of schematron rules have been created to increase the validation capability of the CPv1.2 XSD for CCv1.1. + A total of 10 rule sets have been created to ensure that: + [1] The set of rules to ensure that resources for Discussion Topics are correctly provided; + [2] The set of rules to ensure that resources for Web Links are correctly provided; + [3] The set of rules to ensure that resources for Assessments are correctly provided; + [4] The set of rules to ensure that resources for Question Banks are correctly provided; + [5] The set of rules to ensure that resources for Web Content are correctly provided; + [6] The set of rules to ensure that resources for Associated Content are correctly provided; + [7] The set of general rules to ensure that Dependencies are used correctly; + [8] The set of general rules to ensure that Items are defined correctly; + [9] The set of general rules to ensure that Files are used correctly; + [10] The set of general rules to ensure that Resources are used correctly; + [11] The set of rules to ensure that resources for BasicLTI are correctly provided. + + Rule Set: [1] The set of rules to ensure that resources for Discussion Topics are correctly provided. + The rules are: + (a) Detect for the Discussion Topic Resource when the required 'file' element is missing; + (b) Detect for the Discussion Topic Resource when too many 'file' elements are declared; + (c) Ensure for the Discussion Topic Resource that the 'href' attribute is not used on the 'resource' element; + (d) Detect for the Discussion Topic Resource when it has a prohibited dependency on a Discussion Topic; + (e) Detect for the Discussion Topic Resource when it has a prohibited dependency on a Web Link; + (f) Detect for the Discussion Topic Resource when it has a prohibited dependency on an Assessment; + (g) Detect for the Discussion Topic Resource when it has a prohibited dependency on a Question Bank; + (h) Detect for the Discussion Topic Resource when it has a prohibited dependency on a BasicLTI link; + + [2] The set of rules to ensure that resources for Web Links are correctly provided. + The rules are: + (a) Detect for the Web Links Resource when the required 'file' element is missing; + (b) Detect for the Web Links Resource when too many 'file' elements are declared; + (c) Ensure for the Web Links Resource that the 'href' attribute is not used on the 'resource' element; + (d) Ensure for the Web Links Resource that the 'dependency' element is not used; + + [3] The set of rules to ensure that resources for Assessments are correctly provided. + The rules are: + (a) Detect for the Assessment Resource when the required 'file' element is missing; + (b) Detect for the Assessment Resource when too many 'file' elements are declared; + (c) Ensure for the Assessment Resource that the 'href' attribute is not used on the 'resource' element; + (d) Detect for the Assessment Resource when it has a prohibited dependency on a Discussion Topic; + (e) Detect for the Assessment Resource when it has a prohibited dependency on a Web Link; + (f) Detect for the Assessment Resource when it has a prohibited dependency on an Assessment; + (g) Detect for the Assessment Resource when it has a prohibited dependency on a Question Bank; + (h) Detect for the Assessment Resource when it has a prohibited dependency on a BasicLTI link; + + [4] The set of rules to ensure that resources for Question Banks are correctly provided. + The rules are: + (a) Ensure that no more than one Qestion Bank is defiend as a resource; + (b) Detect for the Question Bank Resource when the required 'file' element is missing; + (c) Detect for the Question Bank Resource when too many 'file' elements are declared; + (d) Ensure for the Question Bank Resource that the 'href' attribute is not used on the 'resource' element; + (e) Detect for the Question Bank Resource when it has a prohibited dependency on a Discussion Topic; + (f) Detect for the Question Bank Resource when it has a prohibited dependency on a Web Link; + (g) Detect for the Question Bank Resource when it has a prohibited dependency on an Assessment; + (h) Detect for the Question Bank Resource when it has a prohibited dependency on a Question Bank; + (i) Detect for the Question Bank Resource when it has a prohibited dependency on a BasicLTI link; + + [5] The set of rules to ensure that resources for Web Content are correctly provided. + The rules are: + (a) Detect for the Web Content Resource when it has a prohibited dependency on a Discussion Topic; + (b) Detect for the Web Content Resource when it has a prohibited dependency on a Web Link; + (c) Detect for the Web Content Resource when it has a prohibited dependency on an Assessment; + (d) Detect for the Web Content Resource when it has a prohibited dependency on a Question Bank; + (e) Detect for the Web Content Resource when it has a prohibited dependency on a Associated Content; + (f) Detect for the Web Content Resource when it has a prohibited dependency on a BasicLTI link; + (g) A Web Content Resource has a missing 'href' attribute (required because the resource is directly referenced by an Item). [TO BE VERIFIED] + + [6] The set of rules to ensure that resources for Associated Content are correctly provided. + The rules are: + (a) Detect for the Associated Content Resource when it has a prohibited dependency on a Discussion Topic; + (b) Detect for the Associated Content Resource when it has a prohibited dependency on a Web Link; + (c) Detect for the Associated Content Resource when it has a prohibited dependency on an Assessment; + (d) Detect for the Associated Content Resource when it has a prohibited dependency on a Question Bank; + (e) Detect for the Associated Content Resource when it has a prohibited dependency on a Associated Content; + (f) Detect for the Associated Content Resource when it has a prohibited dependency on a BasicLTI link; + (g) An Associated Content Resource has a missing 'href' attribute (required because the resource is directly referenced by an Item). [TO BE VERIFIED] + + [7] The set of general rules to ensure that Dependencies are used correctly. + The rules are: + (a) A 'dependency' element has a circular reference to its host 'resource' element with identifier; + (b) In a 'resource' element at least two 'dependency' elements reference the same 'resource' element. + + [8] The set of general rules to ensure that Items are defined correctly. + The rules are: + (a) An Item has a prohibited reference(s) to a Question Bank Resource; + (b) A Learning Object Item contains prohibited child Item(s). + + [9] The set of general rules to ensure that Files are used correctly. + The rules are: + (a) In a 'resource' element at least two 'file' elements have the same 'href' attribute; + + [10] The set of general rules to ensure that Resources are used correctly. + The rules are: + (a) For a 'resource' element with the 'href' attribute the 'file' element is missing; + (b) For a 'resource' element with the 'href' attribute there is no 'file' element with the correct 'href' attribute. + + [11] The set of rules to ensure that resources for BasicLTI are correctly provided. + The rules are: + (a) Detect for the BasicLTI Resource when it has a prohibited dependency on a Discussion Topic; + (b) Detect for the BasicLTI Resource when it has a prohibited dependency on a Web Link; + (c) Detect for the BasicLTI Resource when it has a prohibited dependency on an Assessment; + (d) Detect for the BasicLTI Resource when it has a prohibited dependency on a Question Bank; + (e) Detect for the BasicLTI Resource when it has a prohibited dependency on a Web Content; + (f) Detect for the BasicLTI Resource when it has a prohibited dependency on a BasicLTI link. + + + + + Schematron validation rules for the Common Cartridge v1p1 profile of CP v1.1.4/1.2 + + + + RULE SET 1: The set of rules to ensure that resources for Discussion Topics are correctly provided + + + + [RULE 1a] For the Discussion Topic Resource the required 'file' element is missing. + + + [RULE 1b] For the Discussion Topic Resource there are too many 'file' element references: . + + + [RULE 1c] For the Discussion Topic Resource the 'href' attribute must not be used on the 'resource' element. + + + [RULE 1d] The Discussion Topic Resource has a prohibited dependency on a Discussion Topic: + + + [RULE 1e] The Discussion Topic Resource has a prohibited dependency on a Web Link: + + + [RULE 1f] The Discussion Topic Resource has a prohibited dependency on an Assessment: + + + [RULE 1g] The Discussion Topic Resource has a prohibited dependency on a Question Bank: + + + [RULE 1h] The Discussion Topic Resource has a prohibited dependency on a BasicLTI: + + + + + + + + + RULE SET 2: The set of rules to ensure that resources for Web Links are correctly provided + + + + [RULE 2a] For the Web Link Resource the required 'file' element is missing. + + + [RULE 2b] For the Web Link Resource there are too many 'file' element references: . + + + [RULE 2c] For the Web Link Resource the 'href' attribute must not be used on the 'resource' element. + + + [RULE 2d] For the Web Link Resource the prohibited 'dependency' element is used: . + + + + + + + + + RULE SET 3: The set of rules to ensure that resources for Assessments are correctly provided + + + + [RULE 3a] For the Assessments Resource the required 'file' element is missing. + + + [RULE 3b] For the Assessments Resource there are too many 'file' element references: . + + + [RULE 3c] For the Assessments Resource the 'href' attribute must not be used on the 'resource' element. + + + [RULE 3d] The Assessment Resource has a prohibited dependency on a Discussion Topic: + + + [RULE 3e] The Assessment Resource has a prohibited dependency on a Web Link: + + + [RULE 3f] The Assessment Resource has a prohibited dependency on an Assessment: + + + [RULE 3g] The Assessment Resource has a prohibited dependency on a Question Bank: + + + [RULE 3h] The Assessment Resource has a prohibited dependency on a BasicLTI: + + + + + + + + + RULE SET 4: The set of rules to ensure that resources for Question Banks are correctly provided + + + + [RULE 4a] The are too many Question Bank Resources (a maximum of one is permitted). Number of Question Bank Resources is: . + + + + + + [RULE 4b] For the Question Bank Resource the required 'file' element is missing. + + + [RULE 4c] For the Question Bank Resource there are too many 'file' element references: . + + + [RULE 4d] For the Question Bank Resource the 'href' attribute must not be used on the 'resource' element. + + + [RULE 4e] The Question Bank Resource has a prohibited dependency on a Discussion Topic: + + + [RULE 4f] The Question Bank Resource has a prohibited dependency on a Web Link: + + + [RULE 4g] The Question Bank Resource has a prohibited dependency on an Assessment: + + + [RULE 4h] The Question Bank Resource has a prohibited dependency on a Question Bank: + + + [RULE 4i] The Question Bank Resource has a prohibited dependency on a BasicLTI: + + + + + + + + + RULE SET 5: The set of rules to ensure that resources for Web Content are correctly provided + + + + [RULE 5a] The Web Content has a prohibited dependency on a Discussion Topic: . + + + [RULE 5b] The Web Content has a prohibited dependency on a Web Link: . + + + [RULE 5c] The Web Content has a prohibited dependency on an Assessment: . + + + [RULE 5d] The Web Content has a prohibited dependency on a Question Bank: . + + + [RULE 5e] The Web Content has a prohibited dependency on an Associated Content: . + + + [RULE 5f] The Web Content has a prohibited dependency on a BasicLTI: . + + + + + + + + + RULE SET 6: The set of rules to ensure that resources for Associated Content are correctly provided + + + + [RULE 6a] The Associated Content Resource has a prohibited dependency on a Discussion Topic: . + + + [RULE 6b] The Associated Content Resource has a prohibited dependency on a Web Link: . + + + [RULE 6c] The Associated Content Resource has a prohibited dependency on an Assessment: . + + + [RULE 6d] The Associated Content Resource has a prohibited dependency on a Question Bank: . + + + [RULE 6e] The Associated Content Resource has a prohibited dependency on an Associated Content: . + + + [RULE 6f] The Associated Content Resource has a prohibited dependency on a BasicLTI: . + + + + + + + + + RULE SET 7: The set of rules to ensure that Dependencies are used correctly. + + + + [RULE 7a] A 'dependency' element has a circular reference to its host 'resource' element with identifier: . + + + + + [RULE 7b] In a 'resource' element at least two 'dependency' elements reference the same 'resource' element. . + + + + + + + + + RULE SET 8: The set of rules to ensure that Items are defined correctly. + + + + [RULE 8a] An Item has a prohibited reference(s) to a Question Bank Resource: . + + + + + [RULE 8b] A Learning Object Item contains prohibited child Item(s): . + + + + + + + + + RULE SET 9: The set of rules to ensure that Files are used correctly. + + + + [RULE 9a] In a 'resource' element at least two 'file' elements have the same 'href' attribute: . + + + + + + + + + RULE SET 10: The set of general rules to ensure that Resources are used correctly. + + + + [RULE 10a] For a 'resource' element with the 'href' attribute the 'file' element is missing: . + + + [RULE 10b] For a 'resource' element with the 'href' attribute there is no 'file' element with the correct 'href' attribute: . + + + + + + + + + RULE SET 11: The set of rules to ensure that resources for BasicLTI are correctly provided + + + + [RULE 11a] The BasicLTI has a prohibited dependency on a Discussion Topic: . + + + [RULE 11b] The BasicLTI has a prohibited dependency on a Web Link: . + + + [RULE 11c] The Web Content has a prohibited dependency on an Assessment: . + + + [RULE 11d] The Web Content has a prohibited dependency on a Question Bank: . + + + [RULE 11e] The Web Content has a prohibited dependency on an Associated Content: . + + + [RULE 11f] The Web Content has a prohibited dependency on a BasicLTI: . + + + + + + + + + + + + + + + + + + + + + + + + + + + + Any namespaced element from any namespace may be included within an "any" element. + The namespace for the imported element must be defined in the instance, and the schema must be imported. + The extension has a definition of "strict" i.e. they must have their own namespace. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

This identifies a resource whose files this resource depends upon. The reference to an identifier in the resources section is contained in the Identifierref attribute.

+
+
+ + + +
+ + + + +

A listing of file that this resource is dependent on. The href attribute identifies the location of the file. This may have some meta-data.

+
+
+ + + + +
+ + + + +

This is the structure that describes the shape of the organization. It is used in a hierarchical organizational scheme by ordering and nesting. Each Item has an identifier that is unique within the Manifest file. Identifierref acts as a reference to an identifier in the resources section. An Item has a title and may have meta-data. The parameters and isvisible attributes have been removed for this profile.

+
+
+ + + + + + + +
+ + + + +

This is the structure that describes the top-level shape of the organization and so only a single Item is permitted. The top-level has an identifier that is unique within the Manifest file. It may have meta-data but it has not title. It can contain any number of Items. The parameters and isvisible attributes have been removed for this profile

+
+
+ + + + + +
+ + + + +

A reusable unit of instruction. It encapsulates meta-data, organizations, resource references and authorization.
It must have an identifier that is unique within the Manifest. The version and reference base is optional.
The base provides the relative path offset for the content file(s).

+
+
+ + + + + + + + +
+ + + + +

This is the meta-data describing the Manifest. The schema describes the schema that defines and controls the Manifest.
Schemaversion describes the version of the above schema (e.g., 1,0, 1.1). In Common Cartridge all of the meta-data is described
using the iEEE LOM standard format. CC manifest metadata is required.

+
+
+ + + + + +

This is the meta-data describing the associated class (but not the manifest which has its own meta-data structure).
In Common Cartridge all of the meta-data is described using the IEEE LOM standard format.

+
+
+ + + +
+
+ + + + +

This is the meta-data describing the associated class (but not the manifest which has its own meta-data structure).
In Common Cartridge all of the meta-data is described using the IEEE LOM standard format.

+
+
+ + + +
+
+ +
+
+ + + + +

This is the meta-data describing the associated class (but not the manifest which has its own meta-data structure).
In Common Cartridge all of the meta-data is described using the IEEE LOM standard format.

+
+
+ + + +
+ + + + +

Describes a particular hierarchical organization in this profile; this is the only type of oranization that is permitted. The identifier, for the organization, that is unique within the Manifest file. The organization may have meta-data.

+
+
+ + + + + + + +
+ + + + +

Describes zero or one structures or organizations for the Cartridge. Only one organization is permitted so the default attribute has been removed for this Profile.

+
+
+ + + +
+ + + + +

A reference to a resource which consists of one or more physical files. The Identifer of the resource is unique within the scope of its containing Manifest file. The Type attribute indicates the type of resource - for the Cartridge this is an enumerated set. The resource may have meta-data, zero or more files references, and zero or more dependencies.

+

CCV1.1 PROFILE: The authorizations 'protected' attribute and the 'intendedUse' attribute are added.

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +

This is the container for resource specific metadata..

+
+
+ + + +
+ + + + +

A collection of references to resources. There is no assumption of order or hierarchy. The base attribute provides the relative path offset for the content file(s).

+
+
+ + + + +
+ + + + + + + + + + + + + +
diff --git a/backup/cc/schemas11/ccv1p1_imsdt_v1p1.xsd b/backup/cc/schemas11/ccv1p1_imsdt_v1p1.xsd new file mode 100644 index 00000000000..146ce82ed83 --- /dev/null +++ b/backup/cc/schemas11/ccv1p1_imsdt_v1p1.xsd @@ -0,0 +1,222 @@ + + + + + XSD Data File Information + ------------------------- + Author: Colin Smythe + Date: 31st August, 2010 + Version: 1.1 + Status: Final + Description: This is the IMS GLC Discussion Topics Data Model for the Common Cartridge. + + History: Version 1.0 - the first release of this data model; + Version 1.1 - updates made to the namespace. + + License: IPR, License and Distribution Notices + + This machine readable file is derived from IMS Global Learning Consortium (GLC) specification IMS Common Cartridge Version 1.1 + found at http://www.imsglobal.org/cc and the original IMS GLC schema binding or code base + http://www.imsglobal.org/cc. + + Recipients of this document are requested to submit, with their comments, notification of any + relevant patent claims or other intellectual property rights of which they may be aware that might be + infringed by the schema binding contained in this document. + + IMS GLC takes no position regarding the validity or scope of any intellectual property or other + rights that might be claimed to pertain to the implementation or use of the technology described in this + document or the extent to which any license under such rights might or might not be available; neither + does it represent that it has made any effort to identify any such rights. Information on IMS GLCs + procedures with respect to rights in IMS GLC specifications can be found at the IMS GLC Intellectual Property + Rights web page: http://www.imsglobal.org/ipr/imsipr_policyFinal.pdf. + + Copyright (c) IMS Global Learning Consortium 1999-2011. All Rights Reserved. + + License Notice for Users + + Users of products or services that include this document are hereby granted a worldwide, royalty-free, + non-exclusive license to use this document. + + Distribution Notice for Developers + + Developers of products or services that are not original incorporators of this document and + have not changed this document, that is, are distributing a software product that incorporates this + document as is from a third-party source other than IMS, are hereby granted permission to copy, + display and distribute the contents of this document in any medium for any purpose without fee or + royalty provided that you include this IPR, License and Distribution notice in its entirety on ALL + copies, or portions thereof. + + Developers of products or services that are original incorporators of this document and wish + to provide distribution of this document as is or with modifications and developers of products and + services that are not original incorporators of this document and have changed this document, are + required to register with the IMS GLC community on the IMS GLC website as described in the following two + paragraphs:- + + * If you wish to distribute this document as is, with no modifications, you are hereby granted + permission to copy, display and distribute the contents of this document in any medium for any + purpose without fee or royalty provided that you include this IPR, License and Distribution notice in + its entirety on ALL copies, or portions thereof, that you make and you complete a valid license + registration with IMS and receive an email from IMS granting the license. To register, follow the + instructions on the IMS website: http://www.imsglobal.org/specificationdownload.cfm. Once + registered you are granted permission to transfer unlimited distribution rights of this document for the + purposes of third-party or other distribution of your product or service that incorporates this + document as long as this IPR, License and Distribution notice remains in place in its entirety; + + * If you wish to create and distribute a derived work from this document, you are hereby + granted permission to copy, display and distribute the contents of the derived work in any medium for + any purpose without fee or royalty provided that you include this IPR, License and Distribution + notice in its entirety on ALL copies, or portions thereof, that you make and you complete a valid + profile registration with IMS GLC and receive an email from IMS GLC granting the license. To register, follow + the instructions on the IMS GLC website: http://www.imsglobal.org/profile/. Once registered you are + granted permission to transfer unlimited distribution rights of the derived work for the purposes of + third-party or other distribution of your product or service that incorporates the derived work as long + as this IPR, License and Distribution notice remains in place in its entirety. + + The limited permissions granted above are perpetual and will not be revoked by IMS GLC or its + successors or assigns. + + THIS SPECIFICATION IS BEING OFFERED WITHOUT ANY WARRANTY WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NONINFRINGEMENT IS + EXPRESSLY DISCLAIMED. ANY USE OF THIS SPECIFICATION SHALL BE MADE ENTIRELY AT THE IMPLEMENTERS OWN RISK, AND NEITHER THE CONSORTIUM + NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF + ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY, ARISING FROM THE USE OF THIS SPECIFICATION. + + Source UML File Information + --------------------------- + The source file information must be supplied as an XMI file (without diagram layout information). + The supported UML authoring tools are: + (a) Poseidon – v6 (and later) + + Source XSLT File Information + ---------------------------- + XSL Generator: UMLtoXSDTransformv0p9.xsl + XSLT Processor: Xalan + Release: 1.0 Beta 3 + Date: 31st May, 2009 + + IMS GLC Auto-generation Binding Tool-kit (I-BAT) + ------------------------------------------------ + This file was auto-generated using the IMS GLC Binding Auto-generation Tool-kit (I-BAT). While every + attempt has been made to ensure that this tool auto-generates the files correctly, users should be aware + that this is an experimental tool. Permission is given to make use of this tool. IMS GLC makes no + claim on the materials created by third party users of this tool. Details on how to use this tool + are contained in the IMS GLC "I-BAT" Documentation available at the IMS GLC web-site. + + Tool Copyright: 2005-2010 (c) IMS Global Learning Consortium Inc. All Rights Reserved. + + + + + + + + + + + + + Any namespaced element from any namespace may be included within an "any" element. + The namespace for the imported element must be defined in the instance, and the schema must be imported. + The extension has a definition of "strict" i.e. they must have their own namespace. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The Topic complexType for the discussion topic object. + + + + + + + + + + + + + + + + + + + + The Text for the discussion topic. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backup/cc/schemas11/ccv1p1_imswl_v1p1.xsd b/backup/cc/schemas11/ccv1p1_imswl_v1p1.xsd new file mode 100644 index 00000000000..4a9a016bfc4 --- /dev/null +++ b/backup/cc/schemas11/ccv1p1_imswl_v1p1.xsd @@ -0,0 +1,202 @@ + + + + + XSD Data File Information + ------------------------- + Author: Colin Smythe + Date: 31st August, 2010 + Version: 1.1 + Status: Final + Description: This is the IMS GLC Web Links Data Model for the Common Cartridge. + + History: Version 1.0 - the first release of this data model; + Version 1.1 - updates made to the namespace. + + License: IPR, License and Distribution Notices + + This machine readable file is derived from IMS Global Learning Consortium (GLC) specification IMS Common Cartridge Version 1.1 + found at http://www.imsglobal.org/cc and the original IMS GLC schema binding or code base + http://www.imsglobal.org/cc. + + Recipients of this document are requested to submit, with their comments, notification of any + relevant patent claims or other intellectual property rights of which they may be aware that might be + infringed by the schema binding contained in this document. + + IMS GLC takes no position regarding the validity or scope of any intellectual property or other + rights that might be claimed to pertain to the implementation or use of the technology described in this + document or the extent to which any license under such rights might or might not be available; neither + does it represent that it has made any effort to identify any such rights. Information on IMS GLCs + procedures with respect to rights in IMS GLC specifications can be found at the IMS GLC Intellectual Property + Rights web page: http://www.imsglobal.org/ipr/imsipr_policyFinal.pdf. + + Copyright (c) IMS Global Learning Consortium 1999-2011. All Rights Reserved. + + License Notice for Users + + Users of products or services that include this document are hereby granted a worldwide, royalty-free, + non-exclusive license to use this document. + + Distribution Notice for Developers + + Developers of products or services that are not original incorporators of this document and + have not changed this document, that is, are distributing a software product that incorporates this + document as is from a third-party source other than IMS, are hereby granted permission to copy, + display and distribute the contents of this document in any medium for any purpose without fee or + royalty provided that you include this IPR, License and Distribution notice in its entirety on ALL + copies, or portions thereof. + + Developers of products or services that are original incorporators of this document and wish + to provide distribution of this document as is or with modifications and developers of products and + services that are not original incorporators of this document and have changed this document, are + required to register with the IMS GLC community on the IMS GLC website as described in the following two + paragraphs:- + + * If you wish to distribute this document as is, with no modifications, you are hereby granted + permission to copy, display and distribute the contents of this document in any medium for any + purpose without fee or royalty provided that you include this IPR, License and Distribution notice in + its entirety on ALL copies, or portions thereof, that you make and you complete a valid license + registration with IMS and receive an email from IMS granting the license. To register, follow the + instructions on the IMS website: http://www.imsglobal.org/specificationdownload.cfm. Once + registered you are granted permission to transfer unlimited distribution rights of this document for the + purposes of third-party or other distribution of your product or service that incorporates this + document as long as this IPR, License and Distribution notice remains in place in its entirety; + + * If you wish to create and distribute a derived work from this document, you are hereby + granted permission to copy, display and distribute the contents of the derived work in any medium for + any purpose without fee or royalty provided that you include this IPR, License and Distribution + notice in its entirety on ALL copies, or portions thereof, that you make and you complete a valid + profile registration with IMS GLC and receive an email from IMS GLC granting the license. To register, follow + the instructions on the IMS GLC website: http://www.imsglobal.org/profile/. Once registered you are + granted permission to transfer unlimited distribution rights of the derived work for the purposes of + third-party or other distribution of your product or service that incorporates the derived work as long + as this IPR, License and Distribution notice remains in place in its entirety. + + The limited permissions granted above are perpetual and will not be revoked by IMS GLC or its + successors or assigns. + + THIS SPECIFICATION IS BEING OFFERED WITHOUT ANY WARRANTY WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NONINFRINGEMENT IS + EXPRESSLY DISCLAIMED. ANY USE OF THIS SPECIFICATION SHALL BE MADE ENTIRELY AT THE IMPLEMENTERS OWN RISK, AND NEITHER THE CONSORTIUM + NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF + ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY, ARISING FROM THE USE OF THIS SPECIFICATION. + + Source UML File Information + --------------------------- + The source file information must be supplied as an XMI file (without diagram layout information). + The supported UML authoring tools are: + (a) Poseidon – v6 (and later) + + Source XSLT File Information + ---------------------------- + XSL Generator: UMLtoXSDTransformv0p9.xsl + XSLT Processor: Xalan + Release: 1.0 Beta 3 + Date: 31st May, 2009 + + IMS GLC Auto-generation Binding Tool-kit (I-BAT) + ------------------------------------------------ + This file was auto-generated using the IMS GLC Binding Auto-generation Tool-kit (I-BAT). While every + attempt has been made to ensure that this tool auto-generates the files correctly, users should be aware + that this is an experimental tool. Permission is given to make use of this tool. IMS GLC makes no + claim on the materials created by third party users of this tool. Details on how to use this tool + are contained in the IMS GLC "I-BAT" Documentation available at the IMS GLC web-site. + + Tool Copyright: 2005-2010 (c) IMS Global Learning Consortium Inc. All Rights Reserved. + + + + + + + + + + + + + Any namespaced element from any namespace may be included within an "any" element. + The namespace for the imported element must be defined in the instance, and the schema must be imported. + The extension has a definition of "strict" i.e. they must have their own namespace. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The WebLink complexType for the associated object. + + + + + + + + + + + + + The URL for the web link. + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backup/cc/schemas11/ccv1p1_lommanifest_v1p0.xsd b/backup/cc/schemas11/ccv1p1_lommanifest_v1p0.xsd new file mode 100644 index 00000000000..1c2025b247e --- /dev/null +++ b/backup/cc/schemas11/ccv1p1_lommanifest_v1p0.xsd @@ -0,0 +1,822 @@ + + + + + XSD Data File Information + ------------------------- + Author: Colin Smythe + Date: 31st January, 2011 + Version: 1.1 + Status: Final + Description: This is the IMS GLC Meta-data v1.3 binding of the IEEE LOMv1.0 for the + Common Cartridge v1.1 Manifest Metadata. This is based on the LOM Strict bindings. + The core changes are: + a) MetaMetadata complexType is removed; + b) Annotation complexType is removed; + c) In the Technical complexType only the format element is permitted; + d) In the Educational complexType only the 'learningResourceType' element and + 'intendedEndUserRole' are permitted; + e) In the General complexType the 'structure' and 'aggregationLevel' elements are prohibited; + f) Only the 'contribute' element in the 'LifeCycle' complexType are permitted; + + History: Version 1.1: The first usage of this XSD for the CC Manifest Profile. + + License: IPR, License and Distribution Notices + + This machine readable file is derived from IMS Global Learning Consortium (GLC) specification IMS Common Cartridge Version 1.1 + found at http://www.imsglobal.org/cc and the original IMS GLC schema binding or code base + http://www.imsglobal.org/cc. + + Recipients of this document are requested to submit, with their comments, notification of any + relevant patent claims or other intellectual property rights of which they may be aware that might be + infringed by the schema binding contained in this document. + + IMS GLC takes no position regarding the validity or scope of any intellectual property or other + rights that might be claimed to pertain to the implementation or use of the technology described in this + document or the extent to which any license under such rights might or might not be available; neither + does it represent that it has made any effort to identify any such rights. Information on IMS GLCs + procedures with respect to rights in IMS GLC specifications can be found at the IMS GLC Intellectual Property + Rights web page: http://www.imsglobal.org/ipr/imsipr_policyFinal.pdf. + + Copyright (c) IMS Global Learning Consortium 1999-2011. All Rights Reserved. + + License Notice for Users + + Users of products or services that include this document are hereby granted a worldwide, royalty-free, + non-exclusive license to use this document. + + Distribution Notice for Developers + + Developers of products or services that are not original incorporators of this document and + have not changed this document, that is, are distributing a software product that incorporates this + document as is from a third-party source other than IMS, are hereby granted permission to copy, + display and distribute the contents of this document in any medium for any purpose without fee or + royalty provided that you include this IPR, License and Distribution notice in its entirety on ALL + copies, or portions thereof. + + Developers of products or services that are original incorporators of this document and wish + to provide distribution of this document as is or with modifications and developers of products and + services that are not original incorporators of this document and have changed this document, are + required to register with the IMS GLC community on the IMS GLC website as described in the following two + paragraphs:- + + * If you wish to distribute this document as is, with no modifications, you are hereby granted + permission to copy, display and distribute the contents of this document in any medium for any + purpose without fee or royalty provided that you include this IPR, License and Distribution notice in + its entirety on ALL copies, or portions thereof, that you make and you complete a valid license + registration with IMS and receive an email from IMS granting the license. To register, follow the + instructions on the IMS website: http://www.imsglobal.org/specificationdownload.cfm. Once + registered you are granted permission to transfer unlimited distribution rights of this document for the + purposes of third-party or other distribution of your product or service that incorporates this + document as long as this IPR, License and Distribution notice remains in place in its entirety; + + * If you wish to create and distribute a derived work from this document, you are hereby + granted permission to copy, display and distribute the contents of the derived work in any medium for + any purpose without fee or royalty provided that you include this IPR, License and Distribution + notice in its entirety on ALL copies, or portions thereof, that you make and you complete a valid + profile registration with IMS GLC and receive an email from IMS GLC granting the license. To register, follow + the instructions on the IMS GLC website: http://www.imsglobal.org/profile/. Once registered you are + granted permission to transfer unlimited distribution rights of the derived work for the purposes of + third-party or other distribution of your product or service that incorporates the derived work as long + as this IPR, License and Distribution notice remains in place in its entirety. + + The limited permissions granted above are perpetual and will not be revoked by IMS GLC or its + successors or assigns. + + THIS SPECIFICATION IS BEING OFFERED WITHOUT ANY WARRANTY WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NONINFRINGEMENT IS + EXPRESSLY DISCLAIMED. ANY USE OF THIS SPECIFICATION SHALL BE MADE ENTIRELY AT THE IMPLEMENTERS OWN RISK, AND NEITHER THE CONSORTIUM + NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF + ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY, ARISING FROM THE USE OF THIS SPECIFICATION. + + Source UML File Information + --------------------------- + The source file information must be supplied as an XMI file (without diagram layout information). + The supported UML authoring tools are: + (a) Poseidon – v6 (and later) + + Source XSLT File Information + ---------------------------- + XSL Generator: UMLtoXSDTransformv0p9.xsl + XSLT Processor: Xalan + Release: 1.0 Beta 3 + Date: 31st May, 2009 + + IMS GLC Auto-generation Binding Tool-kit (I-BAT) + ------------------------------------------------ + This file was auto-generated using the IMS GLC Binding Auto-generation Tool-kit (I-BAT). While every + attempt has been made to ensure that this tool auto-generates the files correctly, users should be aware + that this is an experimental tool. Permission is given to make use of this tool. IMS GLC makes no + claim on the materials created by third party users of this tool. Details on how to use this tool + are contained in the IMS GLC "I-BAT" Documentation available at the IMS GLC web-site. + + Tool Copyright: 2005-2011 (c) IMS Global Learning Consortium Inc. All Rights Reserved. + + + + + + Schematron Strict Selection Validation Rules + -------------------------------------------- + This is the set of Schematron rules that have been created to enforce the use of the "Unordered" stereotype. + These rules ensure that the number of entries in an unordered complexType of an element obey the multiplicity constraints. + This is required so that any-order/any-multiplicity complexTypes can be constructed and validated. + + + + Schematron validation rules for the enforcement of the Unordered stereotype. + + + + [RULESET] For the LOM.Type complexType. + + + + + [RULE for Root Class Attribute 1] Invalid number of "general" elements: . + + + + [RULE for Root Class Attribute 2] Invalid number of "lifeCycle" elements: . + + + + [RULE for Root Class Attribute 3] Invalid number of "technical" elements: . + + + + [RULE for Root Class Attribute 5] Invalid number of "rights" elements: . + + + + + + + + + + [RULESET] For the Rights.Type complexType. + + + + + [RULE for Local Attribute 1] Invalid number of "cost" elements: . + + + + [RULE for Local Attribute 2] Invalid number of "copyrightAndOtherRestrictions" elements: . + + + + [RULE for Local Attribute 3] Invalid number of "description" elements: . + + + + + + + + + + [RULESET] For the General.Type complexType. + + + + + [RULE for Local Attribute 2] Invalid number of "title" elements: . + + + + + + + + + + [RULESET] For the ContributeLifeCycle.Type complexType. + + + + + [RULE for Local Attribute 1] Invalid number of "role" elements: . + + + + [RULE for Local Attribute 3] Invalid number of "date" elements: . + + + + + + + + + + [RULESET] For the Relation.Type complexType. + + + + + [RULE for Local Attribute 1] Invalid number of "kind" elements: . + + + + [RULE for Local Attribute 2] Invalid number of "resource" elements: . + + + + + + + + + + [RULESET] For the Resource.Type complexType. + + + + + + + + + + + [RULESET] For the Classification.Type complexType. + + + + + [RULE for Local Attribute 1] Invalid number of "purpose" elements: . + + + + [RULE for Local Attribute 3] Invalid number of "description" elements: . + + + + + + + + + + [RULESET] For the Taxon.Type complexType. + + + + + [RULE for Local Attribute 1] Invalid number of "id" elements: . + + + + [RULE for Local Attribute 2] Invalid number of "entry" elements: . + + + + + + + + + + [RULESET] For the DateTime.Type complexType. + + + + + [RULE for Local Attribute 1] Invalid number of "dateTime" elements: . + + + + [RULE for Local Attribute 2] Invalid number of "description" elements: . + + + + + + + + + + [RULESET] For the Identifier.Type complexType. + + + + + [RULE for Local Attribute 1] Invalid number of "catalog" elements: . + + + + [RULE for Local Attribute 2] Invalid number of "entry" elements: . + + + + + + + + [RULE for Local Attribute 1] Invalid number of "catalog" elements: . + + + + [RULE for Local Attribute 2] Invalid number of "entry" elements: . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The Classification complexType is the container for information which describes where this learning +object falls within a particular classification system. To define multiple classifications, there may be +multiple instances of this category. + + + + + + + + + + + + + + The Context complexType is the container for the information about the principal environment within which the learning and use of this learning object is intended to take place. Suggested good practice is to use one of the values of the value space and to use an additional instance of this data element for further refinement. + + + + + + + + + + + + + + + + + + + + + + + + + + + The Contribute complexType is the container for the entities (i.e. people, organizations) that have +contributed to the state of the learning object. + + + + + + + + + + + + + The CopyrightAndOtherRestrictions complexType defines whether copyright or other restrictions apply +to the use of this learning object. + + + + + + + + + + + + + + + + + + The Cost complexType is the container for whether use of this learning object requires payment. + + + + + + + + + + + + + + + + + + The DateTime abstract complexType is the container for the annotated date/time. An accuracy +of at least one second is supported. The ISO 8601 format is used. An associated description is also provided. + + + + + + + + + + + + The Educational complexType is the container for the information that describes the key educational or pedagogic characteristics of this learning object. This is pedagogical informtion essential to those involved in achieving a quality learning experience. The audience for this metadata includes teachers, managers, authors and learners. CC MANIFEST PROFILE Only a single instance of the 'learningResourceType' and multple instances of the 'ntendedEnduserRole' are permitted. + + + + + + + + + + + + + CC AMANIFEST PROFILE + +The 'structure' and aggregationLevel' elements are prohibited. + + + + + + + + + + + + + + + + The Identifier complexType is the container for the globally unique idenitifer that identifies +the associated parent object. + + + + + + + + + + + + The IntendedEndUserRole complexType is the container for the information about the principal user(s) for which this learning object was designed, most dominant first. For Strict LOM binding this has an enumerated vocabulary. The Classification element can be used to describe the role through the skills the user is intended to master, or the tasks he or she is intended to be able to accomplish. CC Manifest Profile: Only the Iinstructor' 'Mentor' and 'Teacher' vocab values are permitted. + + + + + + + + + + + + + + + + + + + + + + + + + + The Kind complexType is the container for the nature of the relationship between this learning object and the +target learning object, identified by information in the associated Resource complexType. In LOMv1.0 (Strict) this is an +enumerated vocabulary. + +CC MANIFEST PROFILE + +Only the 'value' element is permitted. + + + + + + + + + + + + + + + + + + + + + + + + + + + + The LangString complexType is the container for a group of language specific characterstrings. + + + + + + + + + + + The LearningResourceType complexType is the container for the information about the specific kind of learning object. The most dominant kind shall be first. The vocabulary terms are defined as in OED:1989 and as used by any educational communties of practice. CC MANIFEST PROFILE Only 'value' is permited and this is fixed as 'IMS Common Cartridge'. + + + + + + + + + + + + + + + + + The LifeCycle complexType is the container for the history and current state of this +learning object and those entities that have affected this learning object during its evolution. + +CC MANIFEST PROFILE + +Only the 'contribite' element is permitted. + + + + + + + + + + + The LOM complexType is the container for the metadata instance. + +CC MANIFEST PROFILE + +The MetaMetadata and Annotation complexTypes are prohibited. + + + + + + + + + + + + + + + + + The Purpose complexType is the container for the information on the purpose of +classifying this learning obect. For the Strict LOM binding this is an enumerated vocabulary. + + + + + + + + + + + + + + + + + + + + + + + + + The Relation complexType is the container for the information that defines the relationship between this +learning object and other learning objects, if any. To define multiple relationships, there may be multiple +instances of this category. If there is more than one target learning object the each object shall have a new +relationship instance. + + + + + + + + + + + + The Resource complexType is the container for the information about the target learning object that this relationship references. + + + + + + + + + + + + The Rights complexType describes the intellectual property rights and conditions of use for this learning object. +NOTE: The intent is to reuse results of ongoing work in the Intellectual Property Rights and e-commerce +communities. This category currently provides the absolute minimum level of detail only. + + + + + + + + + + + + + The Role complexType is the container for the kind of contribution. + +CC MANIFEST PROFILE + +Only the 'value' elemet is permitted. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The Taxon complexType is the container for the information about a particular term within a +taxonomy. A taxon is a node that has a defined label or term. A taxon may also have an alphanumeric +designation or identifier for standardized reference. Either or both the label and the entry may be used +to designate a particular taxon. An ordered list of taxons creates a taxonomic path i.e. 'taxononomic +stairway': this is a path from a more general to more specific entry in a classification. + + + + + + + + + + + + The TaxonPath complexType is the container for the information about the taxonomic path in a +specific classification system. Each succeeding level is a refinement in the definition of the +preceding level. There may be different paths in the same or different classifications, which +describe the same characteristic. + + + + + + + + + + + The Technical complexType is the container for the information that describes the technical requirements and +characteristics of this learning object. + +CC MANIFEST PROFILE + +Only the 'format' element is permitted. + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backup/cc/schemas11/ccv1p1_lomresource_v1p0.xsd b/backup/cc/schemas11/ccv1p1_lomresource_v1p0.xsd new file mode 100644 index 00000000000..bed82dd3bcc --- /dev/null +++ b/backup/cc/schemas11/ccv1p1_lomresource_v1p0.xsd @@ -0,0 +1,273 @@ + + + + + XSD Data File Information + ------------------------- + Author: Colin Smythe + Date: 31st January, 2011 + Version: 1.1 + Status: Final + Description: This is the IMS GLC Meta-data v1.3 binding of the IEEE LOMv1.0 for the + Common Cartridge v1.1 Resource Metadata. This is based on the LOM strict binding. + The core changes are: + a) General complexType removed; + b) LifeCycle complexType removed; + c) Metametadata complexType removed; + d) Technical complexType removed; + e) Rights complexType removed; + f) Annotation complexType removed; + g) Classification complexType removed; + h) The educational element is required at least once in the metadata instance; + i) For Educational the context is required once and intendedEndUserRole at least once; + j) All order is now imposed using sequence; + k) All vocabs are constrained as required for the context and intendedEndUserRole elements. + + History: Version 1.0 - the first release of this profile for the CC Resource metadata; + Version 1.1 - the 'mentor' enumeration value is added and the 'school' enumeration value are added + + License: IPR, License and Distribution Notices + + This machine readable file is derived from IMS Global Learning Consortium (GLC) specification IMS Common Cartridge Version 1.1 + found at http://www.imsglobal.org/cc and the original IMS GLC schema binding or code base + http://www.imsglobal.org/cc. + + Recipients of this document are requested to submit, with their comments, notification of any + relevant patent claims or other intellectual property rights of which they may be aware that might be + infringed by the schema binding contained in this document. + + IMS GLC takes no position regarding the validity or scope of any intellectual property or other + rights that might be claimed to pertain to the implementation or use of the technology described in this + document or the extent to which any license under such rights might or might not be available; neither + does it represent that it has made any effort to identify any such rights. Information on IMS GLCs + procedures with respect to rights in IMS GLC specifications can be found at the IMS GLC Intellectual Property + Rights web page: http://www.imsglobal.org/ipr/imsipr_policyFinal.pdf. + + Copyright (c) IMS Global Learning Consortium 1999-2011. All Rights Reserved. + + License Notice for Users + + Users of products or services that include this document are hereby granted a worldwide, royalty-free, + non-exclusive license to use this document. + + Distribution Notice for Developers + + Developers of products or services that are not original incorporators of this document and + have not changed this document, that is, are distributing a software product that incorporates this + document as is from a third-party source other than IMS, are hereby granted permission to copy, + display and distribute the contents of this document in any medium for any purpose without fee or + royalty provided that you include this IPR, License and Distribution notice in its entirety on ALL + copies, or portions thereof. + + Developers of products or services that are original incorporators of this document and wish + to provide distribution of this document as is or with modifications and developers of products and + services that are not original incorporators of this document and have changed this document, are + required to register with the IMS GLC community on the IMS GLC website as described in the following two + paragraphs:- + + * If you wish to distribute this document as is, with no modifications, you are hereby granted + permission to copy, display and distribute the contents of this document in any medium for any + purpose without fee or royalty provided that you include this IPR, License and Distribution notice in + its entirety on ALL copies, or portions thereof, that you make and you complete a valid license + registration with IMS and receive an email from IMS granting the license. To register, follow the + instructions on the IMS website: http://www.imsglobal.org/specificationdownload.cfm. Once + registered you are granted permission to transfer unlimited distribution rights of this document for the + purposes of third-party or other distribution of your product or service that incorporates this + document as long as this IPR, License and Distribution notice remains in place in its entirety; + + * If you wish to create and distribute a derived work from this document, you are hereby + granted permission to copy, display and distribute the contents of the derived work in any medium for + any purpose without fee or royalty provided that you include this IPR, License and Distribution + notice in its entirety on ALL copies, or portions thereof, that you make and you complete a valid + profile registration with IMS GLC and receive an email from IMS GLC granting the license. To register, follow + the instructions on the IMS GLC website: http://www.imsglobal.org/profile/. Once registered you are + granted permission to transfer unlimited distribution rights of the derived work for the purposes of + third-party or other distribution of your product or service that incorporates the derived work as long + as this IPR, License and Distribution notice remains in place in its entirety. + + The limited permissions granted above are perpetual and will not be revoked by IMS GLC or its + successors or assigns. + + THIS SPECIFICATION IS BEING OFFERED WITHOUT ANY WARRANTY WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NONINFRINGEMENT IS + EXPRESSLY DISCLAIMED. ANY USE OF THIS SPECIFICATION SHALL BE MADE ENTIRELY AT THE IMPLEMENTERS OWN RISK, AND NEITHER THE CONSORTIUM + NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF + ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY, ARISING FROM THE USE OF THIS SPECIFICATION. + + Source UML File Information + --------------------------- + The source file information must be supplied as an XMI file (without diagram layout information). + The supported UML authoring tools are: + (a) Poseidon – v6 (and later) + + Source XSLT File Information + ---------------------------- + XSL Generator: UMLtoXSDTransformv0p9.xsl + XSLT Processor: Xalan + Release: 1.0 Beta 3 + Date: 31st May, 2009 + + IMS GLC Auto-generation Binding Tool-kit (I-BAT) + ------------------------------------------------ + This file was auto-generated using the IMS GLC Binding Auto-generation Tool-kit (I-BAT). While every + attempt has been made to ensure that this tool auto-generates the files correctly, users should be aware + that this is an experimental tool. Permission is given to make use of this tool. IMS GLC makes no + claim on the materials created by third party users of this tool. Details on how to use this tool + are contained in the IMS GLC "I-BAT" Documentation available at the IMS GLC web-site. + + Tool Copyright: 2005-2011 (c) IMS Global Learning Consortium Inc. All Rights Reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The Context complexType is the container for the information about the principal environment within which the learning and use of this learning object is intended to take place. Suggested good practice is to use one of the values of the value space and to use an additional instance of this data element for further refinement. + + + + + + + + + + + + + + + + + + + + + + + + + + + The Educational complexType is the container for the information that describes the key educational or pedagogic characteristics of this learning object. This is pedagogical informtion essential to those involved in achieving a quality learning experience. The audience for this metadata includes teachers, managers, authors and learners. CC Resource Profile: Only single context and intendedUserRole elements are permitted. + + + + + + + + + + + + The IntendedEndUserRole complexType is the container for the information about the principal user(s) for which this learning object was designed, most dominant first. For Strict LOM binding this has an enumerated vocabulary. The Classification element can be used to describe the role through the skills the user is intended to master, or the tasks he or she is intended to be able to accomplish. CC Resource Profile: Only the 'Instructor', 'Mentor' and 'Learner' vocab values are permitted. + + + + + + + + + + + + + + + + + + + + + + + + + + The LangString complexType is the container for a group of language specific characterstrings. + + + + + + + + + + + The LOM complexType is the container for the metadata instance. + +CC Resource Profile - only a single Educational element is permitted. + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backup/cc/schemas11/ccv1p1_qtiasiv1p2p1_v1p0.xsd b/backup/cc/schemas11/ccv1p1_qtiasiv1p2p1_v1p0.xsd new file mode 100644 index 00000000000..1ea18f60923 --- /dev/null +++ b/backup/cc/schemas11/ccv1p1_qtiasiv1p2p1_v1p0.xsd @@ -0,0 +1,1890 @@ + + + + + + XSD Data File Information + ------------------------- + Author: Colin Smythe + Date: 31st October, 2010 + Version: 1.1 + Status: Final Release + Description: This model forms part of the IMS Common Cartridge v1.1 specification. This model is the + profile of the IMS QTI v1.2.1 specification. The changes made to the original specification + to create this profile are: + + Root + (a) Only one Assessment or one ObjectBank can be exchanged i.e. not Sections or Items; + (b) The qticomment attribute has been removed. + + Assessment + (a) Only a single Section must be contained in the Assessment; + (b) The metadata is mandatory (see the specification for the fields that must be defined) with a multiplicity of 1; + (c) All of the other Assessment fields have been removed apart from the optional PresentationMaterial; + (d) The title attribute has been made mandatory. + + Object Bank + (a) Only Items can be containd in the object bank; + (b) The Qticomment structure has been removed. + + Section + (a) All of the internal structure has been removed except the containment of Items (at least one is required); + (b) The language attribute has been removed. + + Item + (a) The deprecated attributes have been removed from the ItemMetadata class; + (b) All qticomment attributes have been removed from various classes; + (c) The Item pre and post condition attributes have been removed from the Item class; + (d) The itemproc_extension structure has been removed from the Item class; + (e) The reference structure has been removed from the Item class; + (f) The objectives attribute has been removed from the Item class; + (g) The itemcontrol attribute has been removed from the Item class; + (h) The item rubric attribute and its associated classes have been removed from the Item class; + (i) The duration attribute has been removed from the Item class; + (j) The itemmetadata attribute has been made mandatory in the Item class; + (k) The label, language and maxattempts attributes have been removed from the Item class; + (l) The interpretvar attribute has been removed frm the Outcomes class; + (m) The response_xy, response_num, response_grp and response_extension attributes have + been removed from the Presentation class; + (n) All extension attributes have been removed from various classes; + (o) The ItemType, LevelofDifficulty, RenderingType, ResponseMultiplicity, Status and TypeofSolution + have been deleted; + (p) The ItemFeedback Class has been restructured as only flow_mat is used; + (q) A single decvar is required i.e. for the default variable SCORE. + + Item-Response + (a) The Rrange and Rarea attributes have been removed from the ResponseLabel Class. + + Item-Render + (a) The render_hotspot attributes and the RenderHotspot class have been removed; + (b) The render_slider attributes and the RenderSlider class have been removed; + (c) The render_extension attribute has been removed from the ResponseType class; + (d) The response_na attribute has been removed; + (e) The qticomment attribute has been removed from the ResponseLabel class; + + Item-General + (a) The Interpretvar class has been removed; + (b) The DurationBase class has been removed and all derived attributes from the Conditionvar and CompositionLogic classes; + (c) The var_extension attribute has been removed from the Conditionvar class; + (d) The qticomment attributes have been removed from the Hint and Solution classes; + (e) Setvar is restricted to the Set action; + (f) Variable types are restricted to 'Integer' and 'Decimal'; + (g) The defaultval and cutvalue, attributes for decvar have been removed; + (h) Outcomes is limtied to a single decvar which must have only the variable "SCORE" declared; + (i) The classes or, varlt, varlte, vargt, vargte, varinside, varsubset and unanswered have been removed; + (j) The classes 'and', 'not' and 'conditionvar' have been significantly simplied i.e. see clause above for detail; + (k) The feedbacktype attribute for the displayfeedback element is now mandatory with no default value. + + Selection and Ordering + (a) The entire Selection and Ordering (Package) has been removed. + + Outcomes + (a) The entire Outcomes Processing (Package) has been removed. + + Material + (a) The Reference Class has been removed as this is not required; + (b) All entityref attributes have been removed; + (c) Extensions have been removed; + (d) Only 'mattext', 'matref' and 'matbreak' are permitted as types of material. + + Common + (a) The Rubric class has been removed Items and Sections and it is only permitted to contain a single instance of material; + (b) The ContextControl class has been removed i.e. no Control switches required; + (c) The QtiComment Class has been removed; + (d) The MetadataRule Class has been removed; + (e) the Parameterization Class has been removed; + (f) The 'view' attribute has been removed; + (g) The Vocabulary Class has been removed and its attribute in the QtiMetadata Class also removed. + + History: Version 1.0: This profile is taken from the UML description of the QTIv1.2.1 specification. + Version 1.1: Material has been returned as an alternative to flow_mat in ItemFeedback, + SolutionMaterial and HintMaterial. Also, Assessment Rubric has been permitted but it must + only contain a single instance of material. + + License: IPR, License and Distribution Notices + + This machine readable file is derived from IMS Global Learning Consortium (GLC) specification IMS Common Cartridge Version 1.1 + found at http://www.imsglobal.org/cc and the original IMS GLC schema binding or code base + http://www.imsglobal.org/cc. + + Recipients of this document are requested to submit, with their comments, notification of any + relevant patent claims or other intellectual property rights of which they may be aware that might be + infringed by the schema binding contained in this document. + + IMS GLC takes no position regarding the validity or scope of any intellectual property or other + rights that might be claimed to pertain to the implementation or use of the technology described in this + document or the extent to which any license under such rights might or might not be available; neither + does it represent that it has made any effort to identify any such rights. Information on IMS GLCs + procedures with respect to rights in IMS GLC specifications can be found at the IMS GLC Intellectual Property + Rights web page: http://www.imsglobal.org/ipr/imsipr_policyFinal.pdf. + + Copyright (c) IMS Global Learning Consortium 1999-2011. All Rights Reserved. + + License Notice for Users + + Users of products or services that include this document are hereby granted a worldwide, royalty-free, + non-exclusive license to use this document. + + Distribution Notice for Developers + + Developers of products or services that are not original incorporators of this document and + have not changed this document, that is, are distributing a software product that incorporates this + document as is from a third-party source other than IMS, are hereby granted permission to copy, + display and distribute the contents of this document in any medium for any purpose without fee or + royalty provided that you include this IPR, License and Distribution notice in its entirety on ALL + copies, or portions thereof. + + Developers of products or services that are original incorporators of this document and wish + to provide distribution of this document as is or with modifications and developers of products and + services that are not original incorporators of this document and have changed this document, are + required to register with the IMS GLC community on the IMS GLC website as described in the following two + paragraphs:- + + * If you wish to distribute this document as is, with no modifications, you are hereby granted + permission to copy, display and distribute the contents of this document in any medium for any + purpose without fee or royalty provided that you include this IPR, License and Distribution notice in + its entirety on ALL copies, or portions thereof, that you make and you complete a valid license + registration with IMS and receive an email from IMS granting the license. To register, follow the + instructions on the IMS website: http://www.imsglobal.org/specificationdownload.cfm. Once + registered you are granted permission to transfer unlimited distribution rights of this document for the + purposes of third-party or other distribution of your product or service that incorporates this + document as long as this IPR, License and Distribution notice remains in place in its entirety; + + * If you wish to create and distribute a derived work from this document, you are hereby + granted permission to copy, display and distribute the contents of the derived work in any medium for + any purpose without fee or royalty provided that you include this IPR, License and Distribution + notice in its entirety on ALL copies, or portions thereof, that you make and you complete a valid + profile registration with IMS GLC and receive an email from IMS GLC granting the license. To register, follow + the instructions on the IMS GLC website: http://www.imsglobal.org/profile/. Once registered you are + granted permission to transfer unlimited distribution rights of the derived work for the purposes of + third-party or other distribution of your product or service that incorporates the derived work as long + as this IPR, License and Distribution notice remains in place in its entirety. + + The limited permissions granted above are perpetual and will not be revoked by IMS GLC or its + successors or assigns. + + THIS SPECIFICATION IS BEING OFFERED WITHOUT ANY WARRANTY WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NONINFRINGEMENT IS + EXPRESSLY DISCLAIMED. ANY USE OF THIS SPECIFICATION SHALL BE MADE ENTIRELY AT THE IMPLEMENTERS OWN RISK, AND NEITHER THE CONSORTIUM + NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF + ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY, ARISING FROM THE USE OF THIS SPECIFICATION. + + Source UML File Information + --------------------------- + The source file information must be supplied as an XMI file (without diagram layout information). + The supported UML authoring tools are: + (a) Poseidon – v6 (and later) + + Source XSLT File Information + ---------------------------- + XSL Generator: UMLtoXSDTransformv0p9.xsl + XSLT Processor: Xalan + Release: 1.0 Beta 3 + Date: 31st May, 2009 + + IMS GLC Auto-generation Binding Tool-kit (I-BAT) + ------------------------------------------------ + This file was auto-generated using the IMS GLC Binding Auto-generation Tool-kit (I-BAT). While every + attempt has been made to ensure that this tool auto-generates the files correctly, users should be aware + that this is an experimental tool. Permission is given to make use of this tool. IMS GLC makes no + claim on the materials created by third party users of this tool. Details on how to use this tool + are contained in the IMS GLC "I-BAT" Documentation available at the IMS GLC web-site. + + Tool Copyright: 2005-2010 (c) IMS Global Learning Consortium Inc. All Rights Reserved. + + + + + + Schematron Validation Rules Information + --------------------------------------- + Author: Colin Smythe + Date: 5th January, 2011 + Version: 1.1 + Status: Final Release + + Description: This set of schematron rules have been created to increase the validation capability of the QTIv1.2.1 XSD. + A total of 12 rule sets have been created to ensure that: + [1] Only valid Assessment metadata is defined; + [2] Only valid Question types are defined in the Itemmetatadata fields; + [3] The structure of a True/False question is correct; + [4] The structure of a Multiple-Choice (Single Response) question is correct; + [5] The structure of a Multiple-Choice (Multiple Response) question is correct; + [6] The structure of a Fill In Blank question is correct; + [7] The structure of a Pattern Match question is correct; + [8] The structure of an Essay question is correct; + [9] The structures of the response processing/response-label are correct; + [10] The structure of a Hint in an Item is correct; + [11] The structure of a Solution in an Item is correct; + [12] The structure of the response processing feedback structure in an Item is correct; + [13] Generic features of an Item are correctly implemented. + + Rule Set: [1] The set of rules to ensure that only valid Assessment metadata is defined. + The rules are: + (a) Only valid entries are defined for the Assessment metadata fieldlabel values; + (b) Only valid entries are defined for the Assessment metadata fieldentry values for fieldlabel = 'qmd_assessmenttype'; + (c) Only valid entries are defined for the Assessment metadata fieldentry values for fieldlabel = 'qmd_scoretype'; + (d) Only valid entries are defined for the Assessment metadata fieldentry values for fieldlabel = 'qmd_feedbackpermitted'; + (e) Only valid entries are defined for the Assessment metadata fieldentry values for fieldlabel = 'qmd_hintspermitted'; + (f) Only valid entries are defined for the Assessment metadata fieldentry values for fieldlabel = 'qmd_solutionspermitted'; + (g) Only valid entries are defined for the Assessment metadata fieldentry values for fieldlabel = 'qmd_timelimit'; + (h) Only valid entries are defined for the Assessment metadata fieldentry values for fieldlabel = 'cc_allow_late_submission'; + (i) Only valid entries are defined for the Assessment metadata fieldentry values for fieldlabel = 'cc_maxattempts'; + (j) Only valid entries are defined for the Assessment metadata fieldentry values for fieldlabel = 'cc_profile'; + (k) There must be no more than one Assessment metadata field with fieldlabel='cc_profile'; + (l) There must be no more than one Assessment metadata field with fieldlabel='qmd_assessmenttype'; + (m) There must be no more than one Assessment metadata field with fieldlabel='qmd_scoretype'; + (n) There must be no more than one Assessment metadata field with fieldlabel='qmd_feedbackpermitted'; + (o) There must be no more than one Assessment metadata field with fieldlabel='qmd_hintspermitted'; + (p) There must be no more than one Assessment metadata field with fieldlabel='qmd_solutionspermitted'; + (q) There must be no more than one Assessment metadata field with fieldlabel='qmd_timelimit'; + (r) There must be no more than one Assessment metadata field with fieldlabel='cc_allow_late_submission'; + (s) There must be no more than one Assessment metadata field with fieldlabel='cc_maxattempts'. + + [2] The set of rules to ensure that only valid Question types are defined in the Itemmetatadata fields. + The rules are: + (a) Only valid entries are defined for the Itemmetadata fieldlabel values; + (b) Only valid entries are defined for the Itemmetadata fieldentry values for fieldlabel = 'cc_profile'; + (c) Only valid entries are defined for the Itemmetadata fieldentry values for fieldlabel = 'cc_weighting'; + (d) Only valid entries are defined for the Itemmetadata fieldentry values for fieldlabel = 'qmd_scoringpermitted'; + (e) Only valid entries are defined for the Itemmetadata fieldentry values for fieldlabel = 'qmd_computerscored'; + (f) The Item metadata field with fieldlabel='cc_profile' must be present; + (g) There must only be one Item metadata fields with fieldlabel='cc_profile'for each Item; + (h) There must be no more than one Item metadata field with fieldlabel='cc_weighting'for each Item; + (i) There must be no more than one Item metadata field with fieldlabel='qmd_scoringpermitted' for each Item; + (j) There must be no more than one Item metadata field with fieldlabel='qmd_computerscored'for each Item. + + [3] The set of rules to ensure that the structure of a True/False question is correct. + The rules are: + (a) That @rcardinality='Single'; + (b) The element 'response_str' is not used; + (c) The element 'render_fib' is not used; + (d) That there are zero or two response labels; + (e) That the response processing uses the correct identifiers i.e. varequal/@respident value is equal to the response_lid/@ident; + (f) The varsubstring element must not be used. + + [4] The set of rules to ensure that the structure of a Multiple-Choice (Single Response) question is correct. + The rules are: + (a) That @rcardinality='Single'; + (b) The element 'response_str' is not used; + (c) The element 'render_fib' is not used; + (d) That there are at least three response labels; + (e) That the response processing uses the correct identifiers i.e. varequal/@respident value is equal to the response_lid/@ident; + (f) The varsubstring element must not be used. + + [5] The set of rules to ensure that the structure of a Multiple-Choice (Multiple Response) question is correct. + The rules are: + (a) That @rcardinality='Multiple'; + (b) The element 'response_str' is not used; + (c) The element 'render_fib' is not used; + (d) That there are at least two response labels; + (e) That the response processing uses the correct identifiers i.e. varequal/@respident value is equal to the response_lid/@ident; + (f) The varsubstring element must not be used.. + + [6] The set of rules to ensure that the structure of a Fill-in-Blank question is correct. + The rules are: + (a) The element 'response_lid' is not used; + (b) The element 'render_choice' is not used; + (c) That the response processing uses the correct identifiers i.e. varequal/@respident value is equal to the response_str/@ident; + (d) There is no use of the 'varsubstring' element. + + [7] The set of rules to ensure that the structure of a Pattern Match question is correct. + The rules are: + (a) The element 'response_lid' is not used; + (b) The element 'render_choice' is not used; + (c) That the response processing uses the correct identifiers i.e. varequal/@respident value is equal to the response_str/@ident. + + [8] The set of rules to ensure that the structure of an Essay question is correct. + The rules are: + (a) The element 'response_lid' is not used; + (b) The element 'render_choice' is not used; + (c) There is no use of the 'varequal' element; + (d) There is no use of the 'varsubstring' element; + (e) No more than a single Solution feedback can be supplied; + (f) The fieldentry Item metadata for an Essay question with the fieldlabel='qmd_computerscored' must be set as 'No'. + + [9] The set of rules to ensure that the Response Processing/Response-Label structures are valid. + The rules are: + (a) There are no invalid response labels used in the 'varequal' element for T/F and MC questions. + + [10] The set of rules to ensure that the structure of a Hint in an Item is correct. + The rules are: + (a) The element 'displayfeedback@feedbacktype=Hint' is accompanied by the @linkrefid='hint' attribute; + (b) The element 'itemfeedback@ident=hint' is not followed by the 'solution' element; + (c) The element 'itemfeedback@ident=hint' is not followed by the 'flow_mat' element; + (d) If the element 'displayfeedback@feedbacktype=Hint' is used it must be accompanied by hint feedback. + + [11] The set of rules to ensure that the structure of a Solution in an Item is correct. + The rules are: + (a) The element 'displayfeedback@feedbacktype=Solution' is accompanied by the @linkrefid='solution' attribute; + (b) The element 'itemfeedback@ident=solution' is not followed by the 'hint' element; + (c) The element 'itemfeedback@ident=solution' is not followed by the 'flow_mat' element; + (d) If the element 'displayfeedback@feedbacktype=Solution' is used it must be accompanied by solution feedback. + + [12] The set of rules to ensure that the general structure of the Response Processing in an Item is correct. + The rules are: + (a) The element 'displayfeedback@feedbacktype=Response' is not accompanied by the @linkrefid='solution' attribute; + (b) The element 'displayfeedback@feedbacktype=Response' is not accompanied by the @linkrefid='hint' attribute; + (c) To check that for each element 'displayfeedback@feedbacktype=Response' the corresponding 'itemfeedback' element exists; + (d) To check that a given response processing itemfeedback identifier there is a corresponding displayfeedback trigger for that identifier. + + [13] The set of rules to ensure that the general features in an Item are correct. + The rules are: + (a) To ensure that each Item has a unique @ident attribute. + + + + Schematron validation rules for the Common Cartridge v1p1 profile of QTI v1.2.1 + + + + RULE SET 1: Ensure that only valid metadata is defined in the Assessment metadata fields + + + + [RULE 1a] Invalid Assessment metadata fieldlabel value: . + + + + + + [RULE 1b] Invalid fieldentry Assessment metadata for the fieldlabel='qmd_assessmenttype' value: . + + + + + + [RULE 1c] Invalid fieldentry Assessment metadata for the fieldlabel='qmd_scoretype' value: . + + + + + + [RULE 1d] Invalid fieldentry Assessment metadata for the fieldlabel='qmd_feedbackpermitted' value: . + + + + + + [RULE 1e] Invalid fieldentry Assessment metadata for the fieldlabel='qmd_hintspermitted' value: . + + + + + + [RULE 1f] Invalid fieldentry Assessment metadata for the fieldlabel='qmd_solutionspermitted' value: . + + + + + + [RULE 1g] Invalid fieldentry Assessment metadata for the fieldlabel='qmd_timelimit' i.e. not a valid integer with value: . + + + + + + [RULE 1h] Invalid fieldentry Assessment metadata for the fieldlabel='cc_allow_late_submission' value: . + + + + + + [RULE 1i] Invalid fieldentry Assessment metadata for the fieldlabel='cc_maxattempts' value: . + + + + + + [RULE 1j] Invalid fieldentry Assessment metadata for the fieldlabel='cc_profile' value: . + + + + + + + [RULE 1k] There are repeated assessment metadata fields of fieldlabel='cc_profile' with count=. + + + + [RULE 1l] There are repeated assessment metadata fields of fieldlabel='qmd_assessmenttype' with count=. + + + + [RULE 1m] There are repeated assessment metadata fields of fieldlabel='qmd_scoretype' with count=. + + + + [RULE 1n] There are repeated assessment metadata fields of fieldlabel='qmd_feedbackpermitted' with count=. + + + + [RULE 1o] There are repeated assessment metadata fields of fieldlabel='qmd_hintspermitted' with count=. + + + + [RULE 1p] There are repeated assessment metadata fields of fieldlabel='qmd_solutionspermitted' with count=. + + + + [RULE 1q] There are repeated assessment metadata fields of fieldlabel='qmd_timelimit' with count=. + + + + [RULE 1r] There are repeated assessment metadata fields of fieldlabel='cc_allow_late_submission' with count=. + + + + [RULE 1s] There are repeated assessment metadata fields of fieldlabel='cc_maxattempts' with count=. + + + + + + + + + + RULE SET 2: Ensure that only valid metadata is defined in the Itemmetatadata fields + + + + [RULE 2a] Invalid Itemmetadata fieldlabel value: . + + + + + + [RULE 2b] Invalid fieldentry Question Type (fieldlabel='cc_profile') value: . + + + + + + [RULE 2c] Invalid fieldentry Item metadata weighting for the fieldlabel='cc_weighting' i.e. not an integer in the range 1..99, with value: . + + + + + + [RULE 2d] Invalid fieldentry Item metadata for the fieldlabel='qmd_scoringpermitted' with value: . + + + + + + [RULE 2e] Invalid fieldentry Item metadata for the fieldlabel='qmd_computerscored' with value: . + + + + + + + [RULE 2f] The Item metadata field with fieldlabel='cc_profile' is missing. + + + + [RULE 2g] There are too many Item metadata fields with fieldlabel='cc_profile' i.e. count=. + + + + [RULE 2h] There are too many Item metadata fields with fieldlabel='cc_weighting' i.e. count=. + + + + [RULE 2i] There are too many Item metadata fields with fieldlabel='qmd_scoringpermitted' i.e. count=. + + + + [RULE 2j] There are too many Item metadata fields with fieldlabel='qmd_computerscored' i.e. count=. + + + + + + + + + + RULE SET 3: Ensure that the structure of a True/False question is correct + + + + [RULE 3a] Incorrect cardinality attribute value for the T/F question: + + + + [RULE 3b] The invalid 'response_str' element has been used for a T/F question. + + + + [RULE 3c] The invalid 'render_fib' element has been used for a T/F question. + + + + [RULE 3d] There are too many or too few response labels for the T/F question. + + + + [RULE 3e] The T/F response processing Varequal respident attribute + () + value is not equal to the corresonding Response_lid ident + () + attribute for the True/False question. + + + + [RULE 3f] There is an invalid use of the varsubstring element in a T/F question. + + + + + + + + + + RULE SET 4: Ensure that the structure of a MC-SR question is correct + + + + [RULE 4a] Incorrect cardinality attribute value for the MC-SR question: . + + + + [RULE 4b] The invalid 'response_str' element has been used for a MC-SR question. + + + + [RULE 4c] The invalid 'render_fib' element has been used for a MC-SR question. + + + + [RULE 4d] There are too too few response labels for the MC-SR question. + + + + [RULE 4e] The MC-SR response processing Varequal respident attribute + () + value is not equal to the corresonding Response_lid ident + () + attribute for the Multiple Choice single response question. + + + + [RULE 4f] There is an invalid use of the varsubstring element in a MC-SR question. + + + + + + + + + + RULE SET 5: Ensure that the structure of a MC-MR question is correct + + + + + [RULE 5a] Incorrect cardinality attribute value for the MC-MR question: . + + + + [RULE 5b] The invalid 'response_str' element has been used for a MC-MR question. + + + + [RULE 5c] The invalid 'render_fib' element has been used for a MC-MR question. + + + + [RULE 5d] There are too too few response labels for the MC-MR question. + + + + [RULE 5e] The MC-MR response processing Varequal respident attribute + () + value is not equal to the corresonding Response_lid ident + () + attribute for the Multiple Choice multiple response question. + + + + [RULE 5f] There is an invalid use of the varsubstring element in a MC-MR question. + + + + + + + + + + RULE SET 6: Ensure that the structure of a FIB question is correct + + + + + [RULE 6a] The invalid 'response_lid' element has been used for a FIB question. + + + + [RULE 6b] The invalid 'render_choice' element has been used for a FIB question. + + + + [RULE 6c] The FIB response processing Varequal respident attribute + () + value is not equal to the corresonding Response_str ident + () + attribute for the FIB question. + + + + [RULE 6d] There is an invalid use of the 'varsubstring' element in the FIB question. + + + + + + + + + + RULE SET 7: Ensure that the structure of a Pattern Match question is correct + + + + + [RULE 7a] The invalid 'response_lid' element has been used for a Pattern Match question. + + + + [RULE 7b] The invalid 'render_choice' element has been used for a Pattern Match question. + + + + [RULE 7c] The FIB response processing Varequal respident attribute + () + value is not equal to the corresonding Response_str ident + () + attribute for the Pattern Match question. + + + + + + + + + + RULE SET 8: Ensure that the structure of a Essay question is correct + + + + + [RULE 8a] The invalid 'response_lid' element has been used for an Essay question. + + + + [RULE 8b] The invalid 'render_choice' element has been used for an Essay question. + + + + [RULE 8c] There is an invalid use of the 'varequal' element in an Essay question. + + + + [RULE 8d] There is an invalid use of the 'varsubstring' element in an Essay question. + + + + [RULE 8e] Too many Solution feedback structures are supplied. + + + + [RULE 8f] Invalid fieldentry Item metadata for an Essay question with the fieldlabel='qmd_computerscored' with value: . + + + + + + + + + + + + + + RULE SET 10: Ensure that the structure of a Hint in an Item is correct + + + + + [RULE 10a] The displayfeedback@feedbacktype='Solution' has been used to identify a Hint. + + + + [RULE 10b] The itemfeedback@ident='hint' has been used to identify a Solution. + + + + [RULE 10c] The itemfeedback@ident='hint' has been used to identify Response feedback. + + + + + + + [RULE 10d] A displayfeedback[@feedbacktype='Hint'] trigger has no accompanying hint feedback. + + + + + + + + + RULE SET 11: Ensure that the structure of a Solution in an Item is correct + + + + + [RULE 11a] The displayfeedback@feedbacktype='Hint' has been used to identify a Solution. + + + + [RULE 11b] The itemfeedback@ident='solution' has been used to identify a Hint. + + + + [RULE 11c] The itemfeedback@ident='solution' has been used to identify Response feedback. + + + + + + + [RULE 11d] A displayfeedback[@feedbacktype='Solution'] trigger has no accompanying solution feedback. + + + + + + + + + RULE SET 12: Ensure that the structure of the response processing feedback structure in an Item is correct + + + + + [RULE 12a] The displayfeedback@feedbacktype='Response' has been used to identify a Solution. + + + + [RULE 12b] The displayfeedback@feedbacktype='Response' has been used to identify a Hint. + + + + + + + [RULE 12c] For the given displayfeedback identifier () there is no itemfeedback with the correct identifier (). + + + + + + [RULE 12d] For the given response processing itemfeedback identifier () there is no displayfeedback trigger with the correct identifier (). + + + + + + + + + RULE SET 13: Ensure that the generic features of an Item are correct + + + + + [RULE 13a] There are Items that have common identifiers: . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The root structure can consist of either: + + * A single object bank; + * An assessment; + * A set of item(s); + * A set of section(s); + * Any combination of items and sections. + + As the root this is mandatory and can + occur once. + + Common Cartridge Profile + + A Commn Cartridge is allowed to contain + only an objectbank or an assessement. + + + + + + + + + + + + + + QTI General + + An Assessment object is the logical construction of the test. An Assessment must + contain at least one Section which in turn will contain Items and/or Sections. An + Assessment must eventually be constructed from a set of Items i.e. questions + that are to be offered in the test. An Assessment object contains all of the information + to make the use of individual Items meaningful i.e. apart from the Sections the object + includes the relationships between the Sections, the group evaluation processing and + the corresponding feedback. + + Common Cartridge Profile + + The Assessment must consist of only one Section. The only other permitted attributes + are the mandatory identifier and title. Optional language, metadata, rubric and + presentation_material is also supported. + + + + + + + + + + + + + + + + + QTI General + + An object bank is an unordered set of items and sections. It is recommended + that there is a metadata description for the object bank as a whole. The object + bank should have a globally unique identifier. + + Common Cartridge Profile + + In the Common Cartridge the object-bank can only contain Items. Meta-data + support is available but the profile has no mandated entries. + + + + + + + + + + + + + QTI General + + A Section is the core grouping concept within QTI. A Section consists of one or more Items or Sections (or + references to Items and Sections). In general, the objects contained within a Secton will have some relationship + either in terms of content or content delivery. The Section data structure is used to define arbitrarily complex + hierarchical section and item data structures. It may contain meta-data, objectives, rubric control switches, + assessment-level processing, feedback and selection and sequencing information for sections and items. + + Common Cartridge Profile + + In Common Cartridge the Section can only contain a list of Items. No metadata is permitted. The identifier is + mandatory but the title and language are optional. + + + + + + + + + + + + + + + An Item the smallest exchangeable object within QTI-XML. An Item is more than a + ‘Question’ in that it contains the ‘Question’, the presentation/rendering instructions, + the response processing to be applied to the participant’s response(s), the feedback + that may be presented (including hints and solutions) and the meta-data describing + the Item. + + + + + + + + + + + + + + + + + Contains all of the QTI-specific metada-data + to be applied to the Item. This meta-data can + consist of either entries defined using an + external vocabulary or the individually named + entries. Usage of the contained attributes are + deprecated apart from the 'qtimetadata' attribute. + + + + + + + + + + + Contains all of the instructions for the presentation of the question + during an evaluation. This information includes the actual material + to be presented. The labels for the possible responses are also + identified and these are used by the response processing element + defined elsewhere in the Item. + + + + + + + + + + + + + + + + + + + + + + + + This contains all of the instructions for the response + processing. This includes the scoring variables to contain + the associated scores and the set of response condition + tests that are to be applied to the received user response. + + + + + + + + + + + + + + Contains all of the variable declarations that are to be + made available to the scoring algorithm. Each variable + is declared using the 'decvar' structure apart from the + default variable called ‘SCORE’ that is an integer and + has a default value of zero (0). + + Common Cartridge Profile + + A single variable is permitted. This is "SCORE". + + + + + + + + + + + The container for the feedback that is to be presented as a result of the + user’s responses. The feedback can include hints and solutions and + both of these can be revealed in a variety of different ways. + + + + + + + + + + + + + + + + + + + + Contains the actual test to be applied to the user responses + to determine their correctness or otherwise. Each 'respcondition' + contains an actual test, the assignment of a value to the associate + scoring variables and the identification of the feedback to be + associated with the test. + + + + + + + + + + + + + + + + + + + + + + This is the information that is to be presented to set the context for the + contained objects. This can be used to contain question-based material + that is common to all of the child objects. This is used in Assessment and + Section objects. + + + This is the information that is used to describe the solution. + + + + + + + + + + + This allows the materials to be displayed to the users to be grouped together + using flows. The manner in which these flows are handled is dependent upon + the display-engine. + + + + + + + + + + + + + + + + This is the container for any content that is to be displayed by the question-engine. + The supported content types are text (emphasised or not), images, audio, video, + application and applet. The content can be internally referenced to avoid the need + for duplicate copies. Alternative information can be defined – this is used if the + primary content cannot be displayed. + + Common Cartridge Profile + + Only the 'mattext', 'matref' and 'matbreak' types are permitted. + + + + + + + + + + + + + + + + + + This is the container for alternative content. This content is to be + displayed if, for whatever reason, the primary content cannot be + rendered. Alternative language implementations of the host 'material' + element are also supported using this structure. + + + + + + + + + + + + + + + + This is the container for all of the instructions for the presentation with flow + blocking of the question during a test. This information includes the actual + material to be presented. The labels for the possible responses are also + identified and these are used by the response processing element defined + elsewhere in the Item. + + + + + + + + + + + + + + + + + + Contains the instructions for the question-engine to render the question + using a classical multiple choice format. The number of possible responses + is determined by the 'response_label' structures contained. Both flowed and + non-flowed formats are supported + + + + + + + + + + + + + + + + + + + + + + + + + + Contains the instructions for the question-engine to render the question + using a classical fill-in blank format. The number of possible responses + is determined by the 'response_label' structures contained. Both flowed + and non-flowed formats are supported. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + QTI General + + The QTI-specific meta-data assigned to the parent object i.e. + Assessment, Section, Item or Object-bank. This approach + requires that the approriate external vocabulary is defined and + referenced in label/field tuple. + + Common Cartridge Profile + + The Vocabulary structure has been removed. + + + + + + + + + + + The structure responsible for containing each of + the QTI-specific meta-data fields. The label should + appear in the vocabulary. If no vocabulary is used + then external validation cannot take place. + + + + + + + + + + + + + This is used to contain contextual information i.e. rubric that + is important to the object e.g. it could contain standard data + values that might or might not be useful for answering the + question. + + Common Cartridge Profile + + This is used in assessments to provide instructions. Only a + single mattext is permitted in the material. + + + + + + + + + + + This contains the possible response choices that are presented + to the user. This information includes the material to be shown + to the user and the logical label that is associated with that + response. The label is used in the response processing. Flow + and non-flow approaches are supported. + + + + + + + + + + + + + + + + + + + + + + + + + + + This is the blocking/paragraph equivalent to the 'response_label' + structure. This structure shold always be used to encapsulate the + 'response_label construct. + + + + + + + + + + + + + + + QTI General + + This contains the instructions for the presentation of questions whose response will be either a 'response_lid' (logical identifier), + 'response_xy' (xy-co-ordinate), 'response_str' (a string), 'response_num' (a number) and 'response_grp' ( a group of logical + identifiers). The question can be rendered in a variety of ways depending on the way in which the material is to be presented to the + participant. + + Common Cartridge Profile + + Only the response_lid and response_str response types are supported with render_choice and render_fib rendering. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + QTI General + + This contains the instructions for the presentation of questions whose response will be either a 'response_lid' (logical identifier), + 'response_xy' (xy-co-ordinate), 'response_str' (a string), 'response_num' (a number) and 'response_grp' ( a group of logical + identifiers). The question can be rendered in a variety of ways depending on the way in which the material is to be presented to the + participant. + + Common Cartridge Profile + + Only the response_lid and response_str response types are supported with render_choice and render_fib rendering. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + QTI General + + Contains the solution(s) that are to be revealed to the participant. When these solutions are revealed is outside the scope of the + specification. The information can be revealed in several manners. The default mode is to show the 'Complete' solution. + + Common Cartridge Profile + + The material is presented in the form of flow_mat only. The only form of feedback is 'Complete'. + + + + + + + + + + + + + + + + + + QTI General + + Contains the hints(s) that are to be revealed to the participant. When these hints are revealed is outside the scope of the + specification. The information can be revealed in several manners. The default mode is to show the 'Complete' hint. + + Common Cartridge Profile + + The material is presented in the form of flow_mat only. The only form of feedback is 'Complete'. + + + + + + + + + + + + + + + + + + QTI General + + The conditional test that is to be applied to the user’s response. + A wide range of separate and combinatorial tests can be applied. + + Common Cartridge Profile + + The extension has been removed. All of the conditions operating + on duration have been removed. The only permited conditions are + 'varequal', 'varsubstring', 'and', 'other'. + + + + + + + + + + + + + + + + This is the information that is used to describe the solution. + + + + + + + + + + + + This is the information that is presented as a hint. + + + + + + + + + + + + QTI General + + This defines the set of clauses that can be used within the + logic statements of 'and', 'or' and 'not'. These logic statements + enable the construction of complex conditional tests. + + Common Cartridge Profile + + The extension has been removed. All of the conditions operating + on duration have been removed. The 'or' conditional has been removed + and 'and' and 'not' have been considerably simplified. + + + + + + + + + + + + + + QTI General + + This defines the set of clauses that can be used within the + logic statements of 'and', 'or' and 'not'. These logic statements + enable the construction of complex conditional tests. + + Common Cartridge Profile + + The extension has been removed. All of the conditions operating + on duration have been removed. The 'or' conditional has been removed + and 'and' and 'not' have been considerably simplified. + + + + + + + + + + + + + This is the container of any text that is to be displayed to the users. + It is the base type for normal and emphasised text. + + + + + + + + + + + + + + + + + + + + + + This is used to contain a reference to the required full material block. This + material will have had an identifier assigned to enable such a reference to + be reconciled when the instance is parsed into the system. + + + + + + + + + + + + + This is used to contain a reference to the required full material block. This + material will have had an identifier assigned to enable such a reference to + be reconciled when the instance is parsed into the system. + + + + + + + + + + + + + QTI General + + This is used for the declaration of the scoring variables. + The name of the variable that is to be declared. The default + name is ‘SCORE’. All numeric variables have the associated + ‘x.min’, ‘x.max’ and ‘x.normalised’ variables declared. + Several of the optional attributes depend upon the type of + variable that is declared. + + Common Cartridge Profile + + Only the variable types of decimal and integer are permitted. + Only a single "SCORE" variable is permitted. + + + + + + + + + + + + + + + + + + + + + + + QTI General + + This is responsible for changing the value of the scoring + variable as a result of the associated response processing test. + The default action is to 'Set' the 'SCORE' variable to the value + given in the string. + + Common Cartridge Profile + + Only the actons Set, Add and Subtract are premitted. + + + + + + + + + + + + + + + + + + + + This is the test of equivalence. The data for the test is + contained as a string. The accompanying attributes are + the identifier for the associated 'response_label', the + ordinal 'index' of the response and whether or not the + value is case-sensitive when processing strings. + + + + + + + + + + + + + + + + + + + + + This is used for assigning an associated feedback to the + aggregated scoring if the ‘True’ state results. Feedback + for hints, solutions and response processing are supported. + The feedback is identified using the pointer 'linkrefid'. + + + + + + + + + + + + + + + + + + + + + + This is the test for a contained substring. + The data for comparison is presented as a + string. The associated attributes are the + response label identifier, the ordinal index of + the response and whether or not the value is + case-sensitive when processing the strings. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backup/cc/schemas11/imsbasiclti_v1p0p1.xsd b/backup/cc/schemas11/imsbasiclti_v1p0p1.xsd new file mode 100644 index 00000000000..70246cfd87f --- /dev/null +++ b/backup/cc/schemas11/imsbasiclti_v1p0p1.xsd @@ -0,0 +1,194 @@ + + + + + + + XSD Data File Information + ------------------------- + Author: Chuck Severance (IMS GLC) and Colin Smythe (IMS GLC) + Date: 9th June, 2010 + Version: 1.0.1 + Status: Final Release + Description: This is the description of the basicLTI link description. + + History: V1.0 - the first final release. + V1.0.1 - the multiplicity for the extensions attribute has been changed from 0..1 to 0..*. + + License: IPR, License and Distribution Notices + + This machine readable file is derived from IMS Global Learning Consortium (GLC) specification IMS Basic Learning Tools Interoperability + Version 1.0 found at http://www.imsglobal.org/lti and the original IMS GLC schema binding or code base + http://www.imsglobal.org/lti. + + Recipients of this document are requested to submit, with their comments, notification of any + relevant patent claims or other intellectual property rights of which they may be aware that might be + infringed by the schema binding contained in this document. + + IMS GLC takes no position regarding the validity or scope of any intellectual property or other + rights that might be claimed to pertain to the implementation or use of the technology described in this + document or the extent to which any license under such rights might or might not be available; neither + does it represent that it has made any effort to identify any such rights. Information on IMS GLCs + procedures with respect to rights in IMS GLC specifications can be found at the IMS GLC Intellectual Property + Rights web page: http://www.imsglobal.org/ipr/imsipr_policyFinal.pdf. + + Copyright (c) IMS Global Learning Consortium 1999-2010. All Rights Reserved. + + License Notice for Users + + Users of products or services that include this document are hereby granted a worldwide, royalty-free, + non-exclusive license to use this document. + + Distribution Notice for Developers + + Developers of products or services that are not original incorporators of this document and + have not changed this document, that is, are distributing a software product that incorporates this + document as is from a third-party source other than IMS, are hereby granted permission to copy, + display and distribute the contents of this document in any medium for any purpose without fee or + royalty provided that you include this IPR, License and Distribution notice in its entirety on ALL + copies, or portions thereof. + + Developers of products or services that are original incorporators of this document and wish + to provide distribution of this document as is or with modifications and developers of products and + services that are not original incorporators of this document and have changed this document, are + required to register with the IMS GLC community on the IMS GLC website as described in the following two + paragraphs:- + + * If you wish to distribute this document as is, with no modifications, you are hereby granted + permission to copy, display and distribute the contents of this document in any medium for any + purpose without fee or royalty provided that you include this IPR, License and Distribution notice in + its entirety on ALL copies, or portions thereof, that you make and you complete a valid license + registration with IMS and receive an email from IMS granting the license. To register, follow the + instructions on the IMS website: http://www.imsglobal.org/specificationdownload.cfm. Once + registered you are granted permission to transfer unlimited distribution rights of this document for the + purposes of third-party or other distribution of your product or service that incorporates this + document as long as this IPR, License and Distribution notice remains in place in its entirety; + + * If you wish to create and distribute a derived work from this document, you are hereby + granted permission to copy, display and distribute the contents of the derived work in any medium for + any purpose without fee or royalty provided that you include this IPR, License and Distribution + notice in its entirety on ALL copies, or portions thereof, that you make and you complete a valid + profile registration with IMS GLC and receive an email from IMS GLC granting the license. To register, follow + the instructions on the IMS GLC website: http://www.imsglobal.org/profile/. Once registered you are + granted permission to transfer unlimited distribution rights of the derived work for the purposes of + third-party or other distribution of your product or service that incorporates the derived work as long + as this IPR, License and Distribution notice remains in place in its entirety. + + The limited permissions granted above are perpetual and will not be revoked by IMS GLC or its + successors or assigns. + + THIS SPECIFICATION IS BEING OFFERED WITHOUT ANY WARRANTY WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NONINFRINGEMENT IS + EXPRESSLY DISCLAIMED. ANY USE OF THIS SPECIFICATION SHALL BE MADE ENTIRELY AT THE IMPLEMENTERS OWN RISK, AND NEITHER THE CONSORTIUM + NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF + ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY, ARISING FROM THE USE OF THIS SPECIFICATION. + + Source UML File Information + --------------------------- + The source file information must be supplied as an XMI file (without diagram layout information). + The supported UML authoring tools are: + (a) Poseidon – v6 (and later) + + Source XSLT File Information + ---------------------------- + XSL Generator: UMLtoXSDTransformv0p9.xsl + XSLT Processor: Xalan + Release: 1.0 Beta 3 + Date: 31st May, 2009 + + IMS GLC Auto-generation Binding Tool-kit (I-BAT) + ------------------------------------------------ + This file was auto-generated using the IMS GLC Binding Auto-generation Tool-kit (I-BAT). While every + attempt has been made to ensure that this tool auto-generates the files correctly, users should be aware + that this is an experimental tool. Permission is given to make use of this tool. IMS GLC makes no + claim on the materials created by third party users of this tool. Details on how to use this tool + are contained in the IMS GLC "I-BAT" Documentation available at the IMS GLC web-site. + + Tool Copyright: 2005-2010 (c) IMS Global Learning Consortium Inc. All Rights Reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The BasicLTILink class is the container for information required to use the BasicLTI mechanism. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backup/cc/schemas11/imslticc_v1p0p1.xsd b/backup/cc/schemas11/imslticc_v1p0p1.xsd new file mode 100644 index 00000000000..7dd29deb711 --- /dev/null +++ b/backup/cc/schemas11/imslticc_v1p0p1.xsd @@ -0,0 +1,231 @@ + + + + + + + + XSD Data File Information + ------------------------- + Author: Chuck Severance (IMS GLC) and Colin Smythe (IMS GLC) + Date: 9th June, 2010 + Version: 1.0.1 + Status: Final Release + Description: This is the description of the resource linkfile that is to be placed inside a Common Cartridge. + + History: V1.0 - the first Final Release. + V1.0.1 - changed to use the imsbasiclti_v1p0p1.xsd. + + License: IPR, License and Distribution Notices + + This machine readable file is derived from IMS Global Learning Consortium (GLC) specification IMS Common Cartridge Version 1.1 + found at http://www.imsglobal.org/cc and the original IMS GLC schema binding or code base + http://www.imsglobal.org/cc. + + Recipients of this document are requested to submit, with their comments, notification of any + relevant patent claims or other intellectual property rights of which they may be aware that might be + infringed by the schema binding contained in this document. + + IMS GLC takes no position regarding the validity or scope of any intellectual property or other + rights that might be claimed to pertain to the implementation or use of the technology described in this + document or the extent to which any license under such rights might or might not be available; neither + does it represent that it has made any effort to identify any such rights. Information on IMS GLCs + procedures with respect to rights in IMS GLC specifications can be found at the IMS GLC Intellectual Property + Rights web page: http://www.imsglobal.org/ipr/imsipr_policyFinal.pdf. + + Copyright (c) IMS Global Learning Consortium 1999-2011. All Rights Reserved. + + License Notice for Users + + Users of products or services that include this document are hereby granted a worldwide, royalty-free, + non-exclusive license to use this document. + + Distribution Notice for Developers + + Developers of products or services that are not original incorporators of this document and + have not changed this document, that is, are distributing a software product that incorporates this + document as is from a third-party source other than IMS, are hereby granted permission to copy, + display and distribute the contents of this document in any medium for any purpose without fee or + royalty provided that you include this IPR, License and Distribution notice in its entirety on ALL + copies, or portions thereof. + + Developers of products or services that are original incorporators of this document and wish + to provide distribution of this document as is or with modifications and developers of products and + services that are not original incorporators of this document and have changed this document, are + required to register with the IMS GLC community on the IMS GLC website as described in the following two + paragraphs:- + + * If you wish to distribute this document as is, with no modifications, you are hereby granted + permission to copy, display and distribute the contents of this document in any medium for any + purpose without fee or royalty provided that you include this IPR, License and Distribution notice in + its entirety on ALL copies, or portions thereof, that you make and you complete a valid license + registration with IMS and receive an email from IMS granting the license. To register, follow the + instructions on the IMS website: http://www.imsglobal.org/specificationdownload.cfm. Once + registered you are granted permission to transfer unlimited distribution rights of this document for the + purposes of third-party or other distribution of your product or service that incorporates this + document as long as this IPR, License and Distribution notice remains in place in its entirety; + + * If you wish to create and distribute a derived work from this document, you are hereby + granted permission to copy, display and distribute the contents of the derived work in any medium for + any purpose without fee or royalty provided that you include this IPR, License and Distribution + notice in its entirety on ALL copies, or portions thereof, that you make and you complete a valid + profile registration with IMS GLC and receive an email from IMS GLC granting the license. To register, follow + the instructions on the IMS GLC website: http://www.imsglobal.org/profile/. Once registered you are + granted permission to transfer unlimited distribution rights of the derived work for the purposes of + third-party or other distribution of your product or service that incorporates the derived work as long + as this IPR, License and Distribution notice remains in place in its entirety. + + The limited permissions granted above are perpetual and will not be revoked by IMS GLC or its + successors or assigns. + + THIS SPECIFICATION IS BEING OFFERED WITHOUT ANY WARRANTY WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NONINFRINGEMENT IS + EXPRESSLY DISCLAIMED. ANY USE OF THIS SPECIFICATION SHALL BE MADE ENTIRELY AT THE IMPLEMENTERS OWN RISK, AND NEITHER THE CONSORTIUM + NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF + ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY, ARISING FROM THE USE OF THIS SPECIFICATION. + + Source UML File Information + --------------------------- + The source file information must be supplied as an XMI file (without diagram layout information). + The supported UML authoring tools are: + (a) Poseidon – v6 (and later) + + Source XSLT File Information + ---------------------------- + XSL Generator: UMLtoXSDTransformv0p9.xsl + XSLT Processor: Xalan + Release: 1.0 Beta 3 + Date: 31st May, 2009 + + IMS GLC Auto-generation Binding Tool-kit (I-BAT) + ------------------------------------------------ + This file was auto-generated using the IMS GLC Binding Auto-generation Tool-kit (I-BAT). While every + attempt has been made to ensure that this tool auto-generates the files correctly, users should be aware + that this is an experimental tool. Permission is given to make use of this tool. IMS GLC makes no + claim on the materials created by third party users of this tool. Details on how to use this tool + are contained in the IMS GLC "I-BAT" Documentation available at the IMS GLC web-site. + + Tool Copyright: 2005-2010 (c) IMS Global Learning Consortium Inc. All Rights Reserved. + + + + + + + + + + + + + + + + + Any namespaced element from any namespace may be included within an "any" element. + The namespace for the imported element must be defined in the instance, and the schema must be imported. + The extension has a definition of "strict" i.e. they must have their own namespace. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The CartridgeBasicLTILink class is the container for the information about the use +of BasicLTI with a Common Cartridge. + + + + + + + + + + + + + + + + + The ToolLocator complexType is the container for the tool locator information for the cartridge BasicLTI resource. + + + + + + + + + + + + + + + + The ResourceRef complexType is the container for the resource reference. + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backup/cc/schemas11/imslticm_v1p0.xsd b/backup/cc/schemas11/imslticm_v1p0.xsd new file mode 100644 index 00000000000..b821301be7b --- /dev/null +++ b/backup/cc/schemas11/imslticm_v1p0.xsd @@ -0,0 +1,207 @@ + + + + + XSD Data File Information + ------------------------- + Author: Chuck Severance (IMS GLC) and Colin Smythe (IMS GLC) + Date: 30th April, 2010 + Version: 1.0 + Status: Final Release + Description: This is the description of the Common Messaging objects in LTI. + This version was created for the BasicLTI Final release. + + History: V1.0 - First final release. + + License: IPR, License and Distribution Notices + + This machine readable file is derived from IMS Global Learning Consortium (GLC) specification IMS Basic Learning Tools Interoperability + Version 1.0 found at http://www.imsglobal.org/lti and the original IMS GLC schema binding or code base + http://www.imsglobal.org/lti. + + Recipients of this document are requested to submit, with their comments, notification of any + relevant patent claims or other intellectual property rights of which they may be aware that might be + infringed by the schema binding contained in this document. + + IMS GLC takes no position regarding the validity or scope of any intellectual property or other + rights that might be claimed to pertain to the implementation or use of the technology described in this + document or the extent to which any license under such rights might or might not be available; neither + does it represent that it has made any effort to identify any such rights. Information on IMS GLCs + procedures with respect to rights in IMS GLC specifications can be found at the IMS GLC Intellectual Property + Rights web page: http://www.imsglobal.org/ipr/imsipr_policyFinal.pdf. + + Copyright (c) IMS Global Learning Consortium 1999-2010. All Rights Reserved. + + License Notice for Users + + Users of products or services that include this document are hereby granted a worldwide, royalty-free, + non-exclusive license to use this document. + + Distribution Notice for Developers + + Developers of products or services that are not original incorporators of this document and + have not changed this document, that is, are distributing a software product that incorporates this + document as is from a third-party source other than IMS, are hereby granted permission to copy, + display and distribute the contents of this document in any medium for any purpose without fee or + royalty provided that you include this IPR, License and Distribution notice in its entirety on ALL + copies, or portions thereof. + + Developers of products or services that are original incorporators of this document and wish + to provide distribution of this document as is or with modifications and developers of products and + services that are not original incorporators of this document and have changed this document, are + required to register with the IMS GLC community on the IMS GLC website as described in the following two + paragraphs:- + + * If you wish to distribute this document as is, with no modifications, you are hereby granted + permission to copy, display and distribute the contents of this document in any medium for any + purpose without fee or royalty provided that you include this IPR, License and Distribution notice in + its entirety on ALL copies, or portions thereof, that you make and you complete a valid license + registration with IMS and receive an email from IMS granting the license. To register, follow the + instructions on the IMS website: http://www.imsglobal.org/specificationdownload.cfm. Once + registered you are granted permission to transfer unlimited distribution rights of this document for the + purposes of third-party or other distribution of your product or service that incorporates this + document as long as this IPR, License and Distribution notice remains in place in its entirety; + + * If you wish to create and distribute a derived work from this document, you are hereby + granted permission to copy, display and distribute the contents of the derived work in any medium for + any purpose without fee or royalty provided that you include this IPR, License and Distribution + notice in its entirety on ALL copies, or portions thereof, that you make and you complete a valid + profile registration with IMS GLC and receive an email from IMS GLC granting the license. To register, follow + the instructions on the IMS GLC website: http://www.imsglobal.org/profile/. Once registered you are + granted permission to transfer unlimited distribution rights of the derived work for the purposes of + third-party or other distribution of your product or service that incorporates the derived work as long + as this IPR, License and Distribution notice remains in place in its entirety. + + The limited permissions granted above are perpetual and will not be revoked by IMS GLC or its + successors or assigns. + + THIS SPECIFICATION IS BEING OFFERED WITHOUT ANY WARRANTY WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NONINFRINGEMENT IS + EXPRESSLY DISCLAIMED. ANY USE OF THIS SPECIFICATION SHALL BE MADE ENTIRELY AT THE IMPLEMENTERS OWN RISK, AND NEITHER THE CONSORTIUM + NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF + ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY, ARISING FROM THE USE OF THIS SPECIFICATION. + + Source UML File Information + --------------------------- + The source file information must be supplied as an XMI file (without diagram layout information). + The supported UML authoring tools are: + (a) Poseidon – v6 (and later) + + Source XSLT File Information + ---------------------------- + XSL Generator: UMLtoXSDTransformv0p9.xsl + XSLT Processor: Xalan + Release: 1.0 Beta 3 + Date: 31st May, 2009 + + IMS GLC Auto-generation Binding Tool-kit (I-BAT) + ------------------------------------------------ + This file was auto-generated using the IMS GLC Binding Auto-generation Tool-kit (I-BAT). While every + attempt has been made to ensure that this tool auto-generates the files correctly, users should be aware + that this is an experimental tool. Permission is given to make use of this tool. IMS GLC makes no + claim on the materials created by third party users of this tool. Details on how to use this tool + are contained in the IMS GLC "I-BAT" Documentation available at the IMS GLC web-site. + + Tool Copyright: 2005-2010 (c) IMS Global Learning Consortium Inc. All Rights Reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The PropertySet complexType is the container for the set of properties. + + + + + + + + + + + The Platform complexType is the container for the set of properties for the platform. + + + + + + + + + + + + + + + + The Property complexType is the container for each property. + + + + + + + + + + + + + + + + + + + + + + diff --git a/backup/cc/schemas11/imslticp_v1p0.xsd b/backup/cc/schemas11/imslticp_v1p0.xsd new file mode 100644 index 00000000000..ee3df779106 --- /dev/null +++ b/backup/cc/schemas11/imslticp_v1p0.xsd @@ -0,0 +1,288 @@ + + + + + XSD Data File Information + ------------------------- + Author: Chuck Severance (IMS GLC) and Colin Smythe (IMS GLC) + Date: 30th April, 2010 + Version: 1.0 + Status: Final Release + Description: This is the set of Common Profile objects used in LTI. + This XSD was created as part of the BasicLTI Final Release. + + History: V1.0 - the first Final Release. + + License: IPR, License and Distribution Notices + + This machine readable file is derived from IMS Global Learning Consortium (GLC) specification IMS Basic Learning Tools Interoperability + Version 1.0 found at http://www.imsglobal.org/lti and the original IMS GLC schema binding or code base + http://www.imsglobal.org/lti. + + Recipients of this document are requested to submit, with their comments, notification of any + relevant patent claims or other intellectual property rights of which they may be aware that might be + infringed by the schema binding contained in this document. + + IMS GLC takes no position regarding the validity or scope of any intellectual property or other + rights that might be claimed to pertain to the implementation or use of the technology described in this + document or the extent to which any license under such rights might or might not be available; neither + does it represent that it has made any effort to identify any such rights. Information on IMS GLCs + procedures with respect to rights in IMS GLC specifications can be found at the IMS GLC Intellectual Property + Rights web page: http://www.imsglobal.org/ipr/imsipr_policyFinal.pdf. + + Copyright (c) IMS Global Learning Consortium 1999-2010. All Rights Reserved. + + License Notice for Users + + Users of products or services that include this document are hereby granted a worldwide, royalty-free, + non-exclusive license to use this document. + + Distribution Notice for Developers + + Developers of products or services that are not original incorporators of this document and + have not changed this document, that is, are distributing a software product that incorporates this + document as is from a third-party source other than IMS, are hereby granted permission to copy, + display and distribute the contents of this document in any medium for any purpose without fee or + royalty provided that you include this IPR, License and Distribution notice in its entirety on ALL + copies, or portions thereof. + + Developers of products or services that are original incorporators of this document and wish + to provide distribution of this document as is or with modifications and developers of products and + services that are not original incorporators of this document and have changed this document, are + required to register with the IMS GLC community on the IMS GLC website as described in the following two + paragraphs:- + + * If you wish to distribute this document as is, with no modifications, you are hereby granted + permission to copy, display and distribute the contents of this document in any medium for any + purpose without fee or royalty provided that you include this IPR, License and Distribution notice in + its entirety on ALL copies, or portions thereof, that you make and you complete a valid license + registration with IMS and receive an email from IMS granting the license. To register, follow the + instructions on the IMS website: http://www.imsglobal.org/specificationdownload.cfm. Once + registered you are granted permission to transfer unlimited distribution rights of this document for the + purposes of third-party or other distribution of your product or service that incorporates this + document as long as this IPR, License and Distribution notice remains in place in its entirety; + + * If you wish to create and distribute a derived work from this document, you are hereby + granted permission to copy, display and distribute the contents of the derived work in any medium for + any purpose without fee or royalty provided that you include this IPR, License and Distribution + notice in its entirety on ALL copies, or portions thereof, that you make and you complete a valid + profile registration with IMS GLC and receive an email from IMS GLC granting the license. To register, follow + the instructions on the IMS GLC website: http://www.imsglobal.org/profile/. Once registered you are + granted permission to transfer unlimited distribution rights of the derived work for the purposes of + third-party or other distribution of your product or service that incorporates the derived work as long + as this IPR, License and Distribution notice remains in place in its entirety. + + The limited permissions granted above are perpetual and will not be revoked by IMS GLC or its + successors or assigns. + + THIS SPECIFICATION IS BEING OFFERED WITHOUT ANY WARRANTY WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NONINFRINGEMENT IS + EXPRESSLY DISCLAIMED. ANY USE OF THIS SPECIFICATION SHALL BE MADE ENTIRELY AT THE IMPLEMENTERS OWN RISK, AND NEITHER THE CONSORTIUM + NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF + ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY, ARISING FROM THE USE OF THIS SPECIFICATION. + + Source UML File Information + --------------------------- + The source file information must be supplied as an XMI file (without diagram layout information). + The supported UML authoring tools are: + (a) Poseidon – v6 (and later) + + Source XSLT File Information + ---------------------------- + XSL Generator: UMLtoXSDTransformv0p9.xsl + XSLT Processor: Xalan + Release: 1.0 Beta 3 + Date: 31st May, 2009 + + IMS GLC Auto-generation Binding Tool-kit (I-BAT) + ------------------------------------------------ + This file was auto-generated using the IMS GLC Binding Auto-generation Tool-kit (I-BAT). While every + attempt has been made to ensure that this tool auto-generates the files correctly, users should be aware + that this is an experimental tool. Permission is given to make use of this tool. IMS GLC makes no + claim on the materials created by third party users of this tool. Details on how to use this tool + are contained in the IMS GLC "I-BAT" Documentation available at the IMS GLC web-site. + + Tool Copyright: 2005-2010 (c) IMS Global Learning Consortium Inc. All Rights Reserved. + + + + + + + + + + + + + + + + + + + + + Any namespaced element from any namespace may be included within an "any" element. + The namespace for the imported element must be defined in the instance, and the schema must be imported. + The extension has a definition of "strict" i.e. they must have their own namespace. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The Vendor complexType is the container for the information about the vendor of the tool to be launched/used using BasicLTI. + + + + + + + + + + + + + + + + + + + + + + + The Contact class is the container for the vendor contact information. + + + + + + + + + + + + + + + + + + + + The productInfo complexType is the container for the information about the tool itself. + + + + + + + + + + + + + + + The ToolLocator complexType is the container for information about the electronic location of the tool. + + + + + + + + + + + + + + + + + + + + + The Localized complexType is the container for localized string entries. + + + + + + + + + + + + + + The Icon complexType is the container for information about an icon to be used with the tool. + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backup/cc/schemas11/xml.xsd b/backup/cc/schemas11/xml.xsd new file mode 100644 index 00000000000..8e0c9d45fd6 --- /dev/null +++ b/backup/cc/schemas11/xml.xsd @@ -0,0 +1,145 @@ + + + + + + See http://www.w3.org/XML/1998/namespace.html and + http://www.w3.org/TR/REC-xml for information about this namespace. + + This schema document describes the XML namespace, in a form + suitable for import by other schema documents. + + Note that local names in this namespace are intended to be defined + only by the World Wide Web Consortium or its subgroups. The + following names are currently defined in this namespace and should + not be used with conflicting semantics by any Working Group, + specification, or document instance: + + base (as an attribute name): denotes an attribute whose value + provides a URI to be used as the base for interpreting any + relative URIs in the scope of the element on which it + appears; its value is inherited. This name is reserved + by virtue of its definition in the XML Base specification. + + id (as an attribute name): denotes an attribute whose value + should be interpreted as if declared to be of type ID. + This name is reserved by virtue of its definition in the + xml:id specification. + + lang (as an attribute name): denotes an attribute whose value + is a language code for the natural language of the content of + any element; its value is inherited. This name is reserved + by virtue of its definition in the XML specification. + + space (as an attribute name): denotes an attribute whose + value is a keyword indicating what whitespace processing + discipline is intended for the content of the element; its + value is inherited. This name is reserved by virtue of its + definition in the XML specification. + + Father (in any context at all): denotes Jon Bosak, the chair of + the original XML Working Group. This name is reserved by + the following decision of the W3C XML Plenary and + XML Coordination groups: + + In appreciation for his vision, leadership and dedication + the W3C XML Plenary on this 10th day of February, 2000 + reserves for Jon Bosak in perpetuity the XML name + xml:Father + + + + + This schema defines attributes and an attribute group + suitable for use by + schemas wishing to allow xml:base, xml:lang, xml:space or xml:id + attributes on elements they define. + + To enable this, such a schema must import this schema + for the XML namespace, e.g. as follows: + <schema . . .> + . . . + <import namespace="http://www.w3.org/XML/1998/namespace" + schemaLocation="http://www.w3.org/2001/xml.xsd"/> + + Subsequently, qualified reference to any of the attributes + or the group defined below will have the desired effect, e.g. + + <type . . .> + . . . + <attributeGroup ref="xml:specialAttrs"/> + + will define a type which will schema-validate an instance + element with any of those attributes + + + + In keeping with the XML Schema WG's standard versioning + policy, this schema document will persist at + http://www.w3.org/2007/08/xml.xsd. + At the date of issue it can also be found at + http://www.w3.org/2001/xml.xsd. + The schema document at that URI may however change in the future, + in order to remain compatible with the latest version of XML Schema + itself, or with the XML namespace itself. In other words, if the XML + Schema or XML namespaces change, the version of this document at + http://www.w3.org/2001/xml.xsd will change + accordingly; the version at + http://www.w3.org/2007/08/xml.xsd will not change. + + + + + + Attempting to install the relevant ISO 2- and 3-letter + codes as the enumerated possible values is probably never + going to be a realistic possibility. See + RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry + at http://www.iana.org/assignments/lang-tag-apps.htm for + further information. + + The union allows for the 'un-declaration' of xml:lang with + the empty string. + + + + + + + + + + + + + + + + + + + + + + + + See http://www.w3.org/TR/xmlbase/ for + information about this attribute. + + + + + + See http://www.w3.org/TR/xml-id/ for + information about this attribute. + + + + + + + + + + + diff --git a/backup/cc/sheets/course_header.xml b/backup/cc/sheets/course_header.xml index 05a2430de84..ed35f0a39d3 100644 --- a/backup/cc/sheets/course_header.xml +++ b/backup/cc/sheets/course_header.xml @@ -7,7 +7,7 @@ [#course_name#] [#course_short_name#] - + [#course_description#] topics 1 5 diff --git a/backup/cc/sheets/course_modules_mod_basiclti.xml b/backup/cc/sheets/course_modules_mod_basiclti.xml new file mode 100644 index 00000000000..8a8789b253c --- /dev/null +++ b/backup/cc/sheets/course_modules_mod_basiclti.xml @@ -0,0 +1,30 @@ + + [#mod_instance#] + basiclti + [#mod_basiclti_name#] + [#mod_basiclti_intro#] + 1 + [#mod_basiclti_timec#] + [#mod_basiclti_timem#] + 0 + [#mod_basiclti_toolurl#] + 0 + 0 + 0 + 0 + 0 + $@NULL@$ + 0 + 0 + 100 + $@NULL@$ + $@NULL@$ + $@NULL@$ + [#mod_basiclti_orgid#] + [#mod_basiclti_orgurl#] + [#mod_basiclti_orgdesc#] + 0 + 0 + 0 + 0 + \ No newline at end of file diff --git a/backup/cc/sheets/course_modules_mod_forum.xml b/backup/cc/sheets/course_modules_mod_forum.xml index 56a3029e929..78b21b1e412 100644 --- a/backup/cc/sheets/course_modules_mod_forum.xml +++ b/backup/cc/sheets/course_modules_mod_forum.xml @@ -2,8 +2,8 @@ [#mod_instance#] forum news - - + [#mod_forum_title#] + [#mod_forum_intro#] 0 0 0 diff --git a/backup/cc/sheets/course_modules_mod_label.xml b/backup/cc/sheets/course_modules_mod_label.xml index 7002e16dd18..4e949e46cbb 100644 --- a/backup/cc/sheets/course_modules_mod_label.xml +++ b/backup/cc/sheets/course_modules_mod_label.xml @@ -1,7 +1,7 @@ [#mod_instance#] label - - + [#mod_name#] + [#mod_content#] [#date_now#] diff --git a/backup/cc/sheets/course_modules_mod_lti.xml b/backup/cc/sheets/course_modules_mod_lti.xml new file mode 100644 index 00000000000..5950b0d9cf0 --- /dev/null +++ b/backup/cc/sheets/course_modules_mod_lti.xml @@ -0,0 +1,18 @@ + + [#mod_instance#] + lti + [#mod_basiclti_name#] + [#mod_basiclti_intro#] + 1 + [#mod_basiclti_timec#] + [#mod_basiclti_timem#] + 1 + [#mod_basiclti_toolurl#] + 1 + 0 + 1 + 1 + $@NULL@$ + 100.00000 + 0 + \ No newline at end of file diff --git a/backup/cc/sheets/course_modules_mod_resource.xml b/backup/cc/sheets/course_modules_mod_resource.xml index 650c5976db3..d9d24fb3322 100644 --- a/backup/cc/sheets/course_modules_mod_resource.xml +++ b/backup/cc/sheets/course_modules_mod_resource.xml @@ -1,11 +1,11 @@ [#mod_instance#] resource - + [#mod_name#] [#mod_type#] [#mod_reference#] - - + [#mod_summary#] + [#mod_alltext#] objectframe [#date_now#] diff --git a/backup/cc/sheets/course_question_categories_question_category.xml b/backup/cc/sheets/course_question_categories_question_category.xml index 19fb1b8f4b0..be623bfd4b0 100644 --- a/backup/cc/sheets/course_question_categories_question_category.xml +++ b/backup/cc/sheets/course_question_categories_question_category.xml @@ -1,7 +1,7 @@ [#quiz_id#] - - + Quiz Bank '[#quiz_name#]' + Questions in quiz '[#quiz_name#]'. course diff --git a/backup/cc/sheets/course_question_categories_question_category_question.xml b/backup/cc/sheets/course_question_categories_question_category_question.xml index 6481e141800..99028c41574 100644 --- a/backup/cc/sheets/course_question_categories_question_category_question.xml +++ b/backup/cc/sheets/course_question_categories_question_category_question.xml @@ -1,11 +1,11 @@ [#question_id#] 0 - - + [#question_title#] + [#question_text#] 1 - + [#question_general_feedback#] 1 0 [#question_type#] diff --git a/backup/cc/sheets/course_question_categories_question_category_question_answer.xml b/backup/cc/sheets/course_question_categories_question_category_question_answer.xml index aba35eac48e..2ec6e94556d 100644 --- a/backup/cc/sheets/course_question_categories_question_category_question_answer.xml +++ b/backup/cc/sheets/course_question_categories_question_category_question_answer.xml @@ -1,6 +1,6 @@ [#answer_id#] - + [#answer_text#] [#answer_score#] - + [#answer_feedback#] diff --git a/backup/cc/sheets/info_details_mod_instance.xml b/backup/cc/sheets/info_details_mod_instance.xml index 97a51ada81d..97a679edb0d 100644 --- a/backup/cc/sheets/info_details_mod_instance.xml +++ b/backup/cc/sheets/info_details_mod_instance.xml @@ -1,6 +1,6 @@ [#mod_instance_id#] - + [#mod_name#] true false diff --git a/backup/cc/sheets/moodle_blti_export.xml b/backup/cc/sheets/moodle_blti_export.xml new file mode 100644 index 00000000000..e87ff0c8309 --- /dev/null +++ b/backup/cc/sheets/moodle_blti_export.xml @@ -0,0 +1,1837 @@ + + + + backup-cf101-20110815-0949.zip + 2007101591 + 1.9.10 (Build: 20101025) + 2009111300 + 1.9.7 + 1313412551 + http://localhost/mdl191 + 9d9e34b447116860361beeca0191299f + internal +
+ + forum + false + false + + + + + basiclti + true + false + + + 2 + Yeah2 + true + false + + + + false + none + false + false + false + false + false + false + false + instances +
+
+ + + 3 + Teacher + editingteacher + + + report/courseoverview:view + 1 + 1311692228 + 0 + + + moodle/user:viewhiddendetails + 1 + 1311692105 + 0 + + + moodle/user:viewdetails + 1 + 1311692105 + 0 + + + moodle/user:readuserposts + 1 + 1311692108 + 0 + + + moodle/user:readuserblogs + 1 + 1311692109 + 0 + + + moodle/tag:manage + 1 + 1311692111 + 0 + + + moodle/tag:editblocks + 1 + 1311692112 + 0 + + + moodle/site:viewreports + 1 + 1311692104 + 0 + + + moodle/site:viewfullnames + 1 + 1311692104 + 0 + + + moodle/site:trustcontent + 1 + 1311692104 + 0 + + + moodle/site:restore + 1 + 1311692103 + 0 + + + moodle/site:readallmessages + 1 + 1311692103 + 0 + + + moodle/site:manageblocks + 1 + 1311692104 + 0 + + + moodle/site:import + 1 + 1311692103 + 0 + + + moodle/site:doclinks + 1 + 1311692110 + 0 + + + moodle/site:backup + 1 + 1311692103 + 0 + + + moodle/site:accessallgroups + 1 + 1311692104 + 0 + + + moodle/role:viewhiddenassigns + 1 + 1311692105 + 0 + + + moodle/role:unassignself + 1 + 1311692105 + 0 + + + moodle/role:switchroles + 1 + 1311692105 + 0 + + + moodle/role:safeoverride + 1 + 1311692105 + 0 + + + moodle/role:assign + 1 + 1311692105 + 0 + + + moodle/question:viewmine + 1 + 1311692109 + 0 + + + moodle/question:viewall + 1 + 1311692109 + 0 + + + moodle/question:usemine + 1 + 1311692109 + 0 + + + moodle/question:useall + 1 + 1311692109 + 0 + + + moodle/question:movemine + 1 + 1311692109 + 0 + + + moodle/question:moveall + 1 + 1311692109 + 0 + + + moodle/question:managecategory + 1 + 1311692109 + 0 + + + moodle/question:editmine + 1 + 1311692109 + 0 + + + moodle/question:editall + 1 + 1311692109 + 0 + + + moodle/question:add + 1 + 1311692109 + 0 + + + moodle/notes:view + 1 + 1311692111 + 0 + + + moodle/notes:manage + 1 + 1311692111 + 0 + + + moodle/legacy:editingteacher + 1 + 1311692103 + 0 + + + moodle/grade:viewhidden + 1 + 1311692110 + 0 + + + moodle/grade:viewall + 1 + 1311692110 + 0 + + + moodle/grade:unlock + 1 + 1311692111 + 0 + + + moodle/grade:manageoutcomes + 1 + 1311692110 + 0 + + + moodle/grade:manageletters + 1 + 1311692111 + 0 + + + moodle/grade:manage + 1 + 1311692110 + 0 + + + moodle/grade:lock + 1 + 1311692111 + 0 + + + moodle/grade:import + 1 + 1311692110 + 0 + + + moodle/grade:hide + 1 + 1311692111 + 0 + + + moodle/grade:export + 1 + 1311692110 + 0 + + + moodle/grade:edit + 1 + 1311692110 + 0 + + + moodle/course:visibility + 1 + 1311692106 + 0 + + + moodle/course:viewscales + 1 + 1311692107 + 0 + + + moodle/course:viewparticipants + 1 + 1311692107 + 0 + + + moodle/course:viewhiddenuserfields + 1 + 1311692106 + 0 + + + moodle/course:viewhiddensections + 1 + 1311692110 + 0 + + + moodle/course:viewhiddencourses + 1 + 1311692106 + 0 + + + moodle/course:viewhiddenactivities + 1 + 1311692106 + 0 + + + moodle/course:view + 1 + 1311692106 + 0 + + + moodle/course:useremail + 1 + 1311692110 + 0 + + + moodle/course:update + 1 + 1311692106 + 0 + + + moodle/course:setcurrentsection + 1 + 1311692110 + 0 + + + moodle/course:sectionvisibility + 1 + 1311692110 + 0 + + + moodle/course:reset + 1 + 1311692107 + 0 + + + moodle/course:managescales + 1 + 1311692107 + 0 + + + moodle/course:managemetacourse + 1 + 1311692106 + 0 + + + moodle/course:managegroups + 1 + 1311692107 + 0 + + + moodle/course:managefiles + 1 + 1311692106 + 0 + + + moodle/course:manageactivities + 1 + 1311692106 + 0 + + + moodle/course:changesummary + 1 + 1311692107 + 0 + + + moodle/course:changeshortname + 1 + 1311692107 + 0 + + + moodle/course:changeidnumber + 1 + 1311692107 + 0 + + + moodle/course:changefullname + 1 + 1311692107 + 0 + + + moodle/course:changecategory + 1 + 1311692107 + 0 + + + moodle/course:bulkmessaging + 1 + 1311692106 + 0 + + + moodle/course:activityvisibility + 1 + 1311692106 + 0 + + + moodle/calendar:managegroupentries + 1 + 1311692108 + 0 + + + moodle/calendar:manageentries + 1 + 1311692108 + 0 + + + moodle/blog:view + 1 + 1311692108 + 0 + + + moodle/blog:manageentries + 1 + 1311692108 + 0 + + + moodle/block:view + 1 + 1311692112 + 0 + + + mod/workshop:manage + 1 + 1311692191 + 0 + + + mod/wiki:participate + 1 + 1311692184 + 0 + + + mod/wiki:overridelock + 1 + 1311692185 + 0 + + + mod/wiki:manage + 1 + 1311692185 + 0 + + + mod/survey:readresponses + 1 + 1311692181 + 0 + + + mod/survey:participate + 1 + 1311692181 + 0 + + + mod/survey:download + 1 + 1311692181 + 0 + + + mod/scorm:viewscores + 1 + 1311692177 + 0 + + + mod/scorm:viewreport + 1 + 1311692176 + 0 + + + mod/scorm:savetrack + 1 + 1311692176 + 0 + + + mod/scorm:deleteresponses + 1 + 1311692177 + 0 + + + mod/quiz:viewreports + 1 + 1311692167 + 0 + + + mod/quiz:view + 1 + 1311692167 + 0 + + + mod/quiz:preview + 1 + 1311692167 + 0 + + + mod/quiz:manage + 1 + 1311692167 + 0 + + + mod/quiz:grade + 1 + 1311692167 + 0 + + + mod/quiz:deleteattempts + 1 + 1311692167 + 0 + + + mod/lesson:manage + 1 + 1311692156 + 0 + + + mod/lesson:edit + 1 + 1311692155 + 0 + + + mod/lams:manage + 1 + 1311692150 + 0 + + + mod/hotpot:viewreport + 1 + 1311692147 + 0 + + + mod/hotpot:grade + 1 + 1311692147 + 0 + + + mod/hotpot:deleteattempt + 1 + 1311692148 + 0 + + + mod/hotpot:attempt + 1 + 1311692147 + 0 + + + mod/glossary:write + 1 + 1311692143 + 0 + + + mod/glossary:viewrating + 1 + 1311692144 + 0 + + + mod/glossary:rate + 1 + 1311692144 + 0 + + + mod/glossary:manageentries + 1 + 1311692143 + 0 + + + mod/glossary:managecomments + 1 + 1311692144 + 0 + + + mod/glossary:managecategories + 1 + 1311692143 + 0 + + + mod/glossary:import + 1 + 1311692144 + 0 + + + mod/glossary:export + 1 + 1311692144 + 0 + + + mod/glossary:comment + 1 + 1311692143 + 0 + + + mod/glossary:approve + 1 + 1311692144 + 0 + + + mod/forum:viewsubscribers + 1 + 1311692138 + 0 + + + mod/forum:viewrating + 1 + 1311692137 + 0 + + + mod/forum:viewqandawithoutposting + 1 + 1311692138 + 0 + + + mod/forum:viewhiddentimedposts + 1 + 1311692137 + 0 + + + mod/forum:viewdiscussion + 1 + 1311692137 + 0 + + + mod/forum:viewanyrating + 1 + 1311692137 + 0 + + + mod/forum:startdiscussion + 1 + 1311692137 + 0 + + + mod/forum:splitdiscussions + 1 + 1311692138 + 0 + + + mod/forum:replypost + 1 + 1311692137 + 0 + + + mod/forum:replynews + 1 + 1311692137 + 0 + + + mod/forum:rate + 1 + 1311692138 + 0 + + + mod/forum:movediscussions + 1 + 1311692138 + 0 + + + mod/forum:managesubscriptions + 1 + 1311692138 + 0 + + + mod/forum:initialsubscriptions + 1 + 1311692139 + 0 + + + mod/forum:editanypost + 1 + 1311692138 + 0 + + + mod/forum:deleteownpost + 1 + 1311692138 + 0 + + + mod/forum:deleteanypost + 1 + 1311692138 + 0 + + + mod/forum:createattachment + 1 + 1311692138 + 0 + + + mod/forum:addnews + 1 + 1311692137 + 0 + + + mod/data:writeentry + 1 + 1311692130 + 0 + + + mod/data:viewrating + 1 + 1311692131 + 0 + + + mod/data:viewentry + 1 + 1311692130 + 0 + + + mod/data:viewalluserpresets + 1 + 1311692131 + 0 + + + mod/data:rate + 1 + 1311692131 + 0 + + + mod/data:managetemplates + 1 + 1311692131 + 0 + + + mod/data:manageentries + 1 + 1311692131 + 0 + + + mod/data:managecomments + 1 + 1311692131 + 0 + + + mod/data:comment + 1 + 1311692131 + 0 + + + mod/data:approve + 1 + 1311692131 + 0 + + + mod/choice:readresponses + 1 + 1311692127 + 0 + + + mod/choice:downloadresponses + 1 + 1311692127 + 0 + + + mod/choice:deleteresponses + 1 + 1311692127 + 0 + + + mod/choice:choose + 1 + 1311692127 + 0 + + + mod/chat:readlog + 1 + 1311692125 + 0 + + + mod/chat:deletelog + 1 + 1311692125 + 0 + + + mod/chat:chat + 1 + 1311692125 + 0 + + + mod/assignment:view + 1 + 1311692122 + 0 + + + mod/assignment:grade + 1 + 1311692122 + 0 + + + mod/assess:viewreport + 1 + 1311965861 + 2 + + + mod/assess:manage + 1 + 1311965861 + 2 + + + gradereport/user:view + 1 + 1311692221 + 0 + + + gradereport/outcomes:view + 1 + 1311692220 + 0 + + + gradereport/grader:view + 1 + 1311692220 + 0 + + + gradeimport/xml:view + 1 + 1311692217 + 0 + + + gradeimport/csv:view + 1 + 1311692216 + 0 + + + gradeexport/xml:view + 1 + 1311692213 + 0 + + + gradeexport/xls:view + 1 + 1311692213 + 0 + + + gradeexport/txt:view + 1 + 1311692212 + 0 + + + gradeexport/ods:view + 1 + 1311692212 + 0 + + + coursereport/stats:view + 1 + 1311692225 + 0 + + + coursereport/participation:view + 1 + 1311692225 + 0 + + + coursereport/outline:view + 1 + 1311692225 + 0 + + + coursereport/log:viewtoday + 1 + 1311692225 + 0 + + + coursereport/log:viewlive + 1 + 1311692225 + 0 + + + coursereport/log:view + 1 + 1311692224 + 0 + + + block/rss_client:manageownfeeds + 1 + 1311692204 + 0 + + + block/rss_client:createsharedfeeds + 1 + 1311692204 + 0 + + + block/rss_client:createprivatefeeds + 1 + 1311692204 + 0 + + + block/online_users:viewlist + 1 + 1311692203 + 0 + + + block/homework:view + -1 + 1312038862 + 2 + + + block/email_list:sendmessage + 1 + 1311965874 + 2 + + + block/email_list:editsettings + 1 + 1311965874 + 2 + + + block/email_list:createfolder + 1 + 1311965874 + 2 + + + + + 5 + Student + student + + + moodle/user:viewdetails + 1 + 1311692105 + 0 + + + moodle/user:readuserposts + 1 + 1311692108 + 0 + + + moodle/user:readuserblogs + 1 + 1311692109 + 0 + + + moodle/legacy:student + 1 + 1311692103 + 0 + + + moodle/grade:view + 1 + 1311692110 + 0 + + + moodle/course:viewscales + 1 + 1311692107 + 0 + + + moodle/course:viewparticipants + 1 + 1311692107 + 0 + + + moodle/course:view + 1 + 1311692106 + 0 + + + moodle/blog:view + 1 + 1311692108 + 0 + + + moodle/block:view + 1 + 1311692112 + 0 + + + mod/workshop:participate + 1 + 1311692191 + 0 + + + mod/wiki:participate + 1 + 1311692184 + 0 + + + mod/survey:participate + 1 + 1311692181 + 0 + + + mod/scorm:viewscores + 1 + 1311692176 + 0 + + + mod/scorm:skipview + 1 + 1311692176 + 0 + + + mod/scorm:savetrack + 1 + 1311692176 + 0 + + + mod/quiz:view + 1 + 1311692167 + 0 + + + mod/quiz:reviewmyattempts + 1 + 1311692167 + 0 + + + mod/quiz:attempt + 1 + 1311692167 + 0 + + + mod/lams:participate + 1 + 1311692150 + 0 + + + mod/hotpot:attempt + 1 + 1311692147 + 0 + + + mod/glossary:write + 1 + 1311692143 + 0 + + + mod/glossary:comment + 1 + 1311692143 + 0 + + + mod/forum:viewrating + 1 + 1311692137 + 0 + + + mod/forum:viewdiscussion + 1 + 1311692137 + 0 + + + mod/forum:startdiscussion + 1 + 1311692137 + 0 + + + mod/forum:replypost + 1 + 1311692137 + 0 + + + mod/forum:initialsubscriptions + 1 + 1311692139 + 0 + + + mod/forum:deleteownpost + 1 + 1311692138 + 0 + + + mod/forum:createattachment + 1 + 1311692138 + 0 + + + mod/data:writeentry + 1 + 1311692130 + 0 + + + mod/data:viewentry + 1 + 1311692130 + 0 + + + mod/data:comment + 1 + 1311692130 + 0 + + + mod/choice:choose + 1 + 1311692127 + 0 + + + mod/chat:readlog + 1 + 1311692125 + 0 + + + mod/chat:chat + 1 + 1311692125 + 0 + + + mod/assignment:view + 1 + 1311692122 + 0 + + + mod/assignment:submit + 1 + 1311692122 + 0 + + + mod/assess:submit + 1 + 1311965860 + 2 + + + gradereport/user:view + 1 + 1311692221 + 0 + + + gradereport/overview:view + 1 + 1311692220 + 0 + + + block/online_users:viewlist + 1 + 1311692203 + 0 + + + block/homework:view + 1 + 1312038862 + 2 + + + block/email_list:sendmessage + 1 + 1311965874 + 2 + + + block/email_list:editsettings + 1 + 1311965874 + 2 + + + block/email_list:createfolder + 1 + 1311965874 + 2 + + + + + +
+ 2 + + 1 + Miscellaneous + + + Course Fullname 101 + CF101 + + test + weeks + 1 + 5 + Teacher + Teachers + Student + Students + 0 + 1311735600 + 10 + 83886080 + 0 + 0 + 0 + 0 + + + + USD + 0 + 1 + 0 + 1311696225 + 1311702033 + 0 + 0 + 0 + 864000 + 1 + 0 + 0 + 0 + + + + +
+ + + 7 + participants + 2 + course-view + l + 0 + 1 + Tjs= + + + + + + + 8 + activity_modules + 2 + course-view + l + 1 + 1 + Tjs= + + + + + + + 9 + search_forums + 2 + course-view + l + 2 + 1 + Tjs= + + + + + + + 10 + admin + 2 + course-view + l + 3 + 1 + Tjs= + + + + + + + 11 + course_list + 2 + course-view + l + 4 + 1 + Tjs= + + + + + + + 12 + news_items + 2 + course-view + r + 0 + 1 + Tjs= + + + + + + + 13 + calendar_upcoming + 2 + course-view + r + 1 + 1 + Tjs= + + + + + + + 14 + recent_activity + 2 + course-view + r + 2 + 1 + Tjs= + + + + + + + 18 + email_list + 2 + course-view + r + 3 + 1 + Tjs= + + + + + + + + + 27 + homework + 2 + course-view + r + 4 + 1 + Tjs= + + + + + + + 28 + groups_list + 2 + course-view + r + 5 + 1 + Tzo2OiJvYmplY3QiOjE6e3M6MjQ6ImJsb2NrX2dyb3Vwc19saXN0X2Zvb3RlciI7czoxMDM6IjxzdHJvbmc+PGZvbnQgY29sb3I9IiNmZjAwMDAiIGZhY2U9InZlcmRhbmEsYXJpYWwsaGVsdmV0aWNhLHNhbnMtc2VyaWYiPlNvbWUgZHVtbXkgdGV4dDwvZm9udD48L3N0cm9uZz4iO30= + + + + + + + 29 + calendar_month + 2 + course-view + r + 6 + 1 + Tjs= + + + + + + + +
+ 1 + 0 + $@NULL@$ + 1 +
+
+ 2 + 1 + + 1 + + + 4 + basiclti + 2 + 1313173537 + 0 + 0 + 1 + 0 + 0 + 0 + + + + + + + +
+
+ 3 + 2 + + 1 +
+
+ 4 + 3 + + 1 +
+
+ 5 + 4 + + 1 +
+
+ 6 + 5 + + 1 +
+
+ 7 + 6 + + 1 +
+
+ 8 + 7 + + 1 +
+
+ 9 + 8 + + 1 +
+
+ 10 + 9 + + 1 +
+
+ 11 + 10 + + 1 +
+
+ + + 1 + agroup + a + + 0 + 0 + 1311696376 + 1312545299 + + + 2 + bgroup + b + + 0 + 0 + 1311696386 + 1312545319 + + + 3 + cgroup + c + + 0 + 0 + 1311696395 + 1311696404 + + + 5 + egroup + + + 0 + 0 + 1312547386 + 1312547508 + + + 6 + fgroup + + + 0 + 0 + 1312547420 + 1312547528 + + + 7 + kgroup + + + 0 + 0 + 1312547435 + 1312547546 + + + 8 + ggroup + g + + 0 + 0 + 1312838855 + 1312838870 + + + + + + 1 + $@NULL@$ + ? + 11 + 0 + 0 + 1 + 0 + 0 + 1313083852 + 1313083852 + + + + + 1 + $@NULL@$ + $@NULL@$ + course + $@NULL@$ + 1 + $@NULL@$ + $@NULL@$ + $@NULL@$ + $@NULL@$ + 1 + 100.00000 + 0.00000 + $@NULL@$ + $@NULL@$ + 0.00000 + 1.00000 + 0.00000 + 0.00000 + 0 + $@NULL@$ + 0 + 0 + 0 + 0 + 1313083852 + 1313083852 + + + + + + 2 + Yeah2 + dddd + 1 + 1313173537 + 1 + http://www.imsglobal.org/developers/BLTI/tool.php + 1024 + 1 + 1 + 0 + 0 + $@NULL@$ + + 0 + 100 + 4e457021202cb7.92784742 + 1313173537 + $@NULL@$ + lmsng.school.edu + University of School (LMSng) + + 0 + 1 + 0 + 0 + + + + +
+
diff --git a/backup/cc/validator.php b/backup/cc/validator.php new file mode 100644 index 00000000000..43de9031149 --- /dev/null +++ b/backup/cc/validator.php @@ -0,0 +1,253 @@ +. +/** + * Provides validation classes used by the imscc converters + * + * @package backup-convert + * @copyright 2011 Darko Miletic + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +final class error_messages { + /** + * + * @static error_messages + */ + private static $instance = null; + private function __construct(){} + private function __clone(){} + /** + * @return error_messages + */ + public static function instance() { + if (empty(self::$instance)) { + $c = __CLASS__; + self::$instance = new $c(); + } + return self::$instance; + } + + /** + * @var array + */ + private $items = array(); + + /** + * @param string $msg + */ + public function add($msg) { + if (!empty($msg)) { + $this->items[] = $msg; + } + } + + /** + * @return array + */ + public function errors() { + $this->items; + } + + /** + * Empties the error content + */ + public function reset() { + $this->items = array(); + } + + /** + * @param boolean $web + * @return string + */ + public function to_string($web = false) { + $result = ''; + if ($web) { + $result .= '
    '.PHP_EOL; + } + foreach ($this->items as $error) { + if ($web) { + $result .= '
  1. '; + } + + $result .= $error.PHP_EOL; + + if ($web) { + $result .= '
  2. '.PHP_EOL; + } + } + if ($web) { + $result .= '
'.PHP_EOL; + } + return $result; + } + + /** + * Casting to string method + * @return string + */ + public function __toString() { + return $this->to_string(false); + } + +} + +final class libxml_errors_mgr { + /** + * @var boolean + */ + private $previous = false; + public function __construct(){ + $this->previous = libxml_use_internal_errors(true); + libxml_clear_errors(); + } + + private function collect_errors ($filename=''){ + $errors = libxml_get_errors(); + static $error_types = array( + LIBXML_ERR_ERROR => 'Error' + ,LIBXML_ERR_FATAL => 'Fatal Error' + ,LIBXML_ERR_WARNING => 'Warning' + ); + $result = array(); + foreach($errors as $error){ + $add = ''; + if (!empty($filename)) { + $add = " in {$filename}"; + } elseif (!empty($error->file)) { + $add = " in {$error->file}"; + } + $line = ''; + if (!empty($error->line)) { + $line = " at line {$error->line}"; + } + $err = "{$error_types[$error->level]}{$add}: {$error->message}{$line}"; + error_messages::instance()->add($err); + } + libxml_clear_errors(); + return $result; + } + + public function __destruct(){ + $this->collect_errors(); + if (!$this->previous) { + libxml_use_internal_errors($this->previous); + } + } +} + + +function validate_xml($xml, $schema){ + $result = false; + $manifest_file = realpath($xml); + $schema_file = realpath($schema); + if (empty($manifest_file) || empty($schema_file)) { + return false; + } + + $xml_error = new libxml_errors_mgr(); + $manifest = new DOMDocument(); + $doc->validateOnParse = false; + $result = $manifest->load($manifest_file, LIBXML_NONET) && + $manifest->schemaValidate($schema_file); + + return $result; +} + +class cc_validate_type { + const manifest_validator1 = 'cclibxml2validator.xsd' ; + const assesment_validator1 = '/domainProfile_4/ims_qtiasiv1p2_localised.xsd'; + const discussion_validator1 = '/domainProfile_6/imsdt_v1p0_localised.xsd' ; + const weblink_validator1 = '/domainProfile_5/imswl_v1p0_localised.xsd' ; + + const manifest_validator11 = 'cc11libxml2validator.xsd' ; + const blti_validator11 = 'imslticc_v1p0p1.xsd' ; + const assesment_validator11 = 'ccv1p1_qtiasiv1p2p1_v1p0.xsd'; + const discussion_validator11 = 'ccv1p1_imsdt_v1p1.xsd' ; + const weblink_validator11 = 'ccv1p1_imswl_v1p1.xsd' ; + + /** + * @var string + */ + protected $type = null; + + /** + * @var string + */ + protected $location = null; + + public function __construct($type, $location){ + $this->type = $type; + $this->location = $location; + } + + /** + * Validates the item + * @param string $element - File path for the xml + * @return boolean + */ + public function validate($element) { + $this->last_error = null; + $celement = realpath($element); + $cvalidator = realpath($this->location.DIRECTORY_SEPARATOR.$this->type); + $result = (empty($celement) || empty($cvalidator)); + if (!$result) { + $xml_error = new libxml_errors_mgr(); + $doc = new DOMDocument(); + $doc->validateOnParse = false; + $result = $doc->load($celement, LIBXML_NONET) && + $doc->schemaValidate($cvalidator); + } + return $result; + } + +} + +class manifest_validator extends cc_validate_type { + public function __construct($location){ + parent::__construct(self::manifest_validator11, $location); + } +} + +class manifest10_validator extends cc_validate_type { + public function __construct($location){ + parent::__construct(self::manifest_validator1, $location); + } +} + +class blti_validator extends cc_validate_type { + public function __construct($location){ + parent::__construct(self::blti_validator11, $location); + } +} + +class assesment_validator extends cc_validate_type { + public function __construct($location){ + parent::__construct(self::assesment_validator11, $location); + } +} + +class discussion_validator extends cc_validate_type { + public function __construct($location){ + parent::__construct(self::discussion_validator11, $location); + } +} + +class weblink_validator extends cc_validate_type { + public function __construct($location){ + parent::__construct(self::weblink_validator11, $location); + } +} + diff --git a/backup/converter/imscc11/backuplib.php b/backup/converter/imscc11/backuplib.php new file mode 100644 index 00000000000..52ca7769374 --- /dev/null +++ b/backup/converter/imscc11/backuplib.php @@ -0,0 +1,165 @@ +. + +/** + * Provides {@link imscc11_export_converter} class + * + * @package core + * @subpackage backup-convert + * @copyright 2011 Darko Miletic + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +require_once($CFG->dirroot . '/backup/converter/convertlib.php'); + +class imscc11_export_converter extends base_converter { + public function get_deps() { + global $CFG; + require_once($CFG->dirroot . '/backup/util/settings/setting_dependency.class.php'); + return array( + 'users' => setting_dependency::DISABLED_VALUE, + 'filters' => setting_dependency::DISABLED_VALUE, + 'blocks' => setting_dependency::DISABLED_VALUE + ); + + } + protected function execute() { + + } + public static function description() { + + return array( + 'from' => backup::FORMAT_MOODLE, + 'to' => backup::FORMAT_IMSCC11, + 'cost' => 10 + ); + } + +} + + +class imscc11_store_backup_file extends backup_execution_step { + + protected function define_execution() { + + // Get basepath + $basepath = $this->get_basepath(); + + // Calculate the zip fullpath (in OS temp area it's always backup.imscc) + $zipfile = $basepath . '/backup.imscc'; + + // Perform storage and return it (TODO: shouldn't be array but proper result object) + // Let's send the file to file storage, everything already defined + // First of all, get some information from the backup_controller to help us decide + list($dinfo, $cinfo, $sinfo) = backup_controller_dbops::get_moodle_backup_information($this->get_backupid()); + + // Extract useful information to decide + $file = $sinfo['filename']->value; + $filename = basename($file,'.'.pathinfo($file, PATHINFO_EXTENSION)).'.imscc'; // Backup filename + $userid = $dinfo[0]->userid; // User->id executing the backup + $id = $dinfo[0]->id; // Id of activity/section/course (depends of type) + $courseid = $dinfo[0]->courseid; // Id of the course + + $ctxid = get_context_instance(CONTEXT_USER, $userid)->id; + $component = 'user'; + $filearea = 'backup'; + $itemid = 0; + $fs = get_file_storage(); + $fr = array( + 'contextid' => $ctxid, + 'component' => $component, + 'filearea' => $filearea, + 'itemid' => $itemid, + 'filepath' => '/', + 'filename' => $filename, + 'userid' => $userid, + 'timecreated' => time(), + 'timemodified'=> time()); + // If file already exists, delete if before + // creating it again. This is BC behaviour - copy() + // overwrites by default + if ($fs->file_exists($fr['contextid'], $fr['component'], $fr['filearea'], $fr['itemid'], $fr['filepath'], $fr['filename'])) { + $pathnamehash = $fs->get_pathname_hash($fr['contextid'], $fr['component'], $fr['filearea'], $fr['itemid'], $fr['filepath'], $fr['filename']); + $sf = $fs->get_file_by_hash($pathnamehash); + $sf->delete(); + } + + return array('backup_destination' => $fs->create_file_from_pathname($fr, $zipfile)); + } +} + +class imscc11_zip_contents extends backup_execution_step { + + protected function define_execution() { + + // Get basepath + $basepath = $this->get_basepath(); + + // Get the list of files in directory + $filestemp = get_directory_list($basepath, '', false, true, true); + $files = array(); + foreach ($filestemp as $file) { + // Add zip paths and fs paths to all them + $files[$file] = $basepath . '/' . $file; + } + + // Calculate the zip fullpath (in OS temp area it's always backup.mbz) + $zipfile = $basepath . '/backup.imscc'; + + // Get the zip packer + $zippacker = get_file_packer('application/zip'); + + // Zip files + $zippacker->archive_to_pathname($files, $zipfile); + } +} + +class imscc11_backup_convert extends backup_execution_step { + + protected function define_execution() { + global $CFG; + // Get basepath + $basepath = $this->get_basepath(); + + require_once($CFG->dirroot . '/backup/cc/cc_includes.php'); + + $tempdir = $CFG->dataroot . '/temp/backup/' . uniqid('', true); + + if (mkdir($tempdir, 0777, true)) { + + cc_convert_moodle2::convert($basepath, $tempdir); + //Switch the directories + if (empty($CFG->keeptempdirectoriesonbackup)) { + fulldelete($basepath); + } else { + if (!rename($basepath, $basepath . '_moodle2_source')) { + throw new backup_task_exception('failed_rename_source_tempdir'); + } + } + + if (!rename($tempdir, $basepath)) { + throw new backup_task_exception('failed_move_converted_into_place'); + } + + } + } +} + + + diff --git a/backup/converter/imscc11/lib.php b/backup/converter/imscc11/lib.php new file mode 100644 index 00000000000..15ddace70fc --- /dev/null +++ b/backup/converter/imscc11/lib.php @@ -0,0 +1,124 @@ + +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ + +require_once($CFG->dirroot . '/backup/converter/convertlib.php'); +require_once($CFG->dirroot . '/backup/cc/includes/constants.php'); +require_once($CFG->dirroot . '/backup/cc/cc112moodle.php'); +require_once($CFG->dirroot . '/backup/cc/validator.php'); + + +class imscc11_converter extends base_converter { + + /** + * Log a message + * + * @see parent::log() + * @param string $message message text + * @param int $level message level {@example backup::LOG_WARNING} + * @param null|mixed $a additional information + * @param null|int $depth the message depth + * @param bool $display whether the message should be sent to the output, too + */ + public function log($message, $level, $a = null, $depth = null, $display = false) { + parent::log('(imscc1) '.$message, $level, $a, $depth, $display); + } + + /** + * Detects the Common Cartridge 1.0 format of the backup directory + * + * @param string $tempdir the name of the backup directory + * @return null|string backup::FORMAT_IMSCC11 if the Common Cartridge 1.1 is detected, null otherwise + */ + public static function detect_format($tempdir) { + global $CFG; + + $filepath = $CFG->dataroot . '/temp/backup/' . $tempdir; + $manifest = cc112moodle::get_manifest($filepath); + if (file_exists($manifest)) { + // looks promising, lets load some information + $handle = fopen($manifest, 'r'); + $xml_snippet = fread($handle, 500); + fclose($handle); + + // check if it has the required strings + + $xml_snippet = strtolower($xml_snippet); + $xml_snippet = preg_replace('/\s*/m', '', $xml_snippet); + $xml_snippet = str_replace("'", '', $xml_snippet); + $xml_snippet = str_replace('"', '', $xml_snippet); + + $search_string = "xmlns=http://www.imsglobal.org/xsd/imsccv1p1/imscp_v1p1"; + if (strpos($xml_snippet, $search_string) !== false) { + return backup::FORMAT_IMSCC11; + } + } + + return null; + } + + + /** + * Returns the basic information about the converter + * + * The returned array must contain the following keys: + * 'from' - the supported source format, eg. backup::FORMAT_MOODLE1 + * 'to' - the supported target format, eg. backup::FORMAT_MOODLE + * 'cost' - the cost of the conversion, non-negative non-zero integer + */ + public static function description() { + + return array( + 'from' => backup::FORMAT_IMSCC11, + 'to' => backup::FORMAT_MOODLE1, + 'cost' => 10 + ); + } + + protected function execute() { + global $CFG; + + $manifest = cc112moodle::get_manifest($this->get_tempdir_path()); + if (empty($manifest)) { + throw new imscc11_convert_exception('No Manifest detected!'); + } + + $this->log('validating manifest', backup::LOG_DEBUG, null, 1); + $validator = new manifest_validator($CFG->dirroot . '/backup/cc/schemas11'); + if (!$validator->validate($manifest)) { + $this->log('validation error(s): '.PHP_EOL.error_messages::instance(), backup::LOG_DEBUG, null, 2); + throw new imscc11_convert_exception(error_messages::instance()->to_string(true)); + } + $manifestdir = dirname($manifest); + $cc112moodle = new cc112moodle($manifest); + if ($cc112moodle->is_auth()) { + throw new imscc11_convert_exception('Protected cartridge content - Skipping import!'); + } + $status = $cc112moodle->generate_moodle_xml(); + //Final cleanup + $mdoc = new DOMDocument(); + $mdoc->preserveWhiteSpace = false; + $mdoc->formatOutput = true; + $mdoc->validateOnParse = false; + if ($mdoc->load($manifestdir.'/moodle.xml', LIBXML_NONET)) { + $mdoc->save($this->get_workdir_path().'/moodle.xml', LIBXML_NOEMPTYTAG); + } + //Move the files to the workdir + rename($manifestdir.'/course_files', $this->get_workdir_path().'/course_files'); + } + + +} + +/** +* Exception thrown by this converter +*/ +class imscc11_convert_exception extends convert_exception { +} diff --git a/backup/converter/moodle1/backuplib.php b/backup/converter/moodle1/backuplib.php new file mode 100644 index 00000000000..c9356c18229 --- /dev/null +++ b/backup/converter/moodle1/backuplib.php @@ -0,0 +1,13 @@ +dirroot . '/backup/converter/convertlib.php'); + +class moodle1_export_converter extends base_converter { + public static function is_available() { + return false; + } + + protected function execute() { + + } +} \ No newline at end of file diff --git a/backup/moodle2/backup_final_task.class.php b/backup/moodle2/backup_final_task.class.php index d39a20e610a..78bab3ce630 100644 --- a/backup/moodle2/backup_final_task.class.php +++ b/backup/moodle2/backup_final_task.class.php @@ -35,6 +35,7 @@ class backup_final_task extends backup_task { * Create all the steps that will be part of this task */ public function build() { + global $CFG; // Set the backup::VAR_CONTEXTID setting to course context as far as next steps require that $coursectxid = get_context_instance(CONTEXT_COURSE, $this->get_courseid())->id; @@ -105,8 +106,31 @@ class backup_final_task extends backup_task { // to the backup, settings, license, versions and other useful information $this->add_step(new backup_main_structure_step('mainfile', 'moodle_backup.xml')); + require_once($CFG->dirroot . '/backup/util/helper/convert_helper.class.php'); + + //Checking if we have some converter involved in the process + $converters = convert_helper::available_converters(false); + //Conversion status + $conversion = false; + foreach ($converters as $value) { + if ($this->get_setting_value($value)) { + //zip class + $zip_contents = "{$value}_zip_contents"; + $store_backup_file = "{$value}_store_backup_file"; + $convert = "{$value}_backup_convert"; + + $this->add_step(new $convert("package_convert_{$value}")); + $this->add_step(new $zip_contents("zip_contents_{$value}")); + $this->add_step(new $store_backup_file("save_backupfile_{$value}")); + if (!$conversion) { + $conversion = true; + } + } + } + + // On backup::MODE_IMPORT, we don't have to zip nor store the the file, skip these steps - if ($this->plan->get_mode() != backup::MODE_IMPORT) { + if (($this->plan->get_mode() != backup::MODE_IMPORT) && !$conversion) { // Generate the zip file (mbz extension) $this->add_step(new backup_zip_contents('zip_contents')); diff --git a/backup/moodle2/backup_root_task.class.php b/backup/moodle2/backup_root_task.class.php index 73519e09622..af710e1dd22 100644 --- a/backup/moodle2/backup_root_task.class.php +++ b/backup/moodle2/backup_root_task.class.php @@ -42,20 +42,42 @@ class backup_root_task extends backup_task { // Protected API starts here + protected function converter_deps($main_setting, $converters) { + foreach ($this->settings as $setting) { + $name = $setting->get_name(); + if (in_array($name, $converters)) { + $setvalue = convert_helper::export_converter_dependencies($name, $main_setting->get_name()); + if ($setvalue !== false) { + $setting->add_dependency($main_setting, $setvalue, array('value' => $name)); + } + } + } + } + /** * Define the common setting that any backup type will have */ protected function define_settings() { - + global $CFG; + require_once($CFG->dirroot . '/backup/util/helper/convert_helper.class.php'); // Define filename setting $filename = new backup_filename_setting('filename', base_setting::IS_FILENAME, 'backup.mbz'); $filename->set_ui(get_string('filename', 'backup'), 'backup.mbz', array('size'=>50)); $this->add_setting($filename); + //Sample custom settings + $converters = convert_helper::available_converters(false); + foreach ($converters as $cnv) { + $formatcnv = new backup_users_setting($cnv, base_setting::IS_BOOLEAN, false); + $formatcnv->set_ui(new backup_setting_ui_checkbox($formatcnv, get_string('backupformat'.$cnv, 'backup'))); + $this->add_setting($formatcnv); + } + // Define users setting (keeping it on hand to define dependencies) $users = new backup_users_setting('users', base_setting::IS_BOOLEAN, true); $users->set_ui(new backup_setting_ui_checkbox($users, get_string('rootsettingusers', 'backup'))); $this->add_setting($users); + $this->converter_deps($users, $converters); // Define anonymize (dependent of users) $anonymize = new backup_anonymize_setting('anonymize', base_setting::IS_BOOLEAN, false); @@ -85,11 +107,13 @@ class backup_root_task extends backup_task { $blocks = new backup_generic_setting('blocks', base_setting::IS_BOOLEAN, true); $blocks->set_ui(new backup_setting_ui_checkbox($blocks, get_string('rootsettingblocks', 'backup'))); $this->add_setting($blocks); + $this->converter_deps($blocks, $converters); // Define filters $filters = new backup_generic_setting('filters', base_setting::IS_BOOLEAN, true); $filters->set_ui(new backup_setting_ui_checkbox($filters, get_string('rootsettingfilters', 'backup'))); $this->add_setting($filters); + $this->converter_deps($filters, $converters); // Define comments (dependent of users) $comments = new backup_comments_setting('comments', base_setting::IS_BOOLEAN, true); diff --git a/backup/moodle2/backup_root_task.class.php.orig b/backup/moodle2/backup_root_task.class.php.orig new file mode 100644 index 00000000000..73519e09622 --- /dev/null +++ b/backup/moodle2/backup_root_task.class.php.orig @@ -0,0 +1,118 @@ +. + +/** + * @package moodlecore + * @subpackage backup-moodle2 + * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * Start task that provides all the settings common to all backups and some initialization steps + * + * TODO: Finish phpdocs + */ +class backup_root_task extends backup_task { + + /** + * Create all the steps that will be part of this task + */ + public function build() { + + // Add all the steps needed to prepare any moodle2 backup to work + $this->add_step(new create_and_clean_temp_stuff('create_and_clean_temp_stuff')); + + $this->built = true; + } + +// Protected API starts here + + /** + * Define the common setting that any backup type will have + */ + protected function define_settings() { + + // Define filename setting + $filename = new backup_filename_setting('filename', base_setting::IS_FILENAME, 'backup.mbz'); + $filename->set_ui(get_string('filename', 'backup'), 'backup.mbz', array('size'=>50)); + $this->add_setting($filename); + + // Define users setting (keeping it on hand to define dependencies) + $users = new backup_users_setting('users', base_setting::IS_BOOLEAN, true); + $users->set_ui(new backup_setting_ui_checkbox($users, get_string('rootsettingusers', 'backup'))); + $this->add_setting($users); + + // Define anonymize (dependent of users) + $anonymize = new backup_anonymize_setting('anonymize', base_setting::IS_BOOLEAN, false); + $anonymize->set_ui(new backup_setting_ui_checkbox($anonymize, get_string('rootsettinganonymize', 'backup'))); + $this->add_setting($anonymize); + $users->add_dependency($anonymize); + + // Define role_assignments (dependent of users) + $roleassignments = new backup_role_assignments_setting('role_assignments', base_setting::IS_BOOLEAN, true); + $roleassignments->set_ui(new backup_setting_ui_checkbox($roleassignments, get_string('rootsettingroleassignments', 'backup'))); + $this->add_setting($roleassignments); + $users->add_dependency($roleassignments); + + // Define user_files (dependent of users and anonymize) + $userfiles = new backup_user_files_setting('user_files', base_setting::IS_BOOLEAN, true); + $userfiles->set_ui(new backup_setting_ui_checkbox($userfiles, get_string('rootsettinguserfiles', 'backup'))); + $this->add_setting($userfiles); + $users->add_dependency($userfiles); + $anonymize->add_dependency($userfiles, setting_dependency::DISABLED_TRUE); + + // Define activities + $activities = new backup_activities_setting('activities', base_setting::IS_BOOLEAN, true); + $activities->set_ui(new backup_setting_ui_checkbox($activities, get_string('rootsettingactivities', 'backup'))); + $this->add_setting($activities); + + // Define blocks + $blocks = new backup_generic_setting('blocks', base_setting::IS_BOOLEAN, true); + $blocks->set_ui(new backup_setting_ui_checkbox($blocks, get_string('rootsettingblocks', 'backup'))); + $this->add_setting($blocks); + + // Define filters + $filters = new backup_generic_setting('filters', base_setting::IS_BOOLEAN, true); + $filters->set_ui(new backup_setting_ui_checkbox($filters, get_string('rootsettingfilters', 'backup'))); + $this->add_setting($filters); + + // Define comments (dependent of users) + $comments = new backup_comments_setting('comments', base_setting::IS_BOOLEAN, true); + $comments->set_ui(new backup_setting_ui_checkbox($comments, get_string('rootsettingcomments', 'backup'))); + $this->add_setting($comments); + $users->add_dependency($comments); + + // Define completion (dependent of users) + $completion = new backup_userscompletion_setting('userscompletion', base_setting::IS_BOOLEAN, true); + $completion->set_ui(new backup_setting_ui_checkbox($completion, get_string('rootsettinguserscompletion', 'backup'))); + $this->add_setting($completion); + $users->add_dependency($completion); + + // Define logs (dependent of users) + $logs = new backup_logs_setting('logs', base_setting::IS_BOOLEAN, true); + $logs->set_ui(new backup_setting_ui_checkbox($logs, get_string('rootsettinglogs', 'backup'))); + $this->add_setting($logs); + $users->add_dependency($logs); + + // Define grade_histories (dependent of users) + $gradehistories = new backup_generic_setting('grade_histories', base_setting::IS_BOOLEAN, true); + $gradehistories->set_ui(new backup_setting_ui_checkbox($gradehistories, get_string('rootsettinggradehistories', 'backup'))); + $this->add_setting($gradehistories); + $users->add_dependency($gradehistories); + } +} diff --git a/backup/util/helper/backup_general_helper.class.php b/backup/util/helper/backup_general_helper.class.php index 73b5d3b4014..b5863138e1d 100644 --- a/backup/util/helper/backup_general_helper.class.php +++ b/backup/util/helper/backup_general_helper.class.php @@ -79,6 +79,10 @@ abstract class backup_general_helper extends backup_helper { return array(); } + if (!is_dir($path)) { + return array(); + } + $dir = opendir($path); while (false !== ($file = readdir($dir))) { if ($file == '.' || $file == '..') { // Skip dots diff --git a/backup/util/helper/convert_helper.class.php b/backup/util/helper/convert_helper.class.php index 1be31ae11ca..6f9d1bd4e45 100644 --- a/backup/util/helper/convert_helper.class.php +++ b/backup/util/helper/convert_helper.class.php @@ -50,18 +50,24 @@ abstract class convert_helper { * @see base_converter::is_available() * @return array of strings */ - public static function available_converters() { + public static function available_converters($restore=true) { global $CFG; $converters = array(); $plugins = get_list_of_plugins('backup/converter'); foreach ($plugins as $name) { - $classfile = "$CFG->dirroot/backup/converter/$name/lib.php"; - $classname = "{$name}_converter"; + $filename = $restore ? 'lib.php' : 'backuplib.php'; + $classuf = $restore ? '_converter' : '_export_converter'; + $classfile = "{$CFG->dirroot}/backup/converter/{$name}/{$filename}"; + $classname = "{$name}{$classuf}"; + $zip_contents = "{$name}_zip_contents"; + $store_backup_file = "{$name}_store_backup_file"; + $convert = "{$name}_backup_convert"; if (!file_exists($classfile)) { throw new convert_helper_exception('converter_classfile_not_found', $classfile); } + require_once($classfile); if (!class_exists($classname)) { @@ -69,13 +75,54 @@ abstract class convert_helper { } if (call_user_func($classname .'::is_available')) { + if (!$restore) { + if (!class_exists($zip_contents)) { + throw new convert_helper_exception('converter_classname_not_found', $zip_contents); + } + if (!class_exists($store_backup_file)) { + throw new convert_helper_exception('converter_classname_not_found', $store_backup_file); + } + if (!class_exists($convert)) { + throw new convert_helper_exception('converter_classname_not_found', $convert); + } + } + $converters[] = $name; } + } return $converters; } + public static function export_converter_dependencies($converter, $dependency) { + global $CFG; + + $result = array(); + $filename = 'backuplib.php'; + $classuf = '_export_converter'; + $classfile = "{$CFG->dirroot}/backup/converter/{$converter}/{$filename}"; + $classname = "{$converter}{$classuf}"; + + if (!file_exists($classfile)) { + throw new convert_helper_exception('converter_classfile_not_found', $classfile); + } + require_once($classfile); + + if (!class_exists($classname)) { + throw new convert_helper_exception('converter_classname_not_found', $classname); + } + + if (call_user_func($classname .'::is_available')) { + $deps = call_user_func($classname .'::get_deps'); + if (array_key_exists($dependency, $deps)) { + $result = $deps[$dependency]; + } + } + + return $result; + } + /** * Detects if the given folder contains an unpacked moodle2 backup * diff --git a/backup/util/settings/base_setting.class.php b/backup/util/settings/base_setting.class.php index 82e6eb1b1d9..1e11141fe21 100644 --- a/backup/util/settings/base_setting.class.php +++ b/backup/util/settings/base_setting.class.php @@ -372,6 +372,18 @@ abstract class base_setting { } $dependency = new setting_dependency_disabledif_equals($this, $dependentsetting, $options['value'], $options['defaultvalue']); break; + case setting_dependency::DISABLED_NOT_VALUE : + if (!array_key_exists('value', $options)) { + throw new base_setting_exception('dependency_needs_value'); + } + $dependency = new setting_dependency_disabledif_not_equals($this, $dependentsetting, $options['value'], $options['defaultvalue']); + break; + case setting_dependency::DISABLED_VALUES : + if (!array_key_exists('value', $options)) { + throw new base_setting_exception('dependency_needs_value'); + } + $dependency = new setting_dependency_disabledif_equals2($this, $dependentsetting, $options['value'], $options['defaultvalue']); + break; case setting_dependency::DISABLED_TRUE : $dependency = new setting_dependency_disabledif_equals($this, $dependentsetting, true, $options['defaultvalue']); break; diff --git a/backup/util/settings/setting_dependency.class.php b/backup/util/settings/setting_dependency.class.php index 37099a80d4b..a1ed31e6200 100644 --- a/backup/util/settings/setting_dependency.class.php +++ b/backup/util/settings/setting_dependency.class.php @@ -44,6 +44,8 @@ abstract class setting_dependency { const DISABLED_NOT_CHECKED = 5; const DISABLED_EMPTY = 6; const DISABLED_NOT_EMPTY = 7; + const DISABLED_VALUES = 8; + const DISABLED_NOT_VALUES = 9; /** * The parent setting (primary) @@ -273,6 +275,161 @@ class setting_dependency_disabledif_equals extends setting_dependency { ); } } + +/** +* A dependency that disables the secondary setting if the primary setting is +* not equal to the provided value +* +* @copyright 2011 Darko Miletic +* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later +*/ +class setting_dependency_disabledif_not_equals extends setting_dependency_disabledif_equals { + /** + * Enforces the dependency if required. + * @return bool True if there were changes + */ + public function enforce() { + // This will be set to true if ANYTHING changes + $changes = false; + // First process any value changes + if (!$this->process_value_change($this->setting->get_value())) { + $changes = true; + } + // Second process any status changes + if ($this->process_status_change($this->setting->get_status())) { + $changes = true; + } + // Finally process visibility changes + if ($this->process_visibility_change($this->setting->get_visibility())) { + $changes = true; + } + return $changes; + } + /** + * Returns an array of properties suitable to be used to define a moodleforms + * disabled command + * @return array + */ + public function get_moodleform_properties() { + return array( + 'setting'=>$this->dependentsetting->get_ui_name(), + 'dependenton'=>$this->setting->get_ui_name(), + 'condition'=>'notequal', + 'value'=>$this->value + ); + } +} + +//with array +class setting_dependency_disabledif_equals2 extends setting_dependency { + /** + * The value to compare to + * @var mixed + */ + protected $value; + /** + * Creates the dependency + * + * @param base_setting $setting + * @param base_setting $dependentsetting + * @param mixed $value + * @param mixed $defaultvalue + */ + public function __construct(base_setting $setting, base_setting $dependentsetting, array $value, $defaultvalue = false) { + parent::__construct($setting, $dependentsetting, $defaultvalue); + $this->value = $value; + } + /** + * Returns true if the dependent setting is locked. + * @return bool + */ + public function is_locked() { + // If the setting is locked or the dependent setting should be locked then return true + if ($this->setting->get_status() !== base_setting::NOT_LOCKED || in_array($this->setting->get_value(), $this->value)) { + return true; + } + // Else return based upon the dependent settings status + return ($this->dependentsetting->get_status() !== base_setting::NOT_LOCKED); + } + /** + * Processes a value change in the primary setting + * @param mixed $oldvalue + * @return bool + */ + protected function process_value_change($oldvalue) { + $prevalue = $this->dependentsetting->get_value(); + // If the setting is the desired value enact the dependency + if (in_array($this->setting->get_value(), $this->value)) { + // The dependent setting needs to be locked by hierachy and set to the + // default value. + $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY); + $this->dependentsetting->set_value($this->defaultvalue); + } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) { + // We can unlock the dependent setting + $this->dependentsetting->set_status(base_setting::NOT_LOCKED); + } + // Return true if the value has changed for the dependent setting + return ($prevalue != $this->dependentsetting->get_value()); + } + /** + * Processes a status change in the primary setting + * @param mixed $oldstatus + * @return bool + */ + protected function process_status_change($oldstatus) { + // Store the dependent status + $prevalue = $this->dependentsetting->get_status(); + // Store the current status + $currentstatus = $this->setting->get_status(); + if ($currentstatus == base_setting::NOT_LOCKED) { + if ($prevalue == base_setting::LOCKED_BY_HIERARCHY && !in_array($this->setting->get_value(), $this->value)) { + // Dependency has changes, is not fine, unlock the dependent setting + $this->dependentsetting->set_status(base_setting::NOT_LOCKED); + } + } else { + // Make sure the dependent setting is also locked, in this case by hierarchy + $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY); + } + // Return true if the dependent setting has changed. + return ($prevalue != $this->dependentsetting->get_status()); + } + /** + * Enforces the dependency if required. + * @return bool True if there were changes + */ + public function enforce() { + // This will be set to true if ANYTHING changes + $changes = false; + // First process any value changes + if ($this->process_value_change($this->setting->get_value())) { + $changes = true; + } + // Second process any status changes + if ($this->process_status_change($this->setting->get_status())) { + $changes = true; + } + // Finally process visibility changes + if ($this->process_visibility_change($this->setting->get_visibility())) { + $changes = true; + } + return $changes; + } + /** + * Returns an array of properties suitable to be used to define a moodleforms + * disabled command + * @return array + */ + public function get_moodleform_properties() { + return array( + 'setting'=>$this->dependentsetting->get_ui_name(), + 'dependenton'=>$this->setting->get_ui_name(), + 'condition'=>'eq', + 'value'=>$this->value + ); + } +} + + /** * A dependency that disables the secondary element if the primary element is * true or checked diff --git a/lang/en/backup.php b/lang/en/backup.php index 25c5718f1e7..a7987daa940 100644 --- a/lang/en/backup.php +++ b/lang/en/backup.php @@ -46,7 +46,8 @@ $string['backupdetailsnonstandardinfo'] = 'The selected file is not a standard M $string['backupformat'] = 'Format'; $string['backupformatmoodle1'] = 'Moodle 1'; $string['backupformatmoodle2'] = 'Moodle 2'; -$string['backupformatimscc'] = 'IMS Common Cartridge'; +$string['backupformatimscc1'] = 'IMS Common Cartridge 1.0'; +$string['backupformatimscc11'] = 'IMS Common Cartridge 1.1'; $string['backupformatunknown'] = 'Unknown format'; $string['backupmode'] = 'Mode'; $string['backupmode10'] = 'General';