. /** * Book imscp export lib * * @package booktool_exportimscp * @copyright 2001-3001 Antonio Vicent {@link http://ludens.es} * @copyright 2001-3001 Eloy Lafuente (stronk7) {@link http://stronk7.com} * @copyright 2011 Petr Skoda {@link http://skodak.org} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die; require_once(__DIR__.'/lib.php'); require_once($CFG->dirroot.'/mod/book/locallib.php'); /** * Export one book as IMSCP package * * @param stdClass $book book instance * @param context_module $context * @return bool|stored_file */ function booktool_exportimscp_build_package($book, $context) { global $DB; $fs = get_file_storage(); if ($packagefile = $fs->get_file($context->id, 'booktool_exportimscp', 'package', $book->revision, '/', 'imscp.zip')) { return $packagefile; } // fix structure and test if chapters present if (!book_preload_chapters($book)) { print_error('nochapters', 'booktool_exportimscp'); } // prepare temp area with package contents booktool_exportimscp_prepare_files($book, $context); $packer = get_file_packer('application/zip'); $areafiles = $fs->get_area_files($context->id, 'booktool_exportimscp', 'temp', $book->revision, "sortorder, itemid, filepath, filename", false); $files = array(); foreach ($areafiles as $file) { $path = $file->get_filepath().$file->get_filename(); $path = ltrim($path, '/'); $files[$path] = $file; } unset($areafiles); $packagefile = $packer->archive_to_storage($files, $context->id, 'booktool_exportimscp', 'package', $book->revision, '/', 'imscp.zip'); // drop temp area $fs->delete_area_files($context->id, 'booktool_exportimscp', 'temp', $book->revision); // delete older versions $sql = "SELECT DISTINCT itemid FROM {files} WHERE contextid = :contextid AND component = 'booktool_exportimscp' AND itemid < :revision"; $params = array('contextid'=>$context->id, 'revision'=>$book->revision); $revisions = $DB->get_records_sql($sql, $params); foreach ($revisions as $rev => $unused) { $fs->delete_area_files($context->id, 'booktool_exportimscp', 'temp', $rev); $fs->delete_area_files($context->id, 'booktool_exportimscp', 'package', $rev); } return $packagefile; } /** * Prepare temp area with the files used by book html contents * * @param stdClass $book book instance * @param context_module $context */ function booktool_exportimscp_prepare_files($book, $context) { global $CFG, $DB; $fs = get_file_storage(); $temp_file_record = array('contextid'=>$context->id, 'component'=>'booktool_exportimscp', 'filearea'=>'temp', 'itemid'=>$book->revision); $chapters = $DB->get_records('book_chapters', array('bookid'=>$book->id), 'pagenum'); $chapterresources = array(); foreach ($chapters as $chapter) { $chapterresources[$chapter->id] = array(); $files = $fs->get_area_files($context->id, 'mod_book', 'chapter', $chapter->id, "sortorder, itemid, filepath, filename", false); foreach ($files as $file) { $temp_file_record['filepath'] = '/'.$chapter->pagenum.$file->get_filepath(); $fs->create_file_from_storedfile($temp_file_record, $file); $chapterresources[$chapter->id][] = $chapter->pagenum.$file->get_filepath().$file->get_filename(); } if ($file = $fs->get_file($context->id, 'booktool_exportimscp', 'temp', $book->revision, "/$chapter->pagenum/", 'index.html')) { // this should not exist $file->delete(); } $content = booktool_exportimscp_chapter_content($chapter, $context); $index_file_record = array('contextid'=>$context->id, 'component'=>'booktool_exportimscp', 'filearea'=>'temp', 'itemid'=>$book->revision, 'filepath'=>"/$chapter->pagenum/", 'filename'=>'index.html'); $fs->create_file_from_string($index_file_record, $content); } $css_file_record = array('contextid'=>$context->id, 'component'=>'booktool_exportimscp', 'filearea'=>'temp', 'itemid'=>$book->revision, 'filepath'=>"/css/", 'filename'=>'styles.css'); $fs->create_file_from_pathname($css_file_record, __DIR__.'/imscp.css'); // Init imsmanifest and others $imsmanifest = ''; $imsitems = ''; $imsresources = ''; // Moodle and Book version $moodle_release = $CFG->release; $moodle_version = $CFG->version; $book_version = get_config('mod_book', 'version'); $bookname = format_string($book->name, true, array('context'=>$context)); // Load manifest header $imsmanifest .= ' ' . htmlspecialchars($bookname) . ''; // To store the prev level (book only have 0 and 1) $prevlevel = null; $currlevel = 0; foreach ($chapters as $chapter) { // Calculate current level ((book only have 0 and 1) $currlevel = empty($chapter->subchapter) ? 0 : 1; // Based upon prevlevel and current one, decide what to close if ($prevlevel !== null) { // Calculate the number of spaces (for visual xml-text formating) $prevspaces = substr(' ', 0, $currlevel * 2); // Same level, simply close the item if ($prevlevel == $currlevel) { $imsitems .= $prevspaces . ' ' . "\n"; } // Bigger currlevel, nothing to close // Smaller currlevel, close both the current item and the parent one if ($prevlevel > $currlevel) { $imsitems .= ' ' . "\n"; $imsitems .= ' ' . "\n"; } } // Update prevlevel $prevlevel = $currlevel; // Calculate the number of spaces (for visual xml-text formatting) $currspaces = substr(' ', 0, $currlevel * 2); $chaptertitle = format_string($chapter->title, true, array('context'=>$context)); // Add the imsitems $imsitems .= $currspaces .' \n" . $currspaces . ' ' . htmlspecialchars($chaptertitle) . '' . "\n"; // Add the imsresources // First, check if we have localfiles $localfiles = array(); foreach ($chapterresources[$chapter->id] as $localfile) { $localfiles[] = "\n" . ' '; } // Now add the dependency to css $cssdependency = "\n" . ' '; // Now build the resources section $imsresources .= ' ' . "\n" . ' ' . implode($localfiles) . $cssdependency . "\n". ' ' . "\n"; } // Close items (the latest chapter) // Level 1, close 1 if ($currlevel == 0) { $imsitems .= ' ' . "\n"; } // Level 2, close 2 if ($currlevel == 1) { $imsitems .= ' ' . "\n"; $imsitems .= ' ' . "\n"; } // Define the css common resource $cssresource = ' ' . "\n"; // Add imsitems to manifest $imsmanifest .= "\n" . $imsitems; // Close the organization $imsmanifest .= " "; // Add resources to manifest $imsmanifest .= "\n \n" . $imsresources . $cssresource . " "; // Close manifest $imsmanifest .= "\n\n"; $manifest_file_record = array('contextid'=>$context->id, 'component'=>'booktool_exportimscp', 'filearea'=>'temp', 'itemid'=>$book->revision, 'filepath'=>"/", 'filename'=>'imsmanifest.xml'); $fs->create_file_from_string($manifest_file_record, $imsmanifest); } /** * Returns the html contents of one book's chapter to be exported as IMSCP * * @param stdClass $chapter the chapter to be exported * @param context_module $context context the chapter belongs to * @return string the contents of the chapter */ function booktool_exportimscp_chapter_content($chapter, $context) { $options = new stdClass(); $options->noclean = true; $options->context = $context; // We need to rewrite the pluginfile URLs so the media filters can work. $chaptercontent = file_rewrite_pluginfile_urls($chapter->content, 'pluginfile.php', $context->id, 'mod_book', 'chapter', $chapter->id); $chaptercontent = format_text($chaptercontent, $chapter->contentformat, $options); // Now remove again the full pluginfile URLs. $options = array('reverse' => true); $chaptercontent = file_rewrite_pluginfile_urls($chaptercontent, 'pluginfile.php', $context->id, 'mod_book', 'chapter', $chapter->id, $options); $chaptercontent = str_replace('@@PLUGINFILE@@/', '', $chaptercontent); $chaptertitle = format_string($chapter->title, true, array('context'=>$context)); $content = ''; $content .= '' . "\n"; $content .= '' . "\n"; $content .= '' . "\n"; $content .= '' . "\n"; $content .= '' . "\n"; $content .= '' . $chaptertitle . '' . "\n"; $content .= '' . "\n"; $content .= '' . "\n"; $content .= '

' . $chaptertitle . '

' ."\n"; $content .= $chaptercontent . "\n"; $content .= '' . "\n"; $content .= '' . "\n"; return $content; }