df28d6c5 |
1 | <?PHP // $Id$ |
2 | |
3 | /// FUNCTIONS FOR DATABASE HANDLING //////////////////////////////// |
4 | |
5 | function execute_sql($command, $feedback=true) { |
6 | /// Completely general function - it just runs some SQL and reports success. |
7 | |
8 | global $db; |
9 | |
10 | $result = $db->Execute("$command"); |
11 | |
12 | if ($result) { |
13 | if ($feedback) { |
14 | echo "<P><FONT COLOR=green><B>".get_string("success")."</B></FONT></P>"; |
15 | } |
16 | return true; |
17 | } else { |
18 | if ($feedback) { |
19 | echo "<P><FONT COLOR=red><B>".get_string("error")."</B></FONT></P>"; |
20 | } |
21 | return false; |
22 | } |
23 | } |
24 | |
25 | function modify_database($sqlfile) { |
26 | /// Assumes that the input text file consists of a number |
27 | /// of SQL statements ENDING WITH SEMICOLONS. The semicolons |
28 | /// MUST be the last character in a line. |
29 | /// Lines that are blank or that start with "#" are ignored. |
30 | /// Only tested with mysql dump files (mysqldump -p -d moodle) |
31 | |
32 | global $CFG; |
33 | |
34 | if (file_exists($sqlfile)) { |
35 | $success = true; |
36 | $lines = file($sqlfile); |
37 | $command = ""; |
38 | |
39 | while ( list($i, $line) = each($lines) ) { |
40 | $line = chop($line); |
41 | $length = strlen($line); |
42 | |
43 | if ($length && substr($line, 0, 1) <> "#") { |
44 | if (substr($line, $length-1, 1) == ";") { |
45 | $line = substr($line, 0, $length-1); // strip ; |
46 | $command .= $line; |
47 | $command = str_replace("prefix_", $CFG->prefix, $command); // Table prefixes |
48 | if (! execute_sql($command)) { |
49 | $success = false; |
50 | } |
51 | $command = ""; |
52 | } else { |
53 | $command .= $line; |
54 | } |
55 | } |
56 | } |
57 | |
58 | } else { |
59 | $success = false; |
60 | echo "<P>Tried to modify database, but \"$sqlfile\" doesn't exist!</P>"; |
61 | } |
62 | |
63 | return $success; |
64 | } |
65 | |
66 | |
67 | function record_exists($table, $field="", $value="", $field2="", $value2="", $field3="", $value3="") { |
68 | /// Returns true or false depending on whether the specified record exists |
69 | |
70 | global $CFG; |
71 | |
72 | if ($field and $value) { |
73 | $select = "WHERE $field = '$value'"; |
74 | if ($field2 and $value2) { |
75 | $select .= " AND $field2 = '$value2'"; |
76 | if ($field3 and $value3) { |
77 | $select .= " AND $field3 = '$value3'"; |
78 | } |
79 | } |
80 | } |
81 | |
82 | return record_exists_sql("SELECT * FROM $CFG->prefix$table $select LIMIT 1"); |
83 | } |
84 | |
85 | |
86 | function record_exists_sql($sql) { |
87 | /// Returns true or false depending on whether the specified record exists |
88 | /// The sql statement is provided as a string. |
89 | |
90 | global $db; |
91 | |
92 | $rs = $db->Execute($sql); |
93 | if (!$rs) return false; |
94 | |
95 | if ( $rs->RecordCount() ) { |
96 | return true; |
97 | } else { |
98 | return false; |
99 | } |
100 | } |
101 | |
102 | |
103 | function count_records($table, $field="", $value="", $field2="", $value2="", $field3="", $value3="") { |
104 | /// Get all the records and count them |
105 | |
106 | global $CFG; |
107 | |
108 | if ($field and $value) { |
109 | $select = "WHERE $field = '$value'"; |
110 | if ($field2 and $value2) { |
111 | $select .= " AND $field2 = '$value2'"; |
112 | if ($field3 and $value3) { |
113 | $select .= " AND $field3 = '$value3'"; |
114 | } |
115 | } |
116 | } |
117 | |
118 | return count_records_sql("SELECT COUNT(*) FROM $CFG->prefix$table $select"); |
119 | } |
120 | |
121 | function count_records_sql($sql) { |
122 | /// Get all the records and count them |
123 | /// The sql statement is provided as a string. |
124 | |
125 | global $db; |
126 | |
127 | $rs = $db->Execute("$sql"); |
128 | if (!$rs) return 0; |
129 | |
130 | return $rs->fields[0]; |
131 | } |
132 | |
133 | function get_record($table, $field, $value, $field2="", $value2="", $field3="", $value3="") { |
134 | /// Get a single record as an object |
135 | |
136 | global $CFG; |
137 | |
138 | $select = "WHERE $field = '$value'"; |
139 | |
140 | if ($field2 and $value2) { |
141 | $select .= " AND $field2 = '$value2'"; |
142 | if ($field3 and $value3) { |
143 | $select .= " AND $field3 = '$value3'"; |
144 | } |
145 | } |
146 | |
147 | return get_record_sql("SELECT * FROM $CFG->prefix$table $select"); |
148 | } |
149 | |
150 | function get_record_sql($sql) { |
151 | /// Get a single record as an object |
152 | /// The sql statement is provided as a string. |
153 | |
154 | global $db; |
155 | |
156 | $rs = $db->Execute("$sql"); |
157 | if (!$rs) return false; |
158 | |
159 | if ( $rs->RecordCount() == 1 ) { |
160 | return (object)$rs->fields; |
161 | } else { |
162 | return false; |
163 | } |
164 | } |
165 | |
166 | function get_records($table, $field="", $value="", $sort="", $fields="*") { |
167 | /// Get a number of records as an array of objects |
168 | /// Can optionally be sorted eg "time ASC" or "time DESC" |
169 | /// If "fields" is specified, only those fields are returned |
170 | /// The "key" is the first column returned, eg usually "id" |
171 | |
172 | global $CFG; |
173 | |
174 | if ($field and $value) { |
175 | $select = "WHERE $field = '$value'"; |
176 | } |
177 | if ($sort) { |
178 | $sortorder = "ORDER BY $sort"; |
179 | } |
180 | |
181 | return get_records_sql("SELECT $fields FROM $CFG->prefix$table $select $sortorder"); |
182 | } |
183 | |
184 | |
185 | function get_records_list($table, $field="", $values="", $sort="", $fields="*") { |
186 | // Get a number of records as an array of objects |
187 | // Differs from get_records() in that the values variable |
188 | // can be a comma-separated list of values eg "4,5,6,10" |
189 | // Can optionally be sorted eg "time ASC" or "time DESC" |
190 | // The "key" is the first column returned, eg usually "id" |
191 | |
192 | global $CFG; |
193 | |
194 | if ($field and $value) { |
195 | $select = "WHERE $field in ($values)"; |
196 | } |
197 | if ($sort) { |
198 | $sortorder = "ORDER BY $sort"; |
199 | } |
200 | |
201 | return get_records_sql("SELECT $fields FROM $CFG->prefix$table $select $sortorder"); |
202 | } |
203 | |
204 | |
205 | function get_records_sql($sql) { |
206 | // Get a number of records as an array of objects |
207 | // The "key" is the first column returned, eg usually "id" |
208 | // The sql statement is provided as a string. |
209 | |
210 | global $db; |
211 | |
212 | $rs = $db->Execute("$sql"); |
213 | if (!$rs) return false; |
214 | |
215 | if ( $rs->RecordCount() > 0 ) { |
216 | if ($records = $rs->GetAssoc(true)) { |
217 | foreach ($records as $key => $record) { |
218 | $objects[$key] = (object) $record; |
219 | } |
220 | return $objects; |
221 | } else { |
222 | return false; |
223 | } |
224 | } else { |
225 | return false; |
226 | } |
227 | } |
228 | |
229 | function get_records_sql_menu($sql) { |
230 | // Given an SQL select, this function returns an associative |
231 | // array of the first two columns. This is most useful in |
232 | // combination with the choose_from_menu function to create |
233 | // a form menu. |
234 | |
235 | global $db; |
236 | |
237 | $rs = $db->Execute("$sql"); |
238 | if (!$rs) return false; |
239 | |
240 | if ( $rs->RecordCount() > 0 ) { |
241 | while (!$rs->EOF) { |
242 | $menu[$rs->fields[0]] = $rs->fields[1]; |
243 | $rs->MoveNext(); |
244 | } |
245 | return $menu; |
246 | |
247 | } else { |
248 | return false; |
249 | } |
250 | } |
251 | |
252 | function get_field($table, $return, $field, $value) { |
253 | /// Get a single field from a database record |
254 | |
255 | global $db, $CFG; |
256 | |
257 | $rs = $db->Execute("SELECT $return FROM $CFG->prefix$table WHERE $field = '$value'"); |
258 | if (!$rs) return false; |
259 | |
260 | if ( $rs->RecordCount() == 1 ) { |
261 | return $rs->fields["$return"]; |
262 | } else { |
263 | return false; |
264 | } |
265 | } |
266 | |
267 | function set_field($table, $newfield, $newvalue, $field, $value) { |
268 | /// Set a single field in a database record |
269 | |
270 | global $db, $CFG; |
271 | |
272 | return $db->Execute("UPDATE $CFG->prefix$table SET $newfield = '$newvalue' WHERE $field = '$value'"); |
273 | } |
274 | |
275 | |
276 | function delete_records($table, $field="", $value="", $field2="", $value2="", $field3="", $value3="") { |
277 | /// Delete one or more records from a table |
278 | |
279 | global $db, $CFG; |
280 | |
281 | if ($field and $value) { |
282 | $select = "WHERE $field = '$value'"; |
283 | if ($field2 and $value2) { |
284 | $select .= " AND $field2 = '$value2'"; |
285 | if ($field3 and $value3) { |
286 | $select .= " AND $field3 = '$value3'"; |
287 | } |
288 | } |
289 | } |
290 | |
291 | return $db->Execute("DELETE FROM $CFG->prefix$table $select"); |
292 | } |
293 | |
294 | |
295 | function insert_record($table, $dataobject, $returnid=true) { |
296 | /// Insert a record into a table and return the "id" field if required |
297 | /// If the return ID isn't required, then this just reports success as true/false. |
298 | /// $dataobject is an object containing needed data |
299 | |
300 | global $db, $CFG; |
301 | |
302 | // Determine all the fields needed |
303 | if (! $columns = $db->MetaColumns("$CFG->prefix$table")) { |
304 | return false; |
305 | } |
306 | |
307 | $data = (array)$dataobject; |
308 | |
309 | // Pull out data matching these fields |
310 | foreach ($columns as $column) { |
311 | if ($column->name <> "id" && isset($data[$column->name]) ) { |
312 | $ddd[$column->name] = $data[$column->name]; |
313 | } |
314 | } |
315 | |
316 | // Construct SQL queries |
317 | if (! $numddd = count($ddd)) { |
318 | return false; |
319 | } |
320 | |
321 | $count = 0; |
322 | $inscolumns = ""; |
323 | $insvalues = ""; |
324 | $select = ""; |
325 | |
326 | foreach ($ddd as $key => $value) { |
327 | $count++; |
328 | $inscolumns .= "$key"; |
329 | $insvalues .= "'$value'"; |
330 | $select .= "$key = '$value'"; |
331 | if ($count < $numddd) { |
332 | $inscolumns .= ", "; |
333 | $insvalues .= ", "; |
334 | $select .= " AND "; |
335 | } |
336 | } |
337 | |
338 | if (! $rs = $db->Execute("INSERT INTO $CFG->prefix$table ($inscolumns) VALUES ($insvalues)")) { |
339 | return false; |
340 | } |
341 | |
342 | if ($returnid) { |
343 | // Pull it out again to find the id. This is the most cross-platform method. |
344 | if ($rs = $db->Execute("SELECT id FROM $CFG->prefix$table WHERE $select")) { |
345 | return $rs->fields[0]; |
346 | } else { |
347 | return false; |
348 | } |
349 | } else { |
350 | return true; |
351 | } |
352 | } |
353 | |
354 | |
355 | function update_record($table, $dataobject) { |
356 | /// Update a record in a table |
357 | /// $dataobject is an object containing needed data |
358 | |
359 | global $db, $CFG; |
360 | |
361 | if (! isset($dataobject->id) ) { |
362 | return false; |
363 | } |
364 | |
365 | // Determine all the fields in the table |
366 | if (!$columns = $db->MetaColumns("$CFG->prefix$table")) { |
367 | return false; |
368 | } |
369 | $data = (array)$dataobject; |
370 | |
371 | // Pull out data matching these fields |
372 | foreach ($columns as $column) { |
373 | if ($column->name <> "id" && isset($data[$column->name]) ) { |
374 | $ddd[$column->name] = $data[$column->name]; |
375 | } |
376 | } |
377 | |
378 | // Construct SQL queries |
379 | $numddd = count($ddd); |
380 | $count = 0; |
381 | $update = ""; |
382 | |
383 | foreach ($ddd as $key => $value) { |
384 | $count++; |
385 | $update .= "$key = '$value'"; |
386 | if ($count < $numddd) { |
387 | $update .= ", "; |
388 | } |
389 | } |
390 | |
391 | if ($rs = $db->Execute("UPDATE $CFG->prefix$table SET $update WHERE id = '$dataobject->id'")) { |
392 | return true; |
393 | } else { |
394 | return false; |
395 | } |
396 | } |
397 | |
398 | |
399 | function print_object($object) { |
400 | /// Mostly just for debugging |
401 | |
402 | $array = (array)$object; |
403 | foreach ($array as $key => $item) { |
404 | echo "$key -> $item <BR>"; |
405 | } |
406 | } |
407 | |
408 | |
409 | |
410 | |
411 | /// USER DATABASE //////////////////////////////////////////////// |
412 | |
413 | function get_user_info_from_db($field, $value) { |
414 | /// Get a complete user record, which includes all the info |
415 | /// in the user record, as well as membership information |
416 | /// Suitable for setting as $USER session cookie. |
417 | |
418 | global $db, $CFG; |
419 | |
420 | if (!$field || !$value) |
421 | return false; |
422 | |
423 | if (! $result = $db->Execute("SELECT * FROM {$CFG->prefix}user WHERE $field = '$value' AND deleted <> '1'")) { |
424 | error("Could not find any active users!"); |
425 | } |
426 | |
427 | if ( $result->RecordCount() == 1 ) { |
428 | $user = (object)$result->fields; |
429 | |
430 | $rs = $db->Execute("SELECT course FROM {$CFG->prefix}user_students WHERE user = '$user->id' "); |
431 | while (!$rs->EOF) { |
432 | $course = $rs->fields["course"]; |
433 | $user->student["$course"] = true; |
434 | $rs->MoveNext(); |
435 | } |
436 | |
437 | $rs = $db->Execute("SELECT course FROM {$CFG->prefix}user_teachers WHERE user = '$user->id' "); |
438 | while (!$rs->EOF) { |
439 | $course = $rs->fields["course"]; |
440 | $user->teacher["$course"] = true; |
441 | $rs->MoveNext(); |
442 | } |
443 | |
444 | $rs = $db->Execute("SELECT * FROM {$CFG->prefix}user_admins WHERE user = '$user->id' "); |
445 | while (!$rs->EOF) { |
446 | $user->admin = true; |
447 | $rs->MoveNext(); |
448 | } |
449 | |
450 | if ($course = get_site()) { |
451 | // Everyone is always a member of the top course |
452 | $user->student["$course->id"] = true; |
453 | } |
454 | |
455 | return $user; |
456 | |
457 | } else { |
458 | return false; |
459 | } |
460 | } |
461 | |
462 | function update_user_in_db() { |
463 | /// Updates user record to record their last access |
464 | |
465 | global $db, $USER, $REMOTE_ADDR, $CFG; |
466 | |
467 | if (!isset($USER->id)) |
468 | return false; |
469 | |
470 | $timenow = time(); |
471 | if ($db->Execute("UPDATE {$CFG->prefix}user SET lastIP='$REMOTE_ADDR', lastaccess='$timenow' |
472 | WHERE id = '$USER->id' ")) { |
473 | return true; |
474 | } else { |
475 | return false; |
476 | } |
477 | } |
478 | |
479 | |
480 | function adminlogin($username, $md5password) { |
481 | /// Does this username and password specify a valid admin user? |
482 | |
483 | global $CFG; |
484 | |
485 | return record_exists_sql("SELECT u.id FROM {$CFG->prefix}user u, {$CFG->prefix}user_admins a |
486 | WHERE u.id = a.user |
487 | AND u.username = '$username' |
488 | AND u.password = '$md5password'"); |
489 | } |
490 | |
491 | |
492 | function get_site () { |
493 | /// Returns $course object of the top-level site. |
494 | |
495 | if ( $course = get_record("course", "category", 0)) { |
496 | return $course; |
497 | } else { |
498 | return false; |
499 | } |
500 | } |
501 | |
502 | function get_admin () { |
503 | /// Returns $user object of the main admin user |
504 | |
505 | global $CFG; |
506 | |
507 | if ( $admins = get_admins() ) { |
508 | foreach ($admins as $admin) { |
509 | return $admin; // ie the first one |
510 | } |
511 | } else { |
512 | return false; |
513 | } |
514 | } |
515 | |
516 | function get_admins() { |
517 | /// Returns list of all admins |
518 | |
519 | global $CFG; |
520 | |
521 | return get_records_sql("SELECT u.* FROM {$CFG->prefix}user u, {$CFG->prefix}user_admins a |
522 | WHERE a.user = u.id |
523 | ORDER BY u.id ASC"); |
524 | } |
525 | |
526 | |
527 | function get_teacher($courseid) { |
528 | /// Returns $user object of the main teacher for a course |
529 | |
530 | global $CFG; |
531 | |
532 | if ( $teachers = get_course_teachers($courseid, "t.authority ASC")) { |
533 | foreach ($teachers as $teacher) { |
534 | if ($teacher->authority) { |
535 | return $teacher; // the highest authority teacher |
536 | } |
537 | } |
538 | } else { |
539 | return false; |
540 | } |
541 | } |
542 | |
543 | function get_course_students($courseid, $sort="u.lastaccess DESC") { |
544 | /// Returns list of all students in this course |
545 | |
546 | global $CFG; |
547 | |
548 | return get_records_sql("SELECT u.* FROM {$CFG->prefix}user u, {$CFG->prefix}user_students s |
549 | WHERE s.course = '$courseid' AND s.user = u.id AND u.deleted = '0' |
550 | ORDER BY $sort"); |
551 | } |
552 | |
553 | function get_course_teachers($courseid, $sort="t.authority ASC") { |
554 | /// Returns list of all teachers in this course |
555 | |
556 | global $CFG; |
557 | |
558 | return get_records_sql("SELECT u.*,t.authority,t.role FROM {$CFG->prefix}user u, {$CFG->prefix}user_teachers t |
559 | WHERE t.course = '$courseid' AND t.user = u.id AND u.deleted = '0' |
560 | ORDER BY $sort"); |
561 | } |
562 | |
563 | function get_course_users($courseid, $sort="u.lastaccess DESC") { |
564 | /// Using this method because the direct SQL just would not always work! |
565 | |
566 | $teachers = get_course_teachers($courseid, $sort); |
567 | $students = get_course_students($courseid, $sort); |
568 | |
569 | if ($teachers and $students) { |
570 | return array_merge($teachers, $students); |
571 | } else if ($teachers) { |
572 | return $teachers; |
573 | } else { |
574 | return $students; |
575 | } |
576 | |
577 | /// return get_records_sql("SELECT u.* FROM user u, user_students s, user_teachers t |
578 | /// WHERE (s.course = '$courseid' AND s.user = u.id) OR |
579 | /// (t.course = '$courseid' AND t.user = u.id) |
580 | /// ORDER BY $sort"); |
581 | } |
582 | |
583 | |
584 | |
585 | /// MODULE FUNCTIONS ///////////////////////////////////////////////// |
586 | |
587 | function get_coursemodule_from_instance($modulename, $instance, $courseid) { |
588 | /// Given an instance of a module, finds the coursemodule description |
589 | |
590 | global $CFG; |
591 | |
592 | return get_record_sql("SELECT cm.*, m.name |
593 | FROM {$CFG->prefix}course_modules cm, {$CFG->prefix}modules md, {$CFG->prefix}$modulename m |
594 | WHERE cm.course = '$courseid' AND |
595 | cm.deleted = '0' AND |
596 | cm.instance = m.id AND |
597 | md.name = '$modulename' AND |
598 | md.id = cm.module AND |
599 | m.id = '$instance'"); |
600 | |
601 | } |
602 | |
603 | function get_all_instances_in_course($modulename, $courseid, $sort="cw.section") { |
604 | /// Returns an array of all the active instances of a particular |
605 | /// module in a given course. Returns false on any errors. |
606 | |
607 | global $CFG; |
608 | |
609 | return get_records_sql("SELECT m.*,cw.section,cm.id as coursemodule |
610 | FROM {$CFG->prefix}course_modules cm, {$CFG->prefix}course_sections cw, |
611 | {$CFG->prefix}modules md, {$CFG->prefix}$modulename m |
612 | WHERE cm.course = '$courseid' AND |
613 | cm.instance = m.id AND |
614 | cm.deleted = '0' AND |
615 | cm.section = cw.id AND |
616 | md.name = '$modulename' AND |
617 | md.id = cm.module |
618 | ORDER BY $sort"); |
619 | |
620 | } |
621 | |
622 | ?> |