. /** * This is a very rough importer for odt * * The script supports book * Is based on class office from http://www.phpclasses.org/browse/package/2586.html * * @version $Id: importodt.php,v 1.5 2012/07/25 11:16:04 bdaloukas Exp $ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License * @package game **/ require_once("../../../config.php"); require_once( "../header.php"); require_once("../locallib.php"); $subchapter = optional_param('subchapter', '', PARAM_ALPHA); $overwrite = optional_param('overwrite', 0, PARAM_INT); $attempt = game_getattempt( $game, $detail); $bookid = $game->bookid; if ($bookid == 0) { print_error( get_string( 'bookquiz_not_select_book', 'game')); } if ($form = data_submitted()) { // Filename. if (empty($_FILES['newfile'])) { // File was just uploaded. notify(get_string("uploadproblem") ); } if ((!is_uploaded_file($_FILES['newfile']['tmp_name']) or $_FILES['newfile']['size'] == 0)) { notify(get_string("uploadnofilefound") ); } else { // Valid file is found. if (readdata( $course->id, 'game', $dirtemp, $rlevels, $rtitles, $rtexts, $dirfordelete)) { // First try to reall all of the data in. if ($overwrite) { game_bookquiz_deletebook( $course->id, $bookid); } // Parse all the html files into objects. $pageobjects = extract_data( $course->id, 'book', $bookid, $dirtemp, $subchapter, $rlevels, $rtitles, $rtexts); clean_temp( $dirfordelete); // All done with files so dump em. // Function to preps the data to be sent to DB. $objects = game_bookquiz_create_objects( $pageobjects, $bookid); if (!game_bookquiz_save_objects( $objects)) { // Sends it to DB. print_error('could not save'); } } else { print_error('could not get data'); } print_continue("{$CFG->wwwroot}/mod/game/view.php?id=$cm->id"); echo $OUTPUT->footer($course); exit; } } // Print upload form. print_heading_with_help( get_string( "bookquiz_import_odt", "game"), "importodt", "game"); echo $OUTPUT->box_start('center'); ?>
:
:
  " />
box_end(); echo $OUTPUT->footer($course); // START OF FUNCTIONS. // The rbasedir variable contains the directory where the temp files are. // At the end the directory must be deleted. function readdata( $courseid, $modname, &$rbasedir, &$rlevels, &$rtitles, &$rtexts, &$dirfordelete) { // This function expects a odt file to be uploaded. Then it parses the content.xml to determine. // Then copies the images. global $CFG; // Create a random upload directory in temp. $newdir = $CFG->dataroot."/temp/$modname"; if (!file_exists( $newdir)) { mkdir( $newdir); } $i = 1; srand((double)microtime() * 1000000); while (true) { $rbasedir = "$modname/$i-".rand(0, 10000); $newdir = $CFG->dataroot.'/temp/'.$rbasedir; if (!file_exists( $newdir)) { mkdir( $newdir); $newdir .= '/'; break; } $i++; } $dirfordelete = $rbasedir; $rbasedir .= '/'; $zipfile = $_FILES["newfile"]["name"]; $tempzipfile = $_FILES["newfile"]["tmp_name"]; // Creates our directory. $pathparts = pathinfo($zipfile); // Takes off the extension. $dirname = substr($zipfile, 0, strpos($zipfile, '.'.$pathparts['extension'])); if (!file_exists($newdir.$dirname)) { mkdir($newdir.$dirname); } // Move our uploaded file to temp/game. move_uploaded_file( $tempzipfile, $newdir.$zipfile); // If the file ends with .lnk then use .odt instead. if (substr( $zipfile, -4) == ".lnk") { $zipfile = substr( $zipfile, 0, -4).".odt"; } // Unzip it! unzip_file ( $newdir.$zipfile, $newdir.$dirname, false); $rbasedir .= $dirname; // Update the base. $newdir .= $dirname; // This is the file where we get the names of the files for the slides (in the correct order too). $content = $newdir.'/content.xml'; $data = file_get_contents( $content); $content = $newdir.'/styles.xml'; if (file_exists( $content)) { $datastyle = file_get_contents( $content); } else { $datastyle = ''; } oo_game_convert_ver2( $data, $datastyle, $rlevels, $rtitles, $rtexts); return true; } function oo_game_convert_ver2( $data, $datastyle, &$rlevels, &$rtitles, &$rtexts) { $rlevels = array(); $rtitles = array(); $rtexts = array(); // We have tables, encode it here so all ', '', $data); $data = preg_replace('##es', "base64_encode('\\1')", $data); } $styles = array(); game_bookquiz_convert_ver2_computestyles( $datastyle, $styles, true); game_bookquiz_convert_ver2_computestyles( $data, $styles, false); game_bookquiz_splitsections($data, $positions, $inputs, $titles, $titleframes, $texts); for ($i = 0; $i < count( $positions); $i++) { preg_match_all( "#text:outline-level=\"([0-9]*)\"#es", $inputs[ $i], $matches); $levels = $matches[ 1]; if (count( $levels) > 0) { $level = $levels[ 0]; } else { $level = 0; } $rlevels[] = $level; $rtitles[] = strip_tags( $titles[ $i]); $textframe = game_bookquiz_convert($titleframes[ $i], $styles, $images); $text = game_bookquiz_convert($texts[ $i], $styles, $images); if ($textframe != '') { $text = $textframe.'
'.$text; } echo "
".$titles[ $i]."
".$text."\r\n\r\n\r\n\r\n"; $rtexts[] = $text; } } function extract_data( $courseid, $modname, $id, $basedir, $subchapter, $levels, $titles, $texts) { global $CFG; global $matches; $dirtemp = $CFG->dataroot.'/temp/'.$basedir; for ($i = 0; $i < count( $levels); $i++) { echo $levels[ $i]." ".$titles[ $i]."
"; } $extractedpages = array(); // Directory for images. make_mod_upload_directory( $courseid); // Make sure moddata is made. make_upload_directory( $courseid.'/moddata/'.$modname, false); // We store our images in a subfolder in here. make_upload_directory( $courseid.'/moddata/'.$modname."/".$id, false); $imagedir = $CFG->dataroot.'/'.$courseid.'/moddata/'.$modname."/".$id; if ($CFG->slasharguments) { $imagelink = $CFG->wwwroot.'/file.php/'.$courseid.'/moddata/'.$modname."/".$id; } else { $imagelink = $CFG->wwwroot.'/file.php?file=/'.$courseid.'/moddata/'.$modname."/".$id; } // Try to make a unique subfolder to store the images. $i = 1; while (true) { $newdir = $imagedir.'/'.$i; if (!file_exists( $newdir)) { // Ok doesnt exist so make the directory and update our paths. mkdir( $newdir); $imagedir = $newdir; $imagelink = $imagelink.'/'.$i; break; } $i++; } for ($i = 0; $i < count( $titles); $i++) { // Start building our page. $page = new stdClass; $page->title = $titles[ $i]; $page->content = $texts[ $i]; $page->subchapter = ( $levels[ $i] >= 2); // Check if the nexts are subchapters. for ($j = $i + 1; $j < count( $titles); $j++) { if ($levels[ $j] > 2) { $page->content .= '
'.$titles[ $j].'
'.$texts[ $j]; $i = $j; continue; } break; } preg_match_all('#="Pictures/([a-z .A-Z_0-9]*)"#es', $page->content, $imgs); foreach ($imgs[1] as $img) { $src = $dirtemp.'/Pictures/'.$img; $dest = $imagedir.'/'.$img; rename( $src, $dest); $page->content = str_replace( "Pictures/$img", $imagelink."/".$img, $page->content); } // Add the page to the array. $extractedpages[] = $page; } // End $pages foreach loop. return $extractedpages; } /* Clean up the temp directory */ function clean_temp( $base) { global $CFG; // This function is broken, use it to clean up later. // Should only clean up what we made as well because someone else could be importing ppt as well. $dir = $CFG->dataroot.'/temp/'.$base; remove_dir( $dir); } /* Creates objects an chapter object that is to be inserted into the database */ function game_bookquiz_create_objects( $pageobjects, $bookid) { global $DB; $chapters = array(); $lastpagenum = $DB->get_field('book_chapters', 'MAX(pagenum) as num', array( 'bookid' => $bookid)); foreach ($pageobjects as $pageobject) { $chapter = new stdClass; // Same for all chapters. $chapter->bookid = $bookid; $chapter->pagenum = ++$lastpagenum; $chapter->timecreated = time(); $chapter->timemodified = time(); $chapter->subchapter = 0; if ($pageobject->title == '') { $chapter->title = "Page $count"; // No title set so make a generic one. } else { $chapter->title = addslashes($pageobject->title); } $chapter->subchapter = $pageobject->subchapter; $content = str_replace("\n", '', $pageobject->content); $content = str_replace("\r", '', $content); $content = str_replace(' ', '', $content); // Puts in returns? $content = '

'.$content.'

'; $chapter->content = addslashes( $content); $chapters[] = $chapter; } return $chapters; } // Save the chapter objects to the database. function game_bookquiz_save_objects($chapters) { global $DB; // Nothing fancy, just save them all in order. foreach ($chapters as $chapter) { if (!$newid = $DB->insert_record('book_chapters', $chapter)) { print_error('Could not insert to table book_chapters'); } } return true; } // Splits the data to. function game_bookquiz_splitsections($data, &$positions, &$inputs, &$titles, &$titleframes, &$texts) { preg_match_all('#(.*?)#es', $data, $matches, PREG_OFFSET_CAPTURE); $in = $matches[ 1]; $title = $matches[ 2]; $positions = array(); $inputs = array(); $titles = array(); $oldposition = 0; $oldlen = 0; for ($i = 0; $i < count( $in); $i++) { $inputs[] = $in[ $i][ 0]; $newposition = $in[ $i][ 1]; $positions[] = $newposition; $titlenet = $title[ $i][ 0]; $titleframe = ''; // Frames inside header. preg_match_all('#(.*?)#es', $titlenet, $titlematches, PREG_OFFSET_CAPTURE); $frames = $titlematches[ 2]; if (count( $frames) > 0) { for ($j = 0; $j < count( $frames); $j++) { $titleframe .= $frames[ $j][ 0]; $titlenet = substr( $titlenet, $frames[ $j][ 1] + strlen( $frames[ $j][ 0]) + 13); } } $titles[] = $titlenet; $titleframes[] = $titleframe; if ($i > 0) { $texts[] = substr( $data, $oldposition + $oldlen, $newposition - $oldposition - $oldlen); } $oldlen = strlen( $title[ $i][ 0]) + strlen( $in[ $i][ 0]) + 10; $oldposition = $newposition; } $newposition = strlen( $data); $texts[] = substr( $data, $oldposition + $oldlen, $newposition - $oldposition - $oldlen); } function game_bookquiz_convert( $data, $styles, &$images) { $images = array(); // Get data. preg_match_all('#(.*?)#es', $data, $text); $originals = $text[ 0]; $names = $text[ 1]; $texts = $text[ 2]; for ($i = 0; $i < count( $texts); $i++) { $name = $names[ $i]; $text = $texts[ $i]; // Repairs draw:frame. $pattern = "##es"; preg_match_all( $pattern, $text, $matches); if (count( $matches[ 1]) ) { $new = game_bookquiz_convert_image( $matches, $styles, $images); $data = str_replace( $originals[ $i], $new, $data); } else if ($name == 'RKRK') { $new = game_bookquiz_convert_RKRK( $text); $data = str_replace( $originals[ $i], $new, $data); } else { $new = '

'.game_bookquiz_convert_text( $text, $styles).'

'; $data = str_replace( $originals[ $i], $new, $data); } } // Repairs text:span text:style-name. preg_match_all( '#(.*?)#es', $data, $text); $originals = $text[ 0]; $names = $text[ 1]; $texts = $text[ 2]; for ($i = 0; $i < count( $texts); $i++) { $name = $names[ $i]; $text = $texts[ $i]; $pattern = "##es"; preg_match_all( $pattern, $text, $matches); if (count( $matches[ 1]) ) { $new = game_bookquiz_convert_image( $matches, $styles, $images); $data = str_replace( $originals[ $i], $new, $data); } else if ($name == 'RKRK') { $new = game_bookquiz_convert_RKRK( $text); $data = str_replace( $originals[ $i], $new, $data); } else { $new = "'.game_bookquiz_convert_text( $text, $styles).''; $data = str_replace( $originals[ $i], $new, $data); } } // Repairs text:a. preg_match_all( '#(.*?)#es', $data, $text); $originals = $text[ 0]; $hrefs = $text[ 2]; $texts = $text[ 3]; for ($i = 0; $i < count( $texts); $i++) { $href = $hrefs[ $i]; $text = $texts[ $i]; $new = "$text"; $data = str_replace( $originals[ $i], $new, $data); } // Repair text:list. preg_match_all( '#(.*?)#es', $data, $text); $originals = $text[ 0]; $names = $text[ 1]; $texts = $text[ 2]; for ($i = 0; $i < count( $texts); $i++) { $new = '
    '.$texts[ $i].'
'; $data = str_replace( $originals[ $i], $new, $data); // I have to repair the listitems. preg_match_all( '#(.*?)#es', $data, $listitems); $originallistitems = $listitems[ 0]; $items = $listitems[ 1]; for ($j = 0; $j < count( $items); $j++) { $new = '
  • '.$items[ $j]; $data = str_replace( $originallistitems[ $j], $new, $data); } } $data = str_replace( '', '
    ', $data); return $data; } function game_bookquiz_convert_text( $text, $styles) { $pattern = "#(.*?)#es"; preg_match_all( $pattern, $text, $matches); $originals = $matches[ 0]; $names = $matches[ 1]; $spantexts = $matches[ 2]; for ($i = 0; $i < count( $names); $i++) { $name = $names[ $i]; $style = $styles[ $name]; $new = "".$spantexts[ $i].""; $text = str_replace( $originals[ $i], $new, $text); } return $text; } function game_bookquiz_convert_image( $matches, $xmlstyles, &$images) { $ret = ''; $styles = $matches[ 1]; $pictures = $matches[ 3]; for ($j = 0; $j < count( $pictures); $j++) { $style = $styles[ $j]; $ret .= '
    '; $images[] = $pictures[$j]; } return $ret; } function game_bookquiz_convert_rkrk( $text) { $table = base64_decode($text); $table = stripslashes($table); $table = strtr($table, array('' => '', '' => '', '' => '', '' => '', '' => '', '' => '', '>' => ">\n", '' => '')); preg_match_all('#table:name="(.*?)" table:style-name="(.*?)">#es', $table, $repl); foreach ($repl[0] as $val) { $table = str_replace($val, '', $table); } preg_match_all('##es', $table, $repl); foreach ($repl[0] as $key => $val) { $table = str_replace($val, '', $table); } preg_match_all('##es', $table, $repl); foreach ($repl[0] as $val) { $table = str_replace($val, '', $table); } preg_match_all('##es', $table, $repl); foreach ($repl[0] as $val) { $table = str_replace($val, '
    ', $table); } // Maybe there are a lot of pictures inside a table. preg_match_all('#xlink:href="Pictures/([a-z.A-Z_0-9]*)"#es', $table, $repl); foreach ($repl[ 1] as $picture) { $table = str_replace('', '', $table); } if (strpos( $table, "
    ") === false) { $table .= ""; } $ret = '
    '.$table.'
    '; return $ret; } function game_bookquiz_deletebook( $courseid, $bookid) { global $CFG; if (!delete_records( 'book_chapters', 'bookid', $bookid)) { print_error( "Can't delete records from book_chapters bookid=$bookid"); } game_full_rmdir( "$CFG->dataroot/$courseid/moddata/book/$bookid"); } function game_bookquiz_convert_ver2_computestyles( $data, &$styles, $isstyle) { preg_match_all('#(.*?)#es', $data, $style); $stylenames = $style[ 1]; $styleinfos = $style[ 2]; $styledatas = $style[ 3]; for ($i = 0; $i < count( $stylenames); $i++) { $name = $stylenames[ $i]; $change = false; for (;;) { $pos1 = strpos( $styledatas[ $i], 'style:parent-style-name'); $pos2 = strpos( $styledatas[ $i], '/>'); if (($pos1 === false) or ($pos2 === false)) { break; } if ($pos1 > $pos2) { break; } // Is a parent style. $s = substr( $styledatas[ $i], 0, $pos2 + 2); game_bookquiz_convertstyle_parent( $s, $styles); $styledatas[ $i] = substr( $styledatas[ $i], $pos2 + 2); $change = true; } if ($change) { // Must to recompute name, styledatas, styleinfos. preg_match_all('#(.*?)#es', $data, $style); $name = $style[ 1][ 0]; $styleinfos[ $i] = $style[ 2][ 0]; $styledatas[ $i] = $style[ 3][ 0]; } $styles[ $name] = game_bookquiz_convertstyle( $styledatas[ $i], $styleinfos[ $i], $styles); } } function game_bookquiz_convertstyle_parent( $data, &$styles) { $styleitems = array(); preg_match_all( '#(.*?)style:name="(.*?)"(.*?)style:parent-style-name="(.*?)"(.*?)#es', $data, $infos); $names = $infos[ 2]; $parents = $infos[ 4]; if (count( $parents)) { if (array_key_exists( $parents[ 0], $styles)) { // Is a child style. Must to copy the properties of the parent style. $a = explode( ';', $styles[ $parents[ 0]]); foreach ($a as $s) { $pos = strpos( $s, ':'); $key = substr( $s, 0, $pos); $item = substr( $s, $pos + 1); if ($item == '') { continue; } $styleitems[ $key] = $item; } } $name = $names[ 0]; } $style = ''; foreach ($styleitems as $key => $item) { $style .= ';'.$key.':'.$item; } $styles[ $name] = substr( $style, 1); } function game_bookquiz_convertstyle( $data, $styleinfo, $styles) { $styleitems = array(); preg_match_all( '##es', $data, $infos); $lines = $infos[ 1]; if (count( $lines)) { $line = $lines[ 0]; if ($line != '') { game_bookquiz_convertstyle_paragraph( $line, $styleitems); } } preg_match_all( '##es', $data, $infos); $lines = $infos[ 1]; if (count( $lines)) { $line = $lines[ 0]; if ($line != '') { game_bookquiz_convertstyle_textproperties( $line, $styleitems); } } if (count( $styleitems) == 0) { return ''; } $style = ''; foreach ($styleitems as $key => $item) { $style .= ';'.$key.':'.$item; } return substr( $style, 1); } function game_bookquiz_convertstyle_paragraph( $line, &$styleitems) { preg_match_all( '#(.*?)=(.*?) #es', $line.' ', $datas); $data1 = $datas[ 1]; $data2 = $datas[ 2]; $ret = ''; for ($i = 0; $i < count( $data1); $i++) { $eq1 = $data1[ $i]; $eq2 = $data2[ $i]; if ((substr( $eq2, 0, 1) == '"') and (substr( $eq2, -1, 1) == '"')) { $eq2 = substr( $eq2, 1, -1); } switch ($eq1) { case 'fo:text-align': $styleitems[ 'align'] = $eq2; break; case 'fo:background-color': $styleitems[ 'background-color'] = $eq2; break; } } } function game_bookquiz_convertstyle_textproperties( $line, &$styleitems) { preg_match_all( '#(.*?)=(.*?) #es', $line.' ', $datas); $data1 = $datas[ 1]; $data2 = $datas[ 2]; $ret = ''; for ($i = 0; $i < count( $data1); $i++) { $eq1 = $data1[ $i]; $eq2 = $data2[ $i]; if ((substr( $eq2, 0, 1) == '"') and (substr( $eq2, -1, 1) == '"')) { $eq2 = substr( $eq2, 1, -1); } switch( $eq1) { case 'fo:font-size': case 'fo:color': case 'fo:background-color': case 'fo:font-style': case 'fo:font-weight': $styleitems[ substr( $eq1, 3)] = $eq2; break; case 'style_text_underline_style': if ($eq2 == 'solid') { $styleitems[ 'text-decoration'] = 'underline'; } break; } } }