See Release Notes
Long Term Support Release
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 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. 8 // 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. 13 // 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/>. 16 /** 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 21 */ 22 23 if (!extension_loaded('fileinfo')) { 24 die('You must install fileinfo extension!'); 25 } 26 27 abstract class cc_convert_moodle2 { 28 29 /** 30 * 31 * Enter description here ... 32 * @param unknown_type $packagedir 33 * @param unknown_type $outdir 34 * @throws DOMException 35 * @throws InvalidArgumentException 36 */ 37 public static function convert($packagedir, $outdir) { 38 $dir = realpath($packagedir); 39 if (empty($dir)) { 40 throw new InvalidArgumentException('Directory does not exist!'); 41 } 42 $odir = realpath($outdir); 43 if (empty($odir)) { 44 throw new InvalidArgumentException('Directory does not exist!'); 45 } 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'); 54 55 //Initialize the manifest metadata class 56 $meta = new cc_metadata_manifest(); 57 58 //Package metadata 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); 66 67 // Create the manifest 68 $manifest = new cc_manifest(cc_version::v11); 69 70 $manifest->add_metadata_manifest($meta); 71 72 $organization = null; 73 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)) { 81 //sections 82 $sections = array(); 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)) { 90 $count = 0; 91 foreach ($section_list as $node) { 92 //if ($count > $numsections) { 93 // break; 94 //} 95 $sectionid = $docp->nodeValue('sectionid', $node); 96 $sectiontitle = $docp->nodeValue('title' , $node); 97 $sectionpath = $docp->nodeValue('directory', $node); 98 $sequence = array(); 99 //Get section stuff 100 $section_file = $dir . 101 DIRECTORY_SEPARATOR . 102 $sectionpath . 103 DIRECTORY_SEPARATOR . 104 'section.xml'; 105 if ($secp->load($section_file)) { 106 $rawvalue = $secp->nodeValue('/section/sequence'); 107 if ($rawvalue != '$@NULL@$') { 108 $sequence = explode(',', $rawvalue); 109 } 110 } 111 $sections[$sectionid] = array($sectiontitle, $sequence); 112 $count++; 113 } 114 } 115 //organization title 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); 123 } 124 $manifest->put_nodes(); 125 } 126 127 if (!empty($organization)) { 128 $manifest->add_new_organization($organization); 129 } 130 131 $manifestpath = $outdir.DIRECTORY_SEPARATOR.'imsmanifest.xml'; 132 $manifest->saveTo($manifestpath); 133 } 134 135 } 136 137 /** 138 * 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 144 */ 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)) { 149 return; 150 } 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}"); 170 } 171 } 172 } 173 } 174 } 175 } 176 } 177 178 protected static function item_indenter(cc_i_item &$item, $level = 0) { 179 $indent = (int)$level; 180 $indent = ($indent) <= 0 ? 0 : $indent; 181 $nprev = null; 182 $nfirst = null; 183 for ($pos = 0, $size = $indent; $pos < $size; $pos++) { 184 $nitem = new cc_item(); 185 $nitem->title = ''; 186 if (empty($nfirst)) { 187 $nfirst = $nitem; 188 } 189 if (!empty($nprev)) { 190 $nprev->add_child_item($nitem); 191 } 192 $nprev = $nitem; 193 } 194 $result = $item; 195 if (!empty($nfirst)) { 196 $item->add_child_item($nfirst); 197 $result = $nprev; 198 } 199 return $result; 200 } 201 202 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body