You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
829 lines
29 KiB
829 lines
29 KiB
2 years ago
|
<?php
|
||
|
// This file is part of Moodle - http://moodle.org/
|
||
|
//
|
||
|
// Moodle is free software: you can redistribute it and/or modify
|
||
|
// it under the terms of the GNU General Public License as published by
|
||
|
// the Free Software Foundation, either version 3 of the License, or
|
||
|
// (at your option) any later version.
|
||
|
//
|
||
|
// Moodle is distributed in the hope that it will be useful,
|
||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
// GNU General Public License for more details.
|
||
|
//
|
||
|
// You should have received a copy of the GNU General Public License
|
||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||
|
/**
|
||
|
* @package moodlecore
|
||
|
* @subpackage backup-imscc
|
||
|
* @copyright 2009 Mauro Rondinelli (mauro.rondinelli [AT] uvcms.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');
|
||
|
require_once($CFG->dirroot . '/backup/cc/entity.label.class.php');
|
||
|
require_once($CFG->dirroot . '/backup/cc/entity.resource.class.php');
|
||
|
require_once($CFG->dirroot . '/backup/cc/entity.forum.class.php');
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
// Before iterate over directories, try to find one manifest at top level
|
||
|
if (file_exists($folder . '/imsmanifest.xml')) {
|
||
|
return $folder . '/imsmanifest.xml';
|
||
|
}
|
||
|
|
||
|
$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',
|
||
|
'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');
|
||
|
|
||
|
function __construct ($path_to_manifest) {
|
||
|
|
||
|
static::$manifest = new DOMDocument();
|
||
|
static::$manifest->validateOnParse = false;
|
||
|
|
||
|
static::$path_to_manifest_folder = dirname($path_to_manifest);
|
||
|
|
||
|
static::log_action('Proccess start');
|
||
|
static::log_action('Load the manifest file: ' . $path_to_manifest);
|
||
|
|
||
|
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 = static::newx_path(static::$manifest, static::$namespaces);
|
||
|
|
||
|
$count_auth = $xpath->evaluate('count(/imscc:manifest/cc:authorizations)');
|
||
|
|
||
|
if ($count_auth > 0) {
|
||
|
$response = true;
|
||
|
} else {
|
||
|
$response = false;
|
||
|
}
|
||
|
|
||
|
return $response;
|
||
|
}
|
||
|
|
||
|
protected function get_metadata ($section, $key) {
|
||
|
|
||
|
$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 : '';
|
||
|
|
||
|
return $value;
|
||
|
}
|
||
|
|
||
|
public function generate_moodle_xml () {
|
||
|
|
||
|
global $CFG, $OUTPUT;
|
||
|
|
||
|
$cdir = static::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'course_files';
|
||
|
|
||
|
if (!file_exists($cdir)) {
|
||
|
mkdir($cdir, $CFG->directorypermissions, true);
|
||
|
}
|
||
|
|
||
|
$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 entities();
|
||
|
|
||
|
$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;
|
||
|
echo $OUTPUT->notification('The course is empty');
|
||
|
static::log_action('The course is empty', false);
|
||
|
}
|
||
|
|
||
|
return $status;
|
||
|
|
||
|
}
|
||
|
|
||
|
protected function get_sections_numbers ($instances) {
|
||
|
|
||
|
$count = 0;
|
||
|
|
||
|
if (array_key_exists("index", $instances)) {
|
||
|
foreach ($instances["index"] as $instance) {
|
||
|
if ($instance["deep"] == ROOT_DEEP) {
|
||
|
$count++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $count;
|
||
|
}
|
||
|
|
||
|
protected function create_node_course_header () {
|
||
|
|
||
|
$node_course_header = '';
|
||
|
$sheet_course_header = static::loadsheet(SHEET_COURSE_HEADER);
|
||
|
|
||
|
$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;
|
||
|
}
|
||
|
|
||
|
if (empty($course_title)) {
|
||
|
$this->log_action('The course title not found', true);
|
||
|
}
|
||
|
|
||
|
$course_short_name = $this->create_course_code($course_title);
|
||
|
|
||
|
$find_tags = array('[#course_name#]',
|
||
|
'[#course_short_name#]',
|
||
|
'[#course_description#]',
|
||
|
'[#date_now#]',
|
||
|
'[#section_count#]');
|
||
|
|
||
|
$replace_values = array(entities::safexml($course_title),
|
||
|
entities::safexml($course_short_name),
|
||
|
entities::safexml($course_description),
|
||
|
time(),
|
||
|
$section_count);
|
||
|
|
||
|
$node_course_header = str_replace($find_tags, $replace_values, $sheet_course_header);
|
||
|
|
||
|
return $node_course_header;
|
||
|
}
|
||
|
|
||
|
protected function create_node_question_categories () {
|
||
|
|
||
|
$quiz = new cc_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_node_course_modules_mod () {
|
||
|
|
||
|
$labels = new cc_label();
|
||
|
$resources = new cc_resource();
|
||
|
$forums = new cc_forum();
|
||
|
$quiz = new cc_quiz();
|
||
|
|
||
|
static::log_action('Creating node: COURSE/MODULES/MOD');
|
||
|
|
||
|
// LABELS
|
||
|
$node_course_modules_mod_label = $labels->generate_node();
|
||
|
|
||
|
// 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();
|
||
|
//TODO: label
|
||
|
$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;
|
||
|
}
|
||
|
|
||
|
|
||
|
protected function create_node_course_sections_section () {
|
||
|
|
||
|
static::log_action('Creating node: COURSE/SECTIONS/SECTION');
|
||
|
|
||
|
$node_course_sections_section = '';
|
||
|
$sheet_course_sections_section = static::loadsheet(SHEET_COURSE_SECTIONS_SECTION);
|
||
|
|
||
|
$topics = $this->get_nodes_by_criteria('deep', ROOT_DEEP);
|
||
|
|
||
|
$i = 0;
|
||
|
|
||
|
if (!empty($topics)) {
|
||
|
|
||
|
foreach ($topics as $topic) {
|
||
|
|
||
|
$i++;
|
||
|
$node_node_course_sections_section_mods_mod = $this->create_node_course_sections_section_mods_mod($topic['index']);
|
||
|
|
||
|
if ($topic['moodle_type'] == MOODLE_TYPE_LABEL) {
|
||
|
|
||
|
$find_tags = array('[#section_id#]',
|
||
|
'[#section_number#]',
|
||
|
'[#section_summary#]',
|
||
|
'[#node_course_sections_section_mods_mod#]');
|
||
|
|
||
|
$replace_values = array($i,
|
||
|
$i - 1,
|
||
|
entities::safexml($topic['title']),
|
||
|
$node_node_course_sections_section_mods_mod);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
$find_tags = array('[#section_id#]',
|
||
|
'[#section_number#]',
|
||
|
'[#section_summary#]',
|
||
|
'[#node_course_sections_section_mods_mod#]');
|
||
|
|
||
|
$replace_values = array($i,
|
||
|
$i - 1,
|
||
|
'',
|
||
|
$node_node_course_sections_section_mods_mod);
|
||
|
|
||
|
}
|
||
|
|
||
|
$node_course_sections_section .= str_replace($find_tags, $replace_values, $sheet_course_sections_section);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
return $node_course_sections_section;
|
||
|
}
|
||
|
|
||
|
protected function create_node_course_blocks_block () {
|
||
|
|
||
|
global $CFG;
|
||
|
|
||
|
static::log_action('Creating node: 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';
|
||
|
|
||
|
if (@is_file($format_config) && is_readable($format_config)) {
|
||
|
require ($format_config);
|
||
|
}
|
||
|
|
||
|
if (!empty($format['defaultblocks'])) {
|
||
|
$blocknames = $format['defaultblocks'];
|
||
|
} else {
|
||
|
if (isset($CFG->defaultblocks)) {
|
||
|
$blocknames = $CFG->defaultblocks;
|
||
|
} else {
|
||
|
$blocknames = 'participants,activity_modules,search_forums,course_list:news_items,calendar_upcoming,recent_activity';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$blocknames = explode(':', $blocknames);
|
||
|
$blocks_left = explode(',', $blocknames[0]);
|
||
|
$blocks_right = explode(',', $blocknames[1]);
|
||
|
|
||
|
$find_tags = array('[#block_id#]',
|
||
|
'[#block_name#]',
|
||
|
'[#block_position#]',
|
||
|
'[#block_weight#]');
|
||
|
|
||
|
$i = 0;
|
||
|
$weight = 0;
|
||
|
|
||
|
foreach ($blocks_left as $block) {
|
||
|
$i++;
|
||
|
$weight++;
|
||
|
|
||
|
$replace_values = array($i,
|
||
|
$block,
|
||
|
'l',
|
||
|
$weight);
|
||
|
|
||
|
$node_course_blocks_block .= str_replace($find_tags, $replace_values, $sheet_course_blocks_block);
|
||
|
}
|
||
|
|
||
|
$weight = 0;
|
||
|
|
||
|
foreach ($blocks_right as $block) {
|
||
|
|
||
|
$i++;
|
||
|
$weight ++;
|
||
|
|
||
|
$replace_values = array($i,
|
||
|
$block,
|
||
|
'r',
|
||
|
$weight);
|
||
|
|
||
|
$node_course_blocks_block .= str_replace($find_tags, $replace_values, $sheet_course_blocks_block);
|
||
|
}
|
||
|
|
||
|
return $node_course_blocks_block;
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
* Is activity visible or not
|
||
|
* @param string $identifier
|
||
|
* @return number
|
||
|
*/
|
||
|
protected function get_module_visible($identifier) {
|
||
|
//Should item be hidden or not
|
||
|
$mod_visible = 1;
|
||
|
if (!empty($identifier)) {
|
||
|
$xpath = static::newx_path(static::$manifest, static::$namespaces);
|
||
|
$query = '/imscc:manifest/imscc:resources/imscc:resource[@identifier="' . $identifier . '"]';
|
||
|
$query .= '//lom:intendedEndUserRole/voc:vocabulary/lom:value';
|
||
|
$intendeduserrole = $xpath->query($query);
|
||
|
if (!empty($intendeduserrole) && ($intendeduserrole->length > 0)) {
|
||
|
$role = trim($intendeduserrole->item(0)->nodeValue);
|
||
|
if (strcasecmp('Instructor', $role) == 0) {
|
||
|
$mod_visible = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return $mod_visible;
|
||
|
}
|
||
|
|
||
|
protected function create_node_course_sections_section_mods_mod ($root_parent) {
|
||
|
|
||
|
$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) {
|
||
|
|
||
|
$node_course_sections_section_mods_mod = '';
|
||
|
|
||
|
foreach ($childs as $child) {
|
||
|
|
||
|
if ($child['moodle_type'] == MOODLE_TYPE_LABEL) {
|
||
|
if ($child['index'] == $child['root_parent']) {
|
||
|
$is_summary = true;
|
||
|
} else {
|
||
|
$is_summary = false;
|
||
|
}
|
||
|
} else {
|
||
|
$is_summary = false;
|
||
|
}
|
||
|
|
||
|
if (!$is_summary) {
|
||
|
|
||
|
$indent = $child['deep'] - ROOT_DEEP;
|
||
|
|
||
|
if ($indent > 0) {
|
||
|
$indent = $indent - 1;
|
||
|
}
|
||
|
|
||
|
$find_tags = array('[#mod_id#]',
|
||
|
'[#mod_instance_id#]',
|
||
|
'[#mod_type#]',
|
||
|
'[#date_now#]',
|
||
|
'[#mod_indent#]',
|
||
|
'[#mod_visible#]');
|
||
|
|
||
|
$replace_values = array($child['index'],
|
||
|
$child['instance'],
|
||
|
$child['moodle_type'],
|
||
|
time(),
|
||
|
$indent,
|
||
|
$this->get_module_visible($child['resource_indentifier']));
|
||
|
|
||
|
$node_course_sections_section_mods_mod .= str_replace($find_tags, $replace_values, $sheet_course_sections_section_mods_mod);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$response = $node_course_sections_section_mods_mod;
|
||
|
|
||
|
} else {
|
||
|
$response = '';
|
||
|
}
|
||
|
|
||
|
return $response;
|
||
|
|
||
|
}
|
||
|
|
||
|
public function get_nodes_by_criteria ($key, $value) {
|
||
|
|
||
|
$response = array();
|
||
|
|
||
|
if (array_key_exists('index', static::$instances)) {
|
||
|
foreach (static::$instances['index'] as $item) {
|
||
|
if ($item[$key] == $value) {
|
||
|
$response[] = $item;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $response;
|
||
|
}
|
||
|
|
||
|
//Modified here
|
||
|
protected function create_code_info_details_mod () {
|
||
|
|
||
|
static::log_action('Creating node: INFO/DETAILS/MOD');
|
||
|
|
||
|
$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="' . static::CC_TYPE_QUESTION_BANK . '"]');
|
||
|
|
||
|
$this->create_instances($items);
|
||
|
|
||
|
$count_quiz = $this->count_instances(MOODLE_TYPE_QUIZ);
|
||
|
$count_forum = $this->count_instances(MOODLE_TYPE_FORUM);
|
||
|
$count_resource = $this->count_instances(MOODLE_TYPE_RESOURCE);
|
||
|
$count_label = $this->count_instances(MOODLE_TYPE_LABEL);
|
||
|
|
||
|
$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, 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, 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, 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, static::$instances['instances'][MOODLE_TYPE_LABEL]);
|
||
|
}
|
||
|
|
||
|
$resource_mod = $count_resource ? $this->create_mod_info_details_mod(MOODLE_TYPE_RESOURCE, $resource_instance) : '';
|
||
|
$quiz_mod = $count_quiz ? $this->create_mod_info_details_mod(MOODLE_TYPE_QUIZ, $quiz_instance) : '';
|
||
|
$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) : '';
|
||
|
|
||
|
//TODO: label
|
||
|
return $label_mod . $resource_mod . $quiz_mod . $forum_mod;
|
||
|
|
||
|
}
|
||
|
|
||
|
protected function create_mod_info_details_mod ($mod_type, $node_info_details_mod_instances_instance) {
|
||
|
|
||
|
$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);
|
||
|
|
||
|
return str_replace($find_tags, $replace_values, $sheet_info_details_mod);
|
||
|
}
|
||
|
|
||
|
protected function create_mod_info_details_mod_instances_instance ($sheet, $instances_quantity, $instances) {
|
||
|
|
||
|
$instance = '';
|
||
|
|
||
|
$find_tags = array('[#mod_instance_id#]',
|
||
|
'[#mod_name#]',
|
||
|
'[#mod_user_info#]');
|
||
|
|
||
|
for ($i = 1; $i <= $instances_quantity; $i++) {
|
||
|
|
||
|
$user_info = ($instances[$i - 1]['common_cartriedge_type'] == static::CC_TYPE_FORUM) ? 'true' : 'false';
|
||
|
if ($instances[$i - 1]['common_cartriedge_type'] == static::CC_TYPE_EMPTY) {
|
||
|
if ($instances[$i - 1]['deep'] <= ROOT_DEEP ) {
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$replace_values = array($instances[$i - 1]['instance'],
|
||
|
entities::safexml($instances[$i - 1]['title']),
|
||
|
$user_info);
|
||
|
|
||
|
$instance .= str_replace($find_tags, $replace_values, $sheet);
|
||
|
}
|
||
|
|
||
|
return $instance;
|
||
|
|
||
|
}
|
||
|
|
||
|
protected function create_instances ($items, $level = 0, &$array_index = 0, $index_root = 0) {
|
||
|
|
||
|
$level++;
|
||
|
$i = 1;
|
||
|
|
||
|
if ($items) {
|
||
|
|
||
|
$xpath = self::newx_path(static::$manifest, static::$namespaces);
|
||
|
|
||
|
foreach ($items as $item) {
|
||
|
|
||
|
$array_index++;
|
||
|
|
||
|
if ($item->nodeName == "item") {
|
||
|
$identifierref = '';
|
||
|
if ($item->hasAttribute('identifierref')) {
|
||
|
$identifierref = $item->getAttribute('identifierref');
|
||
|
}
|
||
|
|
||
|
$title = '';
|
||
|
$titles = $xpath->query('imscc:title', $item);
|
||
|
if ($titles->length > 0) {
|
||
|
$title = $titles->item(0)->nodeValue;
|
||
|
}
|
||
|
|
||
|
$cc_type = $this->get_item_cc_type($identifierref);
|
||
|
$moodle_type = $this->convert_to_moodle_type($cc_type);
|
||
|
//Fix the label issue - MDL-33523
|
||
|
if (empty($identifierref) && empty($title)) {
|
||
|
$moodle_type = TYPE_UNKNOWN;
|
||
|
}
|
||
|
}
|
||
|
elseif ($item->nodeName == "resource") {
|
||
|
|
||
|
$identifierref = $xpath->query('@identifier', $item);
|
||
|
$identifierref = !empty($identifierref->item(0)->nodeValue) ? $identifierref->item(0)->nodeValue : '';
|
||
|
|
||
|
$cc_type = $this->get_item_cc_type($identifierref);
|
||
|
$moodle_type = $this->convert_to_moodle_type($cc_type);
|
||
|
|
||
|
$title = 'Quiz Bank ' . ($this->count_instances($moodle_type) + 1);
|
||
|
|
||
|
}
|
||
|
|
||
|
if ($level == ROOT_DEEP) {
|
||
|
$index_root = $array_index;
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
|
||
|
static::$instances['instances'][$moodle_type][] = array('title' => $title,
|
||
|
'instance' => static::$instances['index'][$array_index]['instance'],
|
||
|
'common_cartriedge_type' => $cc_type,
|
||
|
'resource_indentifier' => $identifierref,
|
||
|
'deep' => $level);
|
||
|
|
||
|
$more_items = $xpath->query('imscc:item', $item);
|
||
|
|
||
|
if ($more_items->length > 0) {
|
||
|
$this->create_instances($more_items, $level, $array_index, $index_root);
|
||
|
}
|
||
|
|
||
|
$i++;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function count_instances ($type) {
|
||
|
|
||
|
$quantity = 0;
|
||
|
|
||
|
if (array_key_exists('index', static::$instances)) {
|
||
|
if (static::$instances['index'] && $type) {
|
||
|
|
||
|
foreach (static::$instances['index'] as $instance) {
|
||
|
if (!empty($instance['moodle_type'])) {
|
||
|
$types[] = $instance['moodle_type'];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$quantity_instances = array_count_values($types);
|
||
|
$quantity = array_key_exists($type, $quantity_instances) ? $quantity_instances[$type] : 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $quantity;
|
||
|
}
|
||
|
|
||
|
public function convert_to_moodle_type ($cc_type) {
|
||
|
$type = TYPE_UNKNOWN;
|
||
|
|
||
|
if ($cc_type == static::CC_TYPE_FORUM) {
|
||
|
$type = MOODLE_TYPE_FORUM;
|
||
|
}
|
||
|
|
||
|
if ($cc_type == static::CC_TYPE_QUIZ) {
|
||
|
$type = MOODLE_TYPE_QUIZ;
|
||
|
}
|
||
|
|
||
|
if ($cc_type == static::CC_TYPE_WEBLINK) {
|
||
|
$type = MOODLE_TYPE_RESOURCE;
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
//TODO: label
|
||
|
if ($cc_type == static::CC_TYPE_EMPTY) {
|
||
|
$type = MOODLE_TYPE_LABEL;
|
||
|
}
|
||
|
|
||
|
return $type;
|
||
|
}
|
||
|
|
||
|
public function get_item_cc_type ($identifier) {
|
||
|
|
||
|
$xpath = static::newx_path(static::$manifest, static::$namespaces);
|
||
|
|
||
|
$nodes = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="' . $identifier . '"]/@type');
|
||
|
|
||
|
if ($nodes && !empty($nodes->item(0)->nodeValue)) {
|
||
|
return $nodes->item(0)->nodeValue;
|
||
|
} else {
|
||
|
return '';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static function newx_path (DOMDocument $manifest, $namespaces = '') {
|
||
|
|
||
|
$xpath = new DOMXPath($manifest);
|
||
|
|
||
|
if (!empty($namespaces)) {
|
||
|
foreach ($namespaces as $prefix => $ns) {
|
||
|
if (!$xpath->registerNamespace($prefix, $ns)) {
|
||
|
static::log_action('Cannot register the namespace: ' . $prefix . ':' . $ns, true);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $xpath;
|
||
|
}
|
||
|
|
||
|
public static function loadsheet ($file) {
|
||
|
|
||
|
$content = (is_readable($file) && ($content = file_get_contents($file))) ? $content : false;
|
||
|
|
||
|
static::log_action('Loading sheet: ' . $file);
|
||
|
|
||
|
if (!$content) {
|
||
|
static::log_action('Cannot load the xml sheet: ' . $file, true);
|
||
|
}
|
||
|
|
||
|
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) {
|
||
|
|
||
|
$full_message = strtoupper(date("j/n/Y g:i:s a")) . " - " . $text . "\r";
|
||
|
|
||
|
file_put_contents(static::log_file(), $full_message, FILE_APPEND);
|
||
|
|
||
|
if ($critical_error) {
|
||
|
static::critical_error($text);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected function critical_error ($text) {
|
||
|
|
||
|
$path_to_log = static::log_file();
|
||
|
|
||
|
echo '
|
||
|
|
||
|
<p>
|
||
|
<hr />A critical error has been found!
|
||
|
|
||
|
<p>' . $text . '</p>
|
||
|
|
||
|
|
||
|
<p>
|
||
|
The process has been stopped. Please see the <a href="' . $path_to_log . '">log file</a> for more information.</p>
|
||
|
|
||
|
<p>Log: ' . $path_to_log . '</p>
|
||
|
|
||
|
<hr />
|
||
|
|
||
|
</p>
|
||
|
';
|
||
|
|
||
|
die();
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
}
|