3 * mods/scorm_packages/scorm-1.2/import.php
5 * This file is part of ATutor, see http://www.atutor.ca
7 * Copyright (C) 2005 Matthai Kurian
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 define('AT_INCLUDE_PATH', '../../../include/');
25 if (!isset ($_POST['type'])) {
26 require(AT_INCLUDE_PATH.'vitals.inc.php');
30 $_SESSION['done'] = 1;
32 require(AT_INCLUDE_PATH.'../mods/_core/file_manager/filemanager.inc.php');
33 require(AT_INCLUDE_PATH.'classes/pclzip.lib.php');
35 authenticate(AT_PRIV_PACKAGES);
38 function chmodPackageDir ($path) {
40 if (!is_dir($path)) return;
41 else chmod ($path, 0755);
44 while ($f = readdir($h)) {
45 if ($f == '.' || $f == '..') continue;
46 $fpath = $path.'/'.$f;
47 if (!is_dir($fpath)) {
50 chmodPackageDir ($fpath);
56 $package_base_path = '';
58 $idx = ''; // the current item's index, 1, 1.1, 1.2, 2, 2.1 ...
59 $idxs = array(); // array containing the idx for all items
60 $orgid = 0; // index of current organization 1...
61 $depth = 0; // depth in organization tree
73 if (!isset($_POST['submit'])) {
74 $msg->addFeedback('IMPORT_CANCELLED');
75 header('Location: ../index.php');
79 $cid = intval($_POST['cid']);
82 if (isset($_POST['url']) && ($_POST['url'] != 'http://') ) {
83 if ($content = @file_get_contents($_POST['url'])) {
84 $filename = substr(time(), -6). '.zip';
85 $full_filename = AT_CONTENT_DIR . $filename;
87 if (!$fp = fopen($full_filename, 'w+b')) {
88 echo "Cannot open file ($filename)";
92 if (fwrite($fp, $content, strlen($content) ) === FALSE) {
93 echo "Cannot write to file ($filename)";
98 $_FILES['file']['name'] = $filename;
99 $_FILES['file']['tmp_name'] = $full_filename;
100 $_FILES['file']['size'] = strlen($content);
102 $url_parts = pathinfo($_POST['url']);
103 $package_base_name_url = $url_parts['basename'];
105 $ext = pathinfo($_FILES['file']['name']);
106 $ext = $ext['extension'];
108 if ($_FILES['file']['error'] == 1) {
109 require(AT_INCLUDE_PATH.'header.inc.php');
110 $errors = array('FILE_MAX_SIZE', ini_get('upload_max_filesize'));
111 $msg->printErrors($errors);
112 require(AT_INCLUDE_PATH.'footer.inc.php');
116 if (!$_FILES['file']['name']
117 || (!is_uploaded_file($_FILES['file']['tmp_name']) && !$_POST['url'])
118 || ($ext != 'zip')) {
119 require(AT_INCLUDE_PATH.'header.inc.php');
120 $msg->printErrors('FILE_NOT_SELECTED');
121 require(AT_INCLUDE_PATH.'footer.inc.php');
125 if ($_FILES['file']['size'] == 0) {
126 require(AT_INCLUDE_PATH.'header.inc.php');
127 $msg->printErrors('IMPORTFILE_EMPTY');
128 require(AT_INCLUDE_PATH.'footer.inc.php');
132 $package_path = AT_INCLUDE_PATH . '../sco/';
134 if (!is_dir($package_path)) {
135 if (!@mkdir($package_path, 0755)) {
136 require(AT_INCLUDE_PATH.'header.inc.php');
137 $msg->printErrors('PACKAGE_DIR_FAILED');
138 require(AT_INCLUDE_PATH.'footer.inc.php');
141 chmod ($package_path, 0755);
144 $package_path .= $_SESSION['course_id'].'/';
145 if (!is_dir($package_path)) {
146 if (!@mkdir($package_path, 0755)) {
147 require(AT_INCLUDE_PATH.'header.inc.php');
148 $msg->printErrors('PACKAGE_DIR_FAILED');
149 require(AT_INCLUDE_PATH.'footer.inc.php');
152 chmod ($package_path, 0755);
155 $package_path .= 'tmp/';
156 clr_dir($package_path);
157 if (!is_dir($package_path)) {
158 if (!@mkdir($package_path, 0755)) {
159 require(AT_INCLUDE_PATH.'header.inc.php');
160 $msg->printErrors('PACKAGE_DIR_FAILED');
161 require(AT_INCLUDE_PATH.'footer.inc.php');
164 chmod ($package_path, 0755);
167 $archive = new PclZip($_FILES['file']['tmp_name']);
168 if ($archive->extract (PCLZIP_OPT_PATH, $package_path) == 0) {
170 require(AT_INCLUDE_PATH.'header.inc.php');
171 echo 'Error : '.$archive->errorInfo(true);
172 require(AT_INCLUDE_PATH.'footer.inc.php');
173 clr_dir($package_path);
177 chmodPackageDir ($package_path);
179 $sql = "SELECT max_quota
180 FROM ".TABLE_PREFIX."courses
181 WHERE course_id=$_SESSION[course_id]";
183 $result = mysql_query($sql, $db);
184 $q_row = mysql_fetch_assoc($result);
186 if ($q_row['max_quota'] != AT_COURSESIZE_UNLIMITED) {
188 if ($q_row['max_quota'] == AT_COURSESIZE_DEFAULT) {
189 $q_row['max_quota'] = $MaxCourseSize;
191 $totalBytes = dirsize($import_path);
192 $course_total = dirsize(AT_CONTENT_DIR . $_SESSION['course_id'].'/');
193 $total_after = $q_row['max_quota'] - $course_total - $totalBytes + $MaxCourseFloat;
195 if ($total_after < 0) {
196 require(AT_INCLUDE_PATH.'header.inc.php');
197 $errors = array('NO_CONTENT_SPACE', number_format(-1*($total_after/AT_KBYTE_SIZE), 2 ) );
198 $msg->printErrors($errors);
200 require(AT_INCLUDE_PATH.'footer.inc.php');
201 clr_dir($import_path);
207 parseManifest ($package_path);
212 if (isset($_POST['url'])) {
213 @unlink($full_filename);
216 for ($i=1; $orgitems[$i]; $i++) {
217 array_push ($orgs, $orgitems[$i]['title']);
221 $msg->addFeedback(array('PACKAGE_IMPORT_SUCCESS', $orgs[0]));
224 for ($i=0; $i<$oc; $i++) {
225 $l .= '<li>' . $orgs[$i] . '</li>';
227 $msg->addFeedback(array('PACKAGES_IMPORT_SUCCESS', $l));
230 header('Location: ./index.php');
234 function parseManifest ($import_path) {
237 $ims_manifest_xml = @file_get_contents($import_path.'imsmanifest.xml');
239 if ($ims_manifest_xml === false) {
240 require(AT_INCLUDE_PATH.'header.inc.php');
241 $msg->addError('NO_IMSMANIFEST');
243 require(AT_INCLUDE_PATH.'footer.inc.php');
244 clr_dir($import_path);
248 $xml_parser = xml_parser_create();
250 xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, false);
251 xml_set_element_handler($xml_parser, 'startElement', 'endElement');
252 xml_set_character_data_handler($xml_parser, 'characterData');
254 if (!xml_parse($xml_parser, $ims_manifest_xml, true)) {
255 die(sprintf("XML error: %s at line %d",
256 xml_error_string(xml_get_error_code($xml_parser)),
257 xml_get_current_line_number($xml_parser)));
260 xml_parser_free($xml_parser);
263 function scormType ($i) {
264 global $idxs, $orgitems, $res;
265 $r = $res[$orgitems[$idxs[$i]]['identifierref']]['adlcp:scormtype'];
267 $o = explode ('.', $idxs[$i]);
268 if (sizeOf($o) > 1) return 'cluster';
269 return 'organization';
272 function doValidation () {
277 global $package_path;
279 $ic = sizeOf ($idxs);
284 for ($i=0; $i<$ic; $i++) {
285 $title = addslashes($orgitems[$idxs[$i]]['title']);
287 $href = $res[$orgitems[$idxs[$i]]['identifierref']]['href'];
288 $styp = $res[$orgitems[$idxs[$i]]['identifierref']]['adlcp:scormtype'];
289 $pre = $orgitems[$idxs[$i]]['adlcp:prerequisites'];
290 $max = $orgitems[$idxs[$i]]['adlcp:maxtimeallowed'];
291 $act = $orgitems[$idxs[$i]]['adlcp:timelimitaction'];
292 $lms = $orgitems[$idxs[$i]]['adlcp:datafromlms'];
293 $mas = $orgitems[$idxs[$i]]['adlcp:masteryscore'];
295 if ($idxs[$i].'.1' == $idxs[$i+1]) { // cluster
296 if ($href != '' && ++$warn)
297 $msg->addWarning ('SCORM_ITEM_CLUSTER_HAS_OBJECT');
299 if ($styp == '' && ++$err)
300 $msg->addError ('SCORM_ITEM_SCORMTYPE_MISSING');
301 if ($href == '' && ++$err)
302 $msg->addError ('SCORM_ITEM_HREF_MISSING');
307 header('Location: ./index.php');
314 function doImport () {
320 global $package_path;
322 $now = date('Y-m-d H:i:s');
323 $file = $_FILES['file']['name'];
324 $sql = "INSERT INTO ".TABLE_PREFIX."packages
329 $_SESSION[course_id],
333 $result = mysql_query($sql, $db);
335 require(AT_INCLUDE_PATH.'header.inc.php');
336 $msg->addError('DB_NOT_UPDATED');
338 require(AT_INCLUDE_PATH.'footer.inc.php');
342 $pkg = mysql_insert_id($db);
343 rename ($package_path, dirname($package_path) . '/' . $pkg);
345 $ic = sizeOf ($idxs);
347 for ($i=0; $i<$ic; $i++) {
348 $title = addslashes($orgitems[$idxs[$i]]['title']);
349 $scormtype = scormType($i);
351 switch ($scormtype) {
353 $sql = "INSERT INTO ".TABLE_PREFIX."scorm_1_2_org (
355 ) VALUES ( $pkg, '$title')";
357 $result = mysql_query($sql, $db);
359 require(AT_INCLUDE_PATH.'header.inc.php');
360 $msg->addError('DB_NOT_UPDATED');
362 require(AT_INCLUDE_PATH.'footer.inc.php');
365 $orgid = mysql_insert_id($db);
366 $sql = "INSERT INTO ".TABLE_PREFIX."scorm_1_2_item
376 $result = mysql_query($sql, $db);
380 if (!$orgitems[$idxs[$i]]['adlcp:timelimitaction'])
381 $orgitems[$idxs[$i]]['adlcp:timelimitaction'] =
382 'continue, no message';
385 $href = $res[$orgitems[$idxs[$i]]['identifierref']]['href'];
386 $pre = $orgitems[$idxs[$i]]['adlcp:prerequisites'];
387 $max = $orgitems[$idxs[$i]]['adlcp:maxtimeallowed'];
388 $act = $orgitems[$idxs[$i]]['adlcp:timelimitaction'];
389 $lms = $orgitems[$idxs[$i]]['adlcp:datafromlms'];
390 $mas = $orgitems[$idxs[$i]]['adlcp:masteryscore'];
391 $sql = "INSERT INTO ".TABLE_PREFIX."scorm_1_2_item
400 '$max', '$act', '$lms', '$mas'
402 $result = mysql_query($sql, $db);
404 require(AT_INCLUDE_PATH.'header.inc.php');
405 $msg->addError('DB_NOT_UPDATED');
407 require(AT_INCLUDE_PATH.'footer.inc.php');
415 function startElement($parser, $name, $h) {
417 global $orgid, $itemid, $depth;
418 global $orgitems, $idx, $idxs;
420 global $files, $finfo, $totalsize;
427 $idx = implode ('.', $itemid);
428 array_push ($idxs, $idx);
429 while (list($l, $r) = each($h)) {
430 $orgitems[$idx][$l]=$r;
437 array_push ($ress, $h['identifier']);
438 while (list($l, $r) = each($h)) {
439 $res[$h['identifier']][$l]=$r;
445 array_push ($files, $h['href']);
447 .'import/'.$_SESSION['course_id']
449 $finfo[$h['href']] = @stat($f);
450 $totalsize += $finfo[$h['href']]['size'];
455 function endElement($parser, $name) {
456 global $orgid, $idx, $itemid, $depth, $text, $orgitems;
461 $itemid = array ($orgid);
464 while ($itemid[$depth]) {
470 case 'adlcp:datafromlms':
471 case 'adlcp:maxtimeallowed':
472 case 'adlcp:timelimitaction':
473 case 'adlcp:prerequisites':
474 case 'adlcp:masteryscore':
475 $orgitems[$idx][$name] = trim($text);
483 function characterData($parser, $data){