2 // This file is part of Moodle - http://moodle.org/
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17 * @package backup-convert
18 * @subpackage cc-library
19 * @copyright 2011 Darko Miletic <dmiletic@moodlerooms.com>
20 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 if (!extension_loaded('fileinfo')) {
24 die('You must install fileinfo extension!');
27 abstract class cc_convert_moodle2
{
31 * Enter description here ...
32 * @param unknown_type $packagedir
33 * @param unknown_type $outdir
34 * @throws DOMException
35 * @throws InvalidArgumentException
37 public static function convert($packagedir, $outdir) {
38 $dir = realpath($packagedir);
40 throw new InvalidArgumentException('Directory does not exist!');
42 $odir = realpath($outdir);
44 throw new InvalidArgumentException('Directory does not exist!');
46 $coursefile = $dir.DIRECTORY_SEPARATOR
.'course'.DIRECTORY_SEPARATOR
.'course.xml';
47 $doc = new XMLGenericDocument();
48 if ($doc->load($coursefile)) {
49 $course_name = $doc->nodeValue('/course/fullname');
50 $course_desc = $doc->nodeValue('/course/summary');
51 $course_language = $doc->nodeValue('/course/lang');
52 $course_language = empty($course_language) ?
'en' : $course_language;
53 $course_category = $doc->nodeValue('/course/category/name');
55 //Initialize the manifest metadata class
56 $meta = new cc_metadata_manifest();
59 $metageneral = new cc_metadata_general();
60 $metageneral->set_language($course_language);
61 $metageneral->set_title($course_name, $course_language);
62 $metageneral->set_description($course_desc, $course_language);
63 $metageneral->set_catalog('category');
64 $metageneral->set_entry($course_category);
65 $meta->add_metadata_general($metageneral);
67 // Create the manifest
68 $manifest = new cc_manifest(cc_version
::v11
);
70 $manifest->add_metadata_manifest($meta);
74 //Package structure - default organization and resources
75 //Get the course structure - this will be transformed into organization
76 //Step 1 - Get the list and order of sections/topics
77 $moodle_backup = $dir . DIRECTORY_SEPARATOR
. 'moodle_backup.xml';
78 $secp = new XMLGenericDocument();
79 $docp = new XMLGenericDocument();
80 if ($docp->load($moodle_backup)) {
83 $coursef = new XMLGenericDocument();
84 $course_file = $dir . DIRECTORY_SEPARATOR
.'course' . DIRECTORY_SEPARATOR
. 'course.xml';
85 $coursef->load($course_file);
86 //$numsections = (int)$coursef->nodeValue('/course/numsections');
87 // TODO MDL-35781, this is commented because numsections is now optional attribute
88 $section_list = $docp->nodeList('/moodle_backup/information/contents/sections/section');
89 if (!empty($section_list)) {
91 foreach ($section_list as $node) {
92 //if ($count > $numsections) {
95 $sectionid = $docp->nodeValue('sectionid', $node);
96 $sectiontitle = $docp->nodeValue('title' , $node);
97 $sectionpath = $docp->nodeValue('directory', $node);
100 $section_file = $dir .
101 DIRECTORY_SEPARATOR
.
103 DIRECTORY_SEPARATOR
.
105 if ($secp->load($section_file)) {
106 $rawvalue = $secp->nodeValue('/section/sequence');
107 if ($rawvalue != '$@NULL@$') {
108 $sequence = explode(',', $rawvalue);
111 $sections[$sectionid] = array($sectiontitle, $sequence);
116 $organization = new cc_organization();
117 //Add section/topic items
118 foreach ($sections as $sectionid => $values) {
119 $item = new cc_item();
120 $item->title
= $values[0];
121 self
::process_sequence($item, $manifest, $values[1], $dir, $odir);
122 $organization->add_item($item);
124 $manifest->put_nodes();
127 if (!empty($organization)) {
128 $manifest->add_new_organization($organization);
131 $manifestpath = $outdir.DIRECTORY_SEPARATOR
.'imsmanifest.xml';
132 $manifest->saveTo($manifestpath);
139 * Process the activites and create item structure
140 * @param cc_i_item $item
141 * @param array $sequence
142 * @param string $packageroot - directory path
143 * @throws DOMException
145 protected static function process_sequence(cc_i_item
&$item, cc_i_manifest
&$manifest, array $sequence, $packageroot, $outdir) {
146 $moodle_backup = $packageroot . DIRECTORY_SEPARATOR
. 'moodle_backup.xml';
147 $doc = new XMLGenericDocument();
148 if(!$doc->load($moodle_backup)) {
151 $activities = $doc->nodeList('/moodle_backup/information/contents/activities/activity');
152 if (!empty($activities)) {
153 $dpp = new XMLGenericDocument();
154 foreach ($activities as $activity) {
155 $moduleid = $doc->nodeValue('moduleid', $activity);
156 if (in_array($moduleid, $sequence)) {
157 //detect activity type
158 $directory = $doc->nodeValue('directory', $activity);
159 $path = $packageroot . DIRECTORY_SEPARATOR
. $directory;
160 $module_file = $path . DIRECTORY_SEPARATOR
. 'module.xml';
161 if ($dpp->load($module_file)) {
162 $activity_type = $dpp->nodeValue('/module/modulename');
163 $activity_indentation = $dpp->nodeValue('/module/indent');
164 $aitem = self
::item_indenter($item, $activity_indentation);
165 $caller = "cc_converter_{$activity_type}";
166 if (class_exists($caller)) {
167 $obj = new $caller($aitem, $manifest, $packageroot, $path);
168 if (!$obj->convert($outdir)) {
169 throw new RuntimeException("failed to convert {$activity_type}");
178 protected static function item_indenter(cc_i_item
&$item, $level = 0) {
179 $indent = (int)$level;
180 $indent = ($indent) <= 0 ?
0 : $indent;
183 for ($pos = 0, $size = $indent; $pos < $size; $pos++
) {
184 $nitem = new cc_item();
186 if (empty($nfirst)) {
189 if (!empty($nprev)) {
190 $nprev->add_child_item($nitem);
195 if (!empty($nfirst)) {
196 $item->add_child_item($nfirst);