[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
1 <?php 2 3 // This file is part of Moodle - http://moodle.org/ 4 // 5 // Moodle is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // Moodle is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 17 18 /** 19 * format.php - Default format class for file imports/exports. Doesn't do 20 * everything on it's own -- it needs to be extended. 21 * 22 * Included by import.ph 23 * 24 * @package mod_lesson 25 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} 26 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 27 **/ 28 29 defined('MOODLE_INTERNAL') || die(); 30 31 /** 32 * Import files embedded into answer or response 33 * 34 * @param string $field nfield name (answer or response) 35 * @param array $data imported data 36 * @param object $answer answer object 37 * @param int $contextid 38 **/ 39 function lesson_import_question_files($field, $data, $answer, $contextid) { 40 global $DB; 41 if (!isset($data['itemid'])) { 42 return; 43 } 44 $text = file_save_draft_area_files($data['itemid'], 45 $contextid, 'mod_lesson', 'page_' . $field . 's', $answer->id, 46 array('subdirs' => false, 'maxfiles' => -1, 'maxbytes' => 0), 47 $answer->$field); 48 49 $DB->set_field("lesson_answers", $field, $text, array("id" => $answer->id)); 50 } 51 52 /** 53 * Given some question info and some data about the the answers 54 * this function parses, organises and saves the question 55 * 56 * This is only used when IMPORTING questions and is only called 57 * from format.php 58 * Lifted from mod/quiz/lib.php - 59 * 1. all reference to oldanswers removed 60 * 2. all reference to quiz_multichoice table removed 61 * 3. In shortanswer questions usecase is store in the qoption field 62 * 4. In numeric questions store the range as two answers 63 * 5. truefalse options are ignored 64 * 6. For multichoice questions with more than one answer the qoption field is true 65 * 66 * @param object $question Contains question data like question, type and answers. 67 * @param object $lesson 68 * @param int $contextid 69 * @return object Returns $result->error or $result->notice. 70 **/ 71 function lesson_save_question_options($question, $lesson, $contextid) { 72 global $DB; 73 74 // These lines are required to ensure that all page types have 75 // been loaded for the following switch 76 if (!($lesson instanceof lesson)) { 77 $lesson = new lesson($lesson); 78 } 79 $manager = lesson_page_type_manager::get($lesson); 80 81 $timenow = time(); 82 $result = new stdClass(); 83 switch ($question->qtype) { 84 case LESSON_PAGE_SHORTANSWER: 85 86 $answers = array(); 87 $maxfraction = -1; 88 89 // Insert all the new answers 90 foreach ($question->answer as $key => $dataanswer) { 91 if ($dataanswer != "") { 92 $answer = new stdClass; 93 $answer->lessonid = $question->lessonid; 94 $answer->pageid = $question->id; 95 if ($question->fraction[$key] >=0.5) { 96 $answer->jumpto = LESSON_NEXTPAGE; 97 } 98 $answer->timecreated = $timenow; 99 $answer->grade = $question->fraction[$key] * 100; 100 $answer->answer = $dataanswer; 101 $answer->response = $question->feedback[$key]['text']; 102 $answer->responseformat = $question->feedback[$key]['format']; 103 $answer->id = $DB->insert_record("lesson_answers", $answer); 104 lesson_import_question_files('response', $question->feedback[$key], $answer, $contextid); 105 $answers[] = $answer->id; 106 if ($question->fraction[$key] > $maxfraction) { 107 $maxfraction = $question->fraction[$key]; 108 } 109 } 110 } 111 112 113 /// Perform sanity checks on fractional grades 114 if ($maxfraction != 1) { 115 $maxfraction = $maxfraction * 100; 116 $result->notice = get_string("fractionsnomax", "lesson", $maxfraction); 117 return $result; 118 } 119 break; 120 121 case LESSON_PAGE_NUMERICAL: // Note similarities to shortanswer. 122 123 $answers = array(); 124 $maxfraction = -1; 125 126 127 // for each answer store the pair of min and max values even if they are the same 128 foreach ($question->answer as $key => $dataanswer) { 129 if ($dataanswer != "") { 130 $answer = new stdClass; 131 $answer->lessonid = $question->lessonid; 132 $answer->pageid = $question->id; 133 $answer->jumpto = LESSON_NEXTPAGE; 134 $answer->timecreated = $timenow; 135 $answer->grade = $question->fraction[$key] * 100; 136 $min = $question->answer[$key] - $question->tolerance[$key]; 137 $max = $question->answer[$key] + $question->tolerance[$key]; 138 $answer->answer = $min.":".$max; 139 // $answer->answer = $question->min[$key].":".$question->max[$key]; original line for min/max 140 $answer->response = $question->feedback[$key]['text']; 141 $answer->responseformat = $question->feedback[$key]['format']; 142 $answer->id = $DB->insert_record("lesson_answers", $answer); 143 lesson_import_question_files('response', $question->feedback[$key], $answer, $contextid); 144 145 $answers[] = $answer->id; 146 if ($question->fraction[$key] > $maxfraction) { 147 $maxfraction = $question->fraction[$key]; 148 } 149 } 150 } 151 152 /// Perform sanity checks on fractional grades 153 if ($maxfraction != 1) { 154 $maxfraction = $maxfraction * 100; 155 $result->notice = get_string("fractionsnomax", "lesson", $maxfraction); 156 return $result; 157 } 158 break; 159 160 161 case LESSON_PAGE_TRUEFALSE: 162 163 // the truth 164 $answer = new stdClass(); 165 $answer->lessonid = $question->lessonid; 166 $answer->pageid = $question->id; 167 $answer->timecreated = $timenow; 168 $answer->answer = get_string("true", "lesson"); 169 $answer->grade = $question->correctanswer * 100; 170 if ($answer->grade > 50 ) { 171 $answer->jumpto = LESSON_NEXTPAGE; 172 } 173 if (isset($question->feedbacktrue)) { 174 $answer->response = $question->feedbacktrue['text']; 175 $answer->responseformat = $question->feedbacktrue['format']; 176 } 177 $answer->id = $DB->insert_record("lesson_answers", $answer); 178 lesson_import_question_files('response', $question->feedbacktrue, $answer, $contextid); 179 180 // the lie 181 $answer = new stdClass; 182 $answer->lessonid = $question->lessonid; 183 $answer->pageid = $question->id; 184 $answer->timecreated = $timenow; 185 $answer->answer = get_string("false", "lesson"); 186 $answer->grade = (1 - (int)$question->correctanswer) * 100; 187 if ($answer->grade > 50 ) { 188 $answer->jumpto = LESSON_NEXTPAGE; 189 } 190 if (isset($question->feedbackfalse)) { 191 $answer->response = $question->feedbackfalse['text']; 192 $answer->responseformat = $question->feedbackfalse['format']; 193 } 194 $answer->id = $DB->insert_record("lesson_answers", $answer); 195 lesson_import_question_files('response', $question->feedbackfalse, $answer, $contextid); 196 197 break; 198 199 case LESSON_PAGE_MULTICHOICE: 200 201 $totalfraction = 0; 202 $maxfraction = -1; 203 204 $answers = array(); 205 206 // Insert all the new answers 207 foreach ($question->answer as $key => $dataanswer) { 208 if ($dataanswer != "") { 209 $answer = new stdClass; 210 $answer->lessonid = $question->lessonid; 211 $answer->pageid = $question->id; 212 $answer->timecreated = $timenow; 213 $answer->grade = $question->fraction[$key] * 100; 214 // changed some defaults 215 /* Original Code 216 if ($answer->grade > 50 ) { 217 $answer->jumpto = LESSON_NEXTPAGE; 218 } 219 Replaced with: */ 220 if ($answer->grade > 50 ) { 221 $answer->jumpto = LESSON_NEXTPAGE; 222 $answer->score = 1; 223 } 224 // end Replace 225 $answer->answer = $dataanswer['text']; 226 $answer->answerformat = $dataanswer['format']; 227 $answer->response = $question->feedback[$key]['text']; 228 $answer->responseformat = $question->feedback[$key]['format']; 229 $answer->id = $DB->insert_record("lesson_answers", $answer); 230 lesson_import_question_files('answer', $dataanswer, $answer, $contextid); 231 lesson_import_question_files('response', $question->feedback[$key], $answer, $contextid); 232 233 // for Sanity checks 234 if ($question->fraction[$key] > 0) { 235 $totalfraction += $question->fraction[$key]; 236 } 237 if ($question->fraction[$key] > $maxfraction) { 238 $maxfraction = $question->fraction[$key]; 239 } 240 } 241 } 242 243 /// Perform sanity checks on fractional grades 244 if ($question->single) { 245 if ($maxfraction != 1) { 246 $maxfraction = $maxfraction * 100; 247 $result->notice = get_string("fractionsnomax", "lesson", $maxfraction); 248 return $result; 249 } 250 } else { 251 $totalfraction = round($totalfraction,2); 252 if ($totalfraction != 1) { 253 $totalfraction = $totalfraction * 100; 254 $result->notice = get_string("fractionsaddwrong", "lesson", $totalfraction); 255 return $result; 256 } 257 } 258 break; 259 260 case LESSON_PAGE_MATCHING: 261 262 $subquestions = array(); 263 264 $defaultanswer = new stdClass; 265 $defaultanswer->lessonid = $question->lessonid; 266 $defaultanswer->pageid = $question->id; 267 $defaultanswer->timecreated = $timenow; 268 $defaultanswer->grade = 0; 269 270 // The first answer should always be the correct answer 271 $correctanswer = clone($defaultanswer); 272 $correctanswer->answer = get_string('thatsthecorrectanswer', 'lesson'); 273 $correctanswer->jumpto = LESSON_NEXTPAGE; 274 $DB->insert_record("lesson_answers", $correctanswer); 275 276 // The second answer should always be the wrong answer 277 $wronganswer = clone($defaultanswer); 278 $wronganswer->answer = get_string('thatsthewronganswer', 'lesson'); 279 $DB->insert_record("lesson_answers", $wronganswer); 280 281 $i = 0; 282 // Insert all the new question+answer pairs 283 foreach ($question->subquestions as $key => $questiontext) { 284 $answertext = $question->subanswers[$key]; 285 if (!empty($questiontext) and !empty($answertext)) { 286 $answer = clone($defaultanswer); 287 $answer->answer = $questiontext['text']; 288 $answer->answerformat = $questiontext['format']; 289 $answer->response = $answertext; 290 if ($i == 0) { 291 // first answer contains the correct answer jump 292 $answer->jumpto = LESSON_NEXTPAGE; 293 } 294 $answer->id = $DB->insert_record("lesson_answers", $answer); 295 lesson_import_question_files('answer', $questiontext, $answer, $contextid); 296 $subquestions[] = $answer->id; 297 $i++; 298 } 299 } 300 301 if (count($subquestions) < 3) { 302 $result->notice = get_string("notenoughsubquestions", "lesson"); 303 return $result; 304 } 305 break; 306 default: 307 $result->error = "Unsupported question type ($question->qtype)!"; 308 return $result; 309 } 310 return true; 311 } 312 313 314 class qformat_default { 315 316 var $displayerrors = true; 317 var $category = null; 318 var $questionids = array(); 319 protected $importcontext = null; 320 var $qtypeconvert = array('numerical' => LESSON_PAGE_NUMERICAL, 321 'multichoice' => LESSON_PAGE_MULTICHOICE, 322 'truefalse' => LESSON_PAGE_TRUEFALSE, 323 'shortanswer' => LESSON_PAGE_SHORTANSWER, 324 'match' => LESSON_PAGE_MATCHING 325 ); 326 327 // Importing functions 328 function provide_import() { 329 return false; 330 } 331 332 function set_importcontext($context) { 333 $this->importcontext = $context; 334 } 335 336 /** 337 * Handle parsing error 338 * 339 * @param string $message information about error 340 * @param string $text imported text that triggered the error 341 * @param string $questionname imported question name 342 */ 343 protected function error($message, $text='', $questionname='') { 344 $importerrorquestion = get_string('importerrorquestion', 'question'); 345 346 echo "<div class=\"importerror\">\n"; 347 echo "<strong>$importerrorquestion $questionname</strong>"; 348 if (!empty($text)) { 349 $text = s($text); 350 echo "<blockquote>$text</blockquote>\n"; 351 } 352 echo "<strong>$message</strong>\n"; 353 echo "</div>"; 354 } 355 356 function importpreprocess() { 357 // Does any pre-processing that may be desired 358 return true; 359 } 360 361 function importprocess($filename, $lesson, $pageid) { 362 global $DB, $OUTPUT; 363 364 /// Processes a given file. There's probably little need to change this 365 $timenow = time(); 366 367 if (! $lines = $this->readdata($filename)) { 368 echo $OUTPUT->notification("File could not be read, or was empty"); 369 return false; 370 } 371 372 if (! $questions = $this->readquestions($lines)) { // Extract all the questions 373 echo $OUTPUT->notification("There are no questions in this file!"); 374 return false; 375 } 376 377 //Avoid category as question type 378 echo $OUTPUT->notification(get_string('importcount', 'lesson', 379 $this->count_questions($questions)), 'notifysuccess'); 380 381 $count = 0; 382 $addquestionontop = false; 383 if ($pageid == 0) { 384 $addquestionontop = true; 385 $updatelessonpage = $DB->get_record('lesson_pages', array('lessonid' => $lesson->id, 'prevpageid' => 0)); 386 } else { 387 $updatelessonpage = $DB->get_record('lesson_pages', array('lessonid' => $lesson->id, 'id' => $pageid)); 388 } 389 390 $unsupportedquestions = 0; 391 392 foreach ($questions as $question) { // Process and store each question 393 switch ($question->qtype) { 394 //TODO: Bad way to bypass category in data... Quickfix for MDL-27964 395 case 'category': 396 break; 397 // the good ones 398 case 'shortanswer' : 399 case 'numerical' : 400 case 'truefalse' : 401 case 'multichoice' : 402 case 'match' : 403 $count++; 404 405 //Show nice formated question in one line. 406 echo "<hr><p><b>$count</b>. ".$this->format_question_text($question)."</p>"; 407 408 $newpage = new stdClass; 409 $newpage->lessonid = $lesson->id; 410 $newpage->qtype = $this->qtypeconvert[$question->qtype]; 411 switch ($question->qtype) { 412 case 'shortanswer' : 413 if (isset($question->usecase)) { 414 $newpage->qoption = $question->usecase; 415 } 416 break; 417 case 'multichoice' : 418 if (isset($question->single)) { 419 $newpage->qoption = !$question->single; 420 } 421 break; 422 } 423 $newpage->timecreated = $timenow; 424 if ($question->name != $question->questiontext) { 425 $newpage->title = $question->name; 426 } else { 427 $newpage->title = "Page $count"; 428 } 429 $newpage->contents = $question->questiontext; 430 $newpage->contentsformat = isset($question->questionformat) ? $question->questionformat : FORMAT_HTML; 431 432 // set up page links 433 if ($pageid) { 434 // the new page follows on from this page 435 if (!$page = $DB->get_record("lesson_pages", array("id" => $pageid))) { 436 print_error('invalidpageid', 'lesson'); 437 } 438 $newpage->prevpageid = $pageid; 439 $newpage->nextpageid = $page->nextpageid; 440 // insert the page and reset $pageid 441 $newpageid = $DB->insert_record("lesson_pages", $newpage); 442 // update the linked list 443 $DB->set_field("lesson_pages", "nextpageid", $newpageid, array("id" => $pageid)); 444 } else { 445 // new page is the first page 446 // get the existing (first) page (if any) 447 $params = array ("lessonid" => $lesson->id, "prevpageid" => 0); 448 if (!$page = $DB->get_record_select("lesson_pages", "lessonid = :lessonid AND prevpageid = :prevpageid", $params)) { 449 // there are no existing pages 450 $newpage->prevpageid = 0; // this is a first page 451 $newpage->nextpageid = 0; // this is the only page 452 $newpageid = $DB->insert_record("lesson_pages", $newpage); 453 } else { 454 // there are existing pages put this at the start 455 $newpage->prevpageid = 0; // this is a first page 456 $newpage->nextpageid = $page->id; 457 $newpageid = $DB->insert_record("lesson_pages", $newpage); 458 // update the linked list 459 $DB->set_field("lesson_pages", "prevpageid", $newpageid, array("id" => $page->id)); 460 } 461 } 462 463 // reset $pageid and put the page ID in $question, used in save_question_option() 464 $pageid = $newpageid; 465 $question->id = $newpageid; 466 467 $this->questionids[] = $question->id; 468 469 // Import images in question text. 470 if (isset($question->questiontextitemid)) { 471 $questiontext = file_save_draft_area_files($question->questiontextitemid, 472 $this->importcontext->id, 'mod_lesson', 'page_contents', $newpageid, 473 null , $question->questiontext); 474 // Update content with recoded urls. 475 $DB->set_field("lesson_pages", "contents", $questiontext, array("id" => $newpageid)); 476 } 477 478 // Now to save all the answers and type-specific options 479 480 $question->lessonid = $lesson->id; // needed for foreign key 481 $question->qtype = $this->qtypeconvert[$question->qtype]; 482 $result = lesson_save_question_options($question, $lesson, $this->importcontext->id); 483 484 if (!empty($result->error)) { 485 echo $OUTPUT->notification($result->error); 486 return false; 487 } 488 489 if (!empty($result->notice)) { 490 echo $OUTPUT->notification($result->notice); 491 return true; 492 } 493 break; 494 // the Bad ones 495 default : 496 $unsupportedquestions++; 497 break; 498 } 499 } 500 // Update the prev links if there were existing pages. 501 if (!empty($updatelessonpage)) { 502 if ($addquestionontop) { 503 $DB->set_field("lesson_pages", "prevpageid", $pageid, array("id" => $updatelessonpage->id)); 504 } else { 505 $DB->set_field("lesson_pages", "prevpageid", $pageid, array("id" => $updatelessonpage->nextpageid)); 506 } 507 } 508 if ($unsupportedquestions) { 509 echo $OUTPUT->notification(get_string('unknownqtypesnotimported', 'lesson', $unsupportedquestions)); 510 } 511 return true; 512 } 513 514 /** 515 * Count all non-category questions in the questions array. 516 * 517 * @param array questions An array of question objects. 518 * @return int The count. 519 * 520 */ 521 protected function count_questions($questions) { 522 $count = 0; 523 if (!is_array($questions)) { 524 return $count; 525 } 526 foreach ($questions as $question) { 527 if (!is_object($question) || !isset($question->qtype) || 528 ($question->qtype == 'category')) { 529 continue; 530 } 531 $count++; 532 } 533 return $count; 534 } 535 536 function readdata($filename) { 537 /// Returns complete file with an array, one item per line 538 539 if (is_readable($filename)) { 540 $filearray = file($filename); 541 542 /// Check for Macintosh OS line returns (ie file on one line), and fix 543 if (preg_match("/\r/", $filearray[0]) AND !preg_match("/\n/", $filearray[0])) { 544 return explode("\r", $filearray[0]); 545 } else { 546 return $filearray; 547 } 548 } 549 return false; 550 } 551 552 protected function readquestions($lines) { 553 /// Parses an array of lines into an array of questions, 554 /// where each item is a question object as defined by 555 /// readquestion(). Questions are defined as anything 556 /// between blank lines. 557 558 $questions = array(); 559 $currentquestion = array(); 560 561 foreach ($lines as $line) { 562 $line = trim($line); 563 if (empty($line)) { 564 if (!empty($currentquestion)) { 565 if ($question = $this->readquestion($currentquestion)) { 566 $questions[] = $question; 567 } 568 $currentquestion = array(); 569 } 570 } else { 571 $currentquestion[] = $line; 572 } 573 } 574 575 if (!empty($currentquestion)) { // There may be a final question 576 if ($question = $this->readquestion($currentquestion)) { 577 $questions[] = $question; 578 } 579 } 580 581 return $questions; 582 } 583 584 585 protected function readquestion($lines) { 586 /// Given an array of lines known to define a question in 587 /// this format, this function converts it into a question 588 /// object suitable for processing and insertion into Moodle. 589 590 echo "<p>This flash question format has not yet been completed!</p>"; 591 592 return null; 593 } 594 595 /** 596 * Construct a reasonable default question name, based on the start of the question text. 597 * @param string $questiontext the question text. 598 * @param string $default default question name to use if the constructed one comes out blank. 599 * @return string a reasonable question name. 600 */ 601 public function create_default_question_name($questiontext, $default) { 602 $name = $this->clean_question_name(shorten_text($questiontext, 80)); 603 if ($name) { 604 return $name; 605 } else { 606 return $default; 607 } 608 } 609 610 /** 611 * Ensure that a question name does not contain anything nasty, and will fit in the DB field. 612 * @param string $name the raw question name. 613 * @return string a safe question name. 614 */ 615 public function clean_question_name($name) { 616 $name = clean_param($name, PARAM_TEXT); // Matches what the question editing form does. 617 $name = trim($name); 618 $trimlength = 251; 619 while (core_text::strlen($name) > 255 && $trimlength > 0) { 620 $name = shorten_text($name, $trimlength); 621 $trimlength -= 10; 622 } 623 return $name; 624 } 625 626 function defaultquestion() { 627 // returns an "empty" question 628 // Somewhere to specify question parameters that are not handled 629 // by import but are required db fields. 630 // This should not be overridden. 631 global $CFG; 632 633 $question = new stdClass(); 634 $question->shuffleanswers = get_config('quiz', 'shuffleanswers'); 635 $question->defaultmark = 1; 636 $question->image = ""; 637 $question->usecase = 0; 638 $question->multiplier = array(); 639 $question->generalfeedback = ''; 640 $question->correctfeedback = ''; 641 $question->partiallycorrectfeedback = ''; 642 $question->incorrectfeedback = ''; 643 $question->answernumbering = 'abc'; 644 $question->penalty = 0.1; 645 $question->length = 1; 646 $question->qoption = 0; 647 $question->layout = 1; 648 649 // this option in case the questiontypes class wants 650 // to know where the data came from 651 $question->export_process = true; 652 $question->import_process = true; 653 654 return $question; 655 } 656 657 function importpostprocess() { 658 /// Does any post-processing that may be desired 659 /// Argument is a simple array of question ids that 660 /// have just been added. 661 return true; 662 } 663 664 /** 665 * Convert the question text to plain text, so it can safely be displayed 666 * during import to let the user see roughly what is going on. 667 */ 668 protected function format_question_text($question) { 669 $formatoptions = new stdClass(); 670 $formatoptions->noclean = true; 671 // The html_to_text call strips out all URLs, but format_text complains 672 // if it finds @@PLUGINFILE@@ tokens. So, we need to replace 673 // @@PLUGINFILE@@ with a real URL, but it doesn't matter what. 674 // We use http://example.com/. 675 $text = str_replace('@@PLUGINFILE@@/', 'http://example.com/', $question->questiontext); 676 return html_to_text(format_text($text, 677 $question->questiontextformat, $formatoptions), 0, false); 678 } 679 680 /** 681 * Since the lesson module tries to re-use the question bank import classes in 682 * a crazy way, this is necessary to stop things breaking. 683 */ 684 protected function add_blank_combined_feedback($question) { 685 return $question; 686 } 687 } 688 689 690 /** 691 * Since the lesson module tries to re-use the question bank import classes in 692 * a crazy way, this is necessary to stop things breaking. This should be exactly 693 * the same as the class defined in question/format.php. 694 */ 695 class qformat_based_on_xml extends qformat_default { 696 /** 697 * A lot of imported files contain unwanted entities. 698 * This method tries to clean up all known problems. 699 * @param string str string to correct 700 * @return string the corrected string 701 */ 702 public function cleaninput($str) { 703 704 $html_code_list = array( 705 "'" => "'", 706 "’" => "'", 707 "“" => "\"", 708 "”" => "\"", 709 "–" => "-", 710 "—" => "-", 711 ); 712 $str = strtr($str, $html_code_list); 713 // Use core_text entities_to_utf8 function to convert only numerical entities. 714 $str = core_text::entities_to_utf8($str, false); 715 return $str; 716 } 717 718 /** 719 * Return the array moodle is expecting 720 * for an HTML text. No processing is done on $text. 721 * qformat classes that want to process $text 722 * for instance to import external images files 723 * and recode urls in $text must overwrite this method. 724 * @param array $text some HTML text string 725 * @return array with keys text, format and files. 726 */ 727 public function text_field($text) { 728 return array( 729 'text' => trim($text), 730 'format' => FORMAT_HTML, 731 'files' => array(), 732 ); 733 } 734 735 /** 736 * Return the value of a node, given a path to the node 737 * if it doesn't exist return the default value. 738 * @param array xml data to read 739 * @param array path path to node expressed as array 740 * @param mixed default 741 * @param bool istext process as text 742 * @param string error if set value must exist, return false and issue message if not 743 * @return mixed value 744 */ 745 public function getpath($xml, $path, $default, $istext=false, $error='') { 746 foreach ($path as $index) { 747 if (!isset($xml[$index])) { 748 if (!empty($error)) { 749 $this->error($error); 750 return false; 751 } else { 752 return $default; 753 } 754 } 755 756 $xml = $xml[$index]; 757 } 758 759 if ($istext) { 760 if (!is_string($xml)) { 761 $this->error(get_string('invalidxml', 'qformat_xml')); 762 } 763 $xml = trim($xml); 764 } 765 766 return $xml; 767 } 768 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |