2 /****************************************************************/
4 /****************************************************************/
5 /* Copyright (c) 2002-2008 by Greg Gay & Joel Kronenberg */
6 /* Adaptive Technology Resource Centre / University of Toronto */
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. */
12 /****************************************************************/
14 define('AT_INCLUDE_PATH', '../../include/');
15 require(AT_INCLUDE_PATH.'vitals.inc.php');
17 require(AT_INCLUDE_PATH.'lib/filemanager.inc.php'); /* for clr_dir() and preImportCallBack and dirsize() */
18 require(AT_INCLUDE_PATH.'classes/pclzip.lib.php');
19 require(AT_INCLUDE_PATH.'lib/qti.inc.php');
20 //require(AT_INCLUDE_PATH.'classes/QTI/QTIParser.class.php');
21 require(AT_INCLUDE_PATH.'classes/QTI/QTIImport.class.php');
22 require(AT_INCLUDE_PATH.'classes/A4a/A4aImport.class.php');
24 /* make sure we own this course that we're exporting */
25 authenticate(AT_PRIV_CONTENT);
27 /* to avoid timing out on large files */
29 $_SESSION['done'] = 1;
31 $html_head_tags = array("style", "script");
33 $package_base_path = '';
35 $element_path = array();
36 $imported_glossary = array();
37 $test_attributes = array();
41 /* called at the start of en element */
42 /* builds the $path array which is the path from the root to the current element */
43 function startElement($parser, $name, $attrs) {
44 global $items, $path, $package_base_path;
46 global $xml_base_path, $test_message;
47 global $current_identifier;
49 if ($name == 'manifest' && isset($attrs['xml:base']) && $attrs['xml:base']) {
50 $xml_base_path = $attrs['xml:base'];
51 } else if ($name == 'file') {
53 // special case for webCT content packages that don't specify the `href` attribute
54 // with the `<resource>` element.
55 // we take the `href` from the first `<file>` element.
57 if (isset($items[$current_identifier]) && ($items[$current_identifier]['href'] == '')) {
58 $attrs['href'] = urldecode($attrs['href']);
60 $items[$current_identifier]['href'] = $attrs['href'];
62 $items[$current_identifier]['href'] = $attrs['href'];
64 $temp_path = pathinfo($attrs['href']);
65 $temp_path = explode('/', $temp_path['dirname']);
67 if ($package_base_path == '') {
68 $package_base_path = $temp_path;
71 // $package_base_path = array_intersect($package_base_path, $temp_path);
74 $items[$current_identifier]['new_path'] = implode('/', $temp_path);
77 if ( isset($_POST['allow_test_import']) && isset($items[$current_identifier])
78 && preg_match('/((.*)\/)*tests\_[0-9]+\.xml$/', $attrs['href'])) {
79 $items[$current_identifier]['tests'][] = $attrs['href'];
81 if ( isset($_POST['allow_a4a_import']) && isset($items[$current_identifier])) {
82 $items[$current_identifier]['a4a_import_enabled'] = true;
84 } else if (($name == 'item') && ($attrs['identifierref'] != '')) {
85 $path[] = $attrs['identifierref'];
86 } else if (($name == 'item') && ($attrs['identifier'])) {
87 $path[] = $attrs['identifier'];
88 } else if (($name == 'resource') && is_array($items[$attrs['identifier']])) {
89 $current_identifier = $attrs['identifier'];
92 $attrs['href'] = urldecode($attrs['href']);
94 $items[$attrs['identifier']]['href'] = $attrs['href'];
96 // href points to a remote url
97 if (preg_match('/^http.*:\/\//', trim($attrs['href'])))
98 $items[$attrs['identifier']]['new_path'] = '';
99 else // href points to local file
101 $temp_path = pathinfo($attrs['href']);
102 $temp_path = explode('/', $temp_path['dirname']);
103 if (!$package_base_path) {
104 $package_base_path = $temp_path;
106 $package_base_path = array_intersect($package_base_path, $temp_path);
109 $items[$attrs['identifier']]['new_path'] = implode('/', $temp_path);
113 //if test custom message has not been saved
114 // if (!isset($items[$current_identifier]['test_message'])){
115 // $items[$current_identifier]['test_message'] = $test_message;
118 if (($name == 'item') && ($attrs['parameters'] != '')) {
119 $items[$attrs['identifierref']]['test_message'] = $attrs['parameters'];
122 if (file_exists(AT_CONTENT_DIR .'import/'.$_SESSION['course_id'].'/'.$attrs['href'])){
123 $items[$current_identifier]['file'][] = $attrs['href'];
126 array_push($element_path, $name);
129 /* called when an element ends */
130 /* removed the current element from the $path */
131 function endElement($parser, $name) {
132 global $path, $element_path, $my_data, $items;
133 global $current_identifier;
135 static $resource_num = 0;
137 if ($name == 'item') {
141 //check if this is a test import
142 if ($name == 'schema'){
143 if (trim($my_data)=='IMS Question and Test Interoperability'){
144 $msg->addError('IMPORT_FAILED');
149 if ($current_identifier != ''){
150 $my_data = trim($my_data);
151 $last_file_name = $items[$current_identifier]['file'][(sizeof($items[$current_identifier]['file']))-1];
153 if ($name=='originalAccessMode'){
154 if (in_array('accessModeStatement', $element_path)){
155 $items[$current_identifier]['a4a'][$last_file_name][$resource_num]['access_stmt_originalAccessMode'][] = $my_data;
156 } elseif (in_array('adaptationStatement', $element_path)){
157 $items[$current_identifier]['a4a'][$last_file_name][$resource_num]['adapt_stmt_originalAccessMode'][] = $my_data;
159 } elseif (($name=='language') && in_array('accessModeStatement', $element_path)){
160 $items[$current_identifier]['a4a'][$last_file_name][$resource_num]['language'][] = $my_data;
161 } elseif ($name=='hasAdaptation') {
162 $items[$current_identifier]['a4a'][$last_file_name][$resource_num]['hasAdaptation'][] = $my_data;
163 } elseif ($name=='isAdaptationOf'){
164 $items[$current_identifier]['a4a'][$last_file_name][$resource_num]['isAdaptationOf'][] = $my_data;
165 } elseif ($name=='accessForAllResource'){
167 } elseif($name=='file'){
168 $resource_num = 0; //reset resournce number to 0 when the file tags ends
172 if ($element_path === array('manifest', 'metadata', 'imsmd:lom', 'imsmd:general', 'imsmd:title', 'imsmd:langstring')) {
173 global $package_base_name;
174 $package_base_name = trim($my_data);
177 array_pop($element_path);
181 /* called when there is character data within elements */
182 /* constructs the $items array using the last entry in $path as the parent element */
183 function characterData($parser, $data){
184 global $path, $items, $order, $my_data, $element_path;
186 $str_trimmed_data = trim($data);
188 if (!empty($str_trimmed_data)) {
189 $size = count($path);
191 $current_item_id = $path[$size-1];
193 $parent_item_id = $path[$size-2];
198 if (isset($items[$current_item_id]['parent_content_id']) && is_array($items[$current_item_id])) {
200 /* this item already exists, append the title */
201 /* this fixes {\n, \t, `, &} characters in elements */
203 /* horible kludge to fix the <ns2:objectiveDesc xmlns:ns2="http://www.utoronto.ca/atrc/tile/xsd/tile_objective"> */
205 if (in_array('accessForAllResource', $element_path)){
207 } elseif ($element_path[count($element_path)-1] != 'ns1:objectiveDesc') {
208 $items[$current_item_id]['title'] .= $data;
212 $order[$parent_item_id] ++;
214 $item_tmpl = array( 'title' => $data,
215 'parent_content_id' => $parent_item_id,
216 'ordering' => $order[$parent_item_id]-1);
218 //append other array values if it exists
219 if (is_array($items[$current_item_id])){
220 $items[$current_item_id] = array_merge($items[$current_item_id], $item_tmpl);
222 $items[$current_item_id] = $item_tmpl;
231 /* glossary parser: */
232 function glossaryStartElement($parser, $name, $attrs) {
233 global $element_path;
235 array_push($element_path, $name);
238 /* called when an element ends */
239 /* removed the current element from the $path */
240 function glossaryEndElement($parser, $name) {
241 global $element_path, $my_data, $imported_glossary;
242 static $current_term;
244 if ($element_path === array('glossary', 'item', 'term')) {
245 $current_term = $my_data;
247 } else if ($element_path === array('glossary', 'item', 'definition')) {
248 $imported_glossary[trim($current_term)] = trim($my_data);
251 array_pop($element_path);
255 function glossaryCharacterData($parser, $data){
261 if (!isset($_POST['submit']) && !isset($_POST['cancel'])) {
262 /* just a catch all */
264 $errors = array('FILE_MAX_SIZE', ini_get('post_max_size'));
265 $msg->addError($errors);
267 header('Location: ./index.php');
269 } else if (isset($_POST['cancel'])) {
270 $msg->addFeedback('IMPORT_CANCELLED');
272 header('Location: ./index.php');
276 $cid = intval($_POST['cid']);
278 if (isset($_POST['url']) && ($_POST['url'] != 'http://') ) {
279 if ($content = @file_get_contents($_POST['url'])) {
281 // save file to /content/
282 $filename = substr(time(), -6). '.zip';
283 $full_filename = AT_CONTENT_DIR . $filename;
285 if (!$fp = fopen($full_filename, 'w+b')) {
286 echo "Cannot open file ($filename)";
290 if (fwrite($fp, $content, strlen($content) ) === FALSE) {
291 echo "Cannot write to file ($filename)";
296 $_FILES['file']['name'] = $filename;
297 $_FILES['file']['tmp_name'] = $full_filename;
298 $_FILES['file']['size'] = strlen($content);
300 $url_parts = pathinfo($_POST['url']);
301 $package_base_name_url = $url_parts['basename'];
303 $ext = pathinfo($_FILES['file']['name']);
304 $ext = $ext['extension'];
307 $msg->addError('IMPORTDIR_IMS_NOTVALID');
308 } else if ($_FILES['file']['error'] == 1) {
309 $errors = array('FILE_MAX_SIZE', ini_get('upload_max_filesize'));
310 $msg->addError($errors);
311 } else if ( !$_FILES['file']['name'] || (!is_uploaded_file($_FILES['file']['tmp_name']) && !$_POST['url'])) {
312 $msg->addError('FILE_NOT_SELECTED');
313 } else if ($_FILES['file']['size'] == 0) {
314 $msg->addError('IMPORTFILE_EMPTY');
317 if ($msg->containsErrors()) {
318 if (isset($_GET['tile'])) {
319 header('Location: '.$_base_path.'tools/tile/index.php');
321 header('Location: index.php');
326 /* check if ../content/import/ exists */
327 $import_path = AT_CONTENT_DIR . 'import/';
328 $content_path = AT_CONTENT_DIR;
330 if (!is_dir($import_path)) {
331 if (!@mkdir($import_path, 0700)) {
332 $msg->addError('IMPORTDIR_FAILED');
336 $import_path .= $_SESSION['course_id'].'/';
337 if (is_dir($import_path)) {
338 clr_dir($import_path);
341 if (!@mkdir($import_path, 0700)) {
342 $msg->addError('IMPORTDIR_FAILED');
345 if ($msg->containsErrors()) {
346 if (isset($_GET['tile'])) {
347 header('Location: '.$_base_path.'tools/tile/index.php');
349 header('Location: index.php');
354 /* extract the entire archive into AT_COURSE_CONTENT . import/$course using the call back function to filter out php files */
356 $archive = new PclZip($_FILES['file']['tmp_name']);
357 if ($archive->extract( PCLZIP_OPT_PATH, $import_path,
358 PCLZIP_CB_PRE_EXTRACT, 'preImportCallBack') == 0) {
359 $msg->addError('IMPORT_FAILED');
360 echo 'Error : '.$archive->errorInfo(true);
361 clr_dir($import_path);
362 header('Location: index.php');
365 error_reporting(AT_ERROR_REPORTING);
367 /* get the course's max_quota */
368 $sql = "SELECT max_quota FROM ".TABLE_PREFIX."courses WHERE course_id=$_SESSION[course_id]";
369 $result = mysql_query($sql, $db);
370 $q_row = mysql_fetch_assoc($result);
372 if ($q_row['max_quota'] != AT_COURSESIZE_UNLIMITED) {
374 if ($q_row['max_quota'] == AT_COURSESIZE_DEFAULT) {
375 $q_row['max_quota'] = $MaxCourseSize;
377 $totalBytes = dirsize($import_path);
378 $course_total = dirsize(AT_CONTENT_DIR . $_SESSION['course_id'].'/');
379 $total_after = $q_row['max_quota'] - $course_total - $totalBytes + $MaxCourseFloat;
381 if ($total_after < 0) {
382 /* remove the content dir, since there's no space for it */
383 $errors = array('NO_CONTENT_SPACE', number_format(-1*($total_after/AT_KBYTE_SIZE), 2 ) );
384 $msg->addError($errors);
386 clr_dir($import_path);
388 if (isset($_GET['tile'])) {
389 header('Location: '.$_base_path.'tools/tile/index.php');
391 header('Location: index.php');
398 $items = array(); /* all the content pages */
399 $order = array(); /* keeps track of the ordering for each content page */
400 $path = array(); /* the hierarchy path taken in the menu to get to the current item in the manifest */
403 $items[content_id/resource_id] = array(
405 'real_content_id' // calculated after being inserted
412 $ims_manifest_xml = @file_get_contents($import_path.'imsmanifest.xml');
414 if ($ims_manifest_xml === false) {
415 $msg->addError('NO_IMSMANIFEST');
417 if (file_exists($import_path . 'atutor_backup_version')) {
418 $msg->addError('NO_IMS_BACKUP');
421 clr_dir($import_path);
423 if (isset($_GET['tile'])) {
424 header('Location: '.$_base_path.'tools/tile/index.php');
426 header('Location: index.php');
431 $xml_parser = xml_parser_create();
433 xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, false); /* conform to W3C specs */
434 xml_set_element_handler($xml_parser, 'startElement', 'endElement');
435 xml_set_character_data_handler($xml_parser, 'characterData');
437 if (!xml_parse($xml_parser, $ims_manifest_xml, true)) {
438 die(sprintf("XML error: %s at line %d",
439 xml_error_string(xml_get_error_code($xml_parser)),
440 xml_get_current_line_number($xml_parser)));
443 xml_parser_free($xml_parser);
446 /* check if the glossary terms exist */
447 if (file_exists($import_path . 'glossary.xml')){
448 $glossary_xml = @file_get_contents($import_path.'glossary.xml');
449 $element_path = array();
451 $xml_parser = xml_parser_create();
453 /* insert the glossary terms into the database (if they're not in there already) */
454 /* parse the glossary.xml file and insert the terms */
455 xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, false); /* conform to W3C specs */
456 xml_set_element_handler($xml_parser, 'glossaryStartElement', 'glossaryEndElement');
457 xml_set_character_data_handler($xml_parser, 'glossaryCharacterData');
459 if (!xml_parse($xml_parser, $glossary_xml, true)) {
460 die(sprintf("XML error: %s at line %d",
461 xml_error_string(xml_get_error_code($xml_parser)),
462 xml_get_current_line_number($xml_parser)));
464 xml_parser_free($xml_parser);
465 $contains_glossary_terms = true;
466 foreach ($imported_glossary as $term => $defn) {
467 if (!$glossary[urlencode($term)]) {
468 $sql = "INSERT INTO ".TABLE_PREFIX."glossary VALUES (NULL, $_SESSION[course_id], '$term', '$defn', 0)";
469 mysql_query($sql, $db);
474 // Check if there are any errors during parsing.
475 if ($msg->containsErrors()) {
476 if (isset($_GET['tile'])) {
477 header('Location: '.$_base_path.'tools/tile/index.php');
479 header('Location: index.php');
484 /* generate a unique new package base path based on the package file name and date as needed. */
485 /* the package name will be the dir where the content for this package will be put, as a result */
486 /* the 'content_path' field in the content table will be set to this path. */
487 /* $package_base_name_url comes from the URL file name (NOT the file name of the actual file we open)*/
488 if (!$package_base_name && $package_base_name_url) {
489 $package_base_name = substr($package_base_name_url, 0, -4);
490 } else if (!$package_base_name) {
491 $package_base_name = substr($_FILES['file']['name'], 0, -4);
494 $package_base_name = strtolower($package_base_name);
495 $package_base_name = str_replace(array('\'', '"', ' ', '|', '\\', '/', '<', '>', ':'), '_' , $package_base_name);
496 $package_base_name = preg_replace("/[^A-Za-z0-9._\-]/", '', $package_base_name);
498 if (is_dir(AT_CONTENT_DIR . $_SESSION['course_id'].'/'.$package_base_name)) {
499 $package_base_name .= '_'.date('ymdHis');
502 if ($package_base_path) {
503 $package_base_path = implode('/', $package_base_path);
504 } elseif (empty($package_base_path)){
505 $package_base_path = '';
508 if ($xml_base_path) {
509 $package_base_path = $xml_base_path . $package_base_path;
511 mkdir(AT_CONTENT_DIR .$_SESSION['course_id'].'/'.$xml_base_path);
512 $package_base_name = $xml_base_path . $package_base_name;
516 /* get the top level content ordering offset */
517 $sql = "SELECT MAX(ordering) AS ordering FROM ".TABLE_PREFIX."content WHERE course_id=$_SESSION[course_id] AND content_parent_id=$cid";
518 $result = mysql_query($sql, $db);
519 $row = mysql_fetch_assoc($result);
520 $order_offset = intval($row['ordering']); /* it's nice to have a real number to deal with */
522 foreach ($items as $item_id => $content_info)
525 if (preg_match('/^http.*:\/\//', trim($content_info['href'])) )
527 $content = '<a href="'.$content_info['href'].'" target="_blank">'.$content_info['title'].'</a>';
531 if (isset($content_info['href'], $xml_base_path)) {
532 $content_info['href'] = $xml_base_path . $content_info['href'];
534 if (!isset($content_info['href'])) {
535 // this item doesn't have an identifierref. so create an empty page.
538 $last_modified = date('Y-m-d H:i:s');
540 $file_info = @stat(AT_CONTENT_DIR . 'import/'.$_SESSION['course_id'].'/'.$content_info['href']);
541 if ($file_info === false) {
545 $path_parts = pathinfo(AT_CONTENT_DIR . 'import/'.$_SESSION['course_id'].'/'.$content_info['href']);
546 $ext = strtolower($path_parts['extension']);
548 $last_modified = date('Y-m-d H:i:s', $file_info['mtime']);
550 if (in_array($ext, array('gif', 'jpg', 'bmp', 'png', 'jpeg'))) {
551 /* this is an image */
552 $content = '<img src="'.$content_info['href'].'" alt="'.$content_info['title'].'" />';
553 } else if ($ext == 'swf') {
555 /* Using default size of 550 x 400 */
557 $content = '<object type="application/x-shockwave-flash" data="' . $content_info['href'] . '" width="550" height="400"><param name="movie" value="'. $content_info['href'] .'" /></object>';
559 } else if ($ext == 'mov') {
560 /* this is a quicktime movie */
561 /* Using default size of 550 x 400 */
563 $content = '<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="550" height="400" codebase="http://www.apple.com/qtactivex/qtplugin.cab"><param name="src" value="'. $content_info['href'] . '" /><param name="autoplay" value="true" /><param name="controller" value="true" /><embed src="' . $content_info['href'] .'" width="550" height="400" controller="true" pluginspage="http://www.apple.com/quicktime/download/"></embed></object>';
564 } else if ($ext == 'mp3') {
565 $content = '<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="200" height="15" codebase="http://www.apple.com/qtactivex/qtplugin.cab"><param name="src" value="'. $content_info['href'] . '" /><param name="autoplay" value="false" /><embed src="' . $content_info['href'] .'" width="200" height="15" autoplay="false" pluginspage="http://www.apple.com/quicktime/download/"></embed></object>';
566 } else if (in_array($ext, array('wav', 'au'))) {
567 $content = '<embed SRC="'.$content_info['href'].'" autostart="false" width="145" height="60"><noembed><bgsound src="'.$content_info['href'].'"></noembed></embed>';
569 } else if (in_array($ext, array('txt', 'css', 'html', 'htm', 'csv', 'asc', 'tsv', 'xml', 'xsl'))) {
570 /* this is a plain text file */
571 $content = file_get_contents(AT_CONTENT_DIR . 'import/'.$_SESSION['course_id'].'/'.$content_info['href']);
572 if ($content === false) {
573 /* if we can't stat() it then we're unlikely to be able to read it */
574 /* so we'll never get here. */
578 // get the contents of the 'head' element
579 $head = get_html_head_by_tag($content, $html_head_tags);
581 // Specifically handle eXe package
582 // NOTE: THIS NEEDS WORK! TO FIND A WAY APPLY EXE .CSS FILES ONLY ON COURSE CONTENT PART.
583 // NOW USE OUR OWN .CSS CREATED SOLELY FOR EXE
584 $isExeContent = false;
586 // check xml file in eXe package
587 if (preg_match("/<organization[ ]*identifier=\"eXe*>*/", $ims_manifest_xml))
589 $isExeContent = true;
592 // use ATutor's eXe style sheet as the ones from eXe conflicts with ATutor's style sheets
595 $head = preg_replace ('/(<style.*>)(.*)(<\/style>)/ms', '\\1@import url(/docs/exestyles.css);\\3', $head);
598 // end of specifically handle eXe package
600 $content = get_html_body($content);
601 if ($contains_glossary_terms)
603 // replace glossary content package links to real glossary mark-up using [?] [/?]
604 // refer to bug 3641, edited by Harris
605 $content = preg_replace('/<a href="([.\w\d\s]+[^"]+)" target="body" class="at-term">([.\w\d\s&;"]+|.*)<\/a>/i', '[?]\\2[/?]', $content);
608 /* potential security risk? */
609 if ( strpos($content_info['href'], '..') === false && !preg_match('/((.*)\/)*tests\_[0-9]+\.xml$/', $content_info['href'])) {
610 @unlink(AT_CONTENT_DIR . 'import/'.$_SESSION['course_id'].'/'.$content_info['href']);
613 /* non text file, and can't embed (example: PDF files) */
614 $content = '<a href="'.$content_info['href'].'">'.$content_info['title'].'</a>';
618 $content_parent_id = $cid;
619 if ($content_info['parent_content_id'] !== 0) {
620 $content_parent_id = $items[$content_info['parent_content_id']]['real_content_id'];
624 if ($content_parent_id == $cid) {
625 $my_offset = $order_offset;
628 /* replace the old path greatest common denomiator with the new package path. */
629 /* we don't use str_replace, b/c there's no knowing what the paths may be */
630 /* we only want to replace the first part of the path. */
631 if ($package_base_path != '') {
632 $content_info['new_path'] = $package_base_name . substr($content_info['new_path'], strlen($package_base_path));
634 $content_info['new_path'] = $package_base_name;
637 $head = addslashes($head);
638 $content_info['title'] = addslashes($content_info['title']);
639 $content_info['test_message'] = addslashes($content_info['test_message']);
641 //if this file is a test_xml, create a blank page instead, for imscc.
642 if (preg_match('/((.*)\/)*tests\_[0-9]+\.xml$/', $content_info['href'])){
645 $content = addslashes($content);
648 $sql= 'INSERT INTO '.TABLE_PREFIX.'content'
664 ('.$_SESSION['course_id'].','
665 .intval($content_parent_id).','
666 .($content_info['ordering'] + $my_offset + 1).','
667 .'"'.$last_modified.'",
674 .'"'.$content_info['new_path'].'",'
675 .'"'.$content_info['title'].'",'
677 .'"'.$content_info['test_message'].'")';
679 $result = mysql_query($sql, $db) or die(mysql_error());
681 /* get the content id and update $items */
682 $items[$item_id]['real_content_id'] = mysql_insert_id($db);
684 /* get the tests associated with this content */
685 if (!empty($items[$item_id]['tests'])){
686 $qti_import =& new QTIImport($import_path);
688 foreach ($items[$item_id]['tests'] as $array_id => $test_xml_file){
689 $tests_xml = $import_path.$test_xml_file;
691 //Mimic the array for now.
692 $test_attributes['resource']['href'] = $test_xml_file;
693 $test_attributes['resource']['type'] = 'imsqti_xmlv1p1';
694 $test_attributes['resource']['file'] = $items[$item_id]['file'];
695 // $test_attributes['resource']['file'] = array($test_xml_file);
698 //Get the XML file out and start importing them into our database.
699 //TODO: See question_import.php 287-289.
700 $qids = $qti_import->importQuestions($test_attributes);
703 $tid = $qti_import->importTest();
705 //associate question and tests
706 foreach ($qids as $order=>$qid){
707 if (isset($qti_import->weights[$order])){
708 $weight = round($qti_import->weights[$order]);
712 $new_order = $order + 1;
713 $sql = "INSERT INTO " . TABLE_PREFIX . "tests_questions_assoc" .
714 "(test_id, question_id, weight, ordering, required) " .
715 "VALUES ($tid, $qid, $weight, $new_order, 0)";
716 $result = mysql_query($sql, $db);
719 //associate content and test
720 $sql = 'INSERT INTO ' . TABLE_PREFIX . 'content_tests_assoc' .
721 '(content_id, test_id) ' .
722 'VALUES (' . $items[$item_id]['real_content_id'] . ", $tid)";
723 $result = mysql_query($sql, $db);
725 if (!$msg->containsErrors()) {
726 $msg->addFeedback('IMPORT_SUCCEEDED');
731 /* get the a4a related xml */
732 if (isset($items[$item_id]['a4a_import_enabled']) && isset($items[$item_id]['a4a']) && !empty($items[$item_id]['a4a'])) {
733 $a4a_import = new A4aImport($items[$item_id]['real_content_id']);
734 $a4a_import->setRelativePath($items[$item_id]['new_path']);
735 $a4a_import->importA4a($items[$item_id]['a4a']);
739 if ($package_base_path == '.') {
740 $package_base_path = '';
743 // loop through the files outside the package folder, and copy them to its relative path
744 if (is_dir(AT_CONTENT_DIR . 'import/'.$_SESSION['course_id'].'/resources')) {
745 $handler = opendir(AT_CONTENT_DIR . 'import/'.$_SESSION['course_id'].'/resources');
746 while ($file = readdir($handler)){
747 $filename = AT_CONTENT_DIR . 'import/'.$_SESSION['course_id'].'/resources/'.$file;
748 if(is_file($filename)){
749 @rename($filename, AT_CONTENT_DIR .$_SESSION['course_id'].'/'.$package_base_name.'/'.$file);
754 if (rename(AT_CONTENT_DIR . 'import/'.$_SESSION['course_id'].'/'.$package_base_path, AT_CONTENT_DIR .$_SESSION['course_id'].'/'.$package_base_name) === false) {
755 if (!$msg->containsErrors()) {
756 $msg->addError('IMPORT_FAILED');
759 clr_dir(AT_CONTENT_DIR . 'import/'.$_SESSION['course_id']);
761 if (isset($_POST['url'])) {
762 @unlink($full_filename);
766 if ($_POST['s_cid']){
767 if (!$msg->containsErrors()) {
768 $msg->addFeedback('ACTION_COMPLETED_SUCCESSFULLY');
770 header('Location: ../../editor/edit_content.php?cid='.intval($_POST['cid']));
773 if (!$msg->containsErrors()) {
774 $msg->addFeedback('ACTION_COMPLETED_SUCCESSFULLY');
777 header('Location: '.AT_BASE_HREF.'tools/tile/index.php');
779 header('Location: ./index.php?cid='.intval($_POST['cid']));