/[drupal]/contributions/modules/quiz/includes/moodle_support.php
ViewVC logotype

Contents of /contributions/modules/quiz/includes/moodle_support.php

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.3 - (show annotations) (download) (as text)
Thu Aug 13 16:37:12 2009 UTC (3 months, 2 weeks ago) by sivaji
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +62 -8 lines
File MIME type: text/x-php
Merging GSoC code with HEAD.
1 <?php
2 /**
3 * Mimick Moodle environment so its code can function here in Drupal
4 */
5
6 global $CFG;
7 $CFG = new stdClass();
8 $CFG->dirroot = drupal_get_path('module', 'quiz') .'/includes/moodle';
9 $CFG->libdir = drupal_get_path('module', 'quiz') .'/includes/moodle/lib';
10 $CFG->dataroot = file_directory_path();
11 $CFG->directorypermissions = 0777;
12 $CFG->zip = '/usr/bin/zip'; // FIXME doesn't work on Windows
13
14
15
16 /** Converts the text format from the value to the 'internal'
17 * name or vice versa. $key can either be the value or the name
18 * and you get the other back.
19 *
20 * @param mixed int 0-4 or string one of 'moodle','html','plain','markdown'
21 * @return mixed as above but the other way around!
22 */
23 function text_format_name( $key ) {
24 $lookup = array();
25 $lookup[FORMAT_MOODLE] = 'moodle';
26 $lookup[FORMAT_HTML] = 'html';
27 $lookup[FORMAT_PLAIN] = 'plain';
28 $lookup[FORMAT_MARKDOWN] = 'markdown';
29 $lookup[FORMAT_LATEX] = 'latex'; // added by turadg 2009-05-26
30 $value = "error";
31 if (!is_numeric($key)) {
32 $key = strtolower( $key );
33 $value = array_search( $key, $lookup );
34 }
35 else {
36 if (isset( $lookup[$key] )) {
37 $value = $lookup[ $key ];
38 }
39 }
40 return $value;
41 }
42
43 /**#@+
44 * The core question types.
45 */
46 // from moodle/lib/questionlib.php
47 define("SHORTANSWER", "shortanswer");
48 define("TRUEFALSE", "truefalse");
49 define("MULTICHOICE", "multichoice");
50 define("RANDOM", "random");
51 define("MATCH", "match");
52 define("RANDOMSAMATCH", "randomsamatch");
53 define("DESCRIPTION", "description");
54 define("NUMERICAL", "numerical");
55 define("MULTIANSWER", "multianswer");
56 define("CALCULATED", "calculated");
57 define("ESSAY", "essay");
58 /**#@-*/
59
60 /**
61 * Moodle text formats from moodle/lib/weblib.php
62 * plus LaTeX format
63 */
64 define('FORMAT_MOODLE', 0); // Does all sorts of transformations and filtering
65 define('FORMAT_HTML', 1); // Plain HTML (with some tags stripped)
66 define('FORMAT_PLAIN', 2); // Plain text (even tags are printed in full)
67 define('FORMAT_WIKI', 3); // Wiki-formatted text @deprecated
68 define('FORMAT_MARKDOWN', 4); // Markdown-formatted text http://daringfireball.net/projects/markdown/
69 define('FORMAT_LATEX', 314);
70
71
72 /**
73 * Moodle localized string function from moodle/lib/moodlelib.php
74 * reimplemented hackedly for within the Drupal Quiz module
75 * e.g. get_string("wronggrade", "quiz", $nLineCounter).' '.get_string("fractionsnomax", "quiz", $maxfraction);
76 *
77 * @param string $identifier The key identifier for the localized string
78 * @param string $module The module where the key identifier is stored, usually expressed as the filename in the language pack without the .php on the end but can also be written as mod/forum or grade/export/xls. If none is specified then moodle.php is used.
79 * @param mixed $a An object, string or number that can be used
80 * within translation strings
81 * @param array $extralocations An array of strings with other locations to look for string files
82 * @return string The localized string.
83 */
84 function get_string($identifier, $module='', $a=NULL, $extralocations=NULL) {
85 assert($module=='quiz');
86
87 /// if $a happens to have % in it, double it so sprintf() doesn't break
88 if ($a) {
89 $a = clean_getstring_data( $a );
90 }
91
92 global $CFG;
93 $langfile = "$CFG->dirroot/lang/en_utf8/$module.php";
94 if (file_exists($langfile)) {
95 if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
96 if (eval($result) === FALSE) {
97 trigger_error('Lang error: '.$identifier.':'.$langfile, E_USER_NOTICE);
98 }
99 return $resultstring;
100 }
101 }
102
103 // last resort
104 return '[['. $identifier .']]';
105 }
106
107 /**
108 * This function is only used from {@link get_string()}.
109 *
110 * @internal Only used from get_string, not meant to be public API
111 * @param string $identifier ?
112 * @param string $langfile ?
113 * @param string $destination ?
114 * @return string|false ?
115 * @staticvar array $strings Localized strings
116 * @access private
117 * @todo Finish documenting this function.
118 */
119 // from moodle/lib/moodlelib.php
120 function get_string_from_file($identifier, $langfile, $destination) {
121
122 static $strings; // Keep the strings cached in memory.
123
124 if (empty($strings[$langfile])) {
125 $string = array();
126 include ($langfile);
127 $strings[$langfile] = $string;
128 } else {
129 $string = &$strings[$langfile];
130 }
131
132 if (!isset ($string[$identifier])) {
133 return false;
134 }
135
136 return $destination .'= sprintf("'. $string[$identifier] .'");';
137 }
138
139
140 /**
141 * make_unique_id_code
142 *
143 * @param string $extra ?
144 * @return string
145 * @todo Finish documenting this function
146 */
147 // from moodle/lib/moodlelib.php
148 function make_unique_id_code($extra='') {
149
150 $hostname = 'unknownhost';
151 if (!empty($_SERVER['HTTP_HOST'])) {
152 $hostname = $_SERVER['HTTP_HOST'];
153 } else if (!empty($_ENV['HTTP_HOST'])) {
154 $hostname = $_ENV['HTTP_HOST'];
155 } else if (!empty($_SERVER['SERVER_NAME'])) {
156 $hostname = $_SERVER['SERVER_NAME'];
157 } else if (!empty($_ENV['SERVER_NAME'])) {
158 $hostname = $_ENV['SERVER_NAME'];
159 }
160
161 $date = gmdate("ymdHis");
162
163 $random = random_string(6);
164
165 if ($extra) {
166 return $hostname .'+'. $date .'+'. $random .'+'. $extra;
167 } else {
168 return $hostname .'+'. $date .'+'. $random;
169 }
170 }
171
172 /**
173 * Generate and return a random string of the specified length.
174 *
175 * @param int $length The length of the string to be created.
176 * @return string
177 */
178 // from moodle/lib/moodlelib.php
179 function random_string ($length=15) {
180 $pool = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
181 $pool .= 'abcdefghijklmnopqrstuvwxyz';
182 $pool .= '0123456789';
183 $poollen = strlen($pool);
184 mt_srand ((double) microtime() * 1000000);
185 $string = '';
186 for ($i = 0; $i < $length; $i++) {
187 $string .= substr($pool, (mt_rand()%($poollen)), 1);
188 }
189 return $string;
190 }
191
192 /**
193 * Create a directory.
194 *
195 * @uses $CFG
196 * @param string $directory a string of directory names under $CFG->dataroot eg stuff/assignment/1
197 * param bool $shownotices If true then notification messages will be printed out on error.
198 * @return string|false Returns full path to directory if successful, false if not
199 */
200 // from moodle/lib/setuplib.php and gutted
201 function make_upload_directory($directory, $shownotices=true) {
202 global $CFG;
203 // just use Drupal's method for this
204 $dir = file_directory_path() ."/$directory"; // doesn't work?
205 if (file_exists($dir)) return $dir; // already there
206 $success = mkdir($dir, $CFG->directorypermissions, true);
207 if ($success)
208 return $dir;
209 else
210 return false;
211 }
212
213
214 /**
215 * Print out error message and stop outputting.
216 *
217 * @param string $message
218 */
219 // from moodle/lib/editorlib.php
220 function error($message) {
221 echo '<div style="text-align: center; font-weight: bold; color: red;">';
222 echo '<span style="color: black;">editorObject error:</span> ';
223 echo s($message, true);
224 echo '</div>';
225 exit;
226 }
227
228 /**
229 * Add quotes to HTML characters
230 *
231 * Returns $var with HTML characters (like "<", ">", etc.) properly quoted.
232 * This function is very similar to {@link p()}
233 *
234 * @param string $var the string potentially containing HTML characters
235 * @param boolean $strip to decide if we want to strip slashes or no. Default to false.
236 * true should be used to print data from forms and false for data from DB.
237 * @return string
238 */
239 // from moodle/lib/weblib.php
240 function s($var, $strip=false) {
241
242 if ($var == '0') { // for integer 0, boolean false, string '0'
243 return '0';
244 }
245
246 if ($strip) {
247 return preg_replace("/&amp;(#\d+);/i", "&$1;", htmlspecialchars(stripslashes_safe($var)));
248 } else {
249 return preg_replace("/&amp;(#\d+);/i", "&$1;", htmlspecialchars($var));
250 }
251 }
252
253 /**
254 * Moodle replacement for php stripslashes() function,
255 * works also for objects and arrays.
256 *
257 * The standard php stripslashes() removes ALL backslashes
258 * even from strings - so C:\temp becomes C:temp - this isn't good.
259 * This function should work as a fairly safe replacement
260 * to be called on quoted AND unquoted strings (to be sure)
261 *
262 * @param mixed something to remove unsafe slashes from
263 * @return mixed
264 */
265 // from moodle/lib/weblib.php, with magic_quotes_sybase check removed
266 function stripslashes_safe($mixed) {
267 // there is no need to remove slashes from int, float and bool types
268 if (empty($mixed)) {
269 //nothing to do...
270 } else if (is_string($mixed)) {
271 //the rest, simple and double quotes and backslashes
272 $mixed = str_replace("\\'", "'", $mixed);
273 $mixed = str_replace('\\"', '"', $mixed);
274 $mixed = str_replace('\\\\', '\\', $mixed);
275 } else if (is_array($mixed)) {
276 foreach ($mixed as $key => $value) {
277 $mixed[$key] = stripslashes_safe($value);
278 }
279 } else if (is_object($mixed)) {
280 $vars = get_object_vars($mixed);
281 foreach ($vars as $key => $value) {
282 $mixed->$key = stripslashes_safe($value);
283 }
284 }
285
286 return $mixed;
287 }
288
289 /**
290 * Print a bold message in an optional color.
291 *
292 * @param string $message The message to print out
293 * @param string $style Optional style to display message text in
294 * @param string $align Alignment option
295 * @param bool $return whether to return an output string or echo now
296 */
297 // from moodle/lib/weblib.php
298 function notify($message, $style='notifyproblem', $align='center', $return=false) {
299 if ($style == 'green') {
300 $style = 'notifysuccess'; // backward compatible with old color system
301 }
302
303 $message = clean_text($message);
304
305 $output = '<div class="'.$style.'" style="text-align:'. $align .'">'. $message .'</div>'."\n";
306
307 if ($return) {
308 return $output;
309 }
310 echo $output;
311 }
312
313 /**
314 * Given raw text (eg typed in by a user), this function cleans it up
315 * and removes any nasty tags that could mess up Moodle pages.
316 *
317 * @uses FORMAT_MOODLE
318 * @uses FORMAT_PLAIN
319 * @uses ALLOWED_TAGS
320 * @param string $text The text to be cleaned
321 * @param int $format Identifier of the text format to be used
322 * (FORMAT_MOODLE, FORMAT_HTML, FORMAT_PLAIN, FORMAT_WIKI, FORMAT_MARKDOWN)
323 * @return string The cleaned up text
324 */
325 // from moodle/lib/weblib.php
326 function clean_text($text, $format=FORMAT_MOODLE) {
327
328 global $ALLOWED_TAGS, $CFG;
329
330 if (empty($text) or is_numeric($text)) {
331 return (string)$text;
332 }
333
334 switch ($format) {
335 case FORMAT_PLAIN:
336 case FORMAT_MARKDOWN:
337 return $text;
338
339 default:
340
341 if (!empty($CFG->enablehtmlpurifier)) {
342 $text = purify_html($text);
343 } else {
344 /// Fix non standard entity notations
345 $text = preg_replace('/(&#[0-9]+)(;?)/', "\\1;", $text);
346 $text = preg_replace('/(&#x[0-9a-fA-F]+)(;?)/', "\\1;", $text);
347
348 /// Remove tags that are not allowed
349 $text = strip_tags($text, $ALLOWED_TAGS);
350
351 /// Clean up embedded scripts and , using kses
352 // $text = cleanAttributes($text); // FIXME too much work to port
353
354 /// Again remove tags that are not allowed
355 $text = strip_tags($text, $ALLOWED_TAGS);
356
357 }
358
359 /// Remove potential script events - some extra protection for undiscovered bugs in our code
360 $text = eregi_replace("([^a-z])language([[:space:]]*)=", "\\1Xlanguage=", $text);
361 $text = eregi_replace("([^a-z])on([a-z]+)([[:space:]]*)=", "\\1Xon\\2=", $text);
362
363 return $text;
364 }
365 }
366
367
368 /**
369 * Print an error page displaying an error message. New method - use this for new code.
370 *
371 * @uses $SESSION
372 * @uses $CFG
373 * @param string $errorcode The name of the string from error.php (or other specified file) to print
374 * @param string $link The url where the user will be prompted to continue. If no url is provided the user will be directed to the site index page.
375 * @param object $a Extra words and phrases that might be required in the error string
376 * @param array $extralocations An array of strings with other locations to look for string files
377 * @return does not return, terminates script
378 */
379 // from moodle/lib/weblib.php, and gutted
380 function print_error($errorcode, $module='error', $link='', $a=NULL, $extralocations=NULL) {
381 // use Drupal's stuff, good enough
382
383 $message = get_string($errorcode, $module, $a, $extralocations);
384
385 print "<h1>$message</h1>";
386
387 drupal_set_message("$errorcode $a", $type = 'error', $repeat = TRUE);
388 }
389
390 // from moodle/lib/weblib.php, totally hacked
391 function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL) {
392 return $text;
393 }
394
395
396 // from moodle/lib/questionlib.php
397 function question_has_capability_on($question, $cap, $cachecat = -1) {
398 // assume true for now
399 return true;
400 }
401
402 // from moodle/lib/moodlelib.php
403 function current_language() {
404 // FIXME use Drupal's language
405 return 'en_utf8';
406 }
407
408 // from moodle/lib/moodlelib.php
409 /**
410 * fix up the optional data in get_string()/print_string() etc
411 * ensure possible sprintf() format characters are escaped correctly
412 * needs to handle arbitrary strings and objects
413 * @param mixed $a An object, string or number that can be used
414 * @return mixed the supplied parameter 'cleaned'
415 */
416 function clean_getstring_data( $a ) {
417 if (is_string($a)) {
418 return str_replace( '%','%%',$a );
419 }
420 elseif (is_object($a)) {
421 $a_vars = get_object_vars( $a );
422 $new_a_vars = array();
423 foreach ($a_vars as $fname => $a_var) {
424 $new_a_vars[$fname] = clean_getstring_data( $a_var );
425 }
426 return (object)$new_a_vars;
427 }
428 else {
429 return $a;
430 }
431 }
432
433
434 // from moodle/lib/moodlelib.php
435 /**
436 * Zip an array of files/dirs to a destination zip file
437 * Both parameters must be FULL paths to the files/dirs
438 */
439 function zip_files ($originalfiles, $destination) {
440 global $CFG;
441
442 print "zipping files! originalfiles: ";
443 dprint_r($originalfiles);
444 print "destination: $destination\n";
445
446 //Extract everything from destination
447 $path_parts = pathinfo(cleardoubleslashes($destination));
448 $destpath = $path_parts["dirname"]; //The path of the zip file
449 $destfilename = $path_parts["basename"]; //The name of the zip file
450 $extension = $path_parts["extension"]; //The extension of the file
451
452 foreach ($originalfiles as $file) { //Iterate over each file
453 //Check for every file
454 $tempfile = cleardoubleslashes($file); // no doubleslashes!
455 //Calculate the base path for all files if it isn't set
456 if ($origpath === NULL) {
457 $origpath = rtrim(cleardoubleslashes(dirname($tempfile)), "/");
458 }
459 //See if the file is readable
460 if (!is_readable($tempfile)) { //Is readable
461 continue;
462 }
463 //See if the file/dir is in the same directory than the rest
464 if (rtrim(cleardoubleslashes(dirname($tempfile)), "/") != $origpath) {
465 continue;
466 }
467 //Add the file to the array
468 $files[] = $tempfile;
469 }
470
471 if (class_exists('ZipArchive')) {
472 $zip = new ZipArchive();
473 $filename = $destination;// correct?
474
475 if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
476 exit("cannot open <$filename>\n");
477 }
478
479 foreach ($files as $file) {
480 $nameInZip = basename($originalFile);
481 $zip->addFile($originalFile, $nameInZip);
482 }
483 echo "numfiles: " . $zip->numFiles . "\n";
484 echo "status:" . $zip->status . "\n";
485 $zip->close();
486 } else if (function_exists('gzopen')) {
487 require_once("$CFG->libdir/pclzip/pclzip.lib.php");
488 //rewrite filenames because the old method with PCLZIP_OPT_REMOVE_PATH does not work under win32
489 $zipfiles = array();
490 $start = strlen($origpath)+1;
491 foreach ($files as $file) {
492 $tf = array();
493 $tf[PCLZIP_ATT_FILE_NAME] = $file;
494 $tf[PCLZIP_ATT_FILE_NEW_FULL_NAME] = substr($file, $start);
495 $zipfiles[] = $tf;
496 }
497 //create the archive
498 $archive = new PclZip(cleardoubleslashes("$destpath/$destfilename"));
499 if (($list = $archive->create($zipfiles) == 0)) {
500 notice($archive->errorInfo(true));
501 return false;
502 }
503 } else {
504 print "final else";
505 $filestozip = "";
506 foreach ($files as $filetozip) {
507 $filestozip .= escapeshellarg(basename($filetozip));
508 $filestozip .= " ";
509 }
510 //Construct the command
511 $separator = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? ' &' : ' ;';
512 $command = 'cd '.escapeshellarg($origpath).$separator.
513 escapeshellarg($CFG->zip).' -r '.
514 // TODO had to hack this... bug in Moodle?
515 escapeshellarg(cleardoubleslashes("$destfilename")).' '.$filestozip;
516 //All converted to backslashes in WIN
517 if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
518 $command = str_replace('/','\\',$command);
519 }
520 // print "$command";exit;
521 Exec($command);
522 }
523 }
524
525
526 // from moodle/lib/moodlelib.php
527 /**
528 * Replace 1 or more slashes or backslashes to 1 slash
529 */
530 function cleardoubleslashes ($path) {
531 return preg_replace('/(\/|\\\){1,}/','/',$path);
532 }
533
534 // from moodle/lib/moodlelib.php
535 /**
536 * Delete directory or only it's content
537 * @param string $dir directory path
538 * @param bool $content_only
539 * @return bool success, true also if dir does not exist
540 */
541 function remove_dir($dir, $content_only=false) {
542 if (!file_exists($dir)) {
543 // nothing to do
544 return true;
545 }
546 $handle = opendir($dir);
547 $result = true;
548 while (false!==($item = readdir($handle))) {
549 if($item != '.' && $item != '..') {
550 if(is_dir($dir.'/'.$item)) {
551 $result = remove_dir($dir.'/'.$item) && $result;
552 }else{
553 $result = unlink($dir.'/'.$item) && $result;
554 }
555 }
556 }
557 closedir($handle);
558 if ($content_only) {
559 return $result;
560 }
561 return rmdir($dir); // if anything left the result will be false, noo need for && $result
562 }
563
564
565 /*******************************************
566 * Here down is fake questionlib.php
567 *
568 */
569
570 // fake the questionlib because loading that whole thing won't work
571 // module_load_include('php', 'quiz', "includes/moodle/lib/questionlib");
572 global $QTYPES;
573 module_load_include('php', 'quiz', "includes/moodle/question/format");
574
575 /**#@+
576 * The core question types.
577 */
578 define("SHORTANSWER", "shortanswer");
579 define("TRUEFALSE", "truefalse");
580 define("MULTICHOICE", "multichoice");
581 define("RANDOM", "random");
582 define("MATCH", "match");
583 define("RANDOMSAMATCH", "randomsamatch");
584 define("DESCRIPTION", "description");
585 define("NUMERICAL", "numerical");
586 define("MULTIANSWER", "multianswer");
587 define("CALCULATED", "calculated");
588 define("ESSAY", "essay");
589 /**#@-*/
590
591 $QTYPES[CALCULATED] = new stdClass();
592

  ViewVC Help
Powered by ViewVC 1.1.2