fixed log action inserts
[moodle.git] / lib.php
CommitLineData
02039379
PS
1<?PHP // $Id: lib.php,v 1.1 2006/03/12 18:39:59 skodak Exp $
2
3define('NUM_NONE', '0');
4define('NUM_NUMBERS', '1');
5define('NUM_BULLETS', '2');
6define('NUM_INDENTED', '3');
7
8$NUMBERING_TYPE = array (NUM_NONE => get_string('numbering0', 'book'),
9 NUM_NUMBERS => get_string('numbering1', 'book'),
10 NUM_BULLETS => get_string('numbering2', 'book'),
11 NUM_INDENTED => get_string('numbering3', 'book') );
12
13if (!isset($CFG->book_tocwidth)) {
14 set_config("book_tocwidth", 180); // default toc width
15}
16
17
18/// Library of functions and constants for module 'book'
19
20function book_add_instance($book) {
21/// Given an object containing all the necessary data,
22/// (defined by the form in mod.html) this function
23/// will create a new instance and return the id number
24/// of the new instance.
25
26 $book->timecreated = time();
27 $book->timemodified = $book->timecreated;
28
29 return insert_record('book', $book);
30}
31
32
33function book_update_instance($book) {
34/// Given an object containing all the necessary data,
35/// (defined by the form in mod.html) this function
36/// will update an existing instance with new data.
37
38 $book->timemodified = time();
39 $book->id = $book->instance;
40
41 # May have to add extra stuff in here #
42
43 return update_record('book', $book);
44}
45
46
47function book_delete_instance($id) {
48/// Given an ID of an instance of this module,
49/// this function will permanently delete the instance
50/// and any data that depends on it.
51
52 if (! $book = get_record('book', 'id', $id)) {
53 return false;
54 }
55
56 $result = true;
57
58 delete_records('book_chapters', 'bookid', $book->id);
59
60 if (! delete_records('book', 'id', $book->id)) {
61 $result = false;
62 }
63
64 return $result;
65}
66
67function book_user_outline($course, $user, $mod, $book) {
68/// Return a small object with summary information about what a
69/// user has done with a given particular instance of this module
70/// Used for user activity reports.
71/// $return->time = the time they did it
72/// $return->info = a short text description
73
74 $return = null;
75 return $return;
76}
77
78function book_user_complete($course, $user, $mod, $book) {
79/// Print a detailed representation of what a user has done with
80/// a given particular instance of this module, for user activity reports.
81
82 return true;
83}
84
85function book_print_recent_activity($course, $isteacher, $timestart) {
86/// Given a course and a time, this module should find recent activity
87/// that has occurred in book activities and print it out.
88/// Return true if there was output, or false is there was none.
89
90 global $CFG;
91
92 return false; // True if anything was printed, otherwise false
93}
94
95function book_cron () {
96/// Function to be run periodically according to the moodle cron
97/// This function searches for things that need to be done, such
98/// as sending out mail, toggling flags etc ...
99
100 global $CFG;
101
102 return true;
103}
104
105function book_grades($bookid) {
106/// Must return an array of grades for a given instance of this module,
107/// indexed by user. It also returns a maximum allowed grade.
108
109 return NULL;
110}
111
112function book_get_participants($bookid) {
113//Must return an array of user records (all data) who are participants
114//for a given instance of book. Must include every user involved
115//in the instance, independient of his role (student, teacher, admin...)
116//See other modules as example.
117
118 return false;
119}
120
121function book_scale_used ($bookid,$scaleid) {
122//This function returns if a scale is being used by one book
123//it it has support for grading and scales. Commented code should be
124//modified if necessary. See forum, glossary or journal modules
125//as reference.
126
127 $return = false;
128
129 //$rec = get_record('book','id',$bookid,'scale',"-$scaleid");
130 //
131 //if (!empty($rec) && !empty($scaleid)) {
132 // $return = true;
133 //}
134
135 return $return;
136}
137
138//////////////////////////////////////////////////////////////////////////////////////
139/// Any other book functions go here. Each of them must have a name that
140/// starts with book_
141
142//check chapter ordering and
143//make sure subchapter is not first in book
144//hidden chapter must have all subchapters hidden too
145function book_check_structure($bookid) {
146 if ($chapters = get_records('book_chapters', 'bookid', $bookid, 'pagenum', 'id, pagenum, subchapter, hidden')) {
147 $first = true;
148 $hidesub = true;
149 $i = 1;
150 foreach($chapters as $ch) {
151 if ($first and $ch->subchapter) {
152 $ch->subchapter = 0;
153 }
154 $first = false;
155 if (!$ch->subchapter) {
156 $hidesub = $ch->hidden;
157 } else {
158 $ch->hidden = $hidesub ? true : $ch->hidden;
159 }
160 $ch->pagenum = $i;
161 update_record('book_chapters', $ch);
162 $i++;
163 }
164 }
165}
166
167
168/// prepare button to turn chapter editing on - connected with course editing
169function book_edit_button($id, $courseid, $chapterid) {
170 global $CFG, $USER;
171
172
173 if (isteacheredit($courseid)) {
174 if (!empty($USER->editing)) {
175 $string = get_string("turneditingoff");
176 $edit = '0';
177 } else {
178 $string = get_string("turneditingon");
179 $edit = '1';
180 }
181 return '<form target="'.$CFG->framename.'" method="get" action="'.$CFG->wwwroot.'/mod/book/view.php">'.
182 '<input type="hidden" name="id" value="'.$id.'" />'.
183 '<input type="hidden" name="chapterid" value="'.$chapterid.'" />'.
184 '<input type="hidden" name="edit" value="'.$edit.'" />'.
185 '<input type="submit" value="'.$string.'" /></form>';
186 } else {
187 return '';
188 }
189}
190
191/// general function for logging to table
192function book_log($str1, $str2, $level = 0) {
193 switch ($level) {
194 case 1:
195 echo '<tr><td><span class="dimmed_text">'.$str1.'</span></td><td><span class="dimmed_text">'.$str2.'</span></td></tr>';
196 break;
197 case 2:
198 echo '<tr><td><span style="color: rgb(255, 0, 0);">'.$str1.'</span></td><td><span style="color: rgb(255, 0, 0);">'.$str2.'</span></td></tr>';
199 break;
200 default:
201 echo '<tr><td>'.$str1.'</class></td><td>'.$str2.'</td></tr>';
202 break;
203 }
204}
205
206//=================================================
207// import functions
208//=================================================
209
210/// normalize relative links (= remove ..)
211function book_prepare_link($ref) {
212 if ($ref == '') {
213 return '';
214 }
215 $ref = str_replace('\\','/',$ref); //anti MS hack
216 $cnt = substr_count($ref, '..');
217 for($i=0; $i<$cnt; $i++) {
218 $ref = ereg_replace('[^/]+/\.\./', '', $ref);
219 }
220 //still any '..' left?? == error! error!
221 if (substr_count($ref, '..') > 0) {
222 return '';
223 }
224 if (ereg('[\|\`]', $ref)) { // check for other bad characters
225 return '';
226 }
227 return $ref;
228}
229
230/// read chapter content from file
231function book_read_chapter($base, $ref) {
232 $file = $base.'/'.$ref;
233 if (filesize($file) <= 0 or !is_readable($file)) {
234 book_log($ref, get_string('error'), 2);
235 return;
236 }
237 //first read data
238 $handle = fopen($file, "rb");
239 $contents = fread($handle, filesize($file));
240 fclose($handle);
241 //extract title
242 if (preg_match('/<title>([^<]+)<\/title>/i', $contents, $matches)) {
243 $chapter->title = $matches[1];
244 } else {
245 $chapter->title = $ref;
246 }
247 //extract page body
248 if (preg_match('/<body[^>]*>(.+)<\/body>/is', $contents, $matches)) {
249 $chapter->content = $matches[1];
250 } else {
251 book_log($ref, get_string('error'), 2);
252 return;
253 }
254 book_log($ref, get_string('ok'));
255 $chapter->importsrc = $ref;
256 //extract page head
257 if (preg_match('/<head[^>]*>(.+)<\/head>/is', $contents, $matches)) {
258 $head = $matches[1];
259 if (preg_match('/charset=([^"]+)/is', $head, $matches)) {
260 $enc = $matches[1];
261 $textlib = textlib_get_instance();
262 $chapter->content = $textlib->convert($chapter->content, $enc, current_charset());
263 $chapter->title = $textlib->convert($chapter->title, $enc, current_charset());
264 }
265 if (preg_match_all('/<link[^>]+rel="stylesheet"[^>]*>/i', $head, $matches)) { //dlnsk extract links to css
266 for($i=0; $i<count($matches[0]); $i++){
267 $chapter->content = $matches[0][$i]."\n".$chapter->content;
268 }
269 }
270 }
271 return $chapter;
272}
273
274///relink images and relative links
275function book_relink($id, $bookid, $courseid) {
276 global $CFG;
277 if ($CFG->slasharguments) {
278 $coursebase = $CFG->wwwroot.'/file.php/'.$courseid;
279 } else {
280 $coursebase = $CFG->wwwroot.'/file.php?file=/'.$courseid;
281 }
282 $chapters = get_records('book_chapters', 'bookid', $bookid, 'pagenum', 'id, pagenum, title, content, importsrc');
283 $originals = array();
284 foreach($chapters as $ch) {
285 $originals[$ch->importsrc] = $ch;
286 }
287 foreach($chapters as $ch) {
288 $rel = substr($ch->importsrc, 0, strrpos($ch->importsrc, '/')+1);
289 $base = $coursebase.strtr(urlencode($rel), array("%2F" => "/")); //for better internationalization (dlnsk)
290 $modified = false;
291 //image relinking
292 if ($ch->importsrc && preg_match_all('/(<img[^>]+src=")([^"]+)("[^>]*>)/i', $ch->content, $images)) {
293 for($i = 0; $i<count($images[0]); $i++) {
294 if (!preg_match('/[a-z]+:/i', $images[2][$i])) { // not absolute link
295 $link = book_prepare_link($base.$images[2][$i]);
296 if ($link == '') {
297 continue;
298 }
299 $origtag = $images[0][$i];
300 $newtag = $images[1][$i].$link.$images[3][$i];
301 $ch->content = str_replace($origtag, $newtag, $ch->content);
302 $modified = true;
303 book_log($ch->title, $images[2][$i].' --> '.$link);
304 }
305 }
306 }
307 //css relinking (dlnsk)
308 if ($ch->importsrc && preg_match_all('/(<link[^>]+href=")([^"]+)("[^>]*>)/i', $ch->content, $csslinks)) {
309 for($i = 0; $i<count($csslinks[0]); $i++) {
310 if (!preg_match('/[a-z]+:/i', $csslinks[2][$i])) { // not absolute link
311 $link = book_prepare_link($base.$csslinks[2][$i]);
312 if ($link == '') {
313 continue;
314 }
315 $origtag = $csslinks[0][$i];
316 $newtag = $csslinks[1][$i].$link.$csslinks[3][$i];
317 $ch->content = str_replace($origtag, $newtag, $ch->content);
318 $modified = true;
319 book_log($ch->title, $csslinks[2][$i].' --> '.$link);
320 }
321 }
322 }
323 //general embed relinking - flash and others??
324 if ($ch->importsrc && preg_match_all('/(<embed[^>]+src=")([^"]+)("[^>]*>)/i', $ch->content, $embeds)) {
325 for($i = 0; $i<count($embeds[0]); $i++) {
326 if (!preg_match('/[a-z]+:/i', $embeds[2][$i])) { // not absolute link
327 $link = book_prepare_link($base.$embeds[2][$i]);
328 if ($link == '') {
329 continue;
330 }
331 $origtag = $embeds[0][$i];
332 $newtag = $embeds[1][$i].$link.$embeds[3][$i];
333 $ch->content = str_replace($origtag, $newtag, $ch->content);
334 $modified = true;
335 book_log($ch->title, $embeds[2][$i].' --> '.$link);
336 }
337 }
338 }
339 //flash in IE <param name=movie value="something" - I do hate IE!
340 if ($ch->importsrc && preg_match_all('/<param[^>]+name\s*=\s*"?movie"?[^>]*>/i', $ch->content, $params)) {
341 for($i = 0; $i<count($params[0]); $i++) {
342 if (preg_match('/(value=\s*")([^"]+)(")/i', $params[0][$i], $values)) {
343 if (!preg_match('/[a-z]+:/i', $values[2])) { // not absolute link
344 $link = book_prepare_link($base.$values[2]);
345 if ($link == '') {
346 continue;
347 }
348 $newvalue = $values[1].$link.$values[3];
349 $newparam = str_replace($values[0], $newvalue, $params[0][$i]);
350 $ch->content = str_replace($params[0][$i], $newparam, $ch->content);
351 $modified = true;
352 book_log($ch->title, $values[2].' --> '.$link);
353 }
354 }
355 }
356 }
357 //java applet - add code bases if not present!!!!
358 if ($ch->importsrc && preg_match_all('/<applet[^>]*>/i', $ch->content, $applets)) {
359 for($i = 0; $i<count($applets[0]); $i++) {
360 if (!stripos($applets[0][$i], 'codebase')) {
361 $newapplet = str_ireplace('<applet', '<applet codebase="."', $applets[0][$i]);
362 $ch->content = str_replace($applets[0][$i], $newapplet, $ch->content);
363 $modified = true;
364 }
365 }
366 }
367 //relink java applet code bases
368 if ($ch->importsrc && preg_match_all('/(<applet[^>]+codebase=")([^"]+)("[^>]*>)/i', $ch->content, $codebases)) {
369 for($i = 0; $i<count($codebases[0]); $i++) {
370 if (!preg_match('/[a-z]+:/i', $codebases[2][$i])) { // not absolute link
371 $link = book_prepare_link($base.$codebases[2][$i]);
372 if ($link == '') {
373 continue;
374 }
375 $origtag = $codebases[0][$i];
376 $newtag = $codebases[1][$i].$link.$codebases[3][$i];
377 $ch->content = str_replace($origtag, $newtag, $ch->content);
378 $modified = true;
379 book_log($ch->title, $codebases[2][$i].' --> '.$link);
380 }
381 }
382 }
383 //relative link conversion
384 if ($ch->importsrc && preg_match_all('/(<a[^>]+href=")([^"^#]*)(#[^"]*)?("[^>]*>)/i', $ch->content, $links)) {
385 for($i = 0; $i<count($links[0]); $i++) {
386 if ($links[2][$i] != '' //check for inner anchor links
387 && !preg_match('/[a-z]+:/i', $links[2][$i])) { //not absolute link
388 $origtag = $links[0][$i];
389 $target = book_prepare_link($rel.$links[2][$i]); //target chapter
390 if ($target != '' && array_key_exists($target, $originals)) {
391 $o = $originals[$target];
392 $newtag = $links[1][$i].$CFG->wwwroot.'/mod/book/view.php?id='.$id.'&chapterid='.$o->id.$links[3][$i].$links[4][$i];
393 $newtag = preg_replace('/target=[^\s>]/i','', $newtag);
394 $ch->content = str_replace($origtag, $newtag, $ch->content);
395 $modified = true;
396 book_log($ch->title, $links[2][$i].$links[3][$i].' --> '.$CFG->wwwroot.'/mod/book/view.php?id='.$id.'&chapterid='.$o->id.$links[3][$i]);
397 } else if ($target!='' && (!preg_match('/\.html$|\.htm$/i', $links[2][$i]))) { // other relative non html links converted to download links
398 $target = book_prepare_link($base.$links[2][$i]);
399 $origtag = $links[0][$i];
400 $newtag = $links[1][$i].$target.$links[4][$i];
401 $ch->content = str_replace($origtag, $newtag, $ch->content);
402 $modified = true;
403 book_log($ch->title, $links[2][$i].' --> '.$target);
404 }
405 }
406 }
407 }
408 if ($modified) {
409 $ch->title = addslashes($ch->title);
410 $ch->content = addslashes($ch->content);
411 $ch->importsrc = addslashes($ch->importsrc);
412 if (!update_record('book_chapters', $ch)) {
413 error('Could not update your book');
414 }
415 }
416 }
417}
418
419?>