See Release Notes
Long Term Support Release
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 * @package moodlecore 18 * @subpackage backup-imscc 19 * @copyright 2009 Mauro Rondinelli (mauro.rondinelli [AT] uvcms.com) 20 * @copyright 2011 Darko Miletic (dmiletic@moodlerooms.com) 21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 22 */ 23 24 defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.'); 25 26 class entities { 27 /** 28 * Prepares convert for inclusion into XML 29 * 30 * @param string $value 31 * @return string 32 */ 33 public static function safexml($value) { 34 $result = htmlspecialchars(html_entity_decode($value, ENT_QUOTES, 'UTF-8'), 35 ENT_NOQUOTES, 36 'UTF-8', 37 false); 38 return $result; 39 } 40 41 protected function prepare_content($content) { 42 $result = $content; 43 if (empty($result)) { 44 return ''; 45 } 46 $encoding = null; 47 $xml_error = new libxml_errors_mgr(); 48 $dom = new DOMDocument(); 49 $dom->validateOnParse = false; 50 $dom->strictErrorChecking = false; 51 if ($dom->loadHTML($content)) { 52 $encoding = $dom->xmlEncoding; 53 } 54 if (empty($encoding)) { 55 $encoding = mb_detect_encoding($content, 'auto', true); 56 } 57 if (!empty($encoding) && !mb_check_encoding($content, 'UTF-8')) { 58 $result = mb_convert_encoding($content, 'UTF-8', $encoding); 59 } 60 61 // See if we can strip off body tag and anything outside of it. 62 foreach (array('body', 'html') as $tagname) { 63 $regex = str_replace('##', $tagname, "/<##[^>]*>(.+)<\/##>/is"); 64 if (preg_match($regex, $result, $matches)) { 65 $result = $matches[1]; 66 break; 67 } 68 } 69 return $result; 70 } 71 72 public function load_xml_resource($path_to_file) { 73 74 $resource = new DOMDocument(); 75 76 cc2moodle::log_action('Load the XML resource file: '.$path_to_file); 77 78 if (!$resource->load($path_to_file)) { 79 cc2moodle::log_action('Cannot load the XML resource file: ' . $path_to_file, false); 80 } 81 82 return $resource; 83 } 84 85 public function update_sources($html, $root_path = '') { 86 87 $document = $this->load_html($html); 88 89 $tags = array('img' => 'src' , 'a' => 'href'); 90 91 foreach ($tags as $tag => $attribute) { 92 93 $elements = $document->getElementsByTagName($tag); 94 95 foreach ($elements as $element) { 96 97 $attribute_value = $element->getAttribute($attribute); 98 $protocol = parse_url($attribute_value, PHP_URL_SCHEME); 99 100 if (empty($protocol)) { 101 $attribute_value = str_replace("\$IMS-CC-FILEBASE\$", "", $attribute_value); 102 $attribute_value = $this->full_path($root_path . "/" . $attribute_value, "/"); 103 $attribute_value = "\$@FILEPHP@\$" . "/" . $attribute_value; 104 } 105 106 $element->setAttribute($attribute, $attribute_value); 107 } 108 } 109 110 $html = $this->html_insidebody($document); 111 112 return $html; 113 } 114 115 public function full_path($path, $dir_sep = DIRECTORY_SEPARATOR) { 116 117 $token = '$IMS-CC-FILEBASE$'; 118 $path = str_replace($token, '', $path); 119 120 if (is_string($path) && ($path != '')) { 121 $dot_dir = '.'; 122 $up_dir = '..'; 123 $length = strlen($path); 124 $rtemp = trim($path); 125 $start = strrpos($path, $dir_sep); 126 $can_continue = ($start !== false); 127 $result = $can_continue ? '' : $path; 128 $rcount = 0; 129 130 while ($can_continue) { 131 132 $dir_part = ($start !== false) ? substr($rtemp, $start + 1, $length - $start) : $rtemp; 133 $can_continue = ($dir_part !== false); 134 135 if ($can_continue) { 136 if ($dir_part != $dot_dir) { 137 if ($dir_part == $up_dir) { 138 $rcount++; 139 } else { 140 if ($rcount > 0) { 141 $rcount --; 142 } else { 143 $result = ($result == '') ? $dir_part : $dir_part . $dir_sep . $result; 144 } 145 } 146 } 147 $rtemp = substr($path, 0, $start); 148 $start = strrpos($rtemp, $dir_sep); 149 $can_continue = (($start !== false) || (strlen($rtemp) > 0)); 150 } 151 } 152 } 153 154 return $result; 155 } 156 157 public function include_titles ($html) { 158 159 $document = $this->load_html($html); 160 161 $images = $document->getElementsByTagName('img'); 162 163 foreach ($images as $image) { 164 165 $src = $image->getAttribute('src'); 166 $alt = $image->getAttribute('alt'); 167 $title = $image->getAttribute('title'); 168 169 $filename = pathinfo($src); 170 $filename = $filename['filename']; 171 172 $alt = empty($alt) ? $filename : $alt; 173 $title = empty($title) ? $filename : $title; 174 175 $image->setAttribute('alt', $alt); 176 $image->setAttribute('title', $title); 177 } 178 179 $html = $this->html_insidebody($document); 180 181 return $html; 182 } 183 184 public function get_external_xml ($identifier) { 185 186 $xpath = cc2moodle::newx_path(cc2moodle::$manifest, cc2moodle::$namespaces); 187 188 $files = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="'. 189 $identifier.'"]/imscc:file/@href'); 190 191 if (empty($files)) { 192 $response = ''; 193 } else { 194 $response = $files->item(0)->nodeValue; 195 } 196 197 return $response; 198 } 199 200 public function move_files($files, $destination_folder) { 201 global $CFG, $OUTPUT; 202 203 if (!empty($files)) { 204 205 foreach ($files as $file) { 206 $source = cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . $file; 207 $destination = $destination_folder . DIRECTORY_SEPARATOR . $file; 208 209 $destination_directory = dirname($destination); 210 211 cc2moodle::log_action('Copy the file: ' . $source . ' to ' . $destination); 212 213 if (!file_exists($destination_directory)) { 214 mkdir($destination_directory, $CFG->directorypermissions, true); 215 } 216 217 $copy_success = true; 218 if (is_file($source)) { 219 $copy_success = @copy($source, $destination); 220 } 221 222 if (!$copy_success) { 223 echo $OUTPUT->notification('WARNING: Cannot copy the file ' . $source . ' to ' . $destination); 224 cc2moodle::log_action('Cannot copy the file ' . $source . ' to ' . $destination, false); 225 } 226 } 227 } 228 } 229 230 protected function get_all_files () { 231 global $CFG; 232 233 $all_files = array(); 234 235 $xpath = cc2moodle::newx_path(cc2moodle::$manifest, cc2moodle::$namespaces); 236 237 foreach (cc2moodle::$restypes as $type) { 238 239 $files = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@type="' . $type . '"]/imscc:file/@href'); 240 241 if (!empty($files) && ($files->length > 0)) { 242 foreach ($files as $file) { 243 // Omit html files. 244 $ext = strtolower(pathinfo($file->nodeValue, PATHINFO_EXTENSION)); 245 if (in_array($ext, array('html', 'htm', 'xhtml'))) { 246 continue; 247 } 248 $all_files[] = $file->nodeValue; 249 } 250 } 251 unset($files); 252 } 253 254 // Are there any labels? 255 $xquery = "//imscc:item/imscc:item/imscc:item[imscc:title][not(@identifierref)]"; 256 $labels = $xpath->query($xquery); 257 if (!empty($labels) && ($labels->length > 0)) { 258 $tname = 'course_files'; 259 $dpath = cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . $tname; 260 $rfpath = 'files.gif'; 261 $fpath = $dpath . DIRECTORY_SEPARATOR . $rfpath; 262 263 if (!file_exists($dpath)) { 264 mkdir($dpath, $CFG->directorypermissions, true); 265 } 266 // Copy the folder.gif file. 267 $folder_gif = "{$CFG->dirroot}/pix/i/files.gif"; 268 copy($folder_gif, $fpath); 269 $all_files[] = $rfpath; 270 } 271 272 $all_files = empty($all_files) ? '' : $all_files; 273 274 return $all_files; 275 } 276 277 public function move_all_files() { 278 279 $files = $this->get_all_files(); 280 281 if (!empty($files)) { 282 $this->move_files($files, cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'course_files', true); 283 } 284 285 } 286 287 /** 288 * @param string $html 289 * @return DOMDocument 290 */ 291 private function load_html($html) { 292 // Need to make sure that the html passed has charset meta tag. 293 $metatag = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'; 294 if (strpos($html, $metatag) === false) { 295 $html = '<html><head>'.$metatag.'</head><body>'.$html.'</body></html>'; 296 } 297 298 $document = new DOMDocument(); 299 @$document->loadHTML($html); 300 301 return $document; 302 } 303 304 /** 305 * @param DOMDocument $domdocument 306 * @return string 307 */ 308 private function html_insidebody($domdocument) { 309 $html = ''; 310 $bodyitems = $domdocument->getElementsByTagName('body'); 311 if ($bodyitems->length > 0) { 312 $body = $bodyitems->item(0); 313 $html = str_ireplace(array('<body>', '</body>'), '', $body->C14N()); 314 } 315 316 return $html; 317 } 318 319 public function generate_random_string ($length = 6) { 320 321 $response = ''; 322 $source = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 323 324 if ($length > 0) { 325 326 $response = ''; 327 $source = str_split($source, 1); 328 329 for ($i = 1; $i <= $length; $i++) { 330 $num = mt_rand(1, count($source)); 331 $response .= $source[$num - 1]; 332 } 333 } 334 335 return $response; 336 } 337 338 public function truncate_text($text, $max, $remove_html) { 339 340 if ($max > 10) { 341 $text = substr($text, 0, ($max - 6)) . ' [...]'; 342 } else { 343 $text = substr($text, 0, $max); 344 } 345 346 $text = $remove_html ? strip_tags($text) : $text; 347 348 return $text; 349 } 350 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body