Fix A tag regex searching in book. MDL-15842 ; merged from 19_STABLE
[moodle.git] / generateimscp.php
CommitLineData
dab784a3 1<?PHP // $Id: generateimscp.php,v 1.2 2007/05/20 06:00:26 skodak Exp $
fc9479b8
EL
2
3///////////////////////////////////////////////////////////////////////////
4// //
5// NOTICE OF COPYRIGHT //
6// //
7// Moodle - Modular Object-Oriented Dynamic Learning Environment //
8// http://moodle.com //
9// //
10// Copyright (C) 2001-3001 Antonio Vicent http://ludens.es //
11// (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com //
12// //
13// This program is free software; you can redistribute it and/or modify //
14// it under the terms of the GNU General Public License as published by //
15// the Free Software Foundation; either version 2 of the License, or //
16// (at your option) any later version. //
17// //
18// This program is distributed in the hope that it will be useful, //
19// but WITHOUT ANY WARRANTY; without even the implied warranty of //
20// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
21// GNU General Public License for more details: //
22// //
23// http://www.gnu.org/copyleft/gpl.html //
24// //
25///////////////////////////////////////////////////////////////////////////
26
27require_once('../../config.php');
28require_once('lib.php');
29require_once($CFG->dirroot . '/backup/lib.php');
30require_once($CFG->dirroot . '/lib/filelib.php');
31
dab784a3 32$id = required_param('id', PARAM_INT); // Course Module ID
fc9479b8 33
dab784a3 34require_login();
fc9479b8 35
dab784a3 36if (!$cm = get_coursemodule_from_id('book', $id)) {
fc9479b8
EL
37 error('Course Module ID was incorrect');
38}
39
40if (!$course = get_record('course', 'id', $cm->course)) {
41 error('Course is misconfigured');
42}
43
dab784a3
PS
44$context = get_context_instance(CONTEXT_MODULE, $cm->id);
45require_capability('moodle/course:manageactivities', $context);
fc9479b8
EL
46
47if (!$book = get_record('book', 'id', $cm->instance)) {
48 error('Course module is incorrect');
49}
50
fc9479b8
EL
51$strbooks = get_string('modulenameplural', 'book');
52$strbook = get_string('modulename', 'book');
53$strtop = get_string('top', 'book');
54
55add_to_log($course->id, 'book', 'generateimscp', 'generateimscp.php?id='.$cm->id, $book->id, $cm->id);
56
57/// Get all the chapters
58 $chapters = get_records('book_chapters', 'bookid', $book->id, 'pagenum');
59
60/// Generate the manifest and all the contents
61 chapters2imsmanifest($chapters, $book, $cm);
62
63/// Now zip everything
64 make_upload_directory('temp');
65 $zipfile = $CFG->dataroot . "/temp/". time() . '.zip';
66 $files = get_directory_list($CFG->dataroot . "/$cm->course/moddata/book/$book->id", basename($zipfile), false, true, true);
67 foreach ($files as $key => $value) {
68 $files[$key] = $CFG->dataroot . "/$cm->course/moddata/book/$book->id/" . $value;
69 }
70 zip_files($files, $zipfile);
71/// Now delete all the temp dirs
72 delete_dir_contents($CFG->dataroot . "/$cm->course/moddata/book/$book->id");
73/// Now serve the file
74 send_file($zipfile, clean_filename($book->name) . '.zip', 86400, 0, false, true);
75
76/**
77 * This function will create the default imsmanifest plus contents for the book chapters passed as array
78 * Everything will be created under the book moddata file area *
79 */
80function chapters2imsmanifest ($chapters, $book, $cm) {
81
82 global $CFG;
83
84/// Init imsmanifest and others
85 $imsmanifest = '';
86 $imsitems = '';
87 $imsresources = '';
88
89/// Moodle and Book version
90 $moodle_release = $CFG->release;
91 $moodle_version = $CFG->version;
92 $book_version = get_field('modules', 'version', 'name', 'book');
93
94/// Load manifest header
95 $imsmanifest .= '<?xml version="1.0" encoding="UTF-8"?>
96<!-- This package has been created with Moodle ' . $moodle_release . ' (' . $moodle_version . '), Book module version ' . $book_version . ' - http://moodle.org -->
97<!-- One idea and implementation by Eloy Lafuente (stronk7) and Antonio Vicent (C) 2001-3001 -->
98<manifest xmlns="http://www.imsglobal.org/xsd/imscp_v1p1" xmlns:imsmd="http://www.imsglobal.org/xsd/imsmd_v1p2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" identifier="MANIFEST-' . md5($CFG->wwwroot . '-' . $book->course . '-' . $book->id) . '" xsi:schemaLocation="http://www.imsglobal.org/xsd/imscp_v1p1 imscp_v1p1.xsd http://www.imsglobal.org/xsd/imsmd_v1p2 imsmd_v1p2p2.xsd">
99 <organizations default="MOODLE-' . $book->course . '-' . $book->id . '">
100 <organization identifier="MOODLE-' . $book->course . '-' . $book->id . '" structure="hierarchical">
101 <title>' . htmlspecialchars($book->name) . '</title>';
102
103/// Create the temp directory
104 $moddir = "$cm->course/moddata/book/$book->id";
105 make_upload_directory($moddir);
106
107/// For each chapter, create the corresponding directory and save contents there
108
109/// To store the prev level (book only have 0 and 1)
110 $prevlevel = null;
111 foreach ($chapters as $chapter) {
112 /// Calculate current level ((book only have 0 and 1)
113 $currlevel = empty($chapter->subchapter) ? 0 : 1;
114 /// Based upon prevlevel and current one, decide what to close
115 if ($prevlevel !== null) {
116 /// Calculate the number of spaces (for visual xml-text formating)
117 $prevspaces = substr(' ', 0, $currlevel * 2);
118
119 /// Same level, simply close the item
120 if ($prevlevel == $currlevel) {
121 $imsitems .= $prevspaces . ' </item>' . "\n";
122 }
123 /// Bigger currlevel, nothing to close
124 /// Smaller currlevel, close both the current item and the parent one
125 if ($prevlevel > $currlevel) {
126 $imsitems .= ' </item>' . "\n";
127 $imsitems .= ' </item>' . "\n";
128 }
129 }
130 /// Update prevlevel
131 $prevlevel = $currlevel;
132
133 /// Calculate the number of spaces (for visual xml-text formating)
134 $currspaces = substr(' ', 0, $currlevel * 2);
135
136 /// Create the static html file + local attachments (images...)
137 $chapterdir = "$moddir/$chapter->pagenum";
138 make_upload_directory($chapterdir);
139 $chaptercontent = chapter2html($chapter, $book->course, $book->id);
140 file_put_contents($CFG->dataroot . "/" . $chapterdir . "/index.html", $chaptercontent->content);
141 /// Add the imsitems
142 $imsitems .= $currspaces .' <item identifier="ITEM-' . $book->course . '-' . $book->id . '-' . $chapter->pagenum .'" isvisible="true" identifierref="RES-' . $book->course . '-' . $book->id . '-' . $chapter->pagenum . '">
143 ' . $currspaces . ' <title>' . htmlspecialchars($chapter->title) . '</title>' . "\n";
144
145 /// Add the imsresources
146 /// First, check if we have localfiles
147 $localfiles = '';
148 if ($chaptercontent->localfiles) {
149 foreach ($chaptercontent->localfiles as $localfile) {
150 $localfiles .= "\n" . ' <file href="' . $chapter->pagenum . '/' . $localfile . '" />';
151 }
152 }
153 /// Now add the dependency to css
154 $cssdependency = "\n" . ' <dependency identifierref="RES-' . $book->course . '-' . $book->id . '-css" />';
155 /// Now build the resources section
156 $imsresources .= ' <resource identifier="RES-' . $book->course . '-' . $book->id . '-' . $chapter->pagenum . '" type="webcontent" xml:base="' . $chapter->pagenum . '/" href="index.html">
157 <file href="' . $chapter->pagenum . '/index.html" />' . $localfiles . $cssdependency . '
158 </resource>' . "\n";
159 }
160
161/// Close items (the latest chapter)
162/// Level 1, close 1
163 if ($currlevel == 0) {
164 $imsitems .= ' </item>' . "\n";
165 }
166/// Level 2, close 2
167 if ($currlevel == 1) {
168 $imsitems .= ' </item>' . "\n";
169 $imsitems .= ' </item>' . "\n";
170 }
171
172/// Define the css common resource
173$cssresource = ' <resource identifier="RES-' . $book->course . '-' . $book->id . '-css" type="webcontent" xml:base="css/" href="styles.css">
174 <file href="css/styles.css" />
175 </resource>' . "\n";
176
177/// Add imsitems to manifest
178 $imsmanifest .= "\n" . $imsitems;
179/// Close the organization
180 $imsmanifest .= " </organization>
181 </organizations>";
182/// Add resources to manifest
183 $imsmanifest .= "\n <resources>\n" . $imsresources . $cssresource . " </resources>";
184/// Close manifest
185 $imsmanifest .= "\n</manifest>\n";
186
187 file_put_contents($CFG->dataroot . "/" . $moddir . '/imsmanifest.xml', $imsmanifest );
188
189/// Now send the css resource
190 make_upload_directory("$moddir/css");
191 file_put_contents($CFG->dataroot . "/" . $moddir . "/css/styles.css", file_get_contents("$CFG->dirroot/mod/book/generateimscp.css"));
192}
193
194/**
195 * This function will create one chaptercontent object, with the contents converted to html and
196 * one array of local images to be included
197 */
198function chapter2html($chapter, $courseid, $bookid) {
199
200 global $CFG;
201
202 $content = '';
203 $content .= '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">' . "\n";
204 $content .= '<html>' . "\n";
205 $content .= '<head>' . "\n";
206 $content .= '<meta http-equiv="content-type" content="text/html; charset=utf-8" />' . "\n";
207 $content .= '<link rel="stylesheet" type="text/css" href="../css/styles.css" />' . "\n";
208 $content .= '<title>' . $chapter->title . '</title>' . "\n";
209 $content .= '</head>' . "\n";
210 $content .= '<body>' . "\n";
211 $content .= '<h1 id="header">' . $chapter->title . '</h1>' ."\n";
dab784a3 212 $options = new object();
fc9479b8
EL
213 $options->noclean = true;
214 $content .= format_text($chapter->content, '', $options, $courseid) . "\n";
215 $content .= '</body>' . "\n";
216 $content .= '</html>' . "\n";
217
218/// Now look for course-files in contents
219 $search = array($CFG->wwwroot.'/file.php/'.$courseid,
220 $CFG->wwwroot.'/file.php?file=/'.$courseid);
221 $replace = array('$@FILEPHP@$','$@FILEPHP@$');
222 $content = str_replace($search, $replace, $content);
223
224 $regexp = '/\$@FILEPHP@\$(.*?)"/is';
225 $localfiles = array();
226 $basefiles = array();
227 preg_match_all($regexp, $content, $list);
228
229 if ($list) {
230 /// Build the array of local files
231 foreach (array_unique($list[1]) as $key => $value) {
232 $localfiles['<#'. $key . '#>'] = $value;
233 $basefiles['<#'. $key . '#>'] = basename($value);
234 /// Copy files to current chapter directory
235 if (file_exists($CFG->dataroot . '/' . $courseid . '/' . $value)) {
236 copy($CFG->dataroot . '/' . $courseid . '/' . $value, $CFG->dataroot . '/' . $courseid . '/moddata/book/' . $bookid . '/' . $chapter->pagenum . '/' . basename ($value));
237 }
238 }
239 /// Replace contents by keys
240 $content = str_replace($localfiles, array_keys($localfiles), $content);
241 /// Replace keys by basefiles
242 $content = str_replace(array_keys($basefiles), $basefiles, $content);
243 /// Delete $@FILEPHP@$
244 $content = str_replace('$@FILEPHP@$', '', $content);
245 }
246
247/// Build the final object needed to have all the info in order to create the manifest
dab784a3 248 $object = new object();
fc9479b8
EL
249 $object->content = $content;
250 $object->localfiles = $basefiles;
251
252 return $object;
253}
254
255?>