1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Blackboard V5 and V6 question importer. 19 * 20 * @package qformat_blackboard_six 21 * @copyright 2012 Jean-Michel Vedrine 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 defined('MOODLE_INTERNAL') || die(); 26 27 /** 28 * Base class question import format for zip files with images 29 * 30 * @package qformat_blackboard_six 31 * @copyright 2012 Jean-Michel Vedrine 32 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 33 */ 34 class qformat_blackboard_six_base extends qformat_based_on_xml { 35 /** @var string path to path to root of image tree in unzipped archive. */ 36 public $filebase = ''; 37 /** @var string path to the temporary directory. */ 38 public $tempdir = ''; 39 40 /** 41 * This plugin provide import 42 * @return bool true 43 */ 44 public function provide_import() { 45 return true; 46 } 47 48 /** 49 * Check if the given file is capable of being imported by this plugin. 50 * As {@link file_storage::mimetype()} may use finfo PHP extension if available, 51 * the value returned by $file->get_mimetype for a .dat file is not the same on all servers. 52 * So we must made 2 checks to verify if the plugin can import the file. 53 * @param stored_file $file the file to check 54 * @return bool whether this plugin can import the file 55 */ 56 public function can_import_file($file) { 57 $mimetypes = array( 58 mimeinfo('type', '.dat'), 59 mimeinfo('type', '.zip') 60 ); 61 return in_array($file->get_mimetype(), $mimetypes) || in_array(mimeinfo('type', $file->get_filename()), $mimetypes); 62 } 63 64 public function mime_type() { 65 return mimeinfo('type', '.zip'); 66 } 67 68 /** 69 * Does any post-processing that may be desired 70 * Clean the temporary directory if a zip file was imported 71 * @return bool success 72 */ 73 public function importpostprocess() { 74 if ($this->tempdir != '') { 75 fulldelete($this->tempdir); 76 } 77 return true; 78 } 79 /** 80 * Set the path to the root of images tree 81 * @param string $path path to images root 82 */ 83 public function set_filebase($path) { 84 $this->filebase = $path; 85 } 86 87 /** 88 * Store an image file in a draft filearea 89 * @param array $text, if itemid element don't exists it will be created 90 * @param string $tempdir path to root of image tree 91 * @param string $filepathinsidetempdir path to image in the tree 92 * @param string $filename image's name 93 * @return string new name of the image as it was stored 94 */ 95 protected function store_file_for_text_field(&$text, $tempdir, $filepathinsidetempdir, $filename) { 96 global $USER; 97 $fs = get_file_storage(); 98 if (empty($text['itemid'])) { 99 $text['itemid'] = file_get_unused_draft_itemid(); 100 } 101 // As question file areas don't support subdirs, 102 // convert path to filename. 103 // So that images with same name can be imported. 104 $newfilename = clean_param(str_replace('/', '__', $filepathinsidetempdir . '__' . $filename), PARAM_FILE); 105 $filerecord = array( 106 'contextid' => context_user::instance($USER->id)->id, 107 'component' => 'user', 108 'filearea' => 'draft', 109 'itemid' => $text['itemid'], 110 'filepath' => '/', 111 'filename' => $newfilename, 112 ); 113 $fs->create_file_from_pathname($filerecord, $tempdir . '/' . $filepathinsidetempdir . '/' . $filename); 114 return $newfilename; 115 } 116 117 /** 118 * Given an HTML text with references to images files, 119 * store all images in a draft filearea, 120 * and return an array with all urls in text recoded, 121 * format set to FORMAT_HTML, and itemid set to filearea itemid 122 * @param string $text text to parse and recode 123 * @return array with keys text, format, itemid. 124 */ 125 public function text_field($text) { 126 $data = array(); 127 // Step one, find all file refs then add to array. 128 preg_match_all('|<img[^>]+src="([^"]*)"|i', $text, $out); // Find all src refs. 129 $filepaths = array(); 130 foreach ($out[1] as $path) { 131 $fullpath = $this->filebase . '/' . $path; 132 133 if (is_readable($fullpath) && !in_array($path, $filepaths)) { 134 $dirpath = dirname($path); 135 $filename = basename($path); 136 $newfilename = $this->store_file_for_text_field($data, $this->filebase, $dirpath, $filename); 137 $text = preg_replace("|{$path}|", "@@PLUGINFILE@@/" . $newfilename, $text); 138 $filepaths[] = $path; 139 } 140 141 } 142 $data['text'] = $text; 143 $data['format'] = FORMAT_HTML; 144 return $data; 145 } 146 147 /** 148 * Same as text_field but text is cleaned. 149 * @param string $text text to parse and recode 150 * @return array with keys text, format, itemid. 151 */ 152 public function cleaned_text_field($text) { 153 return $this->text_field($this->cleaninput($text)); 154 } 155 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body