made a copy
[atutor.git] / tools / imscc / ims_export.php
1 <?php
2 /****************************************************************/
3 /* ATutor                                                                                                               */
4 /****************************************************************/
5 /* Copyright (c) 2002-2008 by Greg Gay & Joel Kronenberg        */
6 /* Adaptive Technology Resource Centre / University of Toronto  */
7 /* http://atutor.ca                                                                                             */
8 /*                                                              */
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 /****************************************************************/
13 // $Id: ims_export.php 8211 2008-11-11 22:55:40Z hwong $
14 define('AT_INCLUDE_PATH', '../../include/');
15 require(AT_INCLUDE_PATH.'classes/testQuestions.class.php');
16 require(AT_INCLUDE_PATH.'classes/A4a/A4aExport.class.php');
17
18 /* content id of an optional chapter */
19 $cid = isset($_REQUEST['cid']) ? intval($_REQUEST['cid']) : 0;
20 $c   = isset($_REQUEST['c'])   ? intval($_REQUEST['c'])   : 0;
21
22 if (isset($_REQUEST['to_tile']) && !isset($_POST['cancel'])) {
23         /* for TILE */
24
25         /* redirect to TILE import servlet */
26
27         require(AT_INCLUDE_PATH.'vitals.inc.php');
28         if (!authenticate(AT_PRIV_ADMIN, AT_PRIV_RETURN)) {
29                 /* user can't be authenticated */
30                 header('HTTP/1.1 404 Not Found');
31                 echo 'Document not found.';
32                 exit;
33         }
34
35         $m = md5(DB_PASSWORD . 'x' . ADMIN_PASSWORD . 'x' . $_SERVER['SERVER_ADDR'] . 'x' . $cid . 'x' . $_SESSION['course_id'] . 'x' . date('Ymd'));
36
37         header('Location: '.AT_TILE_IMPORT. '?cp='.urlencode(AT_BASE_HREF. 'tools/imscc/ims_export.php?cid='.$cid.'&c='.$_SESSION['course_id'].'&m='.$m));
38         exit;
39 } else if (isset($_GET['m'])) {
40         /* for TILE */
41
42         /* request (hopefully) coming from a TILE server, send the content package */
43
44         $_user_location = 'public';
45         require(AT_INCLUDE_PATH.'vitals.inc.php');
46         $m = md5(DB_PASSWORD . 'x' . ADMIN_PASSWORD . 'x' . $_SERVER['SERVER_ADDR'] . 'x' . $cid . 'x' . $c . 'x' . date('Ymd'));
47         if (($m != $_GET['m']) || !$c) {
48                 header('HTTP/1.1 404 Not Found');
49                 echo 'Document not found.';
50                 exit;
51         }
52         
53         $course_id = $c;
54 } else {
55         $use_a4a = false;
56         if (isset($_REQUEST['to_a4a'])){
57                 $use_a4a = true;
58         } 
59         require(AT_INCLUDE_PATH.'vitals.inc.php');
60         $course_id = $_SESSION['course_id'];
61 }
62
63 $use_cc                  = true;
64 $instructor_id   = $system_courses[$course_id]['member_id'];
65 $course_desc     = $system_courses[$course_id]['description'];
66 $course_title    = $system_courses[$course_id]['title'];
67 $course_language = $system_courses[$course_id]['primary_language'];
68
69 $courseLanguage =& $languageManager->getLanguage($course_language);
70 //If course language cannot be found, use UTF-8 English
71 //@author harris, Oct 30,2008
72 if ($courseLanguage == null){
73         $courseLanguage =& $languageManager->getLanguage('en');
74 }
75
76 $course_language_charset = $courseLanguage->getCharacterSet();
77 $course_language_code = $courseLanguage->getCode();
78
79 require(AT_INCLUDE_PATH.'classes/zipfile.class.php');                           /* for zipfile */
80 require(AT_INCLUDE_PATH.'classes/vcard.php');                                           /* for vcard */
81 require(AT_INCLUDE_PATH.'classes/XML/XML_HTMLSax/XML_HTMLSax.php');     /* for XML_HTMLSax */
82 require(AT_INCLUDE_PATH.'imscc/ims_template.inc.php');                          /* for ims templates + print_organizations() */
83
84 if (isset($_POST['cancel'])) {
85         $msg->addFeedback('EXPORT_CANCELLED');
86         header('Location: ../index.php');
87         exit;
88 }
89
90
91 $zipfile = new zipfile(); 
92 $zipfile->create_dir('resources/');
93 $zipfile->create_dir('GlossaryItem/');
94
95 /*
96         the following resources are to be identified:
97         even if some of these can't be images, they can still be files in the content dir.
98         theoretically the only urls we wouldn't deal with would be for a <!DOCTYPE and <form>
99
100         img             => src
101         a               => href                         // ignore if href doesn't exist (ie. <a name>)
102         object  => data | classid       // probably only want data
103         applet  => classid | archive                    // whatever these two are should double check to see if it's a valid file (not a dir)
104         link    => href
105         script  => src
106         form    => action
107         input   => src
108         iframe  => src
109
110 */
111 class MyHandler {
112     function MyHandler(){}
113     function openHandler(& $parser,$name,$attrs) {
114                 global $my_files;
115
116                 $name = strtolower($name);
117                 $attrs = array_change_key_case($attrs, CASE_LOWER);
118
119                 $elements = array(      'img'           => 'src',
120                                                         'a'                     => 'href',                              
121                                                         'object'        => array('data', 'classid'),
122                                                         'applet'        => array('classid', 'archive'),
123                                                         'link'          => 'href',
124                                                         'script'        => 'src',
125                                                         'form'          => 'action',
126                                                         'input'         => 'src',
127                                                         'iframe'        => 'src',
128                                                         'embed'         => 'src',
129                                                         'param'         => 'value');
130         
131                 /* check if this attribute specifies the files in different ways: (ie. java) */
132                 if (is_array($elements[$name])) {
133                         $items = $elements[$name];
134
135                         foreach ($items as $item) {
136                                 if ($attrs[$item] != '') {
137
138                                         /* some attributes allow a listing of files to include seperated by commas (ie. applet->archive). */
139                                         if (strpos($attrs[$item], ',') !== false) {
140                                                 $files = explode(',', $attrs[$item]);
141                                                 foreach ($files as $file) {
142                                                         $my_files[] = trim($file);
143                                                 }
144                                         } else {
145                                                 $my_files[] = $attrs[$item];
146                                         }
147                                 }
148                         }
149                 } else if (isset($elements[$name]) && ($attrs[$elements[$name]] != '')) {
150                         /* we know exactly which attribute contains the reference to the file. */
151                         $my_files[] = $attrs[$elements[$name]];
152                 }
153     }
154     function closeHandler(& $parser,$name) { }
155 }
156
157 /* get all the content */
158 $content = array();
159 $paths   = array();
160 $top_content_parent_id = 0;
161
162 $handler=new MyHandler();
163 $parser =& new XML_HTMLSax();
164 $parser->set_object($handler);
165 $parser->set_element_handler('openHandler','closeHandler');
166
167 if (authenticate(AT_PRIV_CONTENT, AT_PRIV_RETURN)) {
168         $sql = "SELECT *, UNIX_TIMESTAMP(last_modified) AS u_ts FROM ".TABLE_PREFIX."content WHERE course_id=$course_id ORDER BY content_parent_id, ordering";
169 } else {
170         $sql = "SELECT *, UNIX_TIMESTAMP(last_modified) AS u_ts FROM ".TABLE_PREFIX."content WHERE course_id=$course_id ORDER BY content_parent_id, ordering";
171 }
172 $result = mysql_query($sql, $db);
173 while ($row = mysql_fetch_assoc($result)) {
174         if (authenticate(AT_PRIV_CONTENT, AT_PRIV_RETURN) || $contentManager->isReleased($row['content_id']) === TRUE) {
175                 $content[$row['content_parent_id']][] = $row;
176                 if ($cid == $row['content_id']) {
177                         $top_content = $row;
178                         $top_content_parent_id = $row['content_parent_id'];
179                 }
180         }
181 }
182
183 if ($cid) {
184         /* filter out the top level sections that we don't want */
185         $top_level = $content[$top_content_parent_id];
186         foreach($top_level as $page) {
187                 if ($page['content_id'] == $cid) {
188                         $content[$top_content_parent_id] = array($page);
189                 } else {
190                         /* this is a page we don't want, so might as well remove it's children too */
191                         unset($content[$page['content_id']]);
192                 }
193         }
194         $ims_course_title = $course_title . ' - ' . $content[$top_content_parent_id][0]['title'];
195 } else {
196         $ims_course_title = $course_title;
197 }
198
199 $imsmanifest_xml = str_replace(array('{COURSE_TITLE}', '{COURSE_DESCRIPTION}', '{COURSE_PRIMARY_LANGUAGE_CHARSET}', '{COURSE_PRIMARY_LANGUAGE_CODE}'), 
200                                                           array($ims_course_title, $course_desc, $course_language_charset, $course_language_code),
201                                                           $ims_template_xml['header']);
202 //debug($imsmanifest_xml);
203 //exit;
204
205 /* get the first content page to default the body frame to */
206 $first = $content[$top_content_parent_id][0];
207
208 $test_ids = array();    //global array to store all the test ids
209
210 /* generate the resources and save the HTML files */
211 $used_glossary_terms = array();
212 ob_start();
213 print_organizations($top_content_parent_id, $content, 0, '', array(), $toc_html);
214 $organizations_str = ob_get_contents();
215 ob_end_clean();
216
217 if (count($used_glossary_terms)) {
218         $used_glossary_terms = array_unique($used_glossary_terms);
219         sort($used_glossary_terms);
220         reset($used_glossary_terms);
221
222         $terms_xml = '';
223         foreach ($used_glossary_terms as $term) {
224                 $term_key = urlencode($term);
225                 $glossary[$term_key] = htmlentities($glossary[$term_key], ENT_QUOTES, 'UTF-8');
226                 $glossary[$term_key] = str_replace('&', '&amp;', $glossary[$term_key]);
227                 $terms_xml .= str_replace(      array('{TERM}', '{DEFINITION}'),
228                                                                         array($escaped_term, $glossary[$term_key]),
229                                                                         $glossary_term_xml);
230         }
231
232         $glossary_xml = str_replace(array('{GLOSSARY_TERMS}', '{COURSE_PRIMARY_LANGUAGE_CHARSET}'),
233                                                             array($terms_xml, $course_language_charset),
234                                                                 $glossary_xml);
235         //add to resource
236         $resources .= $ims_template_xml['resource_glossary'];
237 } else {
238         unset($glossary_xml);
239 }
240
241 /* append the Organizations and Resources to the imsmanifest */
242 $imsmanifest_xml .= str_replace(        array('{ORGANIZATIONS}', '{GLOSSARY}',  '{RESOURCES}', '{TEST_ITEMS}', '{COURSE_TITLE}'),
243                                                                         array($organizations_str, $ims_template_xml['glossary'],        $resources, $test_xml_items, $ims_course_title),
244                                                                         $ims_template_xml['final']);
245
246 /* generate the vcard for the instructor/author */
247 $sql = "SELECT first_name, last_name, email, website, login, phone FROM ".TABLE_PREFIX."members WHERE member_id=$instructor_id";
248 $result = mysql_query($sql, $db);
249 $vcard = new vCard();
250 if ($row = mysql_fetch_assoc($result)) {
251         $vcard->setName($row['last_name'], $row['first_name'], $row['login']);
252         $vcard->setEmail($row['email']);
253         $vcard->setNote('Originated from an ATutor at '.AT_BASE_HREF.'. See ATutor.ca for additional information.');
254         $vcard->setURL($row['website']);
255
256         $imsmanifest_xml = str_replace('{VCARD}', $vcard->getVCard(), $imsmanifest_xml);
257 } else {
258         $imsmanifest_xml = str_replace('{VCARD}', '', $imsmanifest_xml);
259 }
260
261 /* save the imsmanifest.xml file */
262 $zipfile->add_file($imsmanifest_xml, 'imsmanifest.xml');
263
264 if ($glossary_xml) {
265         $zipfile->add_file($glossary_xml,  'GlossaryItem/glossary.xml');
266 }
267 $zipfile->close(); // this is optional, since send_file() closes it anyway
268
269 $ims_course_title = str_replace(array(' ', ':'), '_', $ims_course_title);
270 /**
271  * A problem here with the preg_replace below.
272  * Originally was designed to remove all werid symbols to avoid file corruptions.
273  * In UTF-8, all non-english chars are considered to be 'werid symbols'
274  * We can still replace it as is, or add fileid to the filename to avoid these problems
275  * Well then again people won't be able to tell what this file is about
276  * If we are going to take out the preg_replace, some OS might not be able to understand
277  * these characters and will have problems importing.
278  */
279 $ims_course_title = preg_replace("{[^a-zA-Z0-9._-]}","", trim($ims_course_title));
280 $zipfile->send_file($ims_course_title . '_imscc');
281
282 exit;
283 ?>